Re: [PATCH 1/2] Input: synaptics-rmi4 - clear irqs before set irqs

2019-06-03 Thread Christopher Heiny
On Tue, 2019-06-04 at 10:45 +0800, Aaron Ma wrote:
> Hi Christopher:
> 
> Have got time to review these 2 patches?
> Users reported it works fine since I sent out this patch.

Hi Aaron,

I've been poking around with this off and on.  Unfortunately, more off
than on :-( but here's my current take:

rmi_driver_set_irq_bits() isn't going to be called all that often, and
it's not going to be called at all during normal operation, which is
where the most serious problem would occur.

I haven't entirely convinced myself that there couldn't be a problem
during repeated spontaneous device resets (for example, due to ESD, a
dodgy charger, or firmware bug, among other things).  On the other
hand, all the scenarios I have come up with are both unlikely and so
contrived that the system is probably hosed regardless of what we do in
the driver.

Given that, I'm willing to accept the patch as is.

Cheers,
Chris







> 
> Thanks,
> Aaron
> 
> On 4/3/19 9:58 PM, Aaron Ma wrote:
> > Sure, take your time, if you have any questions let me know please.
> > 
> > Thanks,
> > Aaron




Re: [PATCH 1/2] Input: synaptics-rmi4 - clear irqs before set irqs

2019-04-02 Thread Christopher Heiny
On Thu, 2019-03-28 at 14:02 +0800, Aaron Ma wrote:
> Hi Dmitry and Chiristopher:
> 
> Do you have any suggestion about these 2 patches?
> 
> Many users confirmed that they fixed issues of Trackpoint/Touchpad
> after S3.
> 
> Will you consider them be accepted?

Hi Aaron,

Sorry - I thought I'd replied on the NO SLEEP portion of these patches,
but looking back I don't find the draft or the sent email.  Sorry about
that.  I'll summarize here what I wrote last month.

This isn't so much a "fix" as a "hacky workaround" for the issue.  From
the descriptions in the bug you linked in your original patch
submission, it appears that the root cause is somewhere in SMBus system
(could be SMBus driver, SMBus hardware, or the devices on the SMBus
(touch devices or other devices) - it's hard to tell with the info
available), where the SMBus is failing to come online correctly coming
out of S3 state.  Anyway, this patch doesn't fix the root cause, but
merely works around it.

Setting the NO SLEEP bit will force the touch sensor to remain in a
high power consumption state while the rest of the system is in S3. 
While not a lot of power compared to things like the CPU, display, and
others, it is still non-trivial and will result in shorter time-on-
battery capability.

If you have access to the power pin(s) for the touch sensor(s)/styk(s),
it might be interesting to try turning power off on entering S3, and
restoring it on exit.  That's very hacky, and has the side effect of
slightly delaying touchpad readiness on exit from S3.  Plus you'll need
to restore touch sensor configuration settings on exit.  But it
definitely reduces power consumption.


Separately, I am still concerned about the possibility of dropped touch
events in the IRQ clearing.  I'm not convinced that the code is safe
(as you mentioned in your reply to my earlier comment), so I'll have to
study the implementation more carefully.

Cheers,
Chris



> 
> Thanks,
> Aaron




Re: [PATCH 1/2] Input: synaptics-rmi4 - clear irqs before set irqs

2019-03-08 Thread Christopher Heiny
On Wed, 2019-02-20 at 17:41 +0100, Aaron Ma wrote:
> CAUTION: Email originated externally, do not click links or open
> attachments unless you recognize the sender and know the content is
> safe.
> 
> 
> rmi4 got spam data after S3 resume on some ThinkPads.
> Then TrackPoint lost when be detected by psmouse.
> Clear irqs status before set irqs will make TrackPoint back.
> 
> BugLink: 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.launchpad.net_bugs_1791427=DwIBAg=7dfBJ8cXbWjhc0BhImu8wQ=veOxv1_7HLXIaWG-OKLqp-qvZc3r7ucT1d-68JSWqpM=3nNm4ob6G1wtf502YFuxorJVkSQvdBasje2RrZLxhTM=Z0nHSPAKhQLzdoENAZBYuDC6QmZNOliyiE7h1OOVkBA=
> Cc: 
> Signed-off-by: Aaron Ma 
> ---
>  drivers/input/rmi4/rmi_driver.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/input/rmi4/rmi_driver.c
> b/drivers/input/rmi4/rmi_driver.c
> index fc3ab93b7aea..20631b272f43 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -374,6 +374,17 @@ static int rmi_driver_set_irq_bits(struct
> rmi_device *rmi_dev,
> struct device *dev = _dev->dev;
> 
> mutex_lock(>irq_mutex);
> +
> +   /* Dummy read in order to clear irqs */
> +   error = rmi_read_block(rmi_dev,
> +   data->f01_container->fd.data_base_addr + 1,
> +   data->irq_status, data->num_of_irq_regs);
> +   if (error < 0) {
> +   dev_err(dev, "%s: Failed to read interrupt status!",
> +   __func__);
> +   goto error_unlock;
> +   }
> +
> bitmap_or(data->new_irq_mask,
>   data->current_irq_mask, mask, data->irq_count);
> 
> --
> 2.17.1
> 

Sorry for the long delay in following up on this.

I'm not sure this is a safe action, due to a race condition with the
actual IRQ handler (rmi_process_interrupt_requests from rmi_driver.c). 
Remember that reading the IRQ status register clears all the IRQ bits. 
So you're faced with this possible scenario:
- ATTN asserted, indicating new data in IRQ status register
- rmi_driver_set_irq_bits called
- rmi_driver_set_irq_bits reads IRQ status, clearing bits
- rmi_process_interrupt_requests called
- rmi_process_interrupt_request reads IRQ status, sees no
  bits set, nested IRQs are not handled
This could lead to loss of data or inconsistent system state
information.  For example, a button up or down event may be lost, with
consequent weird behavior by the user interface.

CAVEAT: I haven't had much to do with the RMI4 driver for a long while,
and am just starting to poke around with it again.  I am not very
familiar with the current IRQ handling implementation.  Perhaps there
is a guarantee in the kernel IRQ mechanism that once ATTN is asserted,
then rmi_process_interrupt_requests will be called before anyone else
gets a chance to read the IRQ status register.  If that's the case, let
me know I'm worried about nothing, and ignore this comment.

Cheers,
Chris



Re: [PATCH] Input: synaptics-rmi4 - make F03 a tristate symbol

2017-01-11 Thread Christopher Heiny
On Wed, 2017-01-11 at 18:48 +0100, Benjamin Tissoires wrote:
> On Jan 11 2017 or thereabouts, Arnd Bergmann wrote:
> > 
> > On Wednesday, January 11, 2017 5:28:28 PM CET Benjamin Tissoires
> > wrote:
> > > 
> > > Yep, it was initially written that way, and IIRC there was some
> > > issues
> > > depending on how the drivers were compiled. For example, if
> > > rmi4_core is
> > > Y and some functions are m, you can't load the device initially,
> > > so you
> > > send a -EPROBE_DEFER, but how can you be sure that the function
> > > will
> > > ever be loaded?
> > 
> > I'm not sure if I understand your problem correctly, but normally
> > the way it's done is that the bus driver notifies user space that
> > a new device has appeared on the bus, and udev looks for the right
> > driver for the device, using a MODULE_DEVICE_TABLE list. Once the
> > driver gets loaded, it binds to the device.
> > 
> 
> I agree, but we never managed to make it properly working for RMI4.
> See
> https://lkml.org/lkml/2015/11/5/726 where we decided to switch to a
> static list of functions. Maybe we did not try hard enough, but we
> kept
> the current bus/functions_as_drivers to be able to switch back to the
> modular option,

Actually, long, long ago (well before I got yanked off the RMI4 driver
project for a 'short term emergency' two and a half years ago -
fortunately Andrew was more than able to take it over) it worked that
way.  If you had the bus, a physical driver, and the sensor driver
running, you could build the functions as modules and attach them via
udev or insert them later.

We had this working on the bench at one point, but fairly early in the
submission process seem to have just assumed it would keep working and
stopped regression testing on that feature.  There have been an whole
lot of changes since then, and somewhere along the line functions-as-
loadable-modules stopped working.  Since we weren't testing it anymore,
it wasn't caught.


> 
> > 
> > > 
> > > Given that we need to have all the functions loaded during probe,
> > > we
> > > decided to switch to a monolithic rmi4_core driver that has
> > > everything
> > > it needs inside.
> > 
> > If everything is in one module, you can probably get rid of at
> > least part of the bus abstraction as well and just call the
> > functions
> > directly.
> 
> Agree, though that means we won't be able to switch back. In the
> current
> form it's overly engineered.

Well, I'm not sure I agree with that. :-)  More on that later in this
email. 

> 
> > 
> > 
> > Looking through the driver some more, I also find the
> > 'rmi_driver rmi_physical_driver' concept very odd, you seem to
> > have a device on the bus that is actually just another
> > representation
> > of the parent device and that creates another set of devices for
> > the functions. Either I misunderstand what this is for, or you have
> 
> I think you have this right.
> 
> > 
> > a candidate for cleanup there and once you remove it (by calling
> > rmi_driver_probe() instead of rmi_register_transport_device()
> > to oversimplify the idea), the actual probing for the function
> > drivers becomes much easier to do right.
> > 
> 
> Agree, that would simplify the code a lot. I just don't know how
> important it is for other users of RMI4 to have a modular solution or
> if
> the monolithic approach is a consensus now. The modular solution is
> currently disabled, but we can "always" switch back with a small
> effort.
> 
> My opinion on this matter is that there is no need for the modular
> functions, but others might have a different opinion.

The primary impetus for the original modular function design was to
allow phone/tablet/etc manufacturers to write their own handlers for
some functions without having to write the entire driver or hack up an
existing monolithic driver.  This simplifies engineering for the device
manufacturer a lot.

We also hoped that other peripheral manufacturers would pick up RMI4
for other sorts of sensors and devices - it is an open standard after
all.  However, this didn't happen, possibly due to the complete lack of
promotion of RMI4 as a standard.

Modular functions were also intended to make it easier for community
OSes like AOKP or Paranoid Android to get up and running on products
where in order to fulfill their GPL obligations, the manufacturer
simply dumped a pile of sources, which might not actually be working.
 I'll grant that this could also be achieved with a monolithic driver. 

Several years ago, there also appeared to be a major trend toward
having two or more sensors in a given product, which was a lot easier
to manage with modular functions.  Although lots of prototypes were
built, very few went to production - maybe even none.

And finally, I wanted to enable a platform that was easy for Raspberry
Pi type tinkering with touch sensing functions - modular functions
isolated the parts of the RMI4 system, so the tinkerer need only learn
the parts they wanted to putter with.


Re: [PATCH] Input: synaptics-rmi4 - make F03 a tristate symbol

2017-01-11 Thread Christopher Heiny
On Wed, 2017-01-11 at 18:48 +0100, Benjamin Tissoires wrote:
> On Jan 11 2017 or thereabouts, Arnd Bergmann wrote:
> > 
> > On Wednesday, January 11, 2017 5:28:28 PM CET Benjamin Tissoires
> > wrote:
> > > 
> > > Yep, it was initially written that way, and IIRC there was some
> > > issues
> > > depending on how the drivers were compiled. For example, if
> > > rmi4_core is
> > > Y and some functions are m, you can't load the device initially,
> > > so you
> > > send a -EPROBE_DEFER, but how can you be sure that the function
> > > will
> > > ever be loaded?
> > 
> > I'm not sure if I understand your problem correctly, but normally
> > the way it's done is that the bus driver notifies user space that
> > a new device has appeared on the bus, and udev looks for the right
> > driver for the device, using a MODULE_DEVICE_TABLE list. Once the
> > driver gets loaded, it binds to the device.
> > 
> 
> I agree, but we never managed to make it properly working for RMI4.
> See
> https://lkml.org/lkml/2015/11/5/726 where we decided to switch to a
> static list of functions. Maybe we did not try hard enough, but we
> kept
> the current bus/functions_as_drivers to be able to switch back to the
> modular option,

Actually, long, long ago (well before I got yanked off the RMI4 driver
project for a 'short term emergency' two and a half years ago -
fortunately Andrew was more than able to take it over) it worked that
way.  If you had the bus, a physical driver, and the sensor driver
running, you could build the functions as modules and attach them via
udev or insert them later.

We had this working on the bench at one point, but fairly early in the
submission process seem to have just assumed it would keep working and
stopped regression testing on that feature.  There have been an whole
lot of changes since then, and somewhere along the line functions-as-
loadable-modules stopped working.  Since we weren't testing it anymore,
it wasn't caught.


> 
> > 
> > > 
> > > Given that we need to have all the functions loaded during probe,
> > > we
> > > decided to switch to a monolithic rmi4_core driver that has
> > > everything
> > > it needs inside.
> > 
> > If everything is in one module, you can probably get rid of at
> > least part of the bus abstraction as well and just call the
> > functions
> > directly.
> 
> Agree, though that means we won't be able to switch back. In the
> current
> form it's overly engineered.

Well, I'm not sure I agree with that. :-)  More on that later in this
email. 

> 
> > 
> > 
> > Looking through the driver some more, I also find the
> > 'rmi_driver rmi_physical_driver' concept very odd, you seem to
> > have a device on the bus that is actually just another
> > representation
> > of the parent device and that creates another set of devices for
> > the functions. Either I misunderstand what this is for, or you have
> 
> I think you have this right.
> 
> > 
> > a candidate for cleanup there and once you remove it (by calling
> > rmi_driver_probe() instead of rmi_register_transport_device()
> > to oversimplify the idea), the actual probing for the function
> > drivers becomes much easier to do right.
> > 
> 
> Agree, that would simplify the code a lot. I just don't know how
> important it is for other users of RMI4 to have a modular solution or
> if
> the monolithic approach is a consensus now. The modular solution is
> currently disabled, but we can "always" switch back with a small
> effort.
> 
> My opinion on this matter is that there is no need for the modular
> functions, but others might have a different opinion.

The primary impetus for the original modular function design was to
allow phone/tablet/etc manufacturers to write their own handlers for
some functions without having to write the entire driver or hack up an
existing monolithic driver.  This simplifies engineering for the device
manufacturer a lot.

We also hoped that other peripheral manufacturers would pick up RMI4
for other sorts of sensors and devices - it is an open standard after
all.  However, this didn't happen, possibly due to the complete lack of
promotion of RMI4 as a standard.

Modular functions were also intended to make it easier for community
OSes like AOKP or Paranoid Android to get up and running on products
where in order to fulfill their GPL obligations, the manufacturer
simply dumped a pile of sources, which might not actually be working.
 I'll grant that this could also be achieved with a monolithic driver. 

Several years ago, there also appeared to be a major trend toward
having two or more sensors in a given product, which was a lot easier
to manage with modular functions.  Although lots of prototypes were
built, very few went to production - maybe even none.

And finally, I wanted to enable a platform that was easy for Raspberry
Pi type tinkering with touch sensing functions - modular functions
isolated the parts of the RMI4 system, so the tinkerer need only learn
the parts they wanted to putter with.


Re: [-next, 1/2] Input: synaptics-rmi4 - add support for F55 sensor tuning

2016-10-21 Thread Christopher Heiny
On Thu, 2016-10-20 at 16:31 -0700, Chris Healy wrote:
> As a little background, in the case Nick is referring to with the
> S7813, it was actually with a stock Synaptics Eval Board and stock
> Firmware provided by Synaptics.
> 
> Not sure if that is relevant or not.

Yes, it's quite relevant - thanks for the info!

I've checked with the firmware team and the QA team.  This definitely
appears to be a f/w misconfiguration that escaped the QA process.  QA
is updating their flow to check for this, and FW is looking into how it
happened.

In addition to the workaround I mentioned earlier, another possibility
would be to produce a fixed, spec-compliant firmware image and flash it
onto your S7813.  However, that doesn't eliminate the issue that there
might have been other QA escapes that would need to be handled (should
they arise).

Chris

> 
> On Thu, Oct 20, 2016 at 4:28 PM, Christopher Heiny <cheiny@synaptics.
> com> wrote:
> > On Thu, 2016-10-20 at 23:51 +0100, Nick Dyer wrote:
> > > On Mon, Oct 17, 2016 at 02:30:08PM -0700, Guenter Roeck wrote:
> > > >
> > > > On Fri, Sep 30, 2016 at 08:22:47PM -0700, Guenter Roeck wrote:
> > > > >
> > > > > Sensor tuning support is needed to determine the number of
> > > > > enabled
> > > > > tx and rx electrodes for use in F54 functions.
> > > > >
> > > > > The number of enabled electrodes is not identical to the
> > total
> > > > > number
> > > > > of electrodes as reported with F55:Query0 and F55:Query1. It
> > has
> > > > > to be
> > > > > calculated by analyzing F55:Ctrl1 (sensor receiver
> > assignment)
> > > > > and
> > > > > F55:Ctrl2 (sensor transmitter assignment).
> > > > >
> > > > > Support for additional sensor tuning functions may be added
> > > > > later.
> > > > >
> > > > > Signed-off-by: Guenter Roeck <li...@roeck-us.net>
> > > >
> > > > Ping ... any comments on this patch and on
> > > > https://patchwork.kernel.org/patch/9359061/ ?
> > > >
> > > > Both patches now apply to mainline.
> > > >
> > > > Thanks,
> > > > Guenter
> > >
> > > Hi Guenter-
> > >
> > > I've reviewed and tested (on S7300 and S7813) both these patches
> > now
> > > - you can add my sign-off.
> > >
> > > However, on the S7813 firmware, F55 is on PDT page 3, and nothing
> > > on page 2, so the default behaviour of the mainline driver means
> > it
> > > is
> > > not initialised.
> > >
> > > So I think we need to revert this change in mainline:
> > > https://patchwork.kernel.org/patch/3796971/
> > >
> > > See below the PDT scan with it reverted and some debug added.
> > >
> > > Christopher/Andrew: is there a better heuristic than scanning all
> > 255
> > > pages, given that some firmwares contain gaps?
> > 
> > It's difficult to say.  It is against the RMI4 spec for there to be
> > gaps in the pages - you're supposed to be able to scan until you
> > hit a
> > page with an empty PDT, and then stop.
> > 
> > Since F55 is hardcoded to page 3 for this firmware, it may be a
> > customer specific deviation.  This may have been done to
> > accommodate a
> > customer-written driver that did not scan the PDT, but instead
> > always
> > looked for F55 on page 3.  This idea is supported by the existence
> > of
> > the F51 custom function on page 4, since F51 almost always requires
> > customer driver code to handle it.
> > 
> > In my opinion, the Non-standard bit should have been set in the PDT
> > to
> > indicate that special handling was required, but that wasn't done
> > in
> > this case.
> > 
> > Anyway, given that this sort of thing has escaped into the wild,
> > I'm
> > unsure what to advise.  Just off the top of my head, one
> > possibility is
> > to have a "keep-going" option to scan the first 128 pages (0x00
> > through
> > 0x7F), regardless of whether an empty page is encountered.  This
> > could
> > be triggered either by a product ID on the "known goofy list", or
> > by a
> > boot/load time flag.  I'm sure there are other possibilities,
> > though.
> > 
> >                                         Cheers,
> >                                                 Chris
> > 
> > 
> > >

Re: [-next, 1/2] Input: synaptics-rmi4 - add support for F55 sensor tuning

2016-10-21 Thread Christopher Heiny
On Thu, 2016-10-20 at 16:31 -0700, Chris Healy wrote:
> As a little background, in the case Nick is referring to with the
> S7813, it was actually with a stock Synaptics Eval Board and stock
> Firmware provided by Synaptics.
> 
> Not sure if that is relevant or not.

Yes, it's quite relevant - thanks for the info!

I've checked with the firmware team and the QA team.  This definitely
appears to be a f/w misconfiguration that escaped the QA process.  QA
is updating their flow to check for this, and FW is looking into how it
happened.

In addition to the workaround I mentioned earlier, another possibility
would be to produce a fixed, spec-compliant firmware image and flash it
onto your S7813.  However, that doesn't eliminate the issue that there
might have been other QA escapes that would need to be handled (should
they arise).

Chris

> 
> On Thu, Oct 20, 2016 at 4:28 PM, Christopher Heiny  com> wrote:
> > On Thu, 2016-10-20 at 23:51 +0100, Nick Dyer wrote:
> > > On Mon, Oct 17, 2016 at 02:30:08PM -0700, Guenter Roeck wrote:
> > > >
> > > > On Fri, Sep 30, 2016 at 08:22:47PM -0700, Guenter Roeck wrote:
> > > > >
> > > > > Sensor tuning support is needed to determine the number of
> > > > > enabled
> > > > > tx and rx electrodes for use in F54 functions.
> > > > >
> > > > > The number of enabled electrodes is not identical to the
> > total
> > > > > number
> > > > > of electrodes as reported with F55:Query0 and F55:Query1. It
> > has
> > > > > to be
> > > > > calculated by analyzing F55:Ctrl1 (sensor receiver
> > assignment)
> > > > > and
> > > > > F55:Ctrl2 (sensor transmitter assignment).
> > > > >
> > > > > Support for additional sensor tuning functions may be added
> > > > > later.
> > > > >
> > > > > Signed-off-by: Guenter Roeck 
> > > >
> > > > Ping ... any comments on this patch and on
> > > > https://patchwork.kernel.org/patch/9359061/ ?
> > > >
> > > > Both patches now apply to mainline.
> > > >
> > > > Thanks,
> > > > Guenter
> > >
> > > Hi Guenter-
> > >
> > > I've reviewed and tested (on S7300 and S7813) both these patches
> > now
> > > - you can add my sign-off.
> > >
> > > However, on the S7813 firmware, F55 is on PDT page 3, and nothing
> > > on page 2, so the default behaviour of the mainline driver means
> > it
> > > is
> > > not initialised.
> > >
> > > So I think we need to revert this change in mainline:
> > > https://patchwork.kernel.org/patch/3796971/
> > >
> > > See below the PDT scan with it reverted and some debug added.
> > >
> > > Christopher/Andrew: is there a better heuristic than scanning all
> > 255
> > > pages, given that some firmwares contain gaps?
> > 
> > It's difficult to say.  It is against the RMI4 spec for there to be
> > gaps in the pages - you're supposed to be able to scan until you
> > hit a
> > page with an empty PDT, and then stop.
> > 
> > Since F55 is hardcoded to page 3 for this firmware, it may be a
> > customer specific deviation.  This may have been done to
> > accommodate a
> > customer-written driver that did not scan the PDT, but instead
> > always
> > looked for F55 on page 3.  This idea is supported by the existence
> > of
> > the F51 custom function on page 4, since F51 almost always requires
> > customer driver code to handle it.
> > 
> > In my opinion, the Non-standard bit should have been set in the PDT
> > to
> > indicate that special handling was required, but that wasn't done
> > in
> > this case.
> > 
> > Anyway, given that this sort of thing has escaped into the wild,
> > I'm
> > unsure what to advise.  Just off the top of my head, one
> > possibility is
> > to have a "keep-going" option to scan the first 128 pages (0x00
> > through
> > 0x7F), regardless of whether an empty page is encountered.  This
> > could
> > be triggered either by a product ID on the "known goofy list", or
> > by a
> > boot/load time flag.  I'm sure there are other possibilities,
> > though.
> > 
> >                                         Cheers,
> >                                                 Chris
> > 
> > 
> > >
> > > cheers
> > >
> > >

Re: [-next, 1/2] Input: synaptics-rmi4 - add support for F55 sensor tuning

2016-10-20 Thread Christopher Heiny
On Thu, 2016-10-20 at 23:51 +0100, Nick Dyer wrote:
> On Mon, Oct 17, 2016 at 02:30:08PM -0700, Guenter Roeck wrote:
> > 
> > On Fri, Sep 30, 2016 at 08:22:47PM -0700, Guenter Roeck wrote:
> > > 
> > > Sensor tuning support is needed to determine the number of
> > > enabled
> > > tx and rx electrodes for use in F54 functions.
> > > 
> > > The number of enabled electrodes is not identical to the total
> > > number
> > > of electrodes as reported with F55:Query0 and F55:Query1. It has
> > > to be
> > > calculated by analyzing F55:Ctrl1 (sensor receiver assignment)
> > > and
> > > F55:Ctrl2 (sensor transmitter assignment).
> > > 
> > > Support for additional sensor tuning functions may be added
> > > later.
> > > 
> > > Signed-off-by: Guenter Roeck 
> > 
> > Ping ... any comments on this patch and on
> > https://patchwork.kernel.org/patch/9359061/ ?
> > 
> > Both patches now apply to mainline.
> > 
> > Thanks,
> > Guenter
> 
> Hi Guenter-
> 
> I've reviewed and tested (on S7300 and S7813) both these patches now
> - you can add my sign-off.
> 
> However, on the S7813 firmware, F55 is on PDT page 3, and nothing
> on page 2, so the default behaviour of the mainline driver means it
> is
> not initialised.
> 
> So I think we need to revert this change in mainline:
> https://patchwork.kernel.org/patch/3796971/
> 
> See below the PDT scan with it reverted and some debug added.
> 
> Christopher/Andrew: is there a better heuristic than scanning all 255
> pages, given that some firmwares contain gaps?

It's difficult to say.  It is against the RMI4 spec for there to be
gaps in the pages - you're supposed to be able to scan until you hit a
page with an empty PDT, and then stop.

Since F55 is hardcoded to page 3 for this firmware, it may be a
customer specific deviation.  This may have been done to accommodate a
customer-written driver that did not scan the PDT, but instead always
looked for F55 on page 3.  This idea is supported by the existence of
the F51 custom function on page 4, since F51 almost always requires
customer driver code to handle it.

In my opinion, the Non-standard bit should have been set in the PDT to
indicate that special handling was required, but that wasn't done in
this case.

Anyway, given that this sort of thing has escaped into the wild, I'm
unsure what to advise.  Just off the top of my head, one possibility is
to have a "keep-going" option to scan the first 128 pages (0x00 through
0x7F), regardless of whether an empty page is encountered.  This could
be triggered either by a product ID on the "known goofy list", or by a
boot/load time flag.  I'm sure there are other possibilities, though.

Cheers,
Chris


> 
> cheers
> 
> Nick
> 
> [2.181199] rmi4_physical rmi4-00: Creating functions.
> [2.181210] rmi4_physical rmi4-00: rmi_scan_pdt page 0
> [2.181221] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 233
> [2.182218] rmi4_physical rmi4-00: rmi_read_pdt_entry: F34 V2
> [2.182230] rmi4_physical rmi4-00: Initializing F34.
> [2.182325] rmi4_physical rmi4-00: Registered F34.
> [2.182337] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 227
> [2.183003] rmi4_physical rmi4-00: rmi_read_pdt_entry: F01 V0
> [2.183014] rmi4_physical rmi4-00: Initializing F01.
> [2.187358] rmi4_f01 rmi4-00.fn01: found RMI device, manufacturer:
> Synaptics, product: s7813, fw id: 2174259
> [2.198822] rmi4_physical rmi4-00: Registered F01.
> [2.198834] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 221
> [2.199494] rmi4_physical rmi4-00: rmi_read_pdt_entry: F12 V0
> [2.199505] rmi4_physical rmi4-00: Initializing F12.
> [2.199612] rmi4_f12 rmi4-00.fn12: rmi_f12_probe
> [2.210721] rmi4_physical rmi4-00: Registered F12.
> [2.210732] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 215
> [2.211393] rmi4_physical rmi4-00: rmi_read_pdt_entry: F00 V0
> [2.211404] rmi4_physical rmi4-00: rmi_scan_pdt_page end of page
> [2.211414] rmi4_physical rmi4-00: rmi_scan_pdt page 1
> [2.211424] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 489
> [2.212419] rmi4_physical rmi4-00: rmi_read_pdt_entry: F54 V0
> [2.212431] rmi4_physical rmi4-00: Initializing F54.
> [2.214241] rmi4_f54 rmi4-00.fn54: F54 num_rx_electrodes: 60
> [2.214253] rmi4_f54 rmi4-00.fn54: F54 num_tx_electrodes: 36
> [2.214263] rmi4_f54 rmi4-00.fn54: F54 capabilities: 0x44
> [2.214274] rmi4_f54 rmi4-00.fn54: F54 clock rate: 0x5aa0
> [2.214283] rmi4_f54 rmi4-00.fn54: F54 family: 0x2
> [2.214695] rmi4_physical rmi4-00: Registered F54.
> [2.214708] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 483
> [2.215372] rmi4_physical rmi4-00: rmi_read_pdt_entry: F00 V0
> [2.215384] rmi4_physical rmi4-00: rmi_scan_pdt_page end of page
> [2.215395] rmi4_physical rmi4-00: rmi_scan_pdt page 2
> [2.215405] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 745
> [

Re: [-next, 1/2] Input: synaptics-rmi4 - add support for F55 sensor tuning

2016-10-20 Thread Christopher Heiny
On Thu, 2016-10-20 at 23:51 +0100, Nick Dyer wrote:
> On Mon, Oct 17, 2016 at 02:30:08PM -0700, Guenter Roeck wrote:
> > 
> > On Fri, Sep 30, 2016 at 08:22:47PM -0700, Guenter Roeck wrote:
> > > 
> > > Sensor tuning support is needed to determine the number of
> > > enabled
> > > tx and rx electrodes for use in F54 functions.
> > > 
> > > The number of enabled electrodes is not identical to the total
> > > number
> > > of electrodes as reported with F55:Query0 and F55:Query1. It has
> > > to be
> > > calculated by analyzing F55:Ctrl1 (sensor receiver assignment)
> > > and
> > > F55:Ctrl2 (sensor transmitter assignment).
> > > 
> > > Support for additional sensor tuning functions may be added
> > > later.
> > > 
> > > Signed-off-by: Guenter Roeck 
> > 
> > Ping ... any comments on this patch and on
> > https://patchwork.kernel.org/patch/9359061/ ?
> > 
> > Both patches now apply to mainline.
> > 
> > Thanks,
> > Guenter
> 
> Hi Guenter-
> 
> I've reviewed and tested (on S7300 and S7813) both these patches now
> - you can add my sign-off.
> 
> However, on the S7813 firmware, F55 is on PDT page 3, and nothing
> on page 2, so the default behaviour of the mainline driver means it
> is
> not initialised.
> 
> So I think we need to revert this change in mainline:
> https://patchwork.kernel.org/patch/3796971/
> 
> See below the PDT scan with it reverted and some debug added.
> 
> Christopher/Andrew: is there a better heuristic than scanning all 255
> pages, given that some firmwares contain gaps?

It's difficult to say.  It is against the RMI4 spec for there to be
gaps in the pages - you're supposed to be able to scan until you hit a
page with an empty PDT, and then stop.

Since F55 is hardcoded to page 3 for this firmware, it may be a
customer specific deviation.  This may have been done to accommodate a
customer-written driver that did not scan the PDT, but instead always
looked for F55 on page 3.  This idea is supported by the existence of
the F51 custom function on page 4, since F51 almost always requires
customer driver code to handle it.

In my opinion, the Non-standard bit should have been set in the PDT to
indicate that special handling was required, but that wasn't done in
this case.

Anyway, given that this sort of thing has escaped into the wild, I'm
unsure what to advise.  Just off the top of my head, one possibility is
to have a "keep-going" option to scan the first 128 pages (0x00 through
0x7F), regardless of whether an empty page is encountered.  This could
be triggered either by a product ID on the "known goofy list", or by a
boot/load time flag.  I'm sure there are other possibilities, though.

Cheers,
Chris


> 
> cheers
> 
> Nick
> 
> [2.181199] rmi4_physical rmi4-00: Creating functions.
> [2.181210] rmi4_physical rmi4-00: rmi_scan_pdt page 0
> [2.181221] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 233
> [2.182218] rmi4_physical rmi4-00: rmi_read_pdt_entry: F34 V2
> [2.182230] rmi4_physical rmi4-00: Initializing F34.
> [2.182325] rmi4_physical rmi4-00: Registered F34.
> [2.182337] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 227
> [2.183003] rmi4_physical rmi4-00: rmi_read_pdt_entry: F01 V0
> [2.183014] rmi4_physical rmi4-00: Initializing F01.
> [2.187358] rmi4_f01 rmi4-00.fn01: found RMI device, manufacturer:
> Synaptics, product: s7813, fw id: 2174259
> [2.198822] rmi4_physical rmi4-00: Registered F01.
> [2.198834] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 221
> [2.199494] rmi4_physical rmi4-00: rmi_read_pdt_entry: F12 V0
> [2.199505] rmi4_physical rmi4-00: Initializing F12.
> [2.199612] rmi4_f12 rmi4-00.fn12: rmi_f12_probe
> [2.210721] rmi4_physical rmi4-00: Registered F12.
> [2.210732] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 215
> [2.211393] rmi4_physical rmi4-00: rmi_read_pdt_entry: F00 V0
> [2.211404] rmi4_physical rmi4-00: rmi_scan_pdt_page end of page
> [2.211414] rmi4_physical rmi4-00: rmi_scan_pdt page 1
> [2.211424] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 489
> [2.212419] rmi4_physical rmi4-00: rmi_read_pdt_entry: F54 V0
> [2.212431] rmi4_physical rmi4-00: Initializing F54.
> [2.214241] rmi4_f54 rmi4-00.fn54: F54 num_rx_electrodes: 60
> [2.214253] rmi4_f54 rmi4-00.fn54: F54 num_tx_electrodes: 36
> [2.214263] rmi4_f54 rmi4-00.fn54: F54 capabilities: 0x44
> [2.214274] rmi4_f54 rmi4-00.fn54: F54 clock rate: 0x5aa0
> [2.214283] rmi4_f54 rmi4-00.fn54: F54 family: 0x2
> [2.214695] rmi4_physical rmi4-00: Registered F54.
> [2.214708] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 483
> [2.215372] rmi4_physical rmi4-00: rmi_read_pdt_entry: F00 V0
> [2.215384] rmi4_physical rmi4-00: rmi_scan_pdt_page end of page
> [2.215395] rmi4_physical rmi4-00: rmi_scan_pdt page 2
> [2.215405] rmi4_physical rmi4-00: rmi_scan_pdt_page addr 745
> [2.216404] 

Re: [PATCH] Input: synaptics-rmi4 - fix compiler warnings in F11

2014-07-23 Thread Christopher Heiny

On 07/22/2014 11:11 PM, Dmitry Torokhov wrote:

Signed-off-by: Dmitry Torokhov 


I've reviewed this, and can say:

Acked-by: Christopher Heiny 

but I haven't had a chance to apply it to my build tree.

Andrew - I'll be OOO for a couple of days.  Can you do that, and add a 
Tested-by: or rev the patch, as appropriate?


Thanks,
Chris


---
  drivers/input/rmi4/rmi_f11.c | 135 +++
  1 file changed, 71 insertions(+), 64 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index b739d31..7af4f68 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -553,7 +553,7 @@ struct f11_data {
unsigned long *result_bits;
  };

-enum finger_state_values {
+enum f11_finger_state {
F11_NO_FINGER   = 0x00,
F11_PRESENT = 0x01,
F11_INACCURATE  = 0x02,
@@ -563,12 +563,14 @@ enum finger_state_values {
  /** F11_INACCURATE state is overloaded to indicate pen present. */
  #define F11_PEN F11_INACCURATE

-static int get_tool_type(struct f11_2d_sensor *sensor, u8 finger_state)
+static int rmi_f11_get_tool_type(struct f11_2d_sensor *sensor,
+enum f11_finger_state finger_state)
  {
if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
sensor->sens_query.has_pen &&
finger_state == F11_PEN)
return MT_TOOL_PEN;
+
return MT_TOOL_FINGER;
  }

@@ -603,36 +605,32 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor 
*sensor, u8 n_finger)

  static void rmi_f11_abs_pos_report(struct f11_data *f11,
   struct f11_2d_sensor *sensor,
-  u8 finger_state, u8 n_finger)
+  enum f11_finger_state finger_state,
+  u8 n_finger)
  {
struct f11_2d_data *data = >data;
+   struct input_dev *input = sensor->input;
struct rmi_f11_2d_axis_alignment *axis_align = >axis_align;
+   u8 *pos_data = >abs_pos[n_finger * RMI_F11_ABS_BYTES];
u16 x, y, z;
int w_x, w_y, w_max, w_min, orient;
-   int temp;
-   u8 abs_base = n_finger * RMI_F11_ABS_BYTES;
+   int tool_type = rmi_f11_get_tool_type(sensor, finger_state);
+
+   if (sensor->type_a) {
+   input_report_abs(input, ABS_MT_TRACKING_ID, n_finger);
+   input_report_abs(input, ABS_MT_TOOL_TYPE, tool_type);
+   } else {
+   input_mt_slot(input, n_finger);
+   input_mt_report_slot_state(input, tool_type,
+  finger_state != F11_NO_FINGER);
+   }

if (finger_state) {
-   x = (data->abs_pos[abs_base] << 4) |
-   (data->abs_pos[abs_base + 2] & 0x0F);
-   y = (data->abs_pos[abs_base + 1] << 4) |
-   (data->abs_pos[abs_base + 2] >> 4);
-   w_x = data->abs_pos[abs_base + 3] & 0x0F;
-   w_y = data->abs_pos[abs_base + 3] >> 4;
-   w_max = max(w_x, w_y);
-   w_min = min(w_x, w_y);
-   z = data->abs_pos[abs_base + 4];
-
-   if (axis_align->swap_axes) {
-   temp = x;
-   x = y;
-   y = temp;
-   temp = w_x;
-   w_x = w_y;
-   w_y = temp;
-   }
+   x = (pos_data[0] << 4) | (pos_data[2] & 0x0F);
+   y = (pos_data[1] << 4) | (pos_data[2] >> 4);

-   orient = w_x > w_y ? 1 : 0;
+   if (axis_align->swap_axes)
+   swap(x, y);

if (axis_align->flip_x)
x = max(sensor->max_x - x, 0);
@@ -641,13 +639,13 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
y = max(sensor->max_y - y, 0);

/*
-   * here checking if X offset or y offset are specified is
-   *  redundant.  We just add the offsets or, clip the values
-   *
-   * note: offsets need to be done before clipping occurs,
-   * or we could get funny values that are outside
-   * clipping boundaries.
-   */
+* Here checking if X offset or y offset are specified is
+* redundant. We just add the offsets or clip the values.
+*
+* Note: offsets need to be applied before clipping occurs,
+* or we could get funny values that are outside of
+* clipping boundaries.
+*/
x += axis_align->offset_x;
y += axis_align->offset_

Re: [PATCH] Input: synaptics-rmi4 - fix compiler warnings in F11

2014-07-23 Thread Christopher Heiny

On 07/22/2014 11:11 PM, Dmitry Torokhov wrote:

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


I've reviewed this, and can say:

Acked-by: Christopher Heiny che...@synaptics.com

but I haven't had a chance to apply it to my build tree.

Andrew - I'll be OOO for a couple of days.  Can you do that, and add a 
Tested-by: or rev the patch, as appropriate?


Thanks,
Chris


---
  drivers/input/rmi4/rmi_f11.c | 135 +++
  1 file changed, 71 insertions(+), 64 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index b739d31..7af4f68 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -553,7 +553,7 @@ struct f11_data {
unsigned long *result_bits;
  };

-enum finger_state_values {
+enum f11_finger_state {
F11_NO_FINGER   = 0x00,
F11_PRESENT = 0x01,
F11_INACCURATE  = 0x02,
@@ -563,12 +563,14 @@ enum finger_state_values {
  /** F11_INACCURATE state is overloaded to indicate pen present. */
  #define F11_PEN F11_INACCURATE

-static int get_tool_type(struct f11_2d_sensor *sensor, u8 finger_state)
+static int rmi_f11_get_tool_type(struct f11_2d_sensor *sensor,
+enum f11_finger_state finger_state)
  {
if (IS_ENABLED(CONFIG_RMI4_F11_PEN) 
sensor-sens_query.has_pen 
finger_state == F11_PEN)
return MT_TOOL_PEN;
+
return MT_TOOL_FINGER;
  }

@@ -603,36 +605,32 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor 
*sensor, u8 n_finger)

  static void rmi_f11_abs_pos_report(struct f11_data *f11,
   struct f11_2d_sensor *sensor,
-  u8 finger_state, u8 n_finger)
+  enum f11_finger_state finger_state,
+  u8 n_finger)
  {
struct f11_2d_data *data = sensor-data;
+   struct input_dev *input = sensor-input;
struct rmi_f11_2d_axis_alignment *axis_align = sensor-axis_align;
+   u8 *pos_data = data-abs_pos[n_finger * RMI_F11_ABS_BYTES];
u16 x, y, z;
int w_x, w_y, w_max, w_min, orient;
-   int temp;
-   u8 abs_base = n_finger * RMI_F11_ABS_BYTES;
+   int tool_type = rmi_f11_get_tool_type(sensor, finger_state);
+
+   if (sensor-type_a) {
+   input_report_abs(input, ABS_MT_TRACKING_ID, n_finger);
+   input_report_abs(input, ABS_MT_TOOL_TYPE, tool_type);
+   } else {
+   input_mt_slot(input, n_finger);
+   input_mt_report_slot_state(input, tool_type,
+  finger_state != F11_NO_FINGER);
+   }

if (finger_state) {
-   x = (data-abs_pos[abs_base]  4) |
-   (data-abs_pos[abs_base + 2]  0x0F);
-   y = (data-abs_pos[abs_base + 1]  4) |
-   (data-abs_pos[abs_base + 2]  4);
-   w_x = data-abs_pos[abs_base + 3]  0x0F;
-   w_y = data-abs_pos[abs_base + 3]  4;
-   w_max = max(w_x, w_y);
-   w_min = min(w_x, w_y);
-   z = data-abs_pos[abs_base + 4];
-
-   if (axis_align-swap_axes) {
-   temp = x;
-   x = y;
-   y = temp;
-   temp = w_x;
-   w_x = w_y;
-   w_y = temp;
-   }
+   x = (pos_data[0]  4) | (pos_data[2]  0x0F);
+   y = (pos_data[1]  4) | (pos_data[2]  4);

-   orient = w_x  w_y ? 1 : 0;
+   if (axis_align-swap_axes)
+   swap(x, y);

if (axis_align-flip_x)
x = max(sensor-max_x - x, 0);
@@ -641,13 +639,13 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
y = max(sensor-max_y - y, 0);

/*
-   * here checking if X offset or y offset are specified is
-   *  redundant.  We just add the offsets or, clip the values
-   *
-   * note: offsets need to be done before clipping occurs,
-   * or we could get funny values that are outside
-   * clipping boundaries.
-   */
+* Here checking if X offset or y offset are specified is
+* redundant. We just add the offsets or clip the values.
+*
+* Note: offsets need to be applied before clipping occurs,
+* or we could get funny values that are outside of
+* clipping boundaries.
+*/
x += axis_align-offset_x;
y += axis_align-offset_y;
x =  max(axis_align-clip_x_low, x);
@@ -657,41 +655,44 @@ static void rmi_f11_abs_pos_report(struct f11_data

Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-03-18 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


I've just submitted a patch to correctly call config() after probe(). 
So this becomes...


Signed-off-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_f01.c | 18 --
  1 file changed, 18 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 897d8ac..976aba3 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -303,12 +303,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.doze_interval) {
data->device_control.doze_interval =
pdata->power_management.doze_interval;
-   error = rmi_write(rmi_dev, data->doze_interval_addr,
-   data->device_control.doze_interval);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 doze 
interval register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->doze_interval_addr,
>device_control.doze_interval);
@@ -324,12 +318,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.wakeup_threshold) {
data->device_control.wakeup_threshold =
pdata->power_management.wakeup_threshold;
-   error = rmi_write(rmi_dev, data->wakeup_threshold_addr,
-   data->device_control.wakeup_threshold);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 wakeup 
threshold register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->wakeup_threshold_addr,
>device_control.wakeup_threshold);
@@ -347,12 +335,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.doze_holdoff) {
data->device_control.doze_holdoff =
pdata->power_management.doze_holdoff;
-   error = rmi_write(rmi_dev, data->doze_holdoff_addr,
-   data->device_control.doze_holdoff);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 doze 
holdoff register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->doze_holdoff_addr,
>device_control.doze_holdoff);




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-03-18 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


I've just submitted a patch to correctly call config() after probe(). 
So this becomes...


Signed-off-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_f01.c | 18 --
  1 file changed, 18 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 897d8ac..976aba3 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -303,12 +303,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.doze_interval) {
data-device_control.doze_interval =
pdata-power_management.doze_interval;
-   error = rmi_write(rmi_dev, data-doze_interval_addr,
-   data-device_control.doze_interval);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 doze 
interval register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-doze_interval_addr,
data-device_control.doze_interval);
@@ -324,12 +318,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.wakeup_threshold) {
data-device_control.wakeup_threshold =
pdata-power_management.wakeup_threshold;
-   error = rmi_write(rmi_dev, data-wakeup_threshold_addr,
-   data-device_control.wakeup_threshold);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 wakeup 
threshold register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-wakeup_threshold_addr,
data-device_control.wakeup_threshold);
@@ -347,12 +335,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.doze_holdoff) {
data-device_control.doze_holdoff =
pdata-power_management.doze_holdoff;
-   error = rmi_write(rmi_dev, data-doze_holdoff_addr,
-   data-device_control.doze_holdoff);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 doze 
holdoff register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-doze_holdoff_addr,
data-device_control.doze_holdoff);




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-18 Thread Christopher Heiny

On 02/17/2014 11:23 AM, Dmitry Torokhov wrote:

On Fri, Feb 14, 2014 at 03:00:43PM -0800, Christopher Heiny wrote:

On 02/13/2014 01:54 PM, Dmitry Torokhov wrote:

On Thu, Feb 13, 2014 at 11:23:44AM -0800, Christopher Heiny wrote:

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


Then we should call config() in rmi_function_probe() to ensure that
any platform data or device tree configuration settings get written
to the device.


Well, yes, we may elect to update device configuration in probe, but
then we should not be doing that 2nd time in ->config(). We shoudl pick
either one or another.


But as the code currently stands, config() is only called when a
device reset is detected, not during initialization.  So if there's
platform specific configuration data that needs to be written to a
function, it won't get written until after a device reset occurs,
which might never happen.  So either we need to write that data (or
call config()) in each function's probe(), or in
rmi_function_probe().


Ah, I missed the fact that we do not normally call ->config() unless
device was reset. BTW, if device was reset, shouldn't we tear down
everything and then reenumerate all functions?


That's only required if the reset is a result of the device being 
reflashed.  Since we're dropping support for user-space control of 
reflash, and will instead use an in-driver reflash, we know which resets 
are the result of a reflash and which aren't. The reflash code will do 
the following sequence:


- tell the core to tear down the functions
- perform the reflash operation
- reset the device
- tell the core to re-enumerate the functions


Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-18 Thread Christopher Heiny

On 02/17/2014 11:23 AM, Dmitry Torokhov wrote:

On Fri, Feb 14, 2014 at 03:00:43PM -0800, Christopher Heiny wrote:

On 02/13/2014 01:54 PM, Dmitry Torokhov wrote:

On Thu, Feb 13, 2014 at 11:23:44AM -0800, Christopher Heiny wrote:

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


Then we should call config() in rmi_function_probe() to ensure that
any platform data or device tree configuration settings get written
to the device.


Well, yes, we may elect to update device configuration in probe, but
then we should not be doing that 2nd time in -config(). We shoudl pick
either one or another.


But as the code currently stands, config() is only called when a
device reset is detected, not during initialization.  So if there's
platform specific configuration data that needs to be written to a
function, it won't get written until after a device reset occurs,
which might never happen.  So either we need to write that data (or
call config()) in each function's probe(), or in
rmi_function_probe().


Ah, I missed the fact that we do not normally call -config() unless
device was reset. BTW, if device was reset, shouldn't we tear down
everything and then reenumerate all functions?


That's only required if the reset is a result of the device being 
reflashed.  Since we're dropping support for user-space control of 
reflash, and will instead use an in-driver reflash, we know which resets 
are the result of a reflash and which aren't. The reflash code will do 
the following sequence:


- tell the core to tear down the functions
- perform the reflash operation
- reset the device
- tell the core to re-enumerate the functions


Chris
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-14 Thread Christopher Heiny

On 02/13/2014 01:54 PM, Dmitry Torokhov wrote:

On Thu, Feb 13, 2014 at 11:23:44AM -0800, Christopher Heiny wrote:

>On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

> >Do not write configuration data in probe(), we have config() for that.

>
>Then we should call config() in rmi_function_probe() to ensure that
>any platform data or device tree configuration settings get written
>to the device.

>

Well, yes, we may elect to update device configuration in probe, but
then we should not be doing that 2nd time in ->config(). We shoudl pick
either one or another.


But as the code currently stands, config() is only called when a device 
reset is detected, not during initialization.  So if there's platform 
specific configuration data that needs to be written to a function, it 
won't get written until after a device reset occurs, which might never 
happen.  So either we need to write that data (or call config()) in each 
function's probe(), or in rmi_function_probe().

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-14 Thread Christopher Heiny

On 02/13/2014 01:54 PM, Dmitry Torokhov wrote:

On Thu, Feb 13, 2014 at 11:23:44AM -0800, Christopher Heiny wrote:

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

 Do not write configuration data in probe(), we have config() for that.


Then we should call config() in rmi_function_probe() to ensure that
any platform data or device tree configuration settings get written
to the device.



Well, yes, we may elect to update device configuration in probe, but
then we should not be doing that 2nd time in -config(). We shoudl pick
either one or another.


But as the code currently stands, config() is only called when a device 
reset is detected, not during initialization.  So if there's platform 
specific configuration data that needs to be written to a function, it 
won't get written until after a device reset occurs, which might never 
happen.  So either we need to write that data (or call config()) in each 
function's probe(), or in rmi_function_probe().

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 05/11] Input: synaptics-rmi4 - remove control_mutex from f01_data

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

It is not used by anyone.

Signed-off-by: Dmitry Torokhov 


Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 30e0b50..6f90a6c 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -125,7 +125,6 @@ struct f01_data {
struct f01_basic_properties properties;

struct f01_device_control device_control;
-   struct mutex control_mutex;

u8 device_status;

@@ -214,8 +213,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
struct f01_data *data = fn->data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);

-   mutex_init(>control_mutex);
-
/*
 * Set the configured bit and (optionally) other important stuff
 * in the device control register.




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/11] Input: synaptics-rmi4 - rename instances of f01_data from data to f01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

We have too many "data"s: f01_data, driver_data, pdata, etc. Let's
untangle it a bit.

Signed-off-by: Dmitry Torokhov 


Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 135 ++-
  1 file changed, 68 insertions(+), 67 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 1e49ab4..1219e0c 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -208,7 +208,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
u16 ctrl_base_addr;
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(_dev->dev);
-   struct f01_data *data = fn->data;
+   struct f01_data *f01 = fn->data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
u8 device_status;

@@ -218,8 +218,8 @@ static int rmi_f01_initialize(struct rmi_function *fn)
 */
ctrl_base_addr = fn->fd.control_base_addr;
error = rmi_read_block(rmi_dev, fn->fd.control_base_addr,
-   >device_control.ctrl0,
-   sizeof(data->device_control.ctrl0));
+   >device_control.ctrl0,
+   sizeof(f01->device_control.ctrl0));
if (error < 0) {
dev_err(>dev, "Failed to read F01 control.\n");
return error;
@@ -228,10 +228,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
case RMI_F01_NOSLEEP_DEFAULT:
break;
case RMI_F01_NOSLEEP_OFF:
-   data->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT;
+   f01->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT;
break;
case RMI_F01_NOSLEEP_ON:
-   data->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
+   f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
break;
}

@@ -240,38 +240,38 @@ static int rmi_f01_initialize(struct rmi_function *fn)
 * reboot without power cycle.  If so, clear it so the sensor
 * is certain to function.
 */
-   if ((data->device_control.ctrl0 & RMI_F01_CTRL0_SLEEP_MODE_MASK) !=
+   if ((f01->device_control.ctrl0 & RMI_F01_CTRL0_SLEEP_MODE_MASK) !=
RMI_SLEEP_MODE_NORMAL) {
dev_warn(>dev,
 "WARNING: Non-zero sleep mode found. Clearing...\n");
-   data->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
+   f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
}

-   data->device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;
+   f01->device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;

error = rmi_write_block(rmi_dev, fn->fd.control_base_addr,
-   >device_control.ctrl0,
-   sizeof(data->device_control.ctrl0));
+   >device_control.ctrl0,
+   sizeof(f01->device_control.ctrl0));
if (error < 0) {
dev_err(>dev, "Failed to write F01 control.\n");
return error;
}

-   data->irq_count = driver_data->irq_count;
-   data->num_of_irq_regs = driver_data->num_of_irq_regs;
+   f01->irq_count = driver_data->irq_count;
+   f01->num_of_irq_regs = driver_data->num_of_irq_regs;
ctrl_base_addr += sizeof(u8);

-   data->interrupt_enable_addr = ctrl_base_addr;
+   f01->interrupt_enable_addr = ctrl_base_addr;
error = rmi_read_block(rmi_dev, ctrl_base_addr,
-   data->device_control.interrupt_enable,
-   sizeof(u8) * (data->num_of_irq_regs));
+   f01->device_control.interrupt_enable,
+   sizeof(u8) * (f01->num_of_irq_regs));
if (error < 0) {
dev_err(>dev,
"Failed to read F01 control interrupt enable 
register.\n");
return error;
}

-   ctrl_base_addr += data->num_of_irq_regs;
+   ctrl_base_addr += f01->num_of_irq_regs;

/* dummy read in order to clear irqs */
error = rmi_read(rmi_dev, fn->fd.data_base_addr + 1, );
@@ -281,42 +281,42 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}

error = rmi_f01_read_properties(rmi_dev, fn->fd.query_base_addr,
-   >properties);
+   >properties);
if (error < 0) {
dev_err(>dev, "Failed to read F01 pr

Re: [PATCH 08/11] Input: synaptics-rmi4 - use rmi_read/rmi_write in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Use rmi_read()/rmi_write() for reading/writing single-byte data. Also print
error code when IO fails.

Signed-off-by: Dmitry Torokhov 


Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 170 ++-
  1 file changed, 88 insertions(+), 82 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 1219e0c..a2f05bc 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -171,8 +171,9 @@ static int rmi_f01_read_properties(struct rmi_device 
*rmi_dev,

error = rmi_read_block(rmi_dev, query_base_addr,
   basic_query, sizeof(basic_query));
-   if (error < 0) {
-   dev_err(_dev->dev, "Failed to read device query 
registers.\n");
+   if (error) {
+   dev_err(_dev->dev,
+   "Failed to read device query registers: %d\n", error);
return error;
}

@@ -205,25 +206,25 @@ static int rmi_f01_initialize(struct rmi_function *fn)
  {
u8 temp;
int error;
-   u16 ctrl_base_addr;
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(_dev->dev);
struct f01_data *f01 = fn->data;
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   u16 ctrl_base_addr = fn->fd.control_base_addr;
u8 device_status;

/*
 * Set the configured bit and (optionally) other important stuff
 * in the device control register.
 */
-   ctrl_base_addr = fn->fd.control_base_addr;
-   error = rmi_read_block(rmi_dev, fn->fd.control_base_addr,
-   >device_control.ctrl0,
-   sizeof(f01->device_control.ctrl0));
-   if (error < 0) {
-   dev_err(>dev, "Failed to read F01 control.\n");
+
+   error = rmi_read(rmi_dev, fn->fd.control_base_addr,
+>device_control.ctrl0);
+   if (error) {
+   dev_err(>dev, "Failed to read F01 control: %d\n", error);
return error;
}
+
switch (pdata->power_management.nosleep) {
case RMI_F01_NOSLEEP_DEFAULT:
break;
@@ -249,11 +250,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)

f01->device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;

-   error = rmi_write_block(rmi_dev, fn->fd.control_base_addr,
-   >device_control.ctrl0,
-   sizeof(f01->device_control.ctrl0));
-   if (error < 0) {
-   dev_err(>dev, "Failed to write F01 control.\n");
+   error = rmi_write(rmi_dev, fn->fd.control_base_addr,
+ f01->device_control.ctrl0);
+   if (error) {
+   dev_err(>dev, "Failed to write F01 control: %d\n", error);
return error;
}

@@ -265,9 +265,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
error = rmi_read_block(rmi_dev, ctrl_base_addr,
f01->device_control.interrupt_enable,
sizeof(u8) * (f01->num_of_irq_regs));
-   if (error < 0) {
+   if (error) {
dev_err(>dev,
-   "Failed to read F01 control interrupt enable 
register.\n");
+   "Failed to read F01 control interrupt enable register: 
%d\n",
+   error);
return error;
}

@@ -302,8 +303,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
} else {
error = rmi_read(rmi_dev, f01->doze_interval_addr,
 >device_control.doze_interval);
-   if (error < 0) {
-   dev_err(>dev, "Failed to read F01 doze interval 
register.\n");
+   if (error) {
+   dev_err(>dev,
+   "Failed to read F01 doze interval register: 
%d\n",
+   error);
return error;
}
}
@@ -318,7 +321,9 @@ static int rmi_f01_initialize(struct rmi_function *fn)
error = rmi_read(rmi_dev, f01->wakeup_threshold_addr,
 >device_control.wakeup_threshold);
if (error < 0) {
-   dev_err(>dev, "Failed to read F01 wakeup 
threshold register.\n");
+ 

Re: [PATCH 11/11] Input: synaptics-rmi4 - remove data pointer from RMI fucntion structure

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Device core provides way of accessing driver-private data, we should
use it.

Signed-off-by: Dmitry Torokhov 


Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_bus.h |  1 -
  drivers/input/rmi4/rmi_f01.c | 14 +--
  drivers/input/rmi4/rmi_f11.c | 57 
  3 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 02a2af8..5ad94c6 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -48,7 +48,6 @@ struct rmi_function {
int num_of_irqs;
int irq_pos;
unsigned long *irq_mask;
-   void *data;
struct list_head node;

  #ifdef CONFIG_RMI4_DEBUG
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 36fcf8d..e646f60 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -354,14 +354,14 @@ static int rmi_f01_probe(struct rmi_function *fn)
return -EINVAL;
}

-   fn->data = f01;
+   dev_set_drvdata(>dev, f01);

return 0;
  }

  static int rmi_f01_config(struct rmi_function *fn)
  {
-   struct f01_data *f01 = fn->data;
+   struct f01_data *f01 = dev_get_drvdata(>dev);
int error;

error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
@@ -419,8 +419,7 @@ static int rmi_f01_config(struct rmi_function *fn)
  static int rmi_f01_suspend(struct device *dev)
  {
struct rmi_function *fn = to_rmi_function(dev);
-   struct rmi_device *rmi_dev = fn->rmi_dev;
-   struct f01_data *f01 = fn->data;
+   struct f01_data *f01 = dev_get_drvdata(>dev);
int error;

f01->old_nosleep =
@@ -430,7 +429,7 @@ static int rmi_f01_suspend(struct device *dev)
f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
f01->device_control.ctrl0 |= RMI_SLEEP_MODE_SENSOR_SLEEP;

-   error = rmi_write(rmi_dev, fn->fd.control_base_addr,
+   error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
  f01->device_control.ctrl0);
if (error) {
dev_err(>dev, "Failed to write sleep mode: %d.\n", error);
@@ -447,8 +446,7 @@ static int rmi_f01_suspend(struct device *dev)
  static int rmi_f01_resume(struct device *dev)
  {
struct rmi_function *fn = to_rmi_function(dev);
-   struct rmi_device *rmi_dev = fn->rmi_dev;
-   struct f01_data *f01 = fn->data;
+   struct f01_data *f01 = dev_get_drvdata(>dev);
int error;

if (f01->old_nosleep)
@@ -457,7 +455,7 @@ static int rmi_f01_resume(struct device *dev)
f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL;

-   error = rmi_write(rmi_dev, fn->fd.control_base_addr,
+   error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
  f01->device_control.ctrl0);
if (error) {
dev_err(>dev,
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 5072437..a26b944 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1087,9 +1087,8 @@ static int rmi_f11_get_query_parameters(struct rmi_device 
*rmi_dev,
  /* This operation is done in a number of places, so we have a handy routine
   * for it.
   */
-static void f11_set_abs_params(struct rmi_function *fn)
+static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
  {
-   struct f11_data *f11 = fn->data;
struct f11_2d_sensor *sensor = >sensor;
struct input_dev *input = sensor->input;
/* These two lines are not doing what we want them to.  So we use
@@ -1190,7 +1189,6 @@ static int rmi_f11_initialize(struct rmi_function *fn)
if (!f11)
return -ENOMEM;

-   fn->data = f11;
f11->rezero_wait_ms = pdata->f11_rezero_wait;

query_base_addr = fn->fd.query_base_addr;
@@ -1280,13 +1278,16 @@ static int rmi_f11_initialize(struct rmi_function *fn)
}

mutex_init(>dev_controls_mutex);
+
+   dev_set_drvdata(>dev, f11);
+
return 0;
  }

  static int rmi_f11_register_devices(struct rmi_function *fn)
  {
struct rmi_device *rmi_dev = fn->rmi_dev;
-   struct f11_data *f11 = fn->data;
+   struct f11_data *f11 = dev_get_drvdata(>dev);
struct input_dev *input_dev;
struct input_dev *input_dev_mouse;
struct rmi_driver *driver = rmi_dev->driver;
@@ -1304,8 +1305,8 @@ static int rmi_f11_register_devices(struct rmi_function 
*fn)
rc = driver->set_input_params(rmi_dev, input_dev);
if (rc < 0) {
dev_err(>dev,
-   "%s: Error in setting input devi

Re: [PATCH 06/11] Input: synaptics-rmi4 - remove device_status form f01_data

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

We do not need to persist it - we read it when signalled.

Signed-off-by: Dmitry Torokhov 


Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 15 +++
  1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 6f90a6c..1e49ab4 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -126,8 +126,6 @@ struct f01_data {

struct f01_device_control device_control;

-   u8 device_status;
-
u16 interrupt_enable_addr;
u16 doze_interval_addr;
u16 wakeup_threshold_addr;
@@ -212,6 +210,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
struct rmi_driver_data *driver_data = dev_get_drvdata(_dev->dev);
struct f01_data *data = fn->data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   u8 device_status;

/*
 * Set the configured bit and (optionally) other important stuff
@@ -346,16 +345,16 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}

error = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
-   >device_status, sizeof(data->device_status));
+   _status, sizeof(device_status));
if (error < 0) {
dev_err(>dev, "Failed to read device status.\n");
return error;
}

-   if (RMI_F01_STATUS_UNCONFIGURED(data->device_status)) {
+   if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
dev_err(>dev,
"Device was reset during configuration process, status: 
%#02x!\n",
-   RMI_F01_STATUS_CODE(data->device_status));
+   RMI_F01_STATUS_CODE(device_status));
return -EINVAL;
}

@@ -497,18 +496,18 @@ static int rmi_f01_attention(struct rmi_function *fn,
 unsigned long *irq_bits)
  {
struct rmi_device *rmi_dev = fn->rmi_dev;
-   struct f01_data *data = fn->data;
int retval;
+   u8 device_status;

retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
-   >device_status, sizeof(data->device_status));
+   _status, sizeof(device_status));
if (retval < 0) {
dev_err(>dev, "Failed to read device status, code: %d.\n",
retval);
return retval;
}

-   if (RMI_F01_STATUS_UNCONFIGURED(data->device_status)) {
+   if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
dev_warn(>dev, "Device reset detected.\n");
    retval = rmi_dev->driver->reset_handler(rmi_dev);
if (retval < 0)




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 10/11] Input: synaptics-rmi4 - make accessor for platform data return const pointer

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

When accessing platform data of RMI device let's make sure we do not
accidentally change data that may be shared by returning const pointer.
Also switch to an inline function instead of macro to ensure type safety.


That's a good idea.  We'll want to look at some of our other #define 
accessors as well, I think.


Signed-off-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_bus.h| 7 ++-
  drivers/input/rmi4/rmi_driver.c | 8 
  drivers/input/rmi4/rmi_f01.c| 2 +-
  drivers/input/rmi4/rmi_f11.c| 2 +-
  4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 8d47f52..02a2af8 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -224,7 +224,12 @@ struct rmi_device {
  };

  #define to_rmi_device(d) container_of(d, struct rmi_device, dev)
-#define to_rmi_platform_data(d) ((d)->xport->dev->platform_data)
+
+static inline const struct rmi_device_platform_data *
+rmi_get_platform_data(struct rmi_device *d)
+{
+   return dev_get_platdata(d->xport->dev);
+}

  bool rmi_is_physical_device(struct device *dev);

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 736cfbd..473efbc 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -598,7 +598,7 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev,
u16 cmd_addr = pdt->page_start + pdt->command_base_addr;
u8 cmd_buf = RMI_DEVICE_RESET_CMD;
const struct rmi_device_platform_data *pdata =
-   to_rmi_platform_data(rmi_dev);
+   rmi_get_platform_data(rmi_dev);

error = rmi_write_block(rmi_dev, cmd_addr, _buf, 1);
if (error) {
@@ -621,7 +621,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
  {
struct device *dev = _dev->dev;
struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
int *current_irq_count = ctx;
struct rmi_function *fn;
int i;
@@ -745,7 +745,7 @@ static int rmi_driver_remove(struct device *dev)
struct rmi_device *rmi_dev = to_rmi_device(dev);
struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
const struct rmi_device_platform_data *pdata =
-   to_rmi_platform_data(rmi_dev);
+   rmi_get_platform_data(rmi_dev);

disable_sensor(rmi_dev);
rmi_free_function_list(rmi_dev);
@@ -781,7 +781,7 @@ static int rmi_driver_probe(struct device *dev)
rmi_driver = to_rmi_driver(dev->driver);
rmi_dev->driver = rmi_driver;

-   pdata = to_rmi_platform_data(rmi_dev);
+   pdata = rmi_get_platform_data(rmi_dev);

data = devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL);
if (!data) {
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 0e21004..36fcf8d 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -184,7 +184,7 @@ static int rmi_f01_probe(struct rmi_function *fn)
  {
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(_dev->dev);
-   const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
struct f01_data *f01;
size_t f01_size;
int error;
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 2aa7d17..5072437 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1176,7 +1176,7 @@ static int rmi_f11_initialize(struct rmi_function *fn)
u16 control_base_addr;
u16 max_x_pos, max_y_pos, temp;
int rc;
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
struct f11_2d_sensor *sensor;
u8 buf;





--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/11] Input: synaptics-rmi4 - consolidate memory allocations in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Let's allocate interrupt mask together with the main structure and combine
rmi_f01_alloc_memory, rmi_f01_initialize and rmi_f01_probe into single
function.

Signed-off-by: Dmitry Torokhov 


Signed-off-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 86 
  1 file changed, 30 insertions(+), 56 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index a2f05bc..0e21004 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -130,37 +130,15 @@ struct f01_data {
u16 doze_interval_addr;
u16 wakeup_threshold_addr;
u16 doze_holdoff_addr;
-   int irq_count;
-   int num_of_irq_regs;

  #ifdef CONFIG_PM_SLEEP
bool suspended;
bool old_nosleep;
  #endif
-};
-
-static int rmi_f01_alloc_memory(struct rmi_function *fn,
-   int num_of_irq_regs)
-{
-   struct f01_data *f01;

-   f01 = devm_kzalloc(>dev, sizeof(struct f01_data), GFP_KERNEL);
-   if (!f01) {
-   dev_err(>dev, "Failed to allocate fn_01_data.\n");
-   return -ENOMEM;
-   }
-
-   f01->device_control.interrupt_enable = devm_kzalloc(>dev,
-   sizeof(u8) * (num_of_irq_regs),
-   GFP_KERNEL);
-   if (!f01->device_control.interrupt_enable) {
-   dev_err(>dev, "Failed to allocate interrupt enable.\n");
-   return -ENOMEM;
-   }
-   fn->data = f01;
-
-   return 0;
-}
+   unsigned int num_of_irq_regs;
+   u8 interrupt_enable[];
+};

  static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
   u16 query_base_addr,
@@ -202,16 +180,28 @@ static int rmi_f01_read_properties(struct rmi_device 
*rmi_dev,
return 0;
  }

-static int rmi_f01_initialize(struct rmi_function *fn)
+static int rmi_f01_probe(struct rmi_function *fn)
  {
-   u8 temp;
-   int error;
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(_dev->dev);
-   struct f01_data *f01 = fn->data;
const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   struct f01_data *f01;
+   size_t f01_size;
+   int error;
u16 ctrl_base_addr = fn->fd.control_base_addr;
u8 device_status;
+   u8 temp;
+
+   f01_size = sizeof(struct f01_data) +
+   sizeof(u8) * driver_data->num_of_irq_regs;
+   f01 = devm_kzalloc(>dev, f01_size, GFP_KERNEL);
+   if (!f01) {
+   dev_err(>dev, "Failed to allocate fn01_data.\n");
+   return -ENOMEM;
+   }
+
+   f01->num_of_irq_regs = driver_data->num_of_irq_regs;
+   f01->device_control.interrupt_enable = f01->interrupt_enable;

/*
 * Set the configured bit and (optionally) other important stuff
@@ -257,12 +247,11 @@ static int rmi_f01_initialize(struct rmi_function *fn)
return error;
}

-   f01->irq_count = driver_data->irq_count;
-   f01->num_of_irq_regs = driver_data->num_of_irq_regs;
-   ctrl_base_addr += sizeof(u8);
-
+   /* Advance to interrupt control registers */
+   ctrl_base_addr++;
f01->interrupt_enable_addr = ctrl_base_addr;
-   error = rmi_read_block(rmi_dev, ctrl_base_addr,
+
+   error = rmi_read_block(rmi_dev, f01->interrupt_enable_addr,
f01->device_control.interrupt_enable,
sizeof(u8) * (f01->num_of_irq_regs));
if (error) {
@@ -272,9 +261,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
return error;
}

-   ctrl_base_addr += f01->num_of_irq_regs;
-
-   /* dummy read in order to clear irqs */
+   /* Dummy read in order to clear irqs */
error = rmi_read(rmi_dev, fn->fd.data_base_addr + 1, );
if (error < 0) {
dev_err(>dev, "Failed to read Interrupt Status.\n");
@@ -287,11 +274,13 @@ static int rmi_f01_initialize(struct rmi_function *fn)
dev_err(>dev, "Failed to read F01 properties.\n");
return error;
}
+
dev_info(>dev, "found RMI device, manufacturer: %s, product: %s\n",
-f01->properties.manufacturer_id == 1 ?
-   "Synaptics" : "unknown",
+f01->properties.manufacturer_id == 1 ? "Synaptics" : "unknown",
 f01->properties.product_id);

+   ctrl_base_addr += f01->num_of_irq_regs;
+
/* read control register */
if (f01->properties.has_adjustable_doze) {
f01->

Re: [PATCH 04/11] Input: synaptics-rmi4 - fix LTS handling in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

From: Christopher Heiny 

Both F01_RMI_Ctrl2 and F01_RMI_Ctrl3 (doze_interval and wakeup_threshold)
are controlled by the has_adjustable_doze bit.

Signed-off-by: Christopher Heiny
Signed-off-by: Dmitry Torokhov 


Not sure if this need an Ack, but just in case.

Acked-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 976aba3..30e0b50 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -328,6 +328,9 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}
}

+   if (data->properties.has_lts)
+   ctrl_base_addr++;
+
if (data->properties.has_adjustable_doze_holdoff) {
data->doze_holdoff_addr = ctrl_base_addr;
ctrl_base_addr++;
@@ -383,7 +386,7 @@ static int rmi_f01_config(struct rmi_function *fn)
dev_err(>dev, "Failed to write interrupt enable.\n");
return retval;
}
-   if (data->properties.has_lts) {
+   if (data->properties.has_adjustable_doze) {
retval = rmi_write_block(fn->rmi_dev, data->doze_interval_addr,
 >device_control.doze_interval,
 sizeof(u8));
@@ -391,9 +394,7 @@ static int rmi_f01_config(struct rmi_function *fn)
dev_err(>dev, "Failed to write doze interval.\n");
return retval;
}
-   }

-   if (data->properties.has_adjustable_doze) {
retval = rmi_write_block(fn->rmi_dev,
 data->wakeup_threshold_addr,
     >device_control.wakeup_threshold,




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


Then we should call config() in rmi_function_probe() to ensure that
any platform data or device tree configuration settings get written
to the device.

Thinking about that, it looks like it's not fatal if the config
write fails in that situation.  The device might not function as
intended, but you can hopefully get some use out of it (for
instance, a phone's touchscreen sensitivity might be wacky, but
the user will still be able to dial tech support).

For example:

static int rmi_function_probe(struct device *dev)
{
struct rmi_function *fn = to_rmi_function(dev);
	struct rmi_function_handler *handler = 			 
to_rmi_function_handler(dev->driver);

int error;

if (handler->probe) {
error = handler->probe(fn);
if (error)
return error;
}
if (handler->config) {
error = handler->config(fn);
if (error)
dev_warn(dev, "Driver config failed.\n");
}

return 0;
}



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_f01.c | 18 --
  1 file changed, 18 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 897d8ac..976aba3 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -303,12 +303,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.doze_interval) {
data->device_control.doze_interval =
pdata->power_management.doze_interval;
-   error = rmi_write(rmi_dev, data->doze_interval_addr,
-   data->device_control.doze_interval);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 doze 
interval register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->doze_interval_addr,
>device_control.doze_interval);
@@ -324,12 +318,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.wakeup_threshold) {
data->device_control.wakeup_threshold =
pdata->power_management.wakeup_threshold;
-   error = rmi_write(rmi_dev, data->wakeup_threshold_addr,
-   data->device_control.wakeup_threshold);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 wakeup 
threshold register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->wakeup_threshold_addr,
>device_control.wakeup_threshold);
@@ -347,12 +335,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata->power_management.doze_holdoff) {
data->device_control.doze_holdoff =
pdata->power_management.doze_holdoff;
-   error = rmi_write(rmi_dev, data->doze_holdoff_addr,
-   data->device_control.doze_holdoff);
-   if (error < 0) {
-   dev_err(>dev, "Failed to configure F01 doze 
holdoff register.\n");
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data->doze_holdoff_addr,
>device_control.doze_holdoff);




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 02/11] Input: synaptics-rmi4 - remove unused rmi_f01_remove()

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

It is an empty stub and is not needed.

Signed-off-by: Dmitry Torokhov 


Signed-off-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 6 --
  1 file changed, 6 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 92b90d1..897d8ac 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -451,11 +451,6 @@ static int rmi_f01_probe(struct rmi_function *fn)
return 0;
  }

-static void rmi_f01_remove(struct rmi_function *fn)
-{
-   /* Placeholder for now. */
-}
-
  #ifdef CONFIG_PM_SLEEP
  static int rmi_f01_suspend(struct device *dev)
  {
@@ -554,7 +549,6 @@ static struct rmi_function_handler rmi_f01_handler = {
},
.func   = 0x01,
.probe  = rmi_f01_probe,
-   .remove = rmi_f01_remove,
.config = rmi_f01_config,
.attention  = rmi_f01_attention,
  };




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 01/11] Input: synaptics-rmi4 - do not kfree() managed memory in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Data that is allocated with devm_kzalloc() should not be freed with
kfree(). In fact, we should rely on the fact that memory is managed and let
devres core free it for us.

Reported-by: Courtney Cavin 
Signed-off-by: Dmitry Torokhov 


Signed-off-by: Christopher Heiny 


---
  drivers/input/rmi4/rmi_f01.c | 23 +--
  1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 381ad60..92b90d1 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -272,7 +272,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (error < 0) {
dev_err(>dev,
"Failed to read F01 control interrupt enable 
register.\n");
-   goto error_exit;
+   return error;
}

ctrl_base_addr += data->num_of_irq_regs;
@@ -307,14 +307,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data->device_control.doze_interval);
if (error < 0) {
dev_err(>dev, "Failed to configure F01 doze 
interval register.\n");
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data->doze_interval_addr,
>device_control.doze_interval);
if (error < 0) {
dev_err(>dev, "Failed to read F01 doze interval 
register.\n");
-   goto error_exit;
+   return error;
}
}

@@ -328,14 +328,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data->device_control.wakeup_threshold);
if (error < 0) {
dev_err(>dev, "Failed to configure F01 wakeup 
threshold register.\n");
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data->wakeup_threshold_addr,
>device_control.wakeup_threshold);
if (error < 0) {
dev_err(>dev, "Failed to read F01 wakeup 
threshold register.\n");
-   goto error_exit;
+   return error;
}
}
}
@@ -351,14 +351,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data->device_control.doze_holdoff);
if (error < 0) {
dev_err(>dev, "Failed to configure F01 doze 
holdoff register.\n");
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data->doze_holdoff_addr,
>device_control.doze_holdoff);
if (error < 0) {
dev_err(>dev, "Failed to read F01 doze holdoff 
register.\n");
-   goto error_exit;
+   return error;
}
}
}
@@ -367,22 +367,17 @@ static int rmi_f01_initialize(struct rmi_function *fn)
>device_status, sizeof(data->device_status));
if (error < 0) {
dev_err(>dev, "Failed to read device status.\n");
-   goto error_exit;
+   return error;
}

if (RMI_F01_STATUS_UNCONFIGURED(data->device_status)) {
dev_err(>dev,
"Device was reset during configuration process, status: 
%#02x!\n",
RMI_F01_STATUS_CODE(data->device_status));
-   error = -EINVAL;
-   goto error_exit;
+       return -EINVAL;
}

return 0;
-
- error_exit:
-   kfree(data);
-   return error;
  }

  static int rmi_f01_config(struct rmi_function *fn)




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 01/11] Input: synaptics-rmi4 - do not kfree() managed memory in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Data that is allocated with devm_kzalloc() should not be freed with
kfree(). In fact, we should rely on the fact that memory is managed and let
devres core free it for us.

Reported-by: Courtney Cavin courtney.ca...@sonymobile.com
Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Signed-off-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 23 +--
  1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 381ad60..92b90d1 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -272,7 +272,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (error  0) {
dev_err(fn-dev,
Failed to read F01 control interrupt enable 
register.\n);
-   goto error_exit;
+   return error;
}

ctrl_base_addr += data-num_of_irq_regs;
@@ -307,14 +307,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data-device_control.doze_interval);
if (error  0) {
dev_err(fn-dev, Failed to configure F01 doze 
interval register.\n);
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data-doze_interval_addr,
data-device_control.doze_interval);
if (error  0) {
dev_err(fn-dev, Failed to read F01 doze interval 
register.\n);
-   goto error_exit;
+   return error;
}
}

@@ -328,14 +328,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data-device_control.wakeup_threshold);
if (error  0) {
dev_err(fn-dev, Failed to configure F01 wakeup 
threshold register.\n);
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data-wakeup_threshold_addr,
data-device_control.wakeup_threshold);
if (error  0) {
dev_err(fn-dev, Failed to read F01 wakeup 
threshold register.\n);
-   goto error_exit;
+   return error;
}
}
}
@@ -351,14 +351,14 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data-device_control.doze_holdoff);
if (error  0) {
dev_err(fn-dev, Failed to configure F01 doze 
holdoff register.\n);
-   goto error_exit;
+   return error;
}
} else {
error = rmi_read(rmi_dev, data-doze_holdoff_addr,
data-device_control.doze_holdoff);
if (error  0) {
dev_err(fn-dev, Failed to read F01 doze holdoff 
register.\n);
-   goto error_exit;
+   return error;
}
}
}
@@ -367,22 +367,17 @@ static int rmi_f01_initialize(struct rmi_function *fn)
data-device_status, sizeof(data-device_status));
if (error  0) {
dev_err(fn-dev, Failed to read device status.\n);
-   goto error_exit;
+   return error;
}

if (RMI_F01_STATUS_UNCONFIGURED(data-device_status)) {
dev_err(fn-dev,
Device was reset during configuration process, status: 
%#02x!\n,
RMI_F01_STATUS_CODE(data-device_status));
-   error = -EINVAL;
-   goto error_exit;
+   return -EINVAL;
}

return 0;
-
- error_exit:
-   kfree(data);
-   return error;
  }

  static int rmi_f01_config(struct rmi_function *fn)




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 02/11] Input: synaptics-rmi4 - remove unused rmi_f01_remove()

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

It is an empty stub and is not needed.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Signed-off-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 6 --
  1 file changed, 6 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 92b90d1..897d8ac 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -451,11 +451,6 @@ static int rmi_f01_probe(struct rmi_function *fn)
return 0;
  }

-static void rmi_f01_remove(struct rmi_function *fn)
-{
-   /* Placeholder for now. */
-}
-
  #ifdef CONFIG_PM_SLEEP
  static int rmi_f01_suspend(struct device *dev)
  {
@@ -554,7 +549,6 @@ static struct rmi_function_handler rmi_f01_handler = {
},
.func   = 0x01,
.probe  = rmi_f01_probe,
-   .remove = rmi_f01_remove,
.config = rmi_f01_config,
.attention  = rmi_f01_attention,
  };




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/11] Input: synaptics-rmi4 - do not update configuration in rmi_f01_probe()

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Do not write configuration data in probe(), we have config() for that.


Then we should call config() in rmi_function_probe() to ensure that
any platform data or device tree configuration settings get written
to the device.

Thinking about that, it looks like it's not fatal if the config
write fails in that situation.  The device might not function as
intended, but you can hopefully get some use out of it (for
instance, a phone's touchscreen sensitivity might be wacky, but
the user will still be able to dial tech support).

For example:

static int rmi_function_probe(struct device *dev)
{
struct rmi_function *fn = to_rmi_function(dev);
	struct rmi_function_handler *handler = 			 
to_rmi_function_handler(dev-driver);

int error;

if (handler-probe) {
error = handler-probe(fn);
if (error)
return error;
}
if (handler-config) {
error = handler-config(fn);
if (error)
dev_warn(dev, Driver config failed.\n);
}

return 0;
}



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_f01.c | 18 --
  1 file changed, 18 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 897d8ac..976aba3 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -303,12 +303,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.doze_interval) {
data-device_control.doze_interval =
pdata-power_management.doze_interval;
-   error = rmi_write(rmi_dev, data-doze_interval_addr,
-   data-device_control.doze_interval);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 doze 
interval register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-doze_interval_addr,
data-device_control.doze_interval);
@@ -324,12 +318,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.wakeup_threshold) {
data-device_control.wakeup_threshold =
pdata-power_management.wakeup_threshold;
-   error = rmi_write(rmi_dev, data-wakeup_threshold_addr,
-   data-device_control.wakeup_threshold);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 wakeup 
threshold register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-wakeup_threshold_addr,
data-device_control.wakeup_threshold);
@@ -347,12 +335,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
if (pdata-power_management.doze_holdoff) {
data-device_control.doze_holdoff =
pdata-power_management.doze_holdoff;
-   error = rmi_write(rmi_dev, data-doze_holdoff_addr,
-   data-device_control.doze_holdoff);
-   if (error  0) {
-   dev_err(fn-dev, Failed to configure F01 doze 
holdoff register.\n);
-   return error;
-   }
} else {
error = rmi_read(rmi_dev, data-doze_holdoff_addr,
data-device_control.doze_holdoff);




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 04/11] Input: synaptics-rmi4 - fix LTS handling in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

From: Christopher Heiny che...@synaptics.com

Both F01_RMI_Ctrl2 and F01_RMI_Ctrl3 (doze_interval and wakeup_threshold)
are controlled by the has_adjustable_doze bit.

Signed-off-by: Christopher Heinyche...@synaptics.com
Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Not sure if this need an Ack, but just in case.

Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 976aba3..30e0b50 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -328,6 +328,9 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}
}

+   if (data-properties.has_lts)
+   ctrl_base_addr++;
+
if (data-properties.has_adjustable_doze_holdoff) {
data-doze_holdoff_addr = ctrl_base_addr;
ctrl_base_addr++;
@@ -383,7 +386,7 @@ static int rmi_f01_config(struct rmi_function *fn)
dev_err(fn-dev, Failed to write interrupt enable.\n);
return retval;
}
-   if (data-properties.has_lts) {
+   if (data-properties.has_adjustable_doze) {
retval = rmi_write_block(fn-rmi_dev, data-doze_interval_addr,
 data-device_control.doze_interval,
 sizeof(u8));
@@ -391,9 +394,7 @@ static int rmi_f01_config(struct rmi_function *fn)
dev_err(fn-dev, Failed to write doze interval.\n);
return retval;
}
-   }

-   if (data-properties.has_adjustable_doze) {
retval = rmi_write_block(fn-rmi_dev,
 data-wakeup_threshold_addr,
 data-device_control.wakeup_threshold,




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/11] Input: synaptics-rmi4 - consolidate memory allocations in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Let's allocate interrupt mask together with the main structure and combine
rmi_f01_alloc_memory, rmi_f01_initialize and rmi_f01_probe into single
function.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Signed-off-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 86 
  1 file changed, 30 insertions(+), 56 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index a2f05bc..0e21004 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -130,37 +130,15 @@ struct f01_data {
u16 doze_interval_addr;
u16 wakeup_threshold_addr;
u16 doze_holdoff_addr;
-   int irq_count;
-   int num_of_irq_regs;

  #ifdef CONFIG_PM_SLEEP
bool suspended;
bool old_nosleep;
  #endif
-};
-
-static int rmi_f01_alloc_memory(struct rmi_function *fn,
-   int num_of_irq_regs)
-{
-   struct f01_data *f01;

-   f01 = devm_kzalloc(fn-dev, sizeof(struct f01_data), GFP_KERNEL);
-   if (!f01) {
-   dev_err(fn-dev, Failed to allocate fn_01_data.\n);
-   return -ENOMEM;
-   }
-
-   f01-device_control.interrupt_enable = devm_kzalloc(fn-dev,
-   sizeof(u8) * (num_of_irq_regs),
-   GFP_KERNEL);
-   if (!f01-device_control.interrupt_enable) {
-   dev_err(fn-dev, Failed to allocate interrupt enable.\n);
-   return -ENOMEM;
-   }
-   fn-data = f01;
-
-   return 0;
-}
+   unsigned int num_of_irq_regs;
+   u8 interrupt_enable[];
+};

  static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
   u16 query_base_addr,
@@ -202,16 +180,28 @@ static int rmi_f01_read_properties(struct rmi_device 
*rmi_dev,
return 0;
  }

-static int rmi_f01_initialize(struct rmi_function *fn)
+static int rmi_f01_probe(struct rmi_function *fn)
  {
-   u8 temp;
-   int error;
struct rmi_device *rmi_dev = fn-rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(rmi_dev-dev);
-   struct f01_data *f01 = fn-data;
const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   struct f01_data *f01;
+   size_t f01_size;
+   int error;
u16 ctrl_base_addr = fn-fd.control_base_addr;
u8 device_status;
+   u8 temp;
+
+   f01_size = sizeof(struct f01_data) +
+   sizeof(u8) * driver_data-num_of_irq_regs;
+   f01 = devm_kzalloc(fn-dev, f01_size, GFP_KERNEL);
+   if (!f01) {
+   dev_err(fn-dev, Failed to allocate fn01_data.\n);
+   return -ENOMEM;
+   }
+
+   f01-num_of_irq_regs = driver_data-num_of_irq_regs;
+   f01-device_control.interrupt_enable = f01-interrupt_enable;

/*
 * Set the configured bit and (optionally) other important stuff
@@ -257,12 +247,11 @@ static int rmi_f01_initialize(struct rmi_function *fn)
return error;
}

-   f01-irq_count = driver_data-irq_count;
-   f01-num_of_irq_regs = driver_data-num_of_irq_regs;
-   ctrl_base_addr += sizeof(u8);
-
+   /* Advance to interrupt control registers */
+   ctrl_base_addr++;
f01-interrupt_enable_addr = ctrl_base_addr;
-   error = rmi_read_block(rmi_dev, ctrl_base_addr,
+
+   error = rmi_read_block(rmi_dev, f01-interrupt_enable_addr,
f01-device_control.interrupt_enable,
sizeof(u8) * (f01-num_of_irq_regs));
if (error) {
@@ -272,9 +261,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
return error;
}

-   ctrl_base_addr += f01-num_of_irq_regs;
-
-   /* dummy read in order to clear irqs */
+   /* Dummy read in order to clear irqs */
error = rmi_read(rmi_dev, fn-fd.data_base_addr + 1, temp);
if (error  0) {
dev_err(fn-dev, Failed to read Interrupt Status.\n);
@@ -287,11 +274,13 @@ static int rmi_f01_initialize(struct rmi_function *fn)
dev_err(fn-dev, Failed to read F01 properties.\n);
return error;
}
+
dev_info(fn-dev, found RMI device, manufacturer: %s, product: %s\n,
-f01-properties.manufacturer_id == 1 ?
-   Synaptics : unknown,
+f01-properties.manufacturer_id == 1 ? Synaptics : unknown,
 f01-properties.product_id);

+   ctrl_base_addr += f01-num_of_irq_regs;
+
/* read control register */
if (f01-properties.has_adjustable_doze) {
f01-doze_interval_addr = ctrl_base_addr;
@@ -365,6 +354,8 @@ static int rmi_f01_initialize(struct rmi_function *fn)
return -EINVAL;
}

+   fn-data = f01;
+
return 0

Re: [PATCH 10/11] Input: synaptics-rmi4 - make accessor for platform data return const pointer

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

When accessing platform data of RMI device let's make sure we do not
accidentally change data that may be shared by returning const pointer.
Also switch to an inline function instead of macro to ensure type safety.


That's a good idea.  We'll want to look at some of our other #define 
accessors as well, I think.


Signed-off-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_bus.h| 7 ++-
  drivers/input/rmi4/rmi_driver.c | 8 
  drivers/input/rmi4/rmi_f01.c| 2 +-
  drivers/input/rmi4/rmi_f11.c| 2 +-
  4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 8d47f52..02a2af8 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -224,7 +224,12 @@ struct rmi_device {
  };

  #define to_rmi_device(d) container_of(d, struct rmi_device, dev)
-#define to_rmi_platform_data(d) ((d)-xport-dev-platform_data)
+
+static inline const struct rmi_device_platform_data *
+rmi_get_platform_data(struct rmi_device *d)
+{
+   return dev_get_platdata(d-xport-dev);
+}

  bool rmi_is_physical_device(struct device *dev);

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 736cfbd..473efbc 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -598,7 +598,7 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev,
u16 cmd_addr = pdt-page_start + pdt-command_base_addr;
u8 cmd_buf = RMI_DEVICE_RESET_CMD;
const struct rmi_device_platform_data *pdata =
-   to_rmi_platform_data(rmi_dev);
+   rmi_get_platform_data(rmi_dev);

error = rmi_write_block(rmi_dev, cmd_addr, cmd_buf, 1);
if (error) {
@@ -621,7 +621,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
  {
struct device *dev = rmi_dev-dev;
struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
int *current_irq_count = ctx;
struct rmi_function *fn;
int i;
@@ -745,7 +745,7 @@ static int rmi_driver_remove(struct device *dev)
struct rmi_device *rmi_dev = to_rmi_device(dev);
struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
const struct rmi_device_platform_data *pdata =
-   to_rmi_platform_data(rmi_dev);
+   rmi_get_platform_data(rmi_dev);

disable_sensor(rmi_dev);
rmi_free_function_list(rmi_dev);
@@ -781,7 +781,7 @@ static int rmi_driver_probe(struct device *dev)
rmi_driver = to_rmi_driver(dev-driver);
rmi_dev-driver = rmi_driver;

-   pdata = to_rmi_platform_data(rmi_dev);
+   pdata = rmi_get_platform_data(rmi_dev);

data = devm_kzalloc(dev, sizeof(struct rmi_driver_data), GFP_KERNEL);
if (!data) {
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 0e21004..36fcf8d 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -184,7 +184,7 @@ static int rmi_f01_probe(struct rmi_function *fn)
  {
struct rmi_device *rmi_dev = fn-rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(rmi_dev-dev);
-   const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
struct f01_data *f01;
size_t f01_size;
int error;
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 2aa7d17..5072437 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1176,7 +1176,7 @@ static int rmi_f11_initialize(struct rmi_function *fn)
u16 control_base_addr;
u16 max_x_pos, max_y_pos, temp;
int rc;
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
rmi_get_platform_data(rmi_dev);
struct f11_2d_sensor *sensor;
u8 buf;





--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 06/11] Input: synaptics-rmi4 - remove device_status form f01_data

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

We do not need to persist it - we read it when signalled.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 15 +++
  1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 6f90a6c..1e49ab4 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -126,8 +126,6 @@ struct f01_data {

struct f01_device_control device_control;

-   u8 device_status;
-
u16 interrupt_enable_addr;
u16 doze_interval_addr;
u16 wakeup_threshold_addr;
@@ -212,6 +210,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
struct rmi_driver_data *driver_data = dev_get_drvdata(rmi_dev-dev);
struct f01_data *data = fn-data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   u8 device_status;

/*
 * Set the configured bit and (optionally) other important stuff
@@ -346,16 +345,16 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}

error = rmi_read_block(rmi_dev, fn-fd.data_base_addr,
-   data-device_status, sizeof(data-device_status));
+   device_status, sizeof(device_status));
if (error  0) {
dev_err(fn-dev, Failed to read device status.\n);
return error;
}

-   if (RMI_F01_STATUS_UNCONFIGURED(data-device_status)) {
+   if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
dev_err(fn-dev,
Device was reset during configuration process, status: 
%#02x!\n,
-   RMI_F01_STATUS_CODE(data-device_status));
+   RMI_F01_STATUS_CODE(device_status));
return -EINVAL;
}

@@ -497,18 +496,18 @@ static int rmi_f01_attention(struct rmi_function *fn,
 unsigned long *irq_bits)
  {
struct rmi_device *rmi_dev = fn-rmi_dev;
-   struct f01_data *data = fn-data;
int retval;
+   u8 device_status;

retval = rmi_read_block(rmi_dev, fn-fd.data_base_addr,
-   data-device_status, sizeof(data-device_status));
+   device_status, sizeof(device_status));
if (retval  0) {
dev_err(fn-dev, Failed to read device status, code: %d.\n,
retval);
return retval;
}

-   if (RMI_F01_STATUS_UNCONFIGURED(data-device_status)) {
+   if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
dev_warn(fn-dev, Device reset detected.\n);
retval = rmi_dev-driver-reset_handler(rmi_dev);
if (retval  0)




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 11/11] Input: synaptics-rmi4 - remove data pointer from RMI fucntion structure

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Device core provides way of accessing driver-private data, we should
use it.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_bus.h |  1 -
  drivers/input/rmi4/rmi_f01.c | 14 +--
  drivers/input/rmi4/rmi_f11.c | 57 
  3 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 02a2af8..5ad94c6 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -48,7 +48,6 @@ struct rmi_function {
int num_of_irqs;
int irq_pos;
unsigned long *irq_mask;
-   void *data;
struct list_head node;

  #ifdef CONFIG_RMI4_DEBUG
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 36fcf8d..e646f60 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -354,14 +354,14 @@ static int rmi_f01_probe(struct rmi_function *fn)
return -EINVAL;
}

-   fn-data = f01;
+   dev_set_drvdata(fn-dev, f01);

return 0;
  }

  static int rmi_f01_config(struct rmi_function *fn)
  {
-   struct f01_data *f01 = fn-data;
+   struct f01_data *f01 = dev_get_drvdata(fn-dev);
int error;

error = rmi_write(fn-rmi_dev, fn-fd.control_base_addr,
@@ -419,8 +419,7 @@ static int rmi_f01_config(struct rmi_function *fn)
  static int rmi_f01_suspend(struct device *dev)
  {
struct rmi_function *fn = to_rmi_function(dev);
-   struct rmi_device *rmi_dev = fn-rmi_dev;
-   struct f01_data *f01 = fn-data;
+   struct f01_data *f01 = dev_get_drvdata(fn-dev);
int error;

f01-old_nosleep =
@@ -430,7 +429,7 @@ static int rmi_f01_suspend(struct device *dev)
f01-device_control.ctrl0 = ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
f01-device_control.ctrl0 |= RMI_SLEEP_MODE_SENSOR_SLEEP;

-   error = rmi_write(rmi_dev, fn-fd.control_base_addr,
+   error = rmi_write(fn-rmi_dev, fn-fd.control_base_addr,
  f01-device_control.ctrl0);
if (error) {
dev_err(fn-dev, Failed to write sleep mode: %d.\n, error);
@@ -447,8 +446,7 @@ static int rmi_f01_suspend(struct device *dev)
  static int rmi_f01_resume(struct device *dev)
  {
struct rmi_function *fn = to_rmi_function(dev);
-   struct rmi_device *rmi_dev = fn-rmi_dev;
-   struct f01_data *f01 = fn-data;
+   struct f01_data *f01 = dev_get_drvdata(fn-dev);
int error;

if (f01-old_nosleep)
@@ -457,7 +455,7 @@ static int rmi_f01_resume(struct device *dev)
f01-device_control.ctrl0 = ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
f01-device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL;

-   error = rmi_write(rmi_dev, fn-fd.control_base_addr,
+   error = rmi_write(fn-rmi_dev, fn-fd.control_base_addr,
  f01-device_control.ctrl0);
if (error) {
dev_err(fn-dev,
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 5072437..a26b944 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1087,9 +1087,8 @@ static int rmi_f11_get_query_parameters(struct rmi_device 
*rmi_dev,
  /* This operation is done in a number of places, so we have a handy routine
   * for it.
   */
-static void f11_set_abs_params(struct rmi_function *fn)
+static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
  {
-   struct f11_data *f11 = fn-data;
struct f11_2d_sensor *sensor = f11-sensor;
struct input_dev *input = sensor-input;
/* These two lines are not doing what we want them to.  So we use
@@ -1190,7 +1189,6 @@ static int rmi_f11_initialize(struct rmi_function *fn)
if (!f11)
return -ENOMEM;

-   fn-data = f11;
f11-rezero_wait_ms = pdata-f11_rezero_wait;

query_base_addr = fn-fd.query_base_addr;
@@ -1280,13 +1278,16 @@ static int rmi_f11_initialize(struct rmi_function *fn)
}

mutex_init(f11-dev_controls_mutex);
+
+   dev_set_drvdata(fn-dev, f11);
+
return 0;
  }

  static int rmi_f11_register_devices(struct rmi_function *fn)
  {
struct rmi_device *rmi_dev = fn-rmi_dev;
-   struct f11_data *f11 = fn-data;
+   struct f11_data *f11 = dev_get_drvdata(fn-dev);
struct input_dev *input_dev;
struct input_dev *input_dev_mouse;
struct rmi_driver *driver = rmi_dev-driver;
@@ -1304,8 +1305,8 @@ static int rmi_f11_register_devices(struct rmi_function 
*fn)
rc = driver-set_input_params(rmi_dev, input_dev);
if (rc  0) {
dev_err(fn-dev,
-   %s: Error in setting input device.\n,
-   __func__);
+   %s: Error in setting input device.\n

Re: [PATCH 08/11] Input: synaptics-rmi4 - use rmi_read/rmi_write in F01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

Use rmi_read()/rmi_write() for reading/writing single-byte data. Also print
error code when IO fails.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 170 ++-
  1 file changed, 88 insertions(+), 82 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 1219e0c..a2f05bc 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -171,8 +171,9 @@ static int rmi_f01_read_properties(struct rmi_device 
*rmi_dev,

error = rmi_read_block(rmi_dev, query_base_addr,
   basic_query, sizeof(basic_query));
-   if (error  0) {
-   dev_err(rmi_dev-dev, Failed to read device query 
registers.\n);
+   if (error) {
+   dev_err(rmi_dev-dev,
+   Failed to read device query registers: %d\n, error);
return error;
}

@@ -205,25 +206,25 @@ static int rmi_f01_initialize(struct rmi_function *fn)
  {
u8 temp;
int error;
-   u16 ctrl_base_addr;
struct rmi_device *rmi_dev = fn-rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(rmi_dev-dev);
struct f01_data *f01 = fn-data;
-   struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
+   const struct rmi_device_platform_data *pdata = 
to_rmi_platform_data(rmi_dev);
+   u16 ctrl_base_addr = fn-fd.control_base_addr;
u8 device_status;

/*
 * Set the configured bit and (optionally) other important stuff
 * in the device control register.
 */
-   ctrl_base_addr = fn-fd.control_base_addr;
-   error = rmi_read_block(rmi_dev, fn-fd.control_base_addr,
-   f01-device_control.ctrl0,
-   sizeof(f01-device_control.ctrl0));
-   if (error  0) {
-   dev_err(fn-dev, Failed to read F01 control.\n);
+
+   error = rmi_read(rmi_dev, fn-fd.control_base_addr,
+f01-device_control.ctrl0);
+   if (error) {
+   dev_err(fn-dev, Failed to read F01 control: %d\n, error);
return error;
}
+
switch (pdata-power_management.nosleep) {
case RMI_F01_NOSLEEP_DEFAULT:
break;
@@ -249,11 +250,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)

f01-device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;

-   error = rmi_write_block(rmi_dev, fn-fd.control_base_addr,
-   f01-device_control.ctrl0,
-   sizeof(f01-device_control.ctrl0));
-   if (error  0) {
-   dev_err(fn-dev, Failed to write F01 control.\n);
+   error = rmi_write(rmi_dev, fn-fd.control_base_addr,
+ f01-device_control.ctrl0);
+   if (error) {
+   dev_err(fn-dev, Failed to write F01 control: %d\n, error);
return error;
}

@@ -265,9 +265,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
error = rmi_read_block(rmi_dev, ctrl_base_addr,
f01-device_control.interrupt_enable,
sizeof(u8) * (f01-num_of_irq_regs));
-   if (error  0) {
+   if (error) {
dev_err(fn-dev,
-   Failed to read F01 control interrupt enable 
register.\n);
+   Failed to read F01 control interrupt enable register: 
%d\n,
+   error);
return error;
}

@@ -302,8 +303,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
} else {
error = rmi_read(rmi_dev, f01-doze_interval_addr,
 f01-device_control.doze_interval);
-   if (error  0) {
-   dev_err(fn-dev, Failed to read F01 doze interval 
register.\n);
+   if (error) {
+   dev_err(fn-dev,
+   Failed to read F01 doze interval register: 
%d\n,
+   error);
return error;
}
}
@@ -318,7 +321,9 @@ static int rmi_f01_initialize(struct rmi_function *fn)
error = rmi_read(rmi_dev, f01-wakeup_threshold_addr,
 f01-device_control.wakeup_threshold);
if (error  0) {
-   dev_err(fn-dev, Failed to read F01 wakeup 
threshold register.\n);
+   dev_err(fn-dev,
+   Failed to read F01 wakeup threshold 
register: %d\n,
+   error);
return error

Re: [PATCH 07/11] Input: synaptics-rmi4 - rename instances of f01_data from data to f01

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

We have too many datas: f01_data, driver_data, pdata, etc. Let's
untangle it a bit.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 135 ++-
  1 file changed, 68 insertions(+), 67 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 1e49ab4..1219e0c 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -208,7 +208,7 @@ static int rmi_f01_initialize(struct rmi_function *fn)
u16 ctrl_base_addr;
struct rmi_device *rmi_dev = fn-rmi_dev;
struct rmi_driver_data *driver_data = dev_get_drvdata(rmi_dev-dev);
-   struct f01_data *data = fn-data;
+   struct f01_data *f01 = fn-data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
u8 device_status;

@@ -218,8 +218,8 @@ static int rmi_f01_initialize(struct rmi_function *fn)
 */
ctrl_base_addr = fn-fd.control_base_addr;
error = rmi_read_block(rmi_dev, fn-fd.control_base_addr,
-   data-device_control.ctrl0,
-   sizeof(data-device_control.ctrl0));
+   f01-device_control.ctrl0,
+   sizeof(f01-device_control.ctrl0));
if (error  0) {
dev_err(fn-dev, Failed to read F01 control.\n);
return error;
@@ -228,10 +228,10 @@ static int rmi_f01_initialize(struct rmi_function *fn)
case RMI_F01_NOSLEEP_DEFAULT:
break;
case RMI_F01_NOSLEEP_OFF:
-   data-device_control.ctrl0 = ~RMI_F01_CRTL0_NOSLEEP_BIT;
+   f01-device_control.ctrl0 = ~RMI_F01_CRTL0_NOSLEEP_BIT;
break;
case RMI_F01_NOSLEEP_ON:
-   data-device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
+   f01-device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
break;
}

@@ -240,38 +240,38 @@ static int rmi_f01_initialize(struct rmi_function *fn)
 * reboot without power cycle.  If so, clear it so the sensor
 * is certain to function.
 */
-   if ((data-device_control.ctrl0  RMI_F01_CTRL0_SLEEP_MODE_MASK) !=
+   if ((f01-device_control.ctrl0  RMI_F01_CTRL0_SLEEP_MODE_MASK) !=
RMI_SLEEP_MODE_NORMAL) {
dev_warn(fn-dev,
 WARNING: Non-zero sleep mode found. Clearing...\n);
-   data-device_control.ctrl0 = ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
+   f01-device_control.ctrl0 = ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
}

-   data-device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;
+   f01-device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;

error = rmi_write_block(rmi_dev, fn-fd.control_base_addr,
-   data-device_control.ctrl0,
-   sizeof(data-device_control.ctrl0));
+   f01-device_control.ctrl0,
+   sizeof(f01-device_control.ctrl0));
if (error  0) {
dev_err(fn-dev, Failed to write F01 control.\n);
return error;
}

-   data-irq_count = driver_data-irq_count;
-   data-num_of_irq_regs = driver_data-num_of_irq_regs;
+   f01-irq_count = driver_data-irq_count;
+   f01-num_of_irq_regs = driver_data-num_of_irq_regs;
ctrl_base_addr += sizeof(u8);

-   data-interrupt_enable_addr = ctrl_base_addr;
+   f01-interrupt_enable_addr = ctrl_base_addr;
error = rmi_read_block(rmi_dev, ctrl_base_addr,
-   data-device_control.interrupt_enable,
-   sizeof(u8) * (data-num_of_irq_regs));
+   f01-device_control.interrupt_enable,
+   sizeof(u8) * (f01-num_of_irq_regs));
if (error  0) {
dev_err(fn-dev,
Failed to read F01 control interrupt enable 
register.\n);
return error;
}

-   ctrl_base_addr += data-num_of_irq_regs;
+   ctrl_base_addr += f01-num_of_irq_regs;

/* dummy read in order to clear irqs */
error = rmi_read(rmi_dev, fn-fd.data_base_addr + 1, temp);
@@ -281,42 +281,42 @@ static int rmi_f01_initialize(struct rmi_function *fn)
}

error = rmi_f01_read_properties(rmi_dev, fn-fd.query_base_addr,
-   data-properties);
+   f01-properties);
if (error  0) {
dev_err(fn-dev, Failed to read F01 properties.\n);
return error;
}
dev_info(fn-dev, found RMI device, manufacturer: %s, product: %s\n,
-data-properties.manufacturer_id == 1 ?
+f01-properties.manufacturer_id == 1

Re: [PATCH 05/11] Input: synaptics-rmi4 - remove control_mutex from f01_data

2014-02-13 Thread Christopher Heiny

On 02/12/2014 09:27 PM, Dmitry Torokhov wrote:

It is not used by anyone.

Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com


Acked-by: Christopher Heiny che...@synaptics.com


---
  drivers/input/rmi4/rmi_f01.c | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index 30e0b50..6f90a6c 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -125,7 +125,6 @@ struct f01_data {
struct f01_basic_properties properties;

struct f01_device_control device_control;
-   struct mutex control_mutex;

u8 device_status;

@@ -214,8 +213,6 @@ static int rmi_f01_initialize(struct rmi_function *fn)
struct f01_data *data = fn-data;
struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);

-   mutex_init(data-control_mutex);
-
/*
 * Set the configured bit and (optionally) other important stuff
 * in the device control register.




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 00/05] input: RMI4 Synaptics RMI4 Touchscreen Driver

2014-02-04 Thread Christopher Heiny

On 02/03/2014 11:56 PM, Linus Walleij wrote:

On Sat, Jan 19, 2013 at 2:12 AM, Christopher Heiny  wrote:


This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.


What is happening to the RMI4 driver stuff?

Has this development stalled? The branch in Dmitry's git
seems to be maintained but not much is happening or is
there any progress?


Hi Linus,

Development stalled for several months last year, but picked up again 
last fall.  We've been submitting patches against Dmitry's input tree, 
sending them to linux-input rather than linux-kernel.  If you check the 
linux-input archives on spinics, you can see what's been going on.


If you'd like, we'll make sure to cc you on upcoming patches.  I've got 
some due - hopefully later today.


Chris

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 00/05] input: RMI4 Synaptics RMI4 Touchscreen Driver

2014-02-04 Thread Christopher Heiny

On 02/03/2014 11:56 PM, Linus Walleij wrote:

On Sat, Jan 19, 2013 at 2:12 AM, Christopher Heiny che...@synaptics.com wrote:


This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.


What is happening to the RMI4 driver stuff?

Has this development stalled? The branch in Dmitry's git
seems to be maintained but not much is happening or is
there any progress?


Hi Linus,

Development stalled for several months last year, but picked up again 
last fall.  We've been submitting patches against Dmitry's input tree, 
sending them to linux-input rather than linux-kernel.  If you check the 
linux-input archives on spinics, you can see what's been going on.


If you'd like, we'll make sure to cc you on upcoming patches.  I've got 
some due - hopefully later today.


Chris

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()

2014-01-14 Thread Christopher Heiny
dr, retval, (int)len, buf);

xport->stats.rx_count++;
-   xport->stats.rx_bytes += len;
-
-   retval = i2c_master_recv(client, buf, len);
-   if (retval < 0)
+   if (retval)
xport->stats.rx_errs++;
else
-   dev_dbg(>dev,
-   "read %zd bytes at %#06x: %*ph\n",
-   len, addr, (int)len, buf);
+   xport->stats.rx_bytes += len;

-exit:
mutex_unlock(_i2c->page_mutex);
return retval;
  }




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()

2014-01-14 Thread Christopher Heiny
);
-   if (retval  0)
+   if (retval)
xport-stats.rx_errs++;
else
-   dev_dbg(client-dev,
-   read %zd bytes at %#06x: %*ph\n,
-   len, addr, (int)len, buf);
+   xport-stats.rx_bytes += len;

-exit:
mutex_unlock(rmi_i2c-page_mutex);
return retval;
  }




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] Input: synaptics-rmi4 - split of transport ops into a separate structure

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Split off transport operations from rmi_transport_dev into a separate
structure that will be shared between all devices using the same transport
and use const pointer to access it.

Change signature on transport methods so that length is using the proper
tyep - size_t.

Also rename rmi_transport_info to rmi_transport_stats and move protocol
name (which is the only immutable piece of data there) into the transport
device itself.


Acked-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_bus.h| 64 -
  drivers/input/rmi4/rmi_driver.c |  8 +++---
  drivers/input/rmi4/rmi_i2c.c| 49 ---
  3 files changed, 67 insertions(+), 54 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 3e8b57a..ccf26dc 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -135,26 +135,25 @@ struct rmi_driver {
  #define to_rmi_driver(d) \
container_of(d, struct rmi_driver, driver);

-/** struct rmi_transport_info - diagnostic information about the RMI transport
+/**
+ * struct rmi_transport_stats - diagnostic information about the RMI transport
   * device, used in the xport_info debugfs file.
   *
   * @proto String indicating the protocol being used.
   * @tx_count Number of transmit operations.
- * @tx_bytes Number of bytes transmitted.
   * @tx_errs  Number of errors encountered during transmit operations.
+ * @tx_bytes Number of bytes transmitted.
   * @rx_count Number of receive operations.
- * @rx_bytes Number of bytes received.
   * @rx_errs  Number of errors encountered during receive operations.
- * @att_count Number of times ATTN assertions have been handled.
+ * @rx_bytes Number of bytes received.
   */
-struct rmi_transport_info {
-   const char *proto;
-   long tx_count;
-   long tx_bytes;
-   long tx_errs;
-   long rx_count;
-   long rx_bytes;
-   long rx_errs;
+struct rmi_transport_stats {
+   unsigned long tx_count;
+   unsigned long tx_errs;
+   size_t tx_bytes;
+   unsigned long rx_count;
+   unsigned long rx_errs;
+   size_t rx_bytes;
  };

  /**
@@ -162,13 +161,14 @@ struct rmi_transport_info {
   *
   * @dev: Pointer to the communication device, e.g. i2c or spi
   * @rmi_dev: Pointer to the RMI device
- * @write_block: Writing a block of data to the specified address
- * @read_block: Read a block of data from the specified address.
   * @irq_thread: if not NULL, the sensor driver will use this instead of the
   * default irq_thread implementation.
   * @hard_irq: if not NULL, the sensor driver will use this for the hard IRQ
   * handling
   * @data: Private data pointer
+ * @proto_name: name of the transport protocol (SPI, i2c, etc)
+ * @ops: pointer to transport operations implementation
+ * @stats: transport statistics
   *
   * The RMI transport device implements the glue between different 
communication
   * buses such as I2C and SPI.
@@ -178,20 +178,30 @@ struct rmi_transport_dev {
struct device *dev;
struct rmi_device *rmi_dev;

-   int (*write_block)(struct rmi_transport_dev *xport, u16 addr,
-  const void *buf, const int len);
-   int (*read_block)(struct rmi_transport_dev *xport, u16 addr,
- void *buf, const int len);
-
-   int (*enable_device) (struct rmi_transport_dev *xport);
-   void (*disable_device) (struct rmi_transport_dev *xport);
-
irqreturn_t (*irq_thread)(int irq, void *p);
irqreturn_t (*hard_irq)(int irq, void *p);

void *data;

-   struct rmi_transport_info info;
+   const char *proto_name;
+   const struct rmi_transport_ops *ops;
+   struct rmi_transport_stats stats;
+};
+
+/**
+ * struct rmi_transport_ops - defines transport protocol operations.
+ *
+ * @write_block: Writing a block of data to the specified address
+ * @read_block: Read a block of data from the specified address.
+ */
+struct rmi_transport_ops {
+   int (*write_block)(struct rmi_transport_dev *xport, u16 addr,
+  const void *buf, size_t len);
+   int (*read_block)(struct rmi_transport_dev *xport, u16 addr,
+ void *buf, size_t len);
+
+   int (*enable_device) (struct rmi_transport_dev *xport);
+   void (*disable_device) (struct rmi_transport_dev *xport);
  };

  /**
@@ -232,7 +242,7 @@ bool rmi_is_physical_device(struct device *dev);
   */
  static inline int rmi_read(struct rmi_device *d, u16 addr, void *buf)
  {
-   return d->xport->read_block(d->xport, addr, buf, 1);
+   return d->xport->ops->read_block(d->xport, addr, buf, 1);
  }

  /**
@@ -248,7 +258,7 @@ static inline int rmi_read(struct rmi_device *d, u16 addr, 
void *buf)
  static inline int rmi_read_block(struct rmi_device *d, u16 addr, void *buf,
 

Re: [PATCH 3/4] Input: synaptics-rmi4 - fix I2C functionality check

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

When adapter does not support required functionality (I2C_FUNC_I2C) we were
returning 0 to the upper layers, making them believe that device bound
successfully.


Acked-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_i2c.c | 9 -
  1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index cdc8527..c176218 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -193,11 +193,10 @@ static int rmi_i2c_probe(struct i2c_client *client,
pdata->sensor_name ? pdata->sensor_name : "-no name-",
client->addr, pdata->attn_gpio);

-   retval = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
-   if (!retval) {
-   dev_err(>dev, "i2c_check_functionality error %d.\n",
-   retval);
-   return retval;
+   if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+   dev_err(>dev,
+   "adapter does not support required functionality.\n");
+   return -ENODEV;
}

    if (pdata->gpio_config) {




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/4] Input: synaptics-rmi4 - rework transport device allocation

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Instead of allocating common and private part of transport device
separately make private wrap common part and get rid of private data
pointer in the transport device.

Also rename rmi_i2c_data -> rmi_i2c_xport and data -> rmi_i2c.


Acked-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_bus.h |   3 --
  drivers/input/rmi4/rmi_i2c.c | 112 +--
  2 files changed, 56 insertions(+), 59 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index ccf26dc..decb479 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -165,7 +165,6 @@ struct rmi_transport_stats {
   * default irq_thread implementation.
   * @hard_irq: if not NULL, the sensor driver will use this for the hard IRQ
   * handling
- * @data: Private data pointer
   * @proto_name: name of the transport protocol (SPI, i2c, etc)
   * @ops: pointer to transport operations implementation
   * @stats: transport statistics
@@ -181,8 +180,6 @@ struct rmi_transport_dev {
irqreturn_t (*irq_thread)(int irq, void *p);
irqreturn_t (*hard_irq)(int irq, void *p);

-   void *data;
-
const char *proto_name;
const struct rmi_transport_ops *ops;
struct rmi_transport_stats stats;
diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index 40badf3..cdc8527 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -17,22 +17,25 @@
  #define BUFFER_SIZE_INCREMENT 32

  /**
- * struct rmi_i2c_data - stores information for i2c communication
+ * struct rmi_i2c_xport - stores information for i2c communication
+ *
+ * @xport: The transport interface structure
   *
   * @page_mutex: Locks current page to avoid changing pages in unexpected ways.
   * @page: Keeps track of the current virtual page
- * @xport: Pointer to the transport interface
   *
   * @tx_buf: Buffer used for transmitting data to the sensor over i2c.
   * @tx_buf_size: Size of the buffer
   */
-struct rmi_i2c_data {
+struct rmi_i2c_xport {
+   struct rmi_transport_dev xport;
+   struct i2c_client *client;
+
struct mutex page_mutex;
int page;
-   struct rmi_transport_dev *xport;

u8 *tx_buf;
-   int tx_buf_size;
+   size_t tx_buf_size;
  };

  #define RMI_PAGE_SELECT_REGISTER 0xff
@@ -52,10 +55,10 @@ struct rmi_i2c_data {
   *
   * Returns zero on success, non-zero on failure.
   */
-static int rmi_set_page(struct rmi_transport_dev *xport, u8 page)
+static int rmi_set_page(struct rmi_i2c_xport *rmi_i2c, u8 page)
  {
-   struct i2c_client *client = to_i2c_client(xport->dev);
-   struct rmi_i2c_data *data = xport->data;
+   struct rmi_transport_dev *xport = _i2c->xport;
+   struct i2c_client *client = rmi_i2c->client;
u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
int retval;

@@ -70,37 +73,40 @@ static int rmi_set_page(struct rmi_transport_dev *xport, u8 
page)
"%s: set page failed: %d.", __func__, retval);
return (retval < 0) ? retval : -EIO;
}
-   data->page = page;
+   rmi_i2c->page = page;
return 0;
  }

  static int rmi_i2c_write_block(struct rmi_transport_dev *xport, u16 addr,
   const void *buf, size_t len)
  {
-   struct i2c_client *client = to_i2c_client(xport->dev);
-   struct rmi_i2c_data *data = xport->data;
+   struct rmi_i2c_xport *rmi_i2c =
+   container_of(xport, struct rmi_i2c_xport, xport);
+   struct i2c_client *client = rmi_i2c->client;
size_t tx_size = len + 1;
int retval;

-   mutex_lock(>page_mutex);
-
-   if (!data->tx_buf || data->tx_buf_size < tx_size) {
-   if (data->tx_buf)
-   devm_kfree(>dev, data->tx_buf);
-   data->tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
-   data->tx_buf = devm_kzalloc(>dev, data->tx_buf_size,
-   GFP_KERNEL);
-   if (!data->tx_buf) {
-   data->tx_buf_size = 0;
+   mutex_lock(_i2c->page_mutex);
+
+   if (!rmi_i2c->tx_buf || rmi_i2c->tx_buf_size < tx_size) {
+   if (rmi_i2c->tx_buf)
+   devm_kfree(>dev, rmi_i2c->tx_buf);
+   rmi_i2c->tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
+   rmi_i2c->tx_buf = devm_kzalloc(>dev,
+  rmi_i2c->tx_buf_size,
+  GFP_KERNEL);
+   if (!rmi_i2c->tx_buf) {
+   rmi_i2c->tx_buf_size = 0;
retval = -ENOMEM;
goto exit;
}
}
-   data->tx_buf[0] = a

Re: [PATCH 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Instead of using 2 separate transactions when reading from the device let's
use i2c_transfer. Because we now have single point of failure I had to
change how we collect statistics. I elected to drop control data from the
stats and only track number of bytes read/written for the device data.

Also, since we are not prepared to deal with short reads and writes change
read_block_data and write_block_data to indicate error if we detect short
transfers.


We tried this change once before a couple of years ago, but the 
conversion was unsuccessful on some older platforms.  I've tested it on 
some more current platforms, though, and it works there.  The old 
platforms are running 2.6.xx series kernels, and don't look likely ever 
to be updated, So


Acked-by: Christopher Heiny 



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_i2c.c | 71 
  1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index c176218..51f5bc8 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -57,22 +57,17 @@ struct rmi_i2c_xport {
   */
  static int rmi_set_page(struct rmi_i2c_xport *rmi_i2c, u8 page)
  {
-   struct rmi_transport_dev *xport = _i2c->xport;
struct i2c_client *client = rmi_i2c->client;
u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
int retval;

-   dev_dbg(>dev, "writes 3 bytes: %02x %02x\n",
-   txbuf[0], txbuf[1]);
-   xport->stats.tx_count++;
-   xport->stats.tx_bytes += sizeof(txbuf);
retval = i2c_master_send(client, txbuf, sizeof(txbuf));
if (retval != sizeof(txbuf)) {
-   xport->stats.tx_errs++;
dev_err(>dev,
"%s: set page failed: %d.", __func__, retval);
return (retval < 0) ? retval : -EIO;
}
+
rmi_i2c->page = page;
return 0;
  }
@@ -107,22 +102,27 @@ static int rmi_i2c_write_block(struct rmi_transport_dev 
*xport, u16 addr,

if (RMI_I2C_PAGE(addr) != rmi_i2c->page) {
retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
-   if (retval < 0)
+   if (retval)
goto exit;
}

+   retval = i2c_master_send(client, rmi_i2c->tx_buf, tx_size);
+   if (retval == tx_size)
+   retval = 0;
+   else if (retval >= 0)
+   retval = -EIO;
+
+exit:
dev_dbg(>dev,
-   "writes %zd bytes at %#06x: %*ph\n", len, addr, (int)len, buf);
+   "write %zd bytes at %#06x: %d (%*ph)\n",
+   len, addr, retval, (int)len, buf);

xport->stats.tx_count++;
-   xport->stats.tx_bytes += tx_size;
-   retval = i2c_master_send(client, rmi_i2c->tx_buf, tx_size);
-   if (retval < 0)
+   if (retval)
xport->stats.tx_errs++;
else
-   retval--; /* don't count the address byte */
+   xport->stats.tx_bytes += len;

-exit:
mutex_unlock(_i2c->page_mutex);
return retval;
  }
@@ -133,40 +133,47 @@ static int rmi_i2c_read_block(struct rmi_transport_dev 
*xport, u16 addr,
struct rmi_i2c_xport *rmi_i2c =
container_of(xport, struct rmi_i2c_xport, xport);
struct i2c_client *client = rmi_i2c->client;
-   u8 txbuf[1] = {addr & 0xff};
+   u8 addr_offset = addr & 0xff;
int retval;
+   struct i2c_msg msgs[] = {
+   {
+   .addr   = client->addr,
+   .len= sizeof(addr_offset),
+   .buf= _offset,
+   },
+   {
+   .addr   = client->addr,
+   .flags  = I2C_M_RD,
+   .len= len,
+   .buf= buf,
+   },
+   };

mutex_lock(_i2c->page_mutex);

if (RMI_I2C_PAGE(addr) != rmi_i2c->page) {
retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
-   if (retval < 0)
+   if (retval)
goto exit;
}

-   dev_dbg(>dev, "writes 1 bytes: %02x\n", txbuf[0]);
+   retval = i2c_transfer(client->adapter, msgs, sizeof(msgs));
+   if (retval == sizeof(msgs))
+   retval = 0; /* success */
+   else if (retval >= 0)
+   retval = -EIO;

-   xport->stats.tx_count++;
-   xport->stats.tx_bytes += sizeof(txbuf);
-   retval = i2c_master_send(client, txbuf, sizeof(txbuf));
-   if (retval != sizeof(txbuf)) {
-   xport->stats.tx_errs++;
-   retval = (retval < 0) ? retval : -EIO;
-   goto exit;
-   }
+exit:
+   dev_dbg(

Re: [PATCH 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Instead of using 2 separate transactions when reading from the device let's
use i2c_transfer. Because we now have single point of failure I had to
change how we collect statistics. I elected to drop control data from the
stats and only track number of bytes read/written for the device data.

Also, since we are not prepared to deal with short reads and writes change
read_block_data and write_block_data to indicate error if we detect short
transfers.


We tried this change once before a couple of years ago, but the 
conversion was unsuccessful on some older platforms.  I've tested it on 
some more current platforms, though, and it works there.  The old 
platforms are running 2.6.xx series kernels, and don't look likely ever 
to be updated, So


Acked-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_i2c.c | 71 
  1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index c176218..51f5bc8 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -57,22 +57,17 @@ struct rmi_i2c_xport {
   */
  static int rmi_set_page(struct rmi_i2c_xport *rmi_i2c, u8 page)
  {
-   struct rmi_transport_dev *xport = rmi_i2c-xport;
struct i2c_client *client = rmi_i2c-client;
u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
int retval;

-   dev_dbg(client-dev, writes 3 bytes: %02x %02x\n,
-   txbuf[0], txbuf[1]);
-   xport-stats.tx_count++;
-   xport-stats.tx_bytes += sizeof(txbuf);
retval = i2c_master_send(client, txbuf, sizeof(txbuf));
if (retval != sizeof(txbuf)) {
-   xport-stats.tx_errs++;
dev_err(client-dev,
%s: set page failed: %d., __func__, retval);
return (retval  0) ? retval : -EIO;
}
+
rmi_i2c-page = page;
return 0;
  }
@@ -107,22 +102,27 @@ static int rmi_i2c_write_block(struct rmi_transport_dev 
*xport, u16 addr,

if (RMI_I2C_PAGE(addr) != rmi_i2c-page) {
retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
-   if (retval  0)
+   if (retval)
goto exit;
}

+   retval = i2c_master_send(client, rmi_i2c-tx_buf, tx_size);
+   if (retval == tx_size)
+   retval = 0;
+   else if (retval = 0)
+   retval = -EIO;
+
+exit:
dev_dbg(client-dev,
-   writes %zd bytes at %#06x: %*ph\n, len, addr, (int)len, buf);
+   write %zd bytes at %#06x: %d (%*ph)\n,
+   len, addr, retval, (int)len, buf);

xport-stats.tx_count++;
-   xport-stats.tx_bytes += tx_size;
-   retval = i2c_master_send(client, rmi_i2c-tx_buf, tx_size);
-   if (retval  0)
+   if (retval)
xport-stats.tx_errs++;
else
-   retval--; /* don't count the address byte */
+   xport-stats.tx_bytes += len;

-exit:
mutex_unlock(rmi_i2c-page_mutex);
return retval;
  }
@@ -133,40 +133,47 @@ static int rmi_i2c_read_block(struct rmi_transport_dev 
*xport, u16 addr,
struct rmi_i2c_xport *rmi_i2c =
container_of(xport, struct rmi_i2c_xport, xport);
struct i2c_client *client = rmi_i2c-client;
-   u8 txbuf[1] = {addr  0xff};
+   u8 addr_offset = addr  0xff;
int retval;
+   struct i2c_msg msgs[] = {
+   {
+   .addr   = client-addr,
+   .len= sizeof(addr_offset),
+   .buf= addr_offset,
+   },
+   {
+   .addr   = client-addr,
+   .flags  = I2C_M_RD,
+   .len= len,
+   .buf= buf,
+   },
+   };

mutex_lock(rmi_i2c-page_mutex);

if (RMI_I2C_PAGE(addr) != rmi_i2c-page) {
retval = rmi_set_page(rmi_i2c, RMI_I2C_PAGE(addr));
-   if (retval  0)
+   if (retval)
goto exit;
}

-   dev_dbg(client-dev, writes 1 bytes: %02x\n, txbuf[0]);
+   retval = i2c_transfer(client-adapter, msgs, sizeof(msgs));
+   if (retval == sizeof(msgs))
+   retval = 0; /* success */
+   else if (retval = 0)
+   retval = -EIO;

-   xport-stats.tx_count++;
-   xport-stats.tx_bytes += sizeof(txbuf);
-   retval = i2c_master_send(client, txbuf, sizeof(txbuf));
-   if (retval != sizeof(txbuf)) {
-   xport-stats.tx_errs++;
-   retval = (retval  0) ? retval : -EIO;
-   goto exit;
-   }
+exit:
+   dev_dbg(client-dev,
+   read %zd bytes at %#06x: %d (%*ph)\n,
+   len, addr, retval, (int)len, buf

Re: [PATCH 3/4] Input: synaptics-rmi4 - fix I2C functionality check

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

When adapter does not support required functionality (I2C_FUNC_I2C) we were
returning 0 to the upper layers, making them believe that device bound
successfully.


Acked-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_i2c.c | 9 -
  1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index cdc8527..c176218 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -193,11 +193,10 @@ static int rmi_i2c_probe(struct i2c_client *client,
pdata-sensor_name ? pdata-sensor_name : -no name-,
client-addr, pdata-attn_gpio);

-   retval = i2c_check_functionality(client-adapter, I2C_FUNC_I2C);
-   if (!retval) {
-   dev_err(client-dev, i2c_check_functionality error %d.\n,
-   retval);
-   return retval;
+   if (!i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) {
+   dev_err(client-dev,
+   adapter does not support required functionality.\n);
+   return -ENODEV;
}

if (pdata-gpio_config) {




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/4] Input: synaptics-rmi4 - rework transport device allocation

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Instead of allocating common and private part of transport device
separately make private wrap common part and get rid of private data
pointer in the transport device.

Also rename rmi_i2c_data - rmi_i2c_xport and data - rmi_i2c.


Acked-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_bus.h |   3 --
  drivers/input/rmi4/rmi_i2c.c | 112 +--
  2 files changed, 56 insertions(+), 59 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index ccf26dc..decb479 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -165,7 +165,6 @@ struct rmi_transport_stats {
   * default irq_thread implementation.
   * @hard_irq: if not NULL, the sensor driver will use this for the hard IRQ
   * handling
- * @data: Private data pointer
   * @proto_name: name of the transport protocol (SPI, i2c, etc)
   * @ops: pointer to transport operations implementation
   * @stats: transport statistics
@@ -181,8 +180,6 @@ struct rmi_transport_dev {
irqreturn_t (*irq_thread)(int irq, void *p);
irqreturn_t (*hard_irq)(int irq, void *p);

-   void *data;
-
const char *proto_name;
const struct rmi_transport_ops *ops;
struct rmi_transport_stats stats;
diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index 40badf3..cdc8527 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -17,22 +17,25 @@
  #define BUFFER_SIZE_INCREMENT 32

  /**
- * struct rmi_i2c_data - stores information for i2c communication
+ * struct rmi_i2c_xport - stores information for i2c communication
+ *
+ * @xport: The transport interface structure
   *
   * @page_mutex: Locks current page to avoid changing pages in unexpected ways.
   * @page: Keeps track of the current virtual page
- * @xport: Pointer to the transport interface
   *
   * @tx_buf: Buffer used for transmitting data to the sensor over i2c.
   * @tx_buf_size: Size of the buffer
   */
-struct rmi_i2c_data {
+struct rmi_i2c_xport {
+   struct rmi_transport_dev xport;
+   struct i2c_client *client;
+
struct mutex page_mutex;
int page;
-   struct rmi_transport_dev *xport;

u8 *tx_buf;
-   int tx_buf_size;
+   size_t tx_buf_size;
  };

  #define RMI_PAGE_SELECT_REGISTER 0xff
@@ -52,10 +55,10 @@ struct rmi_i2c_data {
   *
   * Returns zero on success, non-zero on failure.
   */
-static int rmi_set_page(struct rmi_transport_dev *xport, u8 page)
+static int rmi_set_page(struct rmi_i2c_xport *rmi_i2c, u8 page)
  {
-   struct i2c_client *client = to_i2c_client(xport-dev);
-   struct rmi_i2c_data *data = xport-data;
+   struct rmi_transport_dev *xport = rmi_i2c-xport;
+   struct i2c_client *client = rmi_i2c-client;
u8 txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
int retval;

@@ -70,37 +73,40 @@ static int rmi_set_page(struct rmi_transport_dev *xport, u8 
page)
%s: set page failed: %d., __func__, retval);
return (retval  0) ? retval : -EIO;
}
-   data-page = page;
+   rmi_i2c-page = page;
return 0;
  }

  static int rmi_i2c_write_block(struct rmi_transport_dev *xport, u16 addr,
   const void *buf, size_t len)
  {
-   struct i2c_client *client = to_i2c_client(xport-dev);
-   struct rmi_i2c_data *data = xport-data;
+   struct rmi_i2c_xport *rmi_i2c =
+   container_of(xport, struct rmi_i2c_xport, xport);
+   struct i2c_client *client = rmi_i2c-client;
size_t tx_size = len + 1;
int retval;

-   mutex_lock(data-page_mutex);
-
-   if (!data-tx_buf || data-tx_buf_size  tx_size) {
-   if (data-tx_buf)
-   devm_kfree(client-dev, data-tx_buf);
-   data-tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
-   data-tx_buf = devm_kzalloc(client-dev, data-tx_buf_size,
-   GFP_KERNEL);
-   if (!data-tx_buf) {
-   data-tx_buf_size = 0;
+   mutex_lock(rmi_i2c-page_mutex);
+
+   if (!rmi_i2c-tx_buf || rmi_i2c-tx_buf_size  tx_size) {
+   if (rmi_i2c-tx_buf)
+   devm_kfree(client-dev, rmi_i2c-tx_buf);
+   rmi_i2c-tx_buf_size = tx_size + BUFFER_SIZE_INCREMENT;
+   rmi_i2c-tx_buf = devm_kzalloc(client-dev,
+  rmi_i2c-tx_buf_size,
+  GFP_KERNEL);
+   if (!rmi_i2c-tx_buf) {
+   rmi_i2c-tx_buf_size = 0;
retval = -ENOMEM;
goto exit;
}
}
-   data-tx_buf[0] = addr  0xff;
-   memcpy(data-tx_buf + 1, buf, len);

-   if (RMI_I2C_PAGE(addr

Re: [PATCH 1/4] Input: synaptics-rmi4 - split of transport ops into a separate structure

2014-01-10 Thread Christopher Heiny

On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:

Split off transport operations from rmi_transport_dev into a separate
structure that will be shared between all devices using the same transport
and use const pointer to access it.

Change signature on transport methods so that length is using the proper
tyep - size_t.

Also rename rmi_transport_info to rmi_transport_stats and move protocol
name (which is the only immutable piece of data there) into the transport
device itself.


Acked-by: Christopher Heiny che...@synaptics.com



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_bus.h| 64 -
  drivers/input/rmi4/rmi_driver.c |  8 +++---
  drivers/input/rmi4/rmi_i2c.c| 49 ---
  3 files changed, 67 insertions(+), 54 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index 3e8b57a..ccf26dc 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -135,26 +135,25 @@ struct rmi_driver {
  #define to_rmi_driver(d) \
container_of(d, struct rmi_driver, driver);

-/** struct rmi_transport_info - diagnostic information about the RMI transport
+/**
+ * struct rmi_transport_stats - diagnostic information about the RMI transport
   * device, used in the xport_info debugfs file.
   *
   * @proto String indicating the protocol being used.
   * @tx_count Number of transmit operations.
- * @tx_bytes Number of bytes transmitted.
   * @tx_errs  Number of errors encountered during transmit operations.
+ * @tx_bytes Number of bytes transmitted.
   * @rx_count Number of receive operations.
- * @rx_bytes Number of bytes received.
   * @rx_errs  Number of errors encountered during receive operations.
- * @att_count Number of times ATTN assertions have been handled.
+ * @rx_bytes Number of bytes received.
   */
-struct rmi_transport_info {
-   const char *proto;
-   long tx_count;
-   long tx_bytes;
-   long tx_errs;
-   long rx_count;
-   long rx_bytes;
-   long rx_errs;
+struct rmi_transport_stats {
+   unsigned long tx_count;
+   unsigned long tx_errs;
+   size_t tx_bytes;
+   unsigned long rx_count;
+   unsigned long rx_errs;
+   size_t rx_bytes;
  };

  /**
@@ -162,13 +161,14 @@ struct rmi_transport_info {
   *
   * @dev: Pointer to the communication device, e.g. i2c or spi
   * @rmi_dev: Pointer to the RMI device
- * @write_block: Writing a block of data to the specified address
- * @read_block: Read a block of data from the specified address.
   * @irq_thread: if not NULL, the sensor driver will use this instead of the
   * default irq_thread implementation.
   * @hard_irq: if not NULL, the sensor driver will use this for the hard IRQ
   * handling
   * @data: Private data pointer
+ * @proto_name: name of the transport protocol (SPI, i2c, etc)
+ * @ops: pointer to transport operations implementation
+ * @stats: transport statistics
   *
   * The RMI transport device implements the glue between different 
communication
   * buses such as I2C and SPI.
@@ -178,20 +178,30 @@ struct rmi_transport_dev {
struct device *dev;
struct rmi_device *rmi_dev;

-   int (*write_block)(struct rmi_transport_dev *xport, u16 addr,
-  const void *buf, const int len);
-   int (*read_block)(struct rmi_transport_dev *xport, u16 addr,
- void *buf, const int len);
-
-   int (*enable_device) (struct rmi_transport_dev *xport);
-   void (*disable_device) (struct rmi_transport_dev *xport);
-
irqreturn_t (*irq_thread)(int irq, void *p);
irqreturn_t (*hard_irq)(int irq, void *p);

void *data;

-   struct rmi_transport_info info;
+   const char *proto_name;
+   const struct rmi_transport_ops *ops;
+   struct rmi_transport_stats stats;
+};
+
+/**
+ * struct rmi_transport_ops - defines transport protocol operations.
+ *
+ * @write_block: Writing a block of data to the specified address
+ * @read_block: Read a block of data from the specified address.
+ */
+struct rmi_transport_ops {
+   int (*write_block)(struct rmi_transport_dev *xport, u16 addr,
+  const void *buf, size_t len);
+   int (*read_block)(struct rmi_transport_dev *xport, u16 addr,
+ void *buf, size_t len);
+
+   int (*enable_device) (struct rmi_transport_dev *xport);
+   void (*disable_device) (struct rmi_transport_dev *xport);
  };

  /**
@@ -232,7 +242,7 @@ bool rmi_is_physical_device(struct device *dev);
   */
  static inline int rmi_read(struct rmi_device *d, u16 addr, void *buf)
  {
-   return d-xport-read_block(d-xport, addr, buf, 1);
+   return d-xport-ops-read_block(d-xport, addr, buf, 1);
  }

  /**
@@ -248,7 +258,7 @@ static inline int rmi_read(struct rmi_device *d, u16 addr, 
void *buf)
  static inline int rmi_read_block(struct rmi_device *d, u16 addr, void *buf

RE: [PATCH 1/1] drivers: input: touchscreen: Initial support for SYNAPTICS_I2C_RMI touchscreen

2013-07-08 Thread Christopher Heiny
Sorry if this is a duplicate - there's some email issues here at work.

On 07/08/2013 03:39 PM, Dmitry Torokhov wrote:
> On Monday, July 08, 2013 10:21:16 PM Christopher Heiny wrote:
>> On 07/08/2013 01:25 AM, Balint Czobor wrote:
>>> Add initial support for Synaptics RMI over I2C based touchscreens.
>>
>> This is pretty old code - it looks like a modification of patches we
>> submitted last year.  Is there some reason you're not basing it off the
>> latest checkins in synaptics-rmi4 branch of  Dmitry's input tree?
>
> That branch is fairly old as well, I believe you have much never
> version on Github?

Yes, I do, but I figured your branch was the reference.

Balint - there newest code is here:

https://github.com/mightybigcar/synaptics-rmi4

There are two branches.  The main branch tracks work intended for the
next submission.The development branch is a superset of that work,
including all currently supported and in development RMI4 function
implementations.

If you would like to integrate that work into your kernel, I'll be happy
to help out with that (and I suspect Dmitry and others would be too).

Thanks,
Chris

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 1/1] drivers: input: touchscreen: Initial support for SYNAPTICS_I2C_RMI touchscreen

2013-07-08 Thread Christopher Heiny
On 07/08/2013 01:25 AM, Balint Czobor wrote:
> Add initial support for Synaptics RMI over I2C based touchscreens.

This is pretty old code - it looks like a modification of patches we
submitted last year.  Is there some reason you're not basing it off the
latest checkins in synaptics-rmi4 branch of  Dmitry's input tree?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 1/1] drivers: input: touchscreen: Initial support for SYNAPTICS_I2C_RMI touchscreen

2013-07-08 Thread Christopher Heiny
On 07/08/2013 01:25 AM, Balint Czobor wrote:
 Add initial support for Synaptics RMI over I2C based touchscreens.

This is pretty old code - it looks like a modification of patches we
submitted last year.  Is there some reason you're not basing it off the
latest checkins in synaptics-rmi4 branch of  Dmitry's input tree?

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 1/1] drivers: input: touchscreen: Initial support for SYNAPTICS_I2C_RMI touchscreen

2013-07-08 Thread Christopher Heiny
Sorry if this is a duplicate - there's some email issues here at work.

On 07/08/2013 03:39 PM, Dmitry Torokhov wrote:
 On Monday, July 08, 2013 10:21:16 PM Christopher Heiny wrote:
 On 07/08/2013 01:25 AM, Balint Czobor wrote:
 Add initial support for Synaptics RMI over I2C based touchscreens.

 This is pretty old code - it looks like a modification of patches we
 submitted last year.  Is there some reason you're not basing it off the
 latest checkins in synaptics-rmi4 branch of  Dmitry's input tree?

 That branch is fairly old as well, I believe you have much never
 version on Github?

Yes, I do, but I figured your branch was the reference.

Balint - there newest code is here:

https://github.com/mightybigcar/synaptics-rmi4

There are two branches.  The main branch tracks work intended for the
next submission.The development branch is a superset of that work,
including all currently supported and in development RMI4 function
implementations.

If you would like to integrate that work into your kernel, I'll be happy
to help out with that (and I suspect Dmitry and others would be too).

Thanks,
Chris

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 04/05] input: RMI4 F01 device control

2013-02-07 Thread Christopher Heiny

On 01/31/2013 01:14 PM, Christopher Heiny wrote:

On 01/31/2013 12:08 AM, Dmitry Torokhov wrote:

Hi Chris,

On Fri, Jan 18, 2013 at 05:12:44PM -0800, Christopher Heiny wrote:

In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.


I was looking at the various aspects of the RMI4 patchset, trying to
fix the issues that I see, but there is one big issue that I simply do
not have time to tackle - the driver is completely broken on big endian
architectures due to reliance on bitfileds when exchanging the data with
the device.


Grumble.  I brought this up during the original development, but was
assured that it would work fine per the C language spec.  I'll have to
revisit that discussion and report back.


OK, after some trivial research it turns out you're right, and I was 
right originally, but let myself be blindsided by bafflegab.  Doh!


As you mentioned, fixing the endian-ness problem is a pretty wide 
ranging change to the way things are done in the driver.  Fortunately 
it's not a structural change to the architecture of the driver.


But because it affects pretty much the whole code (which is actually a 
LOT more code than we're currently submitting - but that unsubmitted 
code will have to be updated concurrently with the submitted code to 
prevent a trainwreck), I'd like to isolate that fix to a single event.


So I propose we get all our other issues worked out, since a bunch of 
them are already in progress.  Once that stuff is stable, my team can do 
one big change to fix the endian bug.  If the code is stable, we can do 
the update on our end pretty quickly.


How does that sound?

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 04/05] input: RMI4 F01 device control

2013-02-07 Thread Christopher Heiny

On 01/31/2013 01:14 PM, Christopher Heiny wrote:

On 01/31/2013 12:08 AM, Dmitry Torokhov wrote:

Hi Chris,

On Fri, Jan 18, 2013 at 05:12:44PM -0800, Christopher Heiny wrote:

In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.


I was looking at the various aspects of the RMI4 patchset, trying to
fix the issues that I see, but there is one big issue that I simply do
not have time to tackle - the driver is completely broken on big endian
architectures due to reliance on bitfileds when exchanging the data with
the device.


Grumble.  I brought this up during the original development, but was
assured that it would work fine per the C language spec.  I'll have to
revisit that discussion and report back.


OK, after some trivial research it turns out you're right, and I was 
right originally, but let myself be blindsided by bafflegab.  Doh!


As you mentioned, fixing the endian-ness problem is a pretty wide 
ranging change to the way things are done in the driver.  Fortunately 
it's not a structural change to the architecture of the driver.


But because it affects pretty much the whole code (which is actually a 
LOT more code than we're currently submitting - but that unsubmitted 
code will have to be updated concurrently with the submitted code to 
prevent a trainwreck), I'd like to isolate that fix to a single event.


So I propose we get all our other issues worked out, since a bunch of 
them are already in progress.  Once that stuff is stable, my team can do 
one big change to fix the endian bug.  If the code is stable, we can do 
the update on our end pretty quickly.


How does that sound?

Chris
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 04/05] input: RMI4 F01 device control

2013-01-31 Thread Christopher Heiny

On 01/31/2013 12:08 AM, Dmitry Torokhov wrote:

Hi Chris,

On Fri, Jan 18, 2013 at 05:12:44PM -0800, Christopher Heiny wrote:

In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.


I was looking at the various aspects of the RMI4 patchset, trying to
fix the issues that I see, but there is one big issue that I simply do
not have time to tackle - the driver is completely broken on big endian
architectures due to reliance on bitfileds when exchanging the data with
the device.


Grumble.  I brought this up during the original development, but was 
assured that it would work fine per the C language spec.  I'll have to 
revisit that discussion and report back.


Also, I noticed you merged F01 header into F01.  That's going to have to 
be backed out, because F05, F34, and F54 are also interested in the F01 
stuff, as is the (proposed) F01 diagnostic module.  We just aren't 
submitting that code right now in order to keep the code down to a 
managable size.



Consider the following structures:


  struct f01_device_status {
-   u8 status_code:4;
+   enum rmi_device_status status_code:4;
u8 reserved:2;
u8 flash_prog:1;
u8 unconfigured:1;
@@ -159,4 +136,113 @@ struct f01_device_control_0 {
u8 configured:1;
  } __attribute__((__packed__));

+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+struct f01_device_commands {
+   u8 reset:1;
+   u8 reserved:7;
+};
+


To make this work on BE boxes you either need to add #ifdefs to the
structures reversing the order of fields or use bit shifts and masks to
get/set specific bits in bytes.

I tried converting F01 code (you can see the [likely broken as I can't
test] result in my tree), but I really do not have time for F11.

Thanks.




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 04/05] input: RMI4 F01 device control

2013-01-31 Thread Christopher Heiny

On 01/31/2013 12:08 AM, Dmitry Torokhov wrote:

Hi Chris,

On Fri, Jan 18, 2013 at 05:12:44PM -0800, Christopher Heiny wrote:

In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.


I was looking at the various aspects of the RMI4 patchset, trying to
fix the issues that I see, but there is one big issue that I simply do
not have time to tackle - the driver is completely broken on big endian
architectures due to reliance on bitfileds when exchanging the data with
the device.


Grumble.  I brought this up during the original development, but was 
assured that it would work fine per the C language spec.  I'll have to 
revisit that discussion and report back.


Also, I noticed you merged F01 header into F01.  That's going to have to 
be backed out, because F05, F34, and F54 are also interested in the F01 
stuff, as is the (proposed) F01 diagnostic module.  We just aren't 
submitting that code right now in order to keep the code down to a 
managable size.



Consider the following structures:


  struct f01_device_status {
-   u8 status_code:4;
+   enum rmi_device_status status_code:4;
u8 reserved:2;
u8 flash_prog:1;
u8 unconfigured:1;
@@ -159,4 +136,113 @@ struct f01_device_control_0 {
u8 configured:1;
  } __attribute__((__packed__));

+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+struct f01_device_commands {
+   u8 reset:1;
+   u8 reserved:7;
+};
+


To make this work on BE boxes you either need to add #ifdefs to the
structures reversing the order of fields or use bit shifts and masks to
get/set specific bits in bytes.

I tried converting F01 code (you can see the [likely broken as I can't
test] result in my tree), but I really do not have time for F11.

Thanks.




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/05] input: RMI4 I2C physical layer

2013-01-18 Thread Christopher Heiny
Changes here are limited to those described in the 0/5 of this patchset, plus
some tweaks to debugging output.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_i2c.c |  141 ++
 1 files changed, 20 insertions(+), 121 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index ca32101..513791c 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include 
@@ -58,7 +48,7 @@ struct rmi_i2c_data {
u8 *debug_buf;
int debug_buf_size;
 
-   bool comms_debug;
+   u32 comms_debug;
 #ifdef CONFIG_RMI4_DEBUG
struct dentry *debugfs_comms;
 #endif
@@ -66,107 +56,13 @@ struct rmi_i2c_data {
 
 #ifdef CONFIG_RMI4_DEBUG
 
-
-/**
- * struct i2c_debugfs_data - stores information for debugfs
- *
- * @done: Indicates that we are done reading debug data. Subsequent reads
- * will return EOF.
- * @i2c_data: Pointer to the i2c data
- *
- */
-struct i2c_debugfs_data {
-   bool done;
-   struct rmi_i2c_data *i2c_data;
-};
-
-static int debug_open(struct inode *inodep, struct file *filp)
-{
-   struct i2c_debugfs_data *data;
-
-   data = kzalloc(sizeof(struct i2c_debugfs_data), GFP_KERNEL);
-   if (!data)
-   return -ENOMEM;
-
-   data->i2c_data = inodep->i_private;
-   filp->private_data = data;
-   return 0;
-}
-
-static int debug_release(struct inode *inodep, struct file *filp)
-{
-   kfree(filp->private_data);
-   return 0;
-}
-
-static ssize_t comms_debug_read(struct file *filp, char __user *buffer,
-   size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   struct i2c_debugfs_data *dfs = filp->private_data;
-   struct rmi_i2c_data *data = dfs->i2c_data;
-
-   if (dfs->done)
-   return 0;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-
-   dfs->done = 1;
-
-   retval = snprintf(local_buf, PAGE_SIZE, "%u\n", data->comms_debug);
-
-   if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
-   retval = -EFAULT;
-   kfree(local_buf);
-
-   return retval;
-}
-
-static ssize_t comms_debug_write(struct file *filp, const char __user *buffer,
-  size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   unsigned int new_value;
-   struct i2c_debugfs_data *dfs = filp->private_data;
-   struct rmi_i2c_data *data = dfs->i2c_data;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-   retval = copy_from_user(local_buf, buffer, size);
-   if (retval) {
-   kfree(local_buf);
-   return -EFAULT;
-   }
-
-   retval = sscanf(local_buf, "%u", _value);
-   kfree(local_buf);
-   if (retval != 1 || new_value > 1)
-   return -EINVAL;
-
-   data->comms_debug = new_value;
-
-   return size;
-}
-
-
-static const struct file_operations comms_debug_fops = {
-   .owner = THIS_MODULE,
-   .open = debug_open,
-   .release = debug_release,
-   .read = comms_debug_read,
-   .write = comms_debug_write,
-};
-
 static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data *data)
 {
if (!rmi_dev->debugfs_root)
return -ENODEV;
 
-   data->debugfs_comms = debugfs_create_file("comms_debug", RMI_RW_ATTR,
-   rmi_dev->debugfs_root, data, _debug_fops);
+   data->debugfs_comms = debugfs_create_bool("comms_debug", RMI_RW_ATTR,
+   rmi_dev->debugfs_root, >comms_debug);
if (!data->debugfs_comms || IS_ERR(data->debugfs_comms)) {
  

[PATCH 04/05] input: RMI4 F01 device control

2013-01-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_f01.c | 1113 ++
 drivers/input/rmi4/rmi_f01.h |  138 +-
 2 files changed, 250 insertions(+), 1001 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index d7461d7..67afdeb 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -2,902 +2,64 @@
  * Copyright (c) 2011-2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
+
 #include "rmi_driver.h"
 #include "rmi_f01.h"
 
-/**
- * @reset - set this bit to force a firmware reset of the sensor.
- */
-struct f01_device_commands {
-   u8 reset:1;
-   u8 reserved:7;
-};
-
-/**
- * @ctrl0 - see documentation in rmi_f01.h.
- * @interrupt_enable - A mask of per-function interrupts on the touch sensor.
- * @doze_interval - controls the interval between checks for finger presence
- * when the touch sensor is in doze mode, in units of 10ms.
- * @wakeup_threshold - controls the capacitance threshold at which the touch
- * sensor will decide to wake up from that low power state.
- * @doze_holdoff - controls how long the touch sensor waits after the last
- * finger lifts before entering the doze state, in units of 100ms.
- */
-struct f01_device_control {
-   struct f01_device_control_0 ctrl0;
-   u8 *interrupt_enable;
-   u8 doze_interval;
-   u8 wakeup_threshold;
-   u8 doze_holdoff;
-};
-
-/**
- * @has_ds4_queries - if true, the query registers relating to Design Studio 4
- * features are present.
- * @has_multi_phy - if true, multiple physical communications interfaces are
- * supported.
- * @has_guest - if true, a "guest" device is supported.
- */
-struct f01_query_42 {
-   u8 has_ds4_queries:1;
-   u8 has_multi_phy:1;
-   u8 has_guest:1;
-   u8 reserved:5;
-} __attribute__((__packed__));
-
-/**
- * @length - the length of the remaining Query43.* register block, not
- * including the first register.
- * @has_package_id_query -  the package ID query data will be accessible from
- * inside the ProductID query registers.
- * @has_packrat_query -  the packrat query data will be accessible from inside
- * the ProductID query registers.
- * @has_reset_query - the reset pin related registers are valid.
- * @has_maskrev_query - the silicon mask revision number will be reported.
- * @has_i2c_control - the register F01_RMI_Ctrl6 will exist.
- * @has_spi_control - the register F01_RMI_Ctrl7 will exist.
- * @has_attn_control - the register F01_RMI_Ctrl8 will exist.
- * @reset_enabled - the hardware reset pin functionality has been enabled
- * for this device.
- * @reset_polarity - If this bit reports as ‘0’, it means that the reset state
- * is active low. A ‘1’ means that the reset state is active high.
- * @pullup_enabled - If set, it indicates that a built-in weak pull up has
- * been enabled on the Reset pin; clear means that no pull-up is present.
- * @reset_pin_number - This field represents which GPIO pin number has been
- * assigned the reset functionality.
- */
-struct f01_ds4_queries {
-   u8 length:4;
-   u8 reserved_1:4;
-
-   u8 has_package_id_query:1;
-   u8 has_packrat_query:1;
-   u8 has_reset_query:1;
-   u8 has_maskrev_query:1;
-   u8 reserved_2:4;
-
-   u8 has_i2c_control:1;
-   u8 has_spi_control:1;
-   u8 has_attn_control:1;
-   u8 reserved_3:5;
-
-   u8 reset_enabled:1;
-   u8 reset_polarity:1;
-   u8 pullup_enabled:1;
-   u8 reserved_4:1;
-   u8 reset_pin_number:4;
-} __attribute__((__packed__));
-
-struct f01_data {
-   struct f01_device_control device_control;
-   struct f01_basic_queries basic_queries;
-   struct f01_device_status device

[PATCH 00/05] input: RMI4 Synaptics RMI4 Touchscreen Driver

2013-01-18 Thread Christopher Heiny
This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patchset is Dmitry's commit
0af25383d395fb5ece54b79d12d06138bf8b9836 from 2012-11-28.  It supersedes
our previous patch submission from 2012-12-18.

Overall this patchset implements the following changes with respect to
the Dmitry's 2012-11-28 commit:

* updates to Dmitry's RMI4_CORE structure from his 2012-11-28 patches.
This tries to maintain the same approach as Dmitry's implementation, but
we had to move away from using the bus probe() routine, since it wasn't
possible for that routine to readily determine if it had a struct driver() for
an RMI4 sensor or an RMI4 device.  Otherwise, we've stuck close to Dmitry's
work, which has tidied things up nicely.

* We've renamed the structures rmi_function_handler to rmi_function_driver and
rmi_device to rmi_function_dev, mainly because they actually were being treated
as drivers and devices for individual RMI4 functions, and the previous
terminology was somewhat confusing.

* Changed a bunch of bools to u32 to support standard debugfs macros.  Moved
almost all the debugfs and sysfs handling out of these files into their own
modules, simplifying the core functionality of the driver.  Once the core is
stable, we can look into adding modules to support the debug/control
features.

* Many other bools were changed to u8, per Dmitry's request.

* Trivial - file copyright header is updated to be more in line with the rest
of the files under ./input.


We've broken this patch into 6 parts, as follows:
01 - public header file
02 - core sensor and bus implementation
03 - I2C physical layer driver
04.05 - drivers for individual RMI functions


Hopefully this is the last time we'll have wide-ranging structural changes in
the driver code, and future patchsets can be much smaller and confined to
one or two areas of interest.


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Jean Delvare 
Cc: Linus Walleij 
Cc: Joeri de Gram 

---
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/05] input: RMI4 core files

2013-01-18 Thread Christopher Heiny
In addition to the changes described in 0/5 of this patch set, these files
are updated as follows:

* initialization sequence rearranged to support the merging of rmi_f01 and
rmi_driver into the RMI4 core.

* the initial reset and firmware update PDT scans are split into their own
functions in order to account for the fact that the PDT may change after
the initial reset.

* Problems with release_rmidev_device() identified by Greg KH are fixed and
tested.

* EXPORT_SYMBOL() changed to EXPORT_SYMBOL_GPL(), per Greg KH input.


Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_bus.c|  232 +-
 drivers/input/rmi4/rmi_driver.c |  988 ---
 drivers/input/rmi4/rmi_driver.h |   32 +-
 3 files changed, 446 insertions(+), 806 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index acbfd3d..71bc201 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include 
@@ -75,7 +65,8 @@ static struct dentry *rmi_debugfs_root;
 
 static void release_rmidev_device(struct device *dev)
 {
-   device_unregister(dev);
+   struct rmi_device *rmi_dev = to_rmi_device(dev);
+   kfree(rmi_dev);
 }
 
 /**
@@ -110,17 +101,19 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_dbg(phys->dev, "%s: Registered %s as %s.\n", __func__,
pdata->sensor_name, dev_name(_dev->dev));
 
-   if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_debugfs_root) {
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_debugfs_root) {
rmi_dev->debugfs_root = debugfs_create_dir(
dev_name(_dev->dev), rmi_debugfs_root);
if (!rmi_dev->debugfs_root)
dev_err(_dev->dev, "Failed to create debugfs 
root.\n");
}
+#endif
 
phys->rmi_dev = rmi_dev;
return device_register(_dev->dev);
 }
-EXPORT_SYMBOL(rmi_register_phys_device);
+EXPORT_SYMBOL_GPL(rmi_register_phys_device);
 
 /**
  * rmi_unregister_phys_device - unregister a physical device connection
@@ -131,102 +124,84 @@ void rmi_unregister_phys_device(struct rmi_phys_device 
*phys)
 {
struct rmi_device *rmi_dev = phys->rmi_dev;
 
-   if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_dev->debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_dev->debugfs_root)
debugfs_remove(rmi_dev->debugfs_root);
+#endif
 
-   kfree(rmi_dev);
+   device_unregister(_dev->dev);
 }
-EXPORT_SYMBOL(rmi_unregister_phys_device);
+EXPORT_SYMBOL_GPL(rmi_unregister_phys_device);
 
-/**
- * rmi_register_function_handler - register a handler for an RMI function
- * @handler: RMI handler that should be registered.
- * @module: pointer to module that implements the handler
- * @mod_name: name of the module implementing the handler
- *
- * This function performs additional setup of RMI function handler and
- * registers it with the RMI core so that it can be bound to
- * RMI function devices.
- */
-int __rmi_register_function_handler(struct rmi_function_handler *handler,
-struct module *owner,
-const char *mod_name)
+static int rmi_bus_match(struct device *dev, struct device_driver *drv)
 {
-   int error;
+   struct rmi_function_driver *fn_drv;
+   struct rmi_function_dev *fn;
 
-   handler->driver.bus = _bus_type;
-   handler->driver.owner = owner;
-   handler->driver.mod_name = mod_name;
+   /*
+* This seems a little broken to me.  It  means a system can only ever
+* have one kind of sensor driver.  It'll work for now, but I think in
+* the long run we need to revisit this.
+*/
+   if (dev->type == _sensor_type && drv == _sensor_driver.driver)
+  

[PATCH 01/05] input: RMI4 public header file

2013-01-18 Thread Christopher Heiny
In addition to the changes described in part 0/5, this fixes some cut
issues in the comments for module_rmi_function_driver.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 include/linux/rmi.h |   95 +++
 1 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index daca41b..eec926f 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -2,25 +2,16 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #ifndef _RMI_H
 #define _RMI_H
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +22,6 @@
 #include 
 #include 
 #include 
-#include 
 
 extern struct bus_type rmi_bus_type;
 
@@ -73,7 +63,7 @@ enum rmi_attn_polarity {
  *   automatically enabled for this sensor.
  */
 struct rmi_f11_2d_axis_alignment {
-   bool swap_axes;
+   u32 swap_axes;
bool flip_x;
bool flip_y;
int clip_X_low;
@@ -82,7 +72,6 @@ struct rmi_f11_2d_axis_alignment {
int clip_Y_high;
int offset_X;
int offset_Y;
-   int rel_report_enabled;
u8 delta_x_threshold;
u8 delta_y_threshold;
 };
@@ -105,6 +94,7 @@ enum rmi_f11_sensor_type {
 
 /**
  * struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
+ *
  * @axis_align - provides axis alignment overrides (see above).
  * @type_a - all modern RMI F11 firmwares implement Multifinger Type B
  * protocol.  Set this to true to force MF Type A behavior, in case you find
@@ -338,13 +328,14 @@ struct rmi_function_descriptor {
u8 function_version;
 };
 
-struct rmi_function;
+struct rmi_function_dev;
 struct rmi_device;
 
 /**
- * struct rmi_function_handler - driver routines for a particular RMI function.
+ * struct rmi_function_driver - driver routines for a particular RMI function.
  *
  * @func: The RMI function number
+ * @probe: Called when the handler is successfully matched to a function 
device.
  * @reset: Called when a reset of the touch sensor is detected.  The routine
  * should perform any out-of-the-ordinary reset handling that might be
  * necessary.  Restoring of touch sensor configuration registers should be
@@ -361,37 +352,31 @@ struct rmi_device;
  *
  * All callbacks are expected to return 0 on success, error code on failure.
  */
-struct rmi_function_handler {
+struct rmi_function_driver {
struct device_driver driver;
 
u8 func;
-   int (*probe)(struct rmi_function *fn);
-   void (*remove)(struct rmi_function *fn);
-   int (*config)(struct rmi_function *fn);
-   int (*reset)(struct rmi_function *fn);
-   int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
+   int (*probe)(struct rmi_function_dev *fc);
+   int (*remove)(struct rmi_function_dev *fc);
+   int (*config)(struct rmi_function_dev *fc);
+   int (*reset)(struct rmi_function_dev *fc);
+   int (*attention)(struct rmi_function_dev *fc,
+   unsigned long *irq_bits);
 #ifdef CONFIG_PM
-   int (*suspend)(struct rmi_function *fn);
-   int (*resume)(struct rmi_function *fn);
+   int (*suspend)(struct rmi_function_dev *fc);
+   int (*resume)(struct rmi_function_dev *fc);
 #endif
 };
 
-#define to_rmi_function_handler(d) \
-   container_of(d, struct rmi_function_handler, driver)
-
-int __must_check __rmi_register_function_handler(struct rmi_function_handler *,
-struct module *, const char *);
-#define rmi_register_function_handler(handler) \
-   __rmi_register_function_handler(handler, THIS_MODULE, KBUILD_MODNAME)
-
-void rmi_unregister_function_handler(struct rmi_function_handler *);
+#define to_rmi_function_driver(d) \
+   container_of(d, struct rmi_function_driver, driver);
 
 /**
- * struct rmi_function - represents the implementation of an RMI4
- * function for a particular device (basically

[PATCH 01/05] input: RMI4 public header file

2013-01-18 Thread Christopher Heiny
In addition to the changes described in part 0/5, this fixes some cutpaste
issues in the comments for module_rmi_function_driver.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 include/linux/rmi.h |   95 +++
 1 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index daca41b..eec926f 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -2,25 +2,16 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #ifndef _RMI_H
 #define _RMI_H
 #include linux/kernel.h
 #include linux/cdev.h
+#include linux/debugfs.h
 #include linux/device.h
 #include linux/interrupt.h
 #include linux/input.h
@@ -31,7 +22,6 @@
 #include linux/stat.h
 #include linux/types.h
 #include linux/wait.h
-#include linux/debugfs.h
 
 extern struct bus_type rmi_bus_type;
 
@@ -73,7 +63,7 @@ enum rmi_attn_polarity {
  *   automatically enabled for this sensor.
  */
 struct rmi_f11_2d_axis_alignment {
-   bool swap_axes;
+   u32 swap_axes;
bool flip_x;
bool flip_y;
int clip_X_low;
@@ -82,7 +72,6 @@ struct rmi_f11_2d_axis_alignment {
int clip_Y_high;
int offset_X;
int offset_Y;
-   int rel_report_enabled;
u8 delta_x_threshold;
u8 delta_y_threshold;
 };
@@ -105,6 +94,7 @@ enum rmi_f11_sensor_type {
 
 /**
  * struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
+ *
  * @axis_align - provides axis alignment overrides (see above).
  * @type_a - all modern RMI F11 firmwares implement Multifinger Type B
  * protocol.  Set this to true to force MF Type A behavior, in case you find
@@ -338,13 +328,14 @@ struct rmi_function_descriptor {
u8 function_version;
 };
 
-struct rmi_function;
+struct rmi_function_dev;
 struct rmi_device;
 
 /**
- * struct rmi_function_handler - driver routines for a particular RMI function.
+ * struct rmi_function_driver - driver routines for a particular RMI function.
  *
  * @func: The RMI function number
+ * @probe: Called when the handler is successfully matched to a function 
device.
  * @reset: Called when a reset of the touch sensor is detected.  The routine
  * should perform any out-of-the-ordinary reset handling that might be
  * necessary.  Restoring of touch sensor configuration registers should be
@@ -361,37 +352,31 @@ struct rmi_device;
  *
  * All callbacks are expected to return 0 on success, error code on failure.
  */
-struct rmi_function_handler {
+struct rmi_function_driver {
struct device_driver driver;
 
u8 func;
-   int (*probe)(struct rmi_function *fn);
-   void (*remove)(struct rmi_function *fn);
-   int (*config)(struct rmi_function *fn);
-   int (*reset)(struct rmi_function *fn);
-   int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
+   int (*probe)(struct rmi_function_dev *fc);
+   int (*remove)(struct rmi_function_dev *fc);
+   int (*config)(struct rmi_function_dev *fc);
+   int (*reset)(struct rmi_function_dev *fc);
+   int (*attention)(struct rmi_function_dev *fc,
+   unsigned long *irq_bits);
 #ifdef CONFIG_PM
-   int (*suspend)(struct rmi_function *fn);
-   int (*resume)(struct rmi_function *fn);
+   int (*suspend)(struct rmi_function_dev *fc);
+   int (*resume)(struct rmi_function_dev *fc);
 #endif
 };
 
-#define to_rmi_function_handler(d) \
-   container_of(d, struct rmi_function_handler, driver)
-
-int __must_check __rmi_register_function_handler(struct rmi_function_handler *,
-struct module *, const char *);
-#define rmi_register_function_handler(handler) \
-   __rmi_register_function_handler(handler, THIS_MODULE, KBUILD_MODNAME)
-
-void rmi_unregister_function_handler(struct

[PATCH 02/05] input: RMI4 core files

2013-01-18 Thread Christopher Heiny
In addition to the changes described in 0/5 of this patch set, these files
are updated as follows:

* initialization sequence rearranged to support the merging of rmi_f01 and
rmi_driver into the RMI4 core.

* the initial reset and firmware update PDT scans are split into their own
functions in order to account for the fact that the PDT may change after
the initial reset.

* Problems with release_rmidev_device() identified by Greg KH are fixed and
tested.

* EXPORT_SYMBOL() changed to EXPORT_SYMBOL_GPL(), per Greg KH input.


Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_bus.c|  232 +-
 drivers/input/rmi4/rmi_driver.c |  988 ---
 drivers/input/rmi4/rmi_driver.h |   32 +-
 3 files changed, 446 insertions(+), 806 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index acbfd3d..71bc201 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include linux/kernel.h
@@ -75,7 +65,8 @@ static struct dentry *rmi_debugfs_root;
 
 static void release_rmidev_device(struct device *dev)
 {
-   device_unregister(dev);
+   struct rmi_device *rmi_dev = to_rmi_device(dev);
+   kfree(rmi_dev);
 }
 
 /**
@@ -110,17 +101,19 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_dbg(phys-dev, %s: Registered %s as %s.\n, __func__,
pdata-sensor_name, dev_name(rmi_dev-dev));
 
-   if (IS_ENABLED(CONFIG_RMI4_DEBUG)  rmi_debugfs_root) {
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_debugfs_root) {
rmi_dev-debugfs_root = debugfs_create_dir(
dev_name(rmi_dev-dev), rmi_debugfs_root);
if (!rmi_dev-debugfs_root)
dev_err(rmi_dev-dev, Failed to create debugfs 
root.\n);
}
+#endif
 
phys-rmi_dev = rmi_dev;
return device_register(rmi_dev-dev);
 }
-EXPORT_SYMBOL(rmi_register_phys_device);
+EXPORT_SYMBOL_GPL(rmi_register_phys_device);
 
 /**
  * rmi_unregister_phys_device - unregister a physical device connection
@@ -131,102 +124,84 @@ void rmi_unregister_phys_device(struct rmi_phys_device 
*phys)
 {
struct rmi_device *rmi_dev = phys-rmi_dev;
 
-   if (IS_ENABLED(CONFIG_RMI4_DEBUG)  rmi_dev-debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_dev-debugfs_root)
debugfs_remove(rmi_dev-debugfs_root);
+#endif
 
-   kfree(rmi_dev);
+   device_unregister(rmi_dev-dev);
 }
-EXPORT_SYMBOL(rmi_unregister_phys_device);
+EXPORT_SYMBOL_GPL(rmi_unregister_phys_device);
 
-/**
- * rmi_register_function_handler - register a handler for an RMI function
- * @handler: RMI handler that should be registered.
- * @module: pointer to module that implements the handler
- * @mod_name: name of the module implementing the handler
- *
- * This function performs additional setup of RMI function handler and
- * registers it with the RMI core so that it can be bound to
- * RMI function devices.
- */
-int __rmi_register_function_handler(struct rmi_function_handler *handler,
-struct module *owner,
-const char *mod_name)
+static int rmi_bus_match(struct device *dev, struct device_driver *drv)
 {
-   int error;
+   struct rmi_function_driver *fn_drv;
+   struct rmi_function_dev *fn;
 
-   handler-driver.bus = rmi_bus_type;
-   handler-driver.owner = owner;
-   handler-driver.mod_name = mod_name;
+   /*
+* This seems a little broken to me.  It  means a system can only ever
+* have one kind of sensor driver.  It'll work for now, but I think in
+* the long run we need to revisit this.
+*/
+   if (dev-type == rmi_sensor_type  drv

[PATCH 00/05] input: RMI4 Synaptics RMI4 Touchscreen Driver

2013-01-18 Thread Christopher Heiny
This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patchset is Dmitry's commit
0af25383d395fb5ece54b79d12d06138bf8b9836 from 2012-11-28.  It supersedes
our previous patch submission from 2012-12-18.

Overall this patchset implements the following changes with respect to
the Dmitry's 2012-11-28 commit:

* updates to Dmitry's RMI4_CORE structure from his 2012-11-28 patches.
This tries to maintain the same approach as Dmitry's implementation, but
we had to move away from using the bus probe() routine, since it wasn't
possible for that routine to readily determine if it had a struct driver() for
an RMI4 sensor or an RMI4 device.  Otherwise, we've stuck close to Dmitry's
work, which has tidied things up nicely.

* We've renamed the structures rmi_function_handler to rmi_function_driver and
rmi_device to rmi_function_dev, mainly because they actually were being treated
as drivers and devices for individual RMI4 functions, and the previous
terminology was somewhat confusing.

* Changed a bunch of bools to u32 to support standard debugfs macros.  Moved
almost all the debugfs and sysfs handling out of these files into their own
modules, simplifying the core functionality of the driver.  Once the core is
stable, we can look into adding modules to support the debug/control
features.

* Many other bools were changed to u8, per Dmitry's request.

* Trivial - file copyright header is updated to be more in line with the rest
of the files under ./input.


We've broken this patch into 6 parts, as follows:
01 - public header file
02 - core sensor and bus implementation
03 - I2C physical layer driver
04.05 - drivers for individual RMI functions


Hopefully this is the last time we'll have wide-ranging structural changes in
the driver code, and future patchsets can be much smaller and confined to
one or two areas of interest.


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Jean Delvare kh...@linux-fr.org
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com

---
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 04/05] input: RMI4 F01 device control

2013-01-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes device serialization updated to conform to the latest RMI4
specification.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_f01.c | 1113 ++
 drivers/input/rmi4/rmi_f01.h |  138 +-
 2 files changed, 250 insertions(+), 1001 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index d7461d7..67afdeb 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -2,902 +2,64 @@
  * Copyright (c) 2011-2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include linux/kernel.h
-#include linux/debugfs.h
 #include linux/kconfig.h
 #include linux/rmi.h
 #include linux/slab.h
 #include linux/uaccess.h
+
 #include rmi_driver.h
 #include rmi_f01.h
 
-/**
- * @reset - set this bit to force a firmware reset of the sensor.
- */
-struct f01_device_commands {
-   u8 reset:1;
-   u8 reserved:7;
-};
-
-/**
- * @ctrl0 - see documentation in rmi_f01.h.
- * @interrupt_enable - A mask of per-function interrupts on the touch sensor.
- * @doze_interval - controls the interval between checks for finger presence
- * when the touch sensor is in doze mode, in units of 10ms.
- * @wakeup_threshold - controls the capacitance threshold at which the touch
- * sensor will decide to wake up from that low power state.
- * @doze_holdoff - controls how long the touch sensor waits after the last
- * finger lifts before entering the doze state, in units of 100ms.
- */
-struct f01_device_control {
-   struct f01_device_control_0 ctrl0;
-   u8 *interrupt_enable;
-   u8 doze_interval;
-   u8 wakeup_threshold;
-   u8 doze_holdoff;
-};
-
-/**
- * @has_ds4_queries - if true, the query registers relating to Design Studio 4
- * features are present.
- * @has_multi_phy - if true, multiple physical communications interfaces are
- * supported.
- * @has_guest - if true, a guest device is supported.
- */
-struct f01_query_42 {
-   u8 has_ds4_queries:1;
-   u8 has_multi_phy:1;
-   u8 has_guest:1;
-   u8 reserved:5;
-} __attribute__((__packed__));
-
-/**
- * @length - the length of the remaining Query43.* register block, not
- * including the first register.
- * @has_package_id_query -  the package ID query data will be accessible from
- * inside the ProductID query registers.
- * @has_packrat_query -  the packrat query data will be accessible from inside
- * the ProductID query registers.
- * @has_reset_query - the reset pin related registers are valid.
- * @has_maskrev_query - the silicon mask revision number will be reported.
- * @has_i2c_control - the register F01_RMI_Ctrl6 will exist.
- * @has_spi_control - the register F01_RMI_Ctrl7 will exist.
- * @has_attn_control - the register F01_RMI_Ctrl8 will exist.
- * @reset_enabled - the hardware reset pin functionality has been enabled
- * for this device.
- * @reset_polarity - If this bit reports as ‘0’, it means that the reset state
- * is active low. A ‘1’ means that the reset state is active high.
- * @pullup_enabled - If set, it indicates that a built-in weak pull up has
- * been enabled on the Reset pin; clear means that no pull-up is present.
- * @reset_pin_number - This field represents which GPIO pin number has been
- * assigned the reset functionality.
- */
-struct f01_ds4_queries {
-   u8 length:4;
-   u8 reserved_1:4;
-
-   u8 has_package_id_query:1;
-   u8 has_packrat_query:1;
-   u8 has_reset_query:1;
-   u8 has_maskrev_query:1;
-   u8 reserved_2:4;
-
-   u8 has_i2c_control:1;
-   u8 has_spi_control:1;
-   u8 has_attn_control:1;
-   u8 reserved_3:5;
-
-   u8 reset_enabled:1;
-   u8 reset_polarity:1;
-   u8 pullup_enabled:1;
-   u8 reserved_4:1;
-   u8 reset_pin_number:4;
-} __attribute__((__packed__

[PATCH 03/05] input: RMI4 I2C physical layer

2013-01-18 Thread Christopher Heiny
Changes here are limited to those described in the 0/5 of this patchset, plus
some tweaks to debugging output.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_i2c.c |  141 ++
 1 files changed, 20 insertions(+), 121 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index ca32101..513791c 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */
 
 #include linux/kernel.h
@@ -58,7 +48,7 @@ struct rmi_i2c_data {
u8 *debug_buf;
int debug_buf_size;
 
-   bool comms_debug;
+   u32 comms_debug;
 #ifdef CONFIG_RMI4_DEBUG
struct dentry *debugfs_comms;
 #endif
@@ -66,107 +56,13 @@ struct rmi_i2c_data {
 
 #ifdef CONFIG_RMI4_DEBUG
 
-
-/**
- * struct i2c_debugfs_data - stores information for debugfs
- *
- * @done: Indicates that we are done reading debug data. Subsequent reads
- * will return EOF.
- * @i2c_data: Pointer to the i2c data
- *
- */
-struct i2c_debugfs_data {
-   bool done;
-   struct rmi_i2c_data *i2c_data;
-};
-
-static int debug_open(struct inode *inodep, struct file *filp)
-{
-   struct i2c_debugfs_data *data;
-
-   data = kzalloc(sizeof(struct i2c_debugfs_data), GFP_KERNEL);
-   if (!data)
-   return -ENOMEM;
-
-   data-i2c_data = inodep-i_private;
-   filp-private_data = data;
-   return 0;
-}
-
-static int debug_release(struct inode *inodep, struct file *filp)
-{
-   kfree(filp-private_data);
-   return 0;
-}
-
-static ssize_t comms_debug_read(struct file *filp, char __user *buffer,
-   size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   struct i2c_debugfs_data *dfs = filp-private_data;
-   struct rmi_i2c_data *data = dfs-i2c_data;
-
-   if (dfs-done)
-   return 0;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-
-   dfs-done = 1;
-
-   retval = snprintf(local_buf, PAGE_SIZE, %u\n, data-comms_debug);
-
-   if (retval = 0 || copy_to_user(buffer, local_buf, retval))
-   retval = -EFAULT;
-   kfree(local_buf);
-
-   return retval;
-}
-
-static ssize_t comms_debug_write(struct file *filp, const char __user *buffer,
-  size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   unsigned int new_value;
-   struct i2c_debugfs_data *dfs = filp-private_data;
-   struct rmi_i2c_data *data = dfs-i2c_data;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-   retval = copy_from_user(local_buf, buffer, size);
-   if (retval) {
-   kfree(local_buf);
-   return -EFAULT;
-   }
-
-   retval = sscanf(local_buf, %u, new_value);
-   kfree(local_buf);
-   if (retval != 1 || new_value  1)
-   return -EINVAL;
-
-   data-comms_debug = new_value;
-
-   return size;
-}
-
-
-static const struct file_operations comms_debug_fops = {
-   .owner = THIS_MODULE,
-   .open = debug_open,
-   .release = debug_release,
-   .read = comms_debug_read,
-   .write = comms_debug_write,
-};
-
 static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data *data)
 {
if (!rmi_dev-debugfs_root)
return -ENODEV;
 
-   data-debugfs_comms = debugfs_create_file(comms_debug, RMI_RW_ATTR,
-   rmi_dev-debugfs_root, data, comms_debug_fops);
+   data-debugfs_comms = debugfs_create_bool(comms_debug, RMI_RW_ATTR,
+   rmi_dev-debugfs_root, data-comms_debug);
if (!data-debugfs_comms || IS_ERR(data-debugfs_comms

[PATCH 02/05] input: Core files

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patch set, these files
are updated as follows:

* initialization sequence rearranged to support the merging of rmi_f01 and
rmi_driver into the RMI4 core.

* the initial reset and firmware update PDT scans are split into their own
functions in order to account for the fact that the PDT may change after
the initial reset.

* Problems with release_rmidev_device() identified by Greg KH are fixed and
tested.

* EXPORT_SYMBOL() changed to EXPORT_SYMBOL_GPL(), per Greg KH input.

Signed-off-by: Christopher Heiny 
Cc: Greg Kroah-Hartman 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_bus.c|  232 ---
 drivers/input/rmi4/rmi_driver.c |  655 ---
 drivers/input/rmi4/rmi_driver.h |   32 +--
 3 files changed, 468 insertions(+), 451 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index acbfd3d..71bc201 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include 
@@ -75,7 +65,8 @@ static struct dentry *rmi_debugfs_root;

 static void release_rmidev_device(struct device *dev)
 {
-   device_unregister(dev);
+   struct rmi_device *rmi_dev = to_rmi_device(dev);
+   kfree(rmi_dev);
 }

 /**
@@ -110,17 +101,19 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_dbg(phys->dev, "%s: Registered %s as %s.\n", __func__,
pdata->sensor_name, dev_name(_dev->dev));

-   if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_debugfs_root) {
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_debugfs_root) {
rmi_dev->debugfs_root = debugfs_create_dir(
dev_name(_dev->dev), rmi_debugfs_root);
if (!rmi_dev->debugfs_root)
dev_err(_dev->dev, "Failed to create debugfs 
root.\n");
}
+#endif

phys->rmi_dev = rmi_dev;
return device_register(_dev->dev);
 }
-EXPORT_SYMBOL(rmi_register_phys_device);
+EXPORT_SYMBOL_GPL(rmi_register_phys_device);

 /**
  * rmi_unregister_phys_device - unregister a physical device connection
@@ -131,102 +124,84 @@ void rmi_unregister_phys_device(struct rmi_phys_device 
*phys)
 {
struct rmi_device *rmi_dev = phys->rmi_dev;

-   if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_dev->debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_dev->debugfs_root)
debugfs_remove(rmi_dev->debugfs_root);
+#endif

-   kfree(rmi_dev);
+   device_unregister(_dev->dev);
 }
-EXPORT_SYMBOL(rmi_unregister_phys_device);
+EXPORT_SYMBOL_GPL(rmi_unregister_phys_device);

-/**
- * rmi_register_function_handler - register a handler for an RMI function
- * @handler: RMI handler that should be registered.
- * @module: pointer to module that implements the handler
- * @mod_name: name of the module implementing the handler
- *
- * This function performs additional setup of RMI function handler and
- * registers it with the RMI core so that it can be bound to
- * RMI function devices.
- */
-int __rmi_register_function_handler(struct rmi_function_handler *handler,
-struct module *owner,
-const char *mod_name)
+static int rmi_bus_match(struct device *dev, struct device_driver *drv)
 {
-   int error;
+   struct rmi_function_driver *fn_drv;
+   struct rmi_function_dev *fn;

-   handler->driver.bus = _bus_type;
-   handler->driver.owner = owner;
-   handler->driver.mod_name = mod_name;
+   /*
+* This seems a little broken to me.  It  means a system can only ever
+* have one kind of sensor driver.  It'll work for now, but I think in
+* the long run we need to revisit this.
+*/
+   if (dev->type == _sensor_type && drv == _sensor_dri

[PATCH 04/05] input: F01 Device control

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes:

* changes to the handling of sysfs as requested in feedback to our
previous patch.

* device serialization updated to conform to the latest specification.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_f01.c |  733 --
 drivers/input/rmi4/rmi_f01.h |   29 +--
 2 files changed, 425 insertions(+), 337 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index d7461d7..d33fa16 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011-2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include 
@@ -26,6 +16,8 @@
 #include "rmi_driver.h"
 #include "rmi_f01.h"

+#define FUNCTION_NUMBER 0x01
+
 /**
  * @reset - set this bit to force a firmware reset of the sensor.
  */
@@ -109,11 +101,17 @@ struct f01_ds4_queries {
u8 reset_pin_number:4;
 } __attribute__((__packed__));

+/*
+ *
+ * @serialization - 7 bytes of device serialization data.  The meaning of
+ * these bytes varies from product to product, consult your product spec sheet.
+ */
 struct f01_data {
struct f01_device_control device_control;
struct f01_basic_queries basic_queries;
struct f01_device_status device_status;
-   u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
+   u8 serialization[F01_SERIALIZATION_SIZE];
+   u8 product_id[RMI_PRODUCT_ID_LENGTH+1];

u16 interrupt_enable_addr;
u16 doze_interval_addr;
@@ -136,19 +134,19 @@ struct f01_data {
 #ifdef CONFIG_RMI4_DEBUG
 struct f01_debugfs_data {
bool done;
-   struct rmi_function *fn;
+   struct rmi_function_dev *fn_dev;
 };

 static int f01_debug_open(struct inode *inodep, struct file *filp)
 {
struct f01_debugfs_data *data;
-   struct rmi_function *fn = inodep->i_private;
+   struct rmi_function_dev *fn_dev = inodep->i_private;

data = kzalloc(sizeof(struct f01_debugfs_data), GFP_KERNEL);
if (!data)
return -ENOMEM;

-   data->fn = fn;
+   data->fn_dev = fn_dev;
filp->private_data = data;
return 0;
 }
@@ -167,7 +165,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
char local_buf[size];
char *current_buf = local_buf;
struct f01_debugfs_data *data = filp->private_data;
-   struct f01_data *f01 = data->fn->data;
+   struct f01_data *f01 = data->fn_dev->data;

if (data->done)
return 0;
@@ -197,7 +195,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
current_buf += len;
total_len += len;
} else {
-   dev_err(>fn->dev, "Failed to build 
interrupt_enable buffer, code = %d.\n",
+   dev_err(>fn_dev->dev, "Failed to build 
interrupt_enable buffer, code = %d.\n",
len);
return snprintf(local_buf, size, "unknown\n");
}
@@ -206,7 +204,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
if (len > 0)
total_len += len;
else
-   dev_warn(>fn->dev, "%s: Failed to append carriage 
return.\n",
+   dev_warn(>fn_dev->dev, "%s: Failed to append carriage 
return.\n",
 __func__);

if (copy_to_user(buffer, local_buf, total_len))
@@ -224,7 +222,7 @@ static ssize_t interrupt_enable_write(struct file *filp,
int irq_count = 0;
int irq_reg = 0;
struct f01_debugfs_data *data = filp->private_data;
-   struct f01_data *f01 = data->fn->data;
+   struct f01_data *f01 = data->fn_dev-&g

[PATCH 01/05] input: RMI4 header file

2012-12-18 Thread Christopher Heiny
In addition to the changes described in part 0/5, this fixes some cut
issues in the comments for module_rmi_function_driver.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 include/linux/rmi.h |   95 +++
 1 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index daca41b..eec926f 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -2,25 +2,16 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #ifndef _RMI_H
 #define _RMI_H
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +22,6 @@
 #include 
 #include 
 #include 
-#include 

 extern struct bus_type rmi_bus_type;

@@ -73,7 +63,7 @@ enum rmi_attn_polarity {
  *   automatically enabled for this sensor.
  */
 struct rmi_f11_2d_axis_alignment {
-   bool swap_axes;
+   u32 swap_axes;
bool flip_x;
bool flip_y;
int clip_X_low;
@@ -82,7 +72,6 @@ struct rmi_f11_2d_axis_alignment {
int clip_Y_high;
int offset_X;
int offset_Y;
-   int rel_report_enabled;
u8 delta_x_threshold;
u8 delta_y_threshold;
 };
@@ -105,6 +94,7 @@ enum rmi_f11_sensor_type {

 /**
  * struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
+ *
  * @axis_align - provides axis alignment overrides (see above).
  * @type_a - all modern RMI F11 firmwares implement Multifinger Type B
  * protocol.  Set this to true to force MF Type A behavior, in case you find
@@ -338,13 +328,14 @@ struct rmi_function_descriptor {
u8 function_version;
 };

-struct rmi_function;
+struct rmi_function_dev;
 struct rmi_device;

 /**
- * struct rmi_function_handler - driver routines for a particular RMI function.
+ * struct rmi_function_driver - driver routines for a particular RMI function.
  *
  * @func: The RMI function number
+ * @probe: Called when the handler is successfully matched to a function 
device.
  * @reset: Called when a reset of the touch sensor is detected.  The routine
  * should perform any out-of-the-ordinary reset handling that might be
  * necessary.  Restoring of touch sensor configuration registers should be
@@ -361,37 +352,31 @@ struct rmi_device;
  *
  * All callbacks are expected to return 0 on success, error code on failure.
  */
-struct rmi_function_handler {
+struct rmi_function_driver {
struct device_driver driver;

u8 func;
-   int (*probe)(struct rmi_function *fn);
-   void (*remove)(struct rmi_function *fn);
-   int (*config)(struct rmi_function *fn);
-   int (*reset)(struct rmi_function *fn);
-   int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
+   int (*probe)(struct rmi_function_dev *fc);
+   int (*remove)(struct rmi_function_dev *fc);
+   int (*config)(struct rmi_function_dev *fc);
+   int (*reset)(struct rmi_function_dev *fc);
+   int (*attention)(struct rmi_function_dev *fc,
+   unsigned long *irq_bits);
 #ifdef CONFIG_PM
-   int (*suspend)(struct rmi_function *fn);
-   int (*resume)(struct rmi_function *fn);
+   int (*suspend)(struct rmi_function_dev *fc);
+   int (*resume)(struct rmi_function_dev *fc);
 #endif
 };

-#define to_rmi_function_handler(d) \
-   container_of(d, struct rmi_function_handler, driver)
-
-int __must_check __rmi_register_function_handler(struct rmi_function_handler *,
-struct module *, const char *);
-#define rmi_register_function_handler(handler) \
-   __rmi_register_function_handler(handler, THIS_MODULE, KBUILD_MODNAME)
-
-void rmi_unregister_function_handler(struct rmi_function_handler *);
+#define to_rmi_function_driver(d) \
+   container_of(d, struct rmi_function_driver, driver);

 /**
- * struct rmi_function - represents the implementation of an RMI4
- * function for a particular device (basically, a driver

[PATCH 03/05] input: I2C physical layer

2012-12-18 Thread Christopher Heiny
Changes here are limited to those described in the 0/0 of this patchset, plus
some tweaks to debugging output.

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_i2c.c |  141 ++
 1 files changed, 20 insertions(+), 121 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index ca32101..513791c 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include 
@@ -58,7 +48,7 @@ struct rmi_i2c_data {
u8 *debug_buf;
int debug_buf_size;

-   bool comms_debug;
+   u32 comms_debug;
 #ifdef CONFIG_RMI4_DEBUG
struct dentry *debugfs_comms;
 #endif
@@ -66,107 +56,13 @@ struct rmi_i2c_data {

 #ifdef CONFIG_RMI4_DEBUG

-
-/**
- * struct i2c_debugfs_data - stores information for debugfs
- *
- * @done: Indicates that we are done reading debug data. Subsequent reads
- * will return EOF.
- * @i2c_data: Pointer to the i2c data
- *
- */
-struct i2c_debugfs_data {
-   bool done;
-   struct rmi_i2c_data *i2c_data;
-};
-
-static int debug_open(struct inode *inodep, struct file *filp)
-{
-   struct i2c_debugfs_data *data;
-
-   data = kzalloc(sizeof(struct i2c_debugfs_data), GFP_KERNEL);
-   if (!data)
-   return -ENOMEM;
-
-   data->i2c_data = inodep->i_private;
-   filp->private_data = data;
-   return 0;
-}
-
-static int debug_release(struct inode *inodep, struct file *filp)
-{
-   kfree(filp->private_data);
-   return 0;
-}
-
-static ssize_t comms_debug_read(struct file *filp, char __user *buffer,
-   size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   struct i2c_debugfs_data *dfs = filp->private_data;
-   struct rmi_i2c_data *data = dfs->i2c_data;
-
-   if (dfs->done)
-   return 0;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-
-   dfs->done = 1;
-
-   retval = snprintf(local_buf, PAGE_SIZE, "%u\n", data->comms_debug);
-
-   if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
-   retval = -EFAULT;
-   kfree(local_buf);
-
-   return retval;
-}
-
-static ssize_t comms_debug_write(struct file *filp, const char __user *buffer,
-  size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   unsigned int new_value;
-   struct i2c_debugfs_data *dfs = filp->private_data;
-   struct rmi_i2c_data *data = dfs->i2c_data;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-   retval = copy_from_user(local_buf, buffer, size);
-   if (retval) {
-   kfree(local_buf);
-   return -EFAULT;
-   }
-
-   retval = sscanf(local_buf, "%u", _value);
-   kfree(local_buf);
-   if (retval != 1 || new_value > 1)
-   return -EINVAL;
-
-   data->comms_debug = new_value;
-
-   return size;
-}
-
-
-static const struct file_operations comms_debug_fops = {
-   .owner = THIS_MODULE,
-   .open = debug_open,
-   .release = debug_release,
-   .read = comms_debug_read,
-   .write = comms_debug_write,
-};
-
 static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data *data)
 {
if (!rmi_dev->debugfs_root)
return -ENODEV;

-   data->debugfs_comms = debugfs_create_file("comms_debug", RMI_RW_ATTR,
-   rmi_dev->debugfs_root, data, _debug_fops);
+   data->debugfs_comms = debugfs_create_bool("comms_debug", RMI_RW_ATTR,
+   rmi_dev->debugfs_root, >comms_debug);
if (!data->debugfs_comms || IS_ERR(data->debugfs_comms)) {
  

[PATCH 05/05] input: F11 2D input

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes:

* elimination of unused sysfs and debugfs parameters.

* some fixes to the input device parameters.

* removal of some stray Android stuff.

Signed-off-by: Christopher Heiny 
To: Henrik Rydberg 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Joeri de Gram 
Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_f11.c | 1187 +++---
 1 files changed, 197 insertions(+), 990 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 8457ab4..7a8b806 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -2,38 +2,26 @@
  * Copyright (c) 2011,2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #define FUNCTION_DATA f11_data
+#define FUNCTION_NUMBER 0x11

 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include "rmi_driver.h"
-
-#ifdef CONFIG_RMI4_DEBUG
-#include 
-#include 
 #include 
-#endif
+#include "rmi_driver.h"

 #define F11_MAX_NUM_OF_SENSORS 8
 #define F11_MAX_NUM_OF_FINGERS 10
@@ -54,7 +42,6 @@
 #define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
 #define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
 #define NAME_BUFFER_SIZE 256
-#define FUNCTION_NUMBER 0x11

 /** A note about RMI4 F11 register structure.
  *
@@ -439,195 +426,9 @@ struct f11_2d_ctrl0_9 {
u8 ctrl9_reserved:4;
 } __attribute__((__packed__));

-/**
- * @single_tap_int_enable - enable tap gesture recognition.
- * @tap_n_hold_int_enable - enable tap-and-hold gesture recognition.
- * @double_tap_int_enable - enable double-tap gesture recognition.
- * @early_tap_int_enable - enable early tap notification.
- * @flick_int_enable - enable flick detection.
- * @press_int_enable - enable press gesture recognition.
- * @pinch_int_enable - enable pinch detection.
- */
-struct f11_2d_ctrl10 {
-   u8 single_tap_int_enable:1;
-   u8 tap_n_hold_int_enable:1;
-   u8 double_tap_int_enable:1;
-   u8 early_tap_int_enable:1;
-   u8 flick_int_enable:1;
-   u8 press_int_enable:1;
-   u8 pinch_int_enable:1;
-   u8 reserved:1;
-} __attribute__((__packed__));
-
-/**
- * @palm_detect_int_enable - enable palm detection feature.
- * @rotate_int_enable - enable rotate gesture detection.
- * @touch_shape_int_enable - enable the TouchShape feature.
- * @scroll_zone_int_enable - enable scroll zone reporting.
- * @multi_finger_scroll_int_enable - enable the multfinger scroll feature.
- */
-struct f11_2d_ctrl11 {
-   u8 palm_detect_int_enable:1;
-   u8 rotate_int_enable:1;
-   u8 touch_shape_int_enable:1;
-   u8 scroll_zone_int_enable:1;
-   u8 multi_finger_scroll_int_enable:1;
-   u8 reserved:3;
-} __attribute__((__packed__));
-
-/**
- * @sens_adjustment - allows a host to alter the overall sensitivity of a
- * 2-D sensor. A positive value in this register will make the sensor more
- * sensitive than the factory defaults, and a negative value will make it
- * less sensitive.
- * @hyst_adjustment - increase the touch/no-touch hysteresis by 2 Z-units for
- * each one unit increment in this setting.
- */
-struct f11_2d_ctrl14 {
-   s8 sens_adjustment:5;
-   u8 hyst_adjustment:3;
-} __attribute__((__packed__));
-
-/**
- * @max_tap_time - the maximum duration of a tap, in 10-millisecond units.
- */
-struct f11_2d_ctrl15 {
-   u8 max_tap_time:8;
-} __attribute__((__packed__));
-
-/**
- * @min_press_time - The minimum duration required for stationary finger(s) to
- * generate a press gesture, in 10-millisecond units.
- */
-struct f11_2d_ctrl16 {
-   u8 min_press_time:8;
-} __attribute__((__packed__));
-
-/**
- * @max_tap_distance - Determines the maximum finger movement allowed during
- * a tap, in 0.1-millimeter units.
- */
-struct f11_2d_ctrl17 {
-   u8 max_tap_distance:8;
-} __attribute__((__packed__));
-
-/**
- * @min_flick_distance - the minimum finger movement for a flick gesture,
- * in 1-millimeter units.
- * @min_flick_speed - the 

[RFC PATCH 00/05] input: Synaptics RMI4 Touchscreen Driver

2012-12-18 Thread Christopher Heiny
This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patchset is Dmitry's commit
0af25383d395fb5ece54b79d12d06138bf8b9836 from 2012-11-28.

Overall this patchset implements the following changes:

* updates to Dmitry's RMI4_CORE structure from his 2012-11-28 patches.
This tries to maintain the same approach as Dmitry's implementation, but
we had to move away from using the bus probe() routine, since it wasn't
possible for that routine to readily determine if it had a struct driver() for
an RMI4 sensor or an RMI4 device.  Otherwise, we've stuck close to Dmitry's
work, which has tidied things up nicely.

* We've renamed the structures rmi_function_handler to rmi_function_driver and
rmi_device to rmi_function_dev, mainly because they actually were being treated
as drivers and devices for individual RMI4 functions, and the previous
terminology was somewhat confusing.

* Moved much of the debugfs stuff to use standard macros.  This required
changing a bunch of bools to u32s.  Debugfs interfaces that handled multiple
values in a single file were NOT changed, because some debug tools depend on
that format.  Once we've udpate those tools, we'll change or remove the
remaining interfaces.

* Many other bools were changed to u8, per Dmitry's request.

* Trivial - file copyright header is updated to be more in line with the rest
of the files under ./input.


We've broken this patch into 6 parts, as follows:
01 - public header file
02 - core sensor and bus implementation
03 - I2C physical layer driver
04.05 - drivers for individual RMI functions


Hopefully this is the last time we'll have wide-ranging structural changes in
the driver code, and future patchsets can be much smaller and confined to
one or two areas of interest.


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny 
Cc: Dmitry Torokhov 
Cc: Jean Delvare 
Cc: Linus Walleij 
Cc: Joeri de Gram 

---
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 00/05] input: Synaptics RMI4 Touchscreen Driver

2012-12-18 Thread Christopher Heiny
This patchset implements changes based on the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patchset is Dmitry's commit
0af25383d395fb5ece54b79d12d06138bf8b9836 from 2012-11-28.

Overall this patchset implements the following changes:

* updates to Dmitry's RMI4_CORE structure from his 2012-11-28 patches.
This tries to maintain the same approach as Dmitry's implementation, but
we had to move away from using the bus probe() routine, since it wasn't
possible for that routine to readily determine if it had a struct driver() for
an RMI4 sensor or an RMI4 device.  Otherwise, we've stuck close to Dmitry's
work, which has tidied things up nicely.

* We've renamed the structures rmi_function_handler to rmi_function_driver and
rmi_device to rmi_function_dev, mainly because they actually were being treated
as drivers and devices for individual RMI4 functions, and the previous
terminology was somewhat confusing.

* Moved much of the debugfs stuff to use standard macros.  This required
changing a bunch of bools to u32s.  Debugfs interfaces that handled multiple
values in a single file were NOT changed, because some debug tools depend on
that format.  Once we've udpate those tools, we'll change or remove the
remaining interfaces.

* Many other bools were changed to u8, per Dmitry's request.

* Trivial - file copyright header is updated to be more in line with the rest
of the files under ./input.


We've broken this patch into 6 parts, as follows:
01 - public header file
02 - core sensor and bus implementation
03 - I2C physical layer driver
04.05 - drivers for individual RMI functions


Hopefully this is the last time we'll have wide-ranging structural changes in
the driver code, and future patchsets can be much smaller and confined to
one or two areas of interest.


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Jean Delvare kh...@linux-fr.org
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com

---
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 05/05] input: F11 2D input

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes:

* elimination of unused sysfs and debugfs parameters.

* some fixes to the input device parameters.

* removal of some stray Android stuff.

Signed-off-by: Christopher Heiny che...@synaptics.com
To: Henrik Rydberg rydb...@euromail.se
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_f11.c | 1187 +++---
 1 files changed, 197 insertions(+), 990 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 8457ab4..7a8b806 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -2,38 +2,26 @@
  * Copyright (c) 2011,2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #define FUNCTION_DATA f11_data
+#define FUNCTION_NUMBER 0x11

 #include linux/kernel.h
+#include linux/debugfs.h
 #include linux/delay.h
 #include linux/device.h
+#include linux/fs.h
 #include linux/input.h
 #include linux/input/mt.h
 #include linux/kconfig.h
 #include linux/rmi.h
 #include linux/slab.h
-#include rmi_driver.h
-
-#ifdef CONFIG_RMI4_DEBUG
-#include linux/debugfs.h
-#include linux/fs.h
 #include linux/uaccess.h
-#endif
+#include rmi_driver.h

 #define F11_MAX_NUM_OF_SENSORS 8
 #define F11_MAX_NUM_OF_FINGERS 10
@@ -54,7 +42,6 @@
 #define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
 #define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
 #define NAME_BUFFER_SIZE 256
-#define FUNCTION_NUMBER 0x11

 /** A note about RMI4 F11 register structure.
  *
@@ -439,195 +426,9 @@ struct f11_2d_ctrl0_9 {
u8 ctrl9_reserved:4;
 } __attribute__((__packed__));

-/**
- * @single_tap_int_enable - enable tap gesture recognition.
- * @tap_n_hold_int_enable - enable tap-and-hold gesture recognition.
- * @double_tap_int_enable - enable double-tap gesture recognition.
- * @early_tap_int_enable - enable early tap notification.
- * @flick_int_enable - enable flick detection.
- * @press_int_enable - enable press gesture recognition.
- * @pinch_int_enable - enable pinch detection.
- */
-struct f11_2d_ctrl10 {
-   u8 single_tap_int_enable:1;
-   u8 tap_n_hold_int_enable:1;
-   u8 double_tap_int_enable:1;
-   u8 early_tap_int_enable:1;
-   u8 flick_int_enable:1;
-   u8 press_int_enable:1;
-   u8 pinch_int_enable:1;
-   u8 reserved:1;
-} __attribute__((__packed__));
-
-/**
- * @palm_detect_int_enable - enable palm detection feature.
- * @rotate_int_enable - enable rotate gesture detection.
- * @touch_shape_int_enable - enable the TouchShape feature.
- * @scroll_zone_int_enable - enable scroll zone reporting.
- * @multi_finger_scroll_int_enable - enable the multfinger scroll feature.
- */
-struct f11_2d_ctrl11 {
-   u8 palm_detect_int_enable:1;
-   u8 rotate_int_enable:1;
-   u8 touch_shape_int_enable:1;
-   u8 scroll_zone_int_enable:1;
-   u8 multi_finger_scroll_int_enable:1;
-   u8 reserved:3;
-} __attribute__((__packed__));
-
-/**
- * @sens_adjustment - allows a host to alter the overall sensitivity of a
- * 2-D sensor. A positive value in this register will make the sensor more
- * sensitive than the factory defaults, and a negative value will make it
- * less sensitive.
- * @hyst_adjustment - increase the touch/no-touch hysteresis by 2 Z-units for
- * each one unit increment in this setting.
- */
-struct f11_2d_ctrl14 {
-   s8 sens_adjustment:5;
-   u8 hyst_adjustment:3;
-} __attribute__((__packed__));
-
-/**
- * @max_tap_time - the maximum duration of a tap, in 10-millisecond units.
- */
-struct f11_2d_ctrl15 {
-   u8 max_tap_time:8;
-} __attribute__((__packed__));
-
-/**
- * @min_press_time - The minimum duration required for stationary finger(s) to
- * generate a press gesture, in 10-millisecond units.
- */
-struct f11_2d_ctrl16 {
-   u8 min_press_time:8;
-} __attribute__((__packed__));
-
-/**
- * @max_tap_distance - Determines the maximum finger movement allowed

[PATCH 03/05] input: I2C physical layer

2012-12-18 Thread Christopher Heiny
Changes here are limited to those described in the 0/0 of this patchset, plus
some tweaks to debugging output.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_i2c.c |  141 ++
 1 files changed, 20 insertions(+), 121 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index ca32101..513791c 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include linux/kernel.h
@@ -58,7 +48,7 @@ struct rmi_i2c_data {
u8 *debug_buf;
int debug_buf_size;

-   bool comms_debug;
+   u32 comms_debug;
 #ifdef CONFIG_RMI4_DEBUG
struct dentry *debugfs_comms;
 #endif
@@ -66,107 +56,13 @@ struct rmi_i2c_data {

 #ifdef CONFIG_RMI4_DEBUG

-
-/**
- * struct i2c_debugfs_data - stores information for debugfs
- *
- * @done: Indicates that we are done reading debug data. Subsequent reads
- * will return EOF.
- * @i2c_data: Pointer to the i2c data
- *
- */
-struct i2c_debugfs_data {
-   bool done;
-   struct rmi_i2c_data *i2c_data;
-};
-
-static int debug_open(struct inode *inodep, struct file *filp)
-{
-   struct i2c_debugfs_data *data;
-
-   data = kzalloc(sizeof(struct i2c_debugfs_data), GFP_KERNEL);
-   if (!data)
-   return -ENOMEM;
-
-   data-i2c_data = inodep-i_private;
-   filp-private_data = data;
-   return 0;
-}
-
-static int debug_release(struct inode *inodep, struct file *filp)
-{
-   kfree(filp-private_data);
-   return 0;
-}
-
-static ssize_t comms_debug_read(struct file *filp, char __user *buffer,
-   size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   struct i2c_debugfs_data *dfs = filp-private_data;
-   struct rmi_i2c_data *data = dfs-i2c_data;
-
-   if (dfs-done)
-   return 0;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-
-   dfs-done = 1;
-
-   retval = snprintf(local_buf, PAGE_SIZE, %u\n, data-comms_debug);
-
-   if (retval = 0 || copy_to_user(buffer, local_buf, retval))
-   retval = -EFAULT;
-   kfree(local_buf);
-
-   return retval;
-}
-
-static ssize_t comms_debug_write(struct file *filp, const char __user *buffer,
-  size_t size, loff_t *offset) {
-   int retval;
-   char *local_buf;
-   unsigned int new_value;
-   struct i2c_debugfs_data *dfs = filp-private_data;
-   struct rmi_i2c_data *data = dfs-i2c_data;
-
-   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
-   if (!local_buf)
-   return -ENOMEM;
-   retval = copy_from_user(local_buf, buffer, size);
-   if (retval) {
-   kfree(local_buf);
-   return -EFAULT;
-   }
-
-   retval = sscanf(local_buf, %u, new_value);
-   kfree(local_buf);
-   if (retval != 1 || new_value  1)
-   return -EINVAL;
-
-   data-comms_debug = new_value;
-
-   return size;
-}
-
-
-static const struct file_operations comms_debug_fops = {
-   .owner = THIS_MODULE,
-   .open = debug_open,
-   .release = debug_release,
-   .read = comms_debug_read,
-   .write = comms_debug_write,
-};
-
 static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data *data)
 {
if (!rmi_dev-debugfs_root)
return -ENODEV;

-   data-debugfs_comms = debugfs_create_file(comms_debug, RMI_RW_ATTR,
-   rmi_dev-debugfs_root, data, comms_debug_fops);
+   data-debugfs_comms = debugfs_create_bool(comms_debug, RMI_RW_ATTR,
+   rmi_dev-debugfs_root, data-comms_debug);
if (!data-debugfs_comms || IS_ERR(data-debugfs_comms

[PATCH 01/05] input: RMI4 header file

2012-12-18 Thread Christopher Heiny
In addition to the changes described in part 0/5, this fixes some cutpaste
issues in the comments for module_rmi_function_driver.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 include/linux/rmi.h |   95 +++
 1 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index daca41b..eec926f 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -2,25 +2,16 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #ifndef _RMI_H
 #define _RMI_H
 #include linux/kernel.h
 #include linux/cdev.h
+#include linux/debugfs.h
 #include linux/device.h
 #include linux/interrupt.h
 #include linux/input.h
@@ -31,7 +22,6 @@
 #include linux/stat.h
 #include linux/types.h
 #include linux/wait.h
-#include linux/debugfs.h

 extern struct bus_type rmi_bus_type;

@@ -73,7 +63,7 @@ enum rmi_attn_polarity {
  *   automatically enabled for this sensor.
  */
 struct rmi_f11_2d_axis_alignment {
-   bool swap_axes;
+   u32 swap_axes;
bool flip_x;
bool flip_y;
int clip_X_low;
@@ -82,7 +72,6 @@ struct rmi_f11_2d_axis_alignment {
int clip_Y_high;
int offset_X;
int offset_Y;
-   int rel_report_enabled;
u8 delta_x_threshold;
u8 delta_y_threshold;
 };
@@ -105,6 +94,7 @@ enum rmi_f11_sensor_type {

 /**
  * struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
+ *
  * @axis_align - provides axis alignment overrides (see above).
  * @type_a - all modern RMI F11 firmwares implement Multifinger Type B
  * protocol.  Set this to true to force MF Type A behavior, in case you find
@@ -338,13 +328,14 @@ struct rmi_function_descriptor {
u8 function_version;
 };

-struct rmi_function;
+struct rmi_function_dev;
 struct rmi_device;

 /**
- * struct rmi_function_handler - driver routines for a particular RMI function.
+ * struct rmi_function_driver - driver routines for a particular RMI function.
  *
  * @func: The RMI function number
+ * @probe: Called when the handler is successfully matched to a function 
device.
  * @reset: Called when a reset of the touch sensor is detected.  The routine
  * should perform any out-of-the-ordinary reset handling that might be
  * necessary.  Restoring of touch sensor configuration registers should be
@@ -361,37 +352,31 @@ struct rmi_device;
  *
  * All callbacks are expected to return 0 on success, error code on failure.
  */
-struct rmi_function_handler {
+struct rmi_function_driver {
struct device_driver driver;

u8 func;
-   int (*probe)(struct rmi_function *fn);
-   void (*remove)(struct rmi_function *fn);
-   int (*config)(struct rmi_function *fn);
-   int (*reset)(struct rmi_function *fn);
-   int (*attention)(struct rmi_function *fn, unsigned long *irq_bits);
+   int (*probe)(struct rmi_function_dev *fc);
+   int (*remove)(struct rmi_function_dev *fc);
+   int (*config)(struct rmi_function_dev *fc);
+   int (*reset)(struct rmi_function_dev *fc);
+   int (*attention)(struct rmi_function_dev *fc,
+   unsigned long *irq_bits);
 #ifdef CONFIG_PM
-   int (*suspend)(struct rmi_function *fn);
-   int (*resume)(struct rmi_function *fn);
+   int (*suspend)(struct rmi_function_dev *fc);
+   int (*resume)(struct rmi_function_dev *fc);
 #endif
 };

-#define to_rmi_function_handler(d) \
-   container_of(d, struct rmi_function_handler, driver)
-
-int __must_check __rmi_register_function_handler(struct rmi_function_handler *,
-struct module *, const char *);
-#define rmi_register_function_handler(handler) \
-   __rmi_register_function_handler(handler, THIS_MODULE, KBUILD_MODNAME)
-
-void rmi_unregister_function_handler(struct

[PATCH 04/05] input: F01 Device control

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patchset, this patch
includes:

* changes to the handling of sysfs as requested in feedback to our
previous patch.

* device serialization updated to conform to the latest specification.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_f01.c |  733 --
 drivers/input/rmi4/rmi_f01.h |   29 +--
 2 files changed, 425 insertions(+), 337 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index d7461d7..d33fa16 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011-2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include linux/kernel.h
@@ -26,6 +16,8 @@
 #include rmi_driver.h
 #include rmi_f01.h

+#define FUNCTION_NUMBER 0x01
+
 /**
  * @reset - set this bit to force a firmware reset of the sensor.
  */
@@ -109,11 +101,17 @@ struct f01_ds4_queries {
u8 reset_pin_number:4;
 } __attribute__((__packed__));

+/*
+ *
+ * @serialization - 7 bytes of device serialization data.  The meaning of
+ * these bytes varies from product to product, consult your product spec sheet.
+ */
 struct f01_data {
struct f01_device_control device_control;
struct f01_basic_queries basic_queries;
struct f01_device_status device_status;
-   u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
+   u8 serialization[F01_SERIALIZATION_SIZE];
+   u8 product_id[RMI_PRODUCT_ID_LENGTH+1];

u16 interrupt_enable_addr;
u16 doze_interval_addr;
@@ -136,19 +134,19 @@ struct f01_data {
 #ifdef CONFIG_RMI4_DEBUG
 struct f01_debugfs_data {
bool done;
-   struct rmi_function *fn;
+   struct rmi_function_dev *fn_dev;
 };

 static int f01_debug_open(struct inode *inodep, struct file *filp)
 {
struct f01_debugfs_data *data;
-   struct rmi_function *fn = inodep-i_private;
+   struct rmi_function_dev *fn_dev = inodep-i_private;

data = kzalloc(sizeof(struct f01_debugfs_data), GFP_KERNEL);
if (!data)
return -ENOMEM;

-   data-fn = fn;
+   data-fn_dev = fn_dev;
filp-private_data = data;
return 0;
 }
@@ -167,7 +165,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
char local_buf[size];
char *current_buf = local_buf;
struct f01_debugfs_data *data = filp-private_data;
-   struct f01_data *f01 = data-fn-data;
+   struct f01_data *f01 = data-fn_dev-data;

if (data-done)
return 0;
@@ -197,7 +195,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
current_buf += len;
total_len += len;
} else {
-   dev_err(data-fn-dev, Failed to build 
interrupt_enable buffer, code = %d.\n,
+   dev_err(data-fn_dev-dev, Failed to build 
interrupt_enable buffer, code = %d.\n,
len);
return snprintf(local_buf, size, unknown\n);
}
@@ -206,7 +204,7 @@ static ssize_t interrupt_enable_read(struct file *filp, 
char __user *buffer,
if (len  0)
total_len += len;
else
-   dev_warn(data-fn-dev, %s: Failed to append carriage 
return.\n,
+   dev_warn(data-fn_dev-dev, %s: Failed to append carriage 
return.\n,
 __func__);

if (copy_to_user(buffer, local_buf, total_len))
@@ -224,7 +222,7 @@ static ssize_t interrupt_enable_write(struct file *filp,
int irq_count = 0;
int irq_reg = 0;
struct f01_debugfs_data *data = filp-private_data;
-   struct f01_data *f01 = data-fn-data;
+   struct f01_data *f01 = data-fn_dev-data;

retval = copy_from_user(buf

[PATCH 02/05] input: Core files

2012-12-18 Thread Christopher Heiny
In addition to the changes described in 0/0 of this patch set, these files
are updated as follows:

* initialization sequence rearranged to support the merging of rmi_f01 and
rmi_driver into the RMI4 core.

* the initial reset and firmware update PDT scans are split into their own
functions in order to account for the fact that the PDT may change after
the initial reset.

* Problems with release_rmidev_device() identified by Greg KH are fixed and
tested.

* EXPORT_SYMBOL() changed to EXPORT_SYMBOL_GPL(), per Greg KH input.

Signed-off-by: Christopher Heiny che...@synaptics.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com
Acked-by: Jean Delvare kh...@linux-fr.org

---

 drivers/input/rmi4/rmi_bus.c|  232 ---
 drivers/input/rmi4/rmi_driver.c |  655 ---
 drivers/input/rmi4/rmi_driver.h |   32 +--
 3 files changed, 468 insertions(+), 451 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index acbfd3d..71bc201 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -2,19 +2,9 @@
  * Copyright (c) 2011, 2012 Synaptics Incorporated
  * Copyright (c) 2011 Unixphere
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
  */

 #include linux/kernel.h
@@ -75,7 +65,8 @@ static struct dentry *rmi_debugfs_root;

 static void release_rmidev_device(struct device *dev)
 {
-   device_unregister(dev);
+   struct rmi_device *rmi_dev = to_rmi_device(dev);
+   kfree(rmi_dev);
 }

 /**
@@ -110,17 +101,19 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_dbg(phys-dev, %s: Registered %s as %s.\n, __func__,
pdata-sensor_name, dev_name(rmi_dev-dev));

-   if (IS_ENABLED(CONFIG_RMI4_DEBUG)  rmi_debugfs_root) {
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_debugfs_root) {
rmi_dev-debugfs_root = debugfs_create_dir(
dev_name(rmi_dev-dev), rmi_debugfs_root);
if (!rmi_dev-debugfs_root)
dev_err(rmi_dev-dev, Failed to create debugfs 
root.\n);
}
+#endif

phys-rmi_dev = rmi_dev;
return device_register(rmi_dev-dev);
 }
-EXPORT_SYMBOL(rmi_register_phys_device);
+EXPORT_SYMBOL_GPL(rmi_register_phys_device);

 /**
  * rmi_unregister_phys_device - unregister a physical device connection
@@ -131,102 +124,84 @@ void rmi_unregister_phys_device(struct rmi_phys_device 
*phys)
 {
struct rmi_device *rmi_dev = phys-rmi_dev;

-   if (IS_ENABLED(CONFIG_RMI4_DEBUG)  rmi_dev-debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+   if (rmi_dev-debugfs_root)
debugfs_remove(rmi_dev-debugfs_root);
+#endif

-   kfree(rmi_dev);
+   device_unregister(rmi_dev-dev);
 }
-EXPORT_SYMBOL(rmi_unregister_phys_device);
+EXPORT_SYMBOL_GPL(rmi_unregister_phys_device);

-/**
- * rmi_register_function_handler - register a handler for an RMI function
- * @handler: RMI handler that should be registered.
- * @module: pointer to module that implements the handler
- * @mod_name: name of the module implementing the handler
- *
- * This function performs additional setup of RMI function handler and
- * registers it with the RMI core so that it can be bound to
- * RMI function devices.
- */
-int __rmi_register_function_handler(struct rmi_function_handler *handler,
-struct module *owner,
-const char *mod_name)
+static int rmi_bus_match(struct device *dev, struct device_driver *drv)
 {
-   int error;
+   struct rmi_function_driver *fn_drv;
+   struct rmi_function_dev *fn;

-   handler-driver.bus = rmi_bus_type;
-   handler-driver.owner = owner;
-   handler-driver.mod_name = mod_name;
+   /*
+* This seems a little broken to me.  It  means a system can only ever
+* have one kind of sensor driver.  It'll work for now, but I think in
+* the long run we need to revisit this.
+*/
+   if (dev-type

RE: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into the core

2012-12-01 Thread Christopher Heiny
Sorry for top posting this - I forgot to email while still at work.

I've been poking at this, and think (a) it's possible that I'm being too 
paranoid, and (b) it looks like it'll work with some of the future stuff.  So 
I'll back off my objections for the moment, and give these changes a try, 
possibly with some slight modifications.

Thanks!
Chris

From: linux-input-ow...@vger.kernel.org [linux-input-ow...@vger.kernel.org] on 
behalf of Dmitry Torokhov [dmitry.torok...@gmail.com]
Sent: Thursday, November 29, 2012 9:21 AM
To: Christopher Heiny
Cc: Linus Walleij; Linux Input; Linux Kernel; Allie Xiong; Vivian Ly; Daniel 
Rosenberg; Alexandra Chin; Joerie de Gram; Wolfram Sang; Mathieu Poirier
Subject: Re: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into 
the core

Hi Chris,
On Wed, Nov 28, 2012 at 08:54:32PM -0800, Christopher Heiny wrote:
> On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:
> >There is no point in having the sensor driver and F01 handler separate
> >from the RMI core since it is not useful without them and having them
> >all together simplifies initialization among other things.
>
> Hi Dmitry,
>
> I've been looking at this patch as well as your patch 3/4 changes,
> and I'm not sure it's for the better.
>
> One thing that confuses me is that these appear to go against the
> advice we've been getting over the past months to rely more on
> standard kernel bus and driver implementations, instead of the
> "roll-your-own" implementation we had been using before.
>
> More importantly, the patches inextricably link the sensor driver
> implementation and the F01 driver implementation to the bus
> implementation, and means that any given system can have only one
> way of managing F01.  As you observed, a sensor is pretty much
> useless without an F01 handler, but I am reasonably sure that there
> will be future systems that have more than one RMI4 sensor in them,
> and there is a strong possibility that these sensors may have
> different requirements for handling F01.  In the near future, then,
> these changes will have to be refactored back to something more like
> the structure of our 2012/11/16 patch set.
>
> Additionally, having F01 as a special case means that when we start
> implementing things such as support for request_firmware(), there
> will have to be a bunch of special case code to deal with F01, since
> it's no longer "just another function driver".  That seems to go in
> exactly the opposite direction of the simplification that you're
> trying to achieve.

But F01 continues to being "just another function driver" even with my
changes. It is still registered as rmi_fucntion_handler and uses
standard matching mechanisms to bind to rmi_functions registered by the
sensor driver. What I changed is the fact that rmi_f01 is no longer a
separate module which could be loaded after loading rmi_bus and it can't
be unloaded without unloading rmi_bus. This simplifies things and makes
it easier to have rmi core compiled as a module.

Also I do not quite follow your idea that devices might have different
requirements for handling F01. If that is true then be _can't_ implement
"F01" as "another function driver"... But that is orthogonal for the 3/4
change we are discussing here.

Thanks.

--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into the core

2012-12-01 Thread Christopher Heiny
Sorry for top posting this - I forgot to email while still at work.

I've been poking at this, and think (a) it's possible that I'm being too 
paranoid, and (b) it looks like it'll work with some of the future stuff.  So 
I'll back off my objections for the moment, and give these changes a try, 
possibly with some slight modifications.

Thanks!
Chris

From: linux-input-ow...@vger.kernel.org [linux-input-ow...@vger.kernel.org] on 
behalf of Dmitry Torokhov [dmitry.torok...@gmail.com]
Sent: Thursday, November 29, 2012 9:21 AM
To: Christopher Heiny
Cc: Linus Walleij; Linux Input; Linux Kernel; Allie Xiong; Vivian Ly; Daniel 
Rosenberg; Alexandra Chin; Joerie de Gram; Wolfram Sang; Mathieu Poirier
Subject: Re: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into 
the core

Hi Chris,
On Wed, Nov 28, 2012 at 08:54:32PM -0800, Christopher Heiny wrote:
 On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:
 There is no point in having the sensor driver and F01 handler separate
 from the RMI core since it is not useful without them and having them
 all together simplifies initialization among other things.

 Hi Dmitry,

 I've been looking at this patch as well as your patch 3/4 changes,
 and I'm not sure it's for the better.

 One thing that confuses me is that these appear to go against the
 advice we've been getting over the past months to rely more on
 standard kernel bus and driver implementations, instead of the
 roll-your-own implementation we had been using before.

 More importantly, the patches inextricably link the sensor driver
 implementation and the F01 driver implementation to the bus
 implementation, and means that any given system can have only one
 way of managing F01.  As you observed, a sensor is pretty much
 useless without an F01 handler, but I am reasonably sure that there
 will be future systems that have more than one RMI4 sensor in them,
 and there is a strong possibility that these sensors may have
 different requirements for handling F01.  In the near future, then,
 these changes will have to be refactored back to something more like
 the structure of our 2012/11/16 patch set.

 Additionally, having F01 as a special case means that when we start
 implementing things such as support for request_firmware(), there
 will have to be a bunch of special case code to deal with F01, since
 it's no longer just another function driver.  That seems to go in
 exactly the opposite direction of the simplification that you're
 trying to achieve.

But F01 continues to being just another function driver even with my
changes. It is still registered as rmi_fucntion_handler and uses
standard matching mechanisms to bind to rmi_functions registered by the
sensor driver. What I changed is the fact that rmi_f01 is no longer a
separate module which could be loaded after loading rmi_bus and it can't
be unloaded without unloading rmi_bus. This simplifies things and makes
it easier to have rmi core compiled as a module.

Also I do not quite follow your idea that devices might have different
requirements for handling F01. If that is true then be _can't_ implement
F01 as another function driver... But that is orthogonal for the 3/4
change we are discussing here.

Thanks.

--
Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into the core

2012-11-28 Thread Christopher Heiny
+obj-$(CONFIG_RMI4_CORE) += rmi_core.o
+rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o
+
+# Function drivers
  obj-$(CONFIG_RMI4_F11) += rmi_f11.o

+# Transports
+obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
+
  ccflags-$(CONFIG_RMI4_DEBUG) += -DDEBUG

  ifeq ($(KERNELRELEASE),)
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index a912349..47cf0d5 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -206,6 +206,27 @@ static int __init rmi_bus_init(void)

mutex_init(_bus_mutex);

+   error = bus_register(_bus_type);
+   if (error) {
+   pr_err("%s: error registering the RMI bus: %d\n",
+   __func__, error);
+   return error;
+   }
+
+   error = rmi_register_f01_handler();
+   if (error) {
+   pr_err("%s: error registering the RMI F01 handler: %d\n",
+   __func__, error);
+   goto err_unregister_bus;
+   }
+
+   error = rmi_register_sensor_driver();
+   if (error) {
+   pr_err("%s: error registering the RMI sensor driver: %d\n",
+   __func__, error);
+   goto err_unregister_f01;
+   }
+
if (IS_ENABLED(CONFIG_RMI4_DEBUG)) {
rmi_debugfs_root = debugfs_create_dir(rmi_bus_type.name, NULL);
if (!rmi_debugfs_root)
@@ -218,24 +239,26 @@ static int __init rmi_bus_init(void)
}
}

-   error = bus_register(_bus_type);
-   if (error < 0) {
-   pr_err("%s: error registering the RMI bus: %d\n", __func__,
-  error);
-   return error;
-   }
-   pr_debug("%s: successfully registered RMI bus.\n", __func__);
-
return 0;
+
+err_unregister_f01:
+   rmi_unregister_f01_handler();
+err_unregister_bus:
+   bus_unregister(_bus_type);
+   return error;
  }

  static void __exit rmi_bus_exit(void)
  {
-   /* We should only ever get here if all drivers are unloaded, so
+   /*
+* We should only ever get here if all drivers are unloaded, so
 * all we have to do at this point is unregister ourselves.
 */
if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_debugfs_root)
debugfs_remove(rmi_debugfs_root);
+
+   rmi_unregister_sensor_driver();
+   rmi_unregister_f01_handler();
bus_unregister(_bus_type);
  }

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index e8a4b52..6b6ac0c 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -1608,7 +1608,7 @@ static int __devinit rmi_driver_probe(struct device *dev)
  static UNIVERSAL_DEV_PM_OPS(rmi_driver_pm, rmi_driver_suspend,
rmi_driver_resume, NULL);

-static struct rmi_driver sensor_driver = {
+static struct rmi_driver rmi_sensor_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "rmi_generic",
@@ -1624,38 +1624,30 @@ static struct rmi_driver sensor_driver = {
.set_input_params = rmi_driver_set_input_params,
  };

-static int __init rmi_driver_init(void)
+int __init rmi_register_sensor_driver(void)
  {
-   int retval;
+   int error;

-   retval = driver_register(_driver.driver);
-   if (retval) {
+   error = driver_register(_sensor_driver.driver);
+   if (error) {
pr_err("%s: driver register failed, code=%d.\n", __func__,
-  retval);
-   return retval;
+  error);
+   return error;
}

/* Ask the bus to let us know when drivers are bound to devices. */
-   retval = bus_register_notifier(_bus_type, _bus_notifier);
-   if (retval) {
+   error = bus_register_notifier(_bus_type, _bus_notifier);
+   if (error) {
pr_err("%s: failed to register bus notifier, code=%d.\n",
-  __func__, retval);
-   return retval;
+  __func__, error);
+   return error;
}

-   return retval;
+   return 0;
  }

-static void __exit rmi_driver_exit(void)
+void __exit rmi_unregister_sensor_driver(void)
  {
bus_unregister_notifier(_bus_type, _bus_notifier);
-   driver_unregister(_driver.driver);
+   driver_unregister(_sensor_driver.driver);
  }
-
-module_init(rmi_driver_init);
-module_exit(rmi_driver_exit);
-
-MODULE_AUTHOR("Christopher Heiny ");
-MODULE_DESCRIPTION("RMI F01 module");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(RMI_DRIVER_VERSION);




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/4] Input: RMI4 - move sensor driver and F01 handler into the core

2012-11-28 Thread Christopher Heiny
-$(CONFIG_RMI4_F11) += rmi_f11.o

+# Transports
+obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
+
  ccflags-$(CONFIG_RMI4_DEBUG) += -DDEBUG

  ifeq ($(KERNELRELEASE),)
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index a912349..47cf0d5 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -206,6 +206,27 @@ static int __init rmi_bus_init(void)

mutex_init(rmi_bus_mutex);

+   error = bus_register(rmi_bus_type);
+   if (error) {
+   pr_err(%s: error registering the RMI bus: %d\n,
+   __func__, error);
+   return error;
+   }
+
+   error = rmi_register_f01_handler();
+   if (error) {
+   pr_err(%s: error registering the RMI F01 handler: %d\n,
+   __func__, error);
+   goto err_unregister_bus;
+   }
+
+   error = rmi_register_sensor_driver();
+   if (error) {
+   pr_err(%s: error registering the RMI sensor driver: %d\n,
+   __func__, error);
+   goto err_unregister_f01;
+   }
+
if (IS_ENABLED(CONFIG_RMI4_DEBUG)) {
rmi_debugfs_root = debugfs_create_dir(rmi_bus_type.name, NULL);
if (!rmi_debugfs_root)
@@ -218,24 +239,26 @@ static int __init rmi_bus_init(void)
}
}

-   error = bus_register(rmi_bus_type);
-   if (error  0) {
-   pr_err(%s: error registering the RMI bus: %d\n, __func__,
-  error);
-   return error;
-   }
-   pr_debug(%s: successfully registered RMI bus.\n, __func__);
-
return 0;
+
+err_unregister_f01:
+   rmi_unregister_f01_handler();
+err_unregister_bus:
+   bus_unregister(rmi_bus_type);
+   return error;
  }

  static void __exit rmi_bus_exit(void)
  {
-   /* We should only ever get here if all drivers are unloaded, so
+   /*
+* We should only ever get here if all drivers are unloaded, so
 * all we have to do at this point is unregister ourselves.
 */
if (IS_ENABLED(CONFIG_RMI4_DEBUG)  rmi_debugfs_root)
debugfs_remove(rmi_debugfs_root);
+
+   rmi_unregister_sensor_driver();
+   rmi_unregister_f01_handler();
bus_unregister(rmi_bus_type);
  }

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index e8a4b52..6b6ac0c 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -1608,7 +1608,7 @@ static int __devinit rmi_driver_probe(struct device *dev)
  static UNIVERSAL_DEV_PM_OPS(rmi_driver_pm, rmi_driver_suspend,
rmi_driver_resume, NULL);

-static struct rmi_driver sensor_driver = {
+static struct rmi_driver rmi_sensor_driver = {
.driver = {
.owner = THIS_MODULE,
.name = rmi_generic,
@@ -1624,38 +1624,30 @@ static struct rmi_driver sensor_driver = {
.set_input_params = rmi_driver_set_input_params,
  };

-static int __init rmi_driver_init(void)
+int __init rmi_register_sensor_driver(void)
  {
-   int retval;
+   int error;

-   retval = driver_register(sensor_driver.driver);
-   if (retval) {
+   error = driver_register(rmi_sensor_driver.driver);
+   if (error) {
pr_err(%s: driver register failed, code=%d.\n, __func__,
-  retval);
-   return retval;
+  error);
+   return error;
}

/* Ask the bus to let us know when drivers are bound to devices. */
-   retval = bus_register_notifier(rmi_bus_type, rmi_bus_notifier);
-   if (retval) {
+   error = bus_register_notifier(rmi_bus_type, rmi_bus_notifier);
+   if (error) {
pr_err(%s: failed to register bus notifier, code=%d.\n,
-  __func__, retval);
-   return retval;
+  __func__, error);
+   return error;
}

-   return retval;
+   return 0;
  }

-static void __exit rmi_driver_exit(void)
+void __exit rmi_unregister_sensor_driver(void)
  {
bus_unregister_notifier(rmi_bus_type, rmi_bus_notifier);
-   driver_unregister(sensor_driver.driver);
+   driver_unregister(rmi_sensor_driver.driver);
  }
-
-module_init(rmi_driver_init);
-module_exit(rmi_driver_exit);
-
-MODULE_AUTHOR(Christopher Heiny che...@synaptics.com);
-MODULE_DESCRIPTION(RMI generic driver);
-MODULE_LICENSE(GPL);
-MODULE_VERSION(RMI_DRIVER_VERSION);
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 1fc4676..e71ffdc 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -136,4 +136,10 @@ extern void rmi4_fw_update(struct rmi_device *rmi_dev,
  #define rmi4_fw_update(rmi_dev, f01_pdt, f34_pdt)
  #endif

+int rmi_register_sensor_driver(void);
+void rmi_unregister_sensor_driver(void);
+
+int rmi_register_f01_handler(void);
+void

Re: [RFC PATCH 05/06] input/rmi4: F01 - device control

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:29 AM, Dmitry Torokhov wrote:

On Mon, Nov 26, 2012 at 02:31:27PM -0800, Christopher Heiny wrote:

>On 11/26/2012 01:40 AM, Dmitry Torokhov wrote:

> >Hi Christopher,
> >
> >On Fri, Nov 16, 2012 at 07:58:53PM -0800, Christopher Heiny wrote:

> >>RMI Function 01 implements basic device control and power management
> >>behaviors for the RMI4 sensor.
> >>
> >>rmi_f01.h exports definitions that we expect to be used by other 
functionality
> >>in the future (such as firmware reflash).

> >
> >Please see my comments below.

>
>Hi Dmitry,
>
>Thanks for the feedback and the patch.  I've got just one question,
>included below, with a bunch of snipping).
>
>Chris
>

> >

> >>
> >>
> >>Signed-off-by: Christopher Heiny
> >>
> >>Cc: Dmitry Torokhov
> >>Cc: Linus Walleij
> >>Cc: Naveen Kumar Gaddipati
> >>Cc: Joeri de Gram
> >>
> >>
> >>---
> >>
> >>  drivers/input/rmi4/rmi_f01.c | 1348 
++
> >>  drivers/input/rmi4/rmi_f01.h |  160 +
> >>  2 files changed, 1508 insertions(+), 0 deletions(-)
> >>
> >>diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
> >>new file mode 100644
> >>index 000..038266c
> >>--- /dev/null
> >>+++ b/drivers/input/rmi4/rmi_f01.c
> >>@@ -0,0 +1,1348 @@
> >>+/*
> >>+ * Copyright (c) 2011-2012 Synaptics Incorporated
> >>+ * Copyright (c) 2011 Unixphere
> >>+ *
> >>+ * This program is free software; you can redistribute it and/or modify
> >>+ * it under the terms of the GNU General Public License as published by
> >>+ * the Free Software Foundation; either version 2 of the License, or
> >>+ * (at your option) any later version.

>
>[snip]
>

> >>+/**
> >>+ * @reset - set this bit to force a firmware reset of the sensor.
> >>+ */
> >>+struct f01_device_commands {
> >>+  bool reset:1;
> >>+  u8 reserved:7;

> >
> >When specifying bitwise fields please use u8, u16, etc only.

>
>Um, OK.  Previously patch feedback suggested to use bool instead of
>u8 for single bit fields (see here:
>http://www.spinics.net/lists/linux-input/msg22198.html).  So I'm a
>little confused.  It's no big deal to change it back, but I'd like
>confirmation that it is really what we should do.

>

I believe that it is better to specify exact bitness of the base type of
the bitfield so you do not surprised by the alignment.


OK, thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] Input: RMI4 - introduce rmi_module_driver() macro

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:

This also allows us to cut down on the boilerplate code in the function
handler modules.


I like this idea a lot.  We'll adopt it.

Thanks!
Chris



Signed-off-by: Dmitry Torokhov 
---
  drivers/input/rmi4/rmi_f11.c | 13 +
  include/linux/rmi.h  | 14 ++
  2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index dbb6060..8457ab4 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -2756,18 +2756,7 @@ static struct rmi_function_handler rmi_f11_handler = {
  #endif  /* defined(CONFIG_HAS_EARLYSUSPEND) */
  };

-static int __init rmi_f11_module_init(void)
-{
-   return rmi_register_function_handler(_f11_handler);
-}
-
-static void __exit rmi_f11_module_exit(void)
-{
-   rmi_unregister_function_handler(_f11_handler);
-}
-
-module_init(rmi_f11_module_init);
-module_exit(rmi_f11_module_exit);
+module_rmi_driver(rmi_f11_handler);

  MODULE_AUTHOR("Christopher Heiny 


--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] Input RMI4 - rename rmi_function_container to rmi_function

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:

To save my old fingers...

Signed-off-by: Dmitry Torokhov
---

It looks like this driver(s) need some love and I might have some time so I
will refresh my "synaptics" branch with the patches you have sent and start
working off it. If you have updates I would appreciate if you also make them
available relative to that branch. When we are ready we'll squash them all
together and apply to the official branch.


No problem - let me know which branch/tag to work with, and we'll be 
happy to patch against that for the next round.




Thanks.

  drivers/input/rmi4/rmi_driver.c | 158 +++--
  drivers/input/rmi4/rmi_driver.h |   4 +-
  drivers/input/rmi4/rmi_f01.c| 298 
  drivers/input/rmi4/rmi_f11.c| 258 +-
  include/linux/rmi.h |  22 ++-
  5 files changed, 368 insertions(+), 372 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a73ae..e8a4b52 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -594,7 +594,7 @@ static struct device_attribute bsr_attribute = __ATTR(bsr, 
RMI_RW_ATTR,

  static void rmi_free_function_list(struct rmi_device *rmi_dev)
  {
-   struct rmi_function_container *entry, *n;
+   struct rmi_function *entry, *n;
struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);

if (!data) {
@@ -613,44 +613,44 @@ static void rmi_free_function_list(struct rmi_device 
*rmi_dev)
}
  }

-static void release_fc_device(struct device *dev)
+static void release_function_device(struct device *dev)
  {
dev_dbg(dev, "REMOVING KOBJ!");
kobject_put(>kobj);
  }


Hmmm.  Since rmi_function_container has evolved into a child device of 
the RMI4 module, maybe it would be better renamed rmi_function_device or 
rmi_function_dev?  I find this clearer, but can live with just 
rmi_function if you prefer that.



Similarly, rmi_function_handler has evolved into a driver for such 
devices, so perhaps it should be renamed rmi_function_driver?


[snip]

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] Input RMI4 - rename rmi_function_container to rmi_function

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:

To save my old fingers...

Signed-off-by: Dmitry Torokhovdmitry.torok...@gmail.com
---

It looks like this driver(s) need some love and I might have some time so I
will refresh my synaptics branch with the patches you have sent and start
working off it. If you have updates I would appreciate if you also make them
available relative to that branch. When we are ready we'll squash them all
together and apply to the official branch.


No problem - let me know which branch/tag to work with, and we'll be 
happy to patch against that for the next round.




Thanks.

  drivers/input/rmi4/rmi_driver.c | 158 +++--
  drivers/input/rmi4/rmi_driver.h |   4 +-
  drivers/input/rmi4/rmi_f01.c| 298 
  drivers/input/rmi4/rmi_f11.c| 258 +-
  include/linux/rmi.h |  22 ++-
  5 files changed, 368 insertions(+), 372 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a73ae..e8a4b52 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -594,7 +594,7 @@ static struct device_attribute bsr_attribute = __ATTR(bsr, 
RMI_RW_ATTR,

  static void rmi_free_function_list(struct rmi_device *rmi_dev)
  {
-   struct rmi_function_container *entry, *n;
+   struct rmi_function *entry, *n;
struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);

if (!data) {
@@ -613,44 +613,44 @@ static void rmi_free_function_list(struct rmi_device 
*rmi_dev)
}
  }

-static void release_fc_device(struct device *dev)
+static void release_function_device(struct device *dev)
  {
dev_dbg(dev, REMOVING KOBJ!);
kobject_put(dev-kobj);
  }


Hmmm.  Since rmi_function_container has evolved into a child device of 
the RMI4 module, maybe it would be better renamed rmi_function_device or 
rmi_function_dev?  I find this clearer, but can live with just 
rmi_function if you prefer that.



Similarly, rmi_function_handler has evolved into a driver for such 
devices, so perhaps it should be renamed rmi_function_driver?


[snip]

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] Input: RMI4 - introduce rmi_module_driver() macro

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:21 AM, Dmitry Torokhov wrote:

This also allows us to cut down on the boilerplate code in the function
handler modules.


I like this idea a lot.  We'll adopt it.

Thanks!
Chris



Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
---
  drivers/input/rmi4/rmi_f11.c | 13 +
  include/linux/rmi.h  | 14 ++
  2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index dbb6060..8457ab4 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -2756,18 +2756,7 @@ static struct rmi_function_handler rmi_f11_handler = {
  #endif  /* defined(CONFIG_HAS_EARLYSUSPEND) */
  };

-static int __init rmi_f11_module_init(void)
-{
-   return rmi_register_function_handler(rmi_f11_handler);
-}
-
-static void __exit rmi_f11_module_exit(void)
-{
-   rmi_unregister_function_handler(rmi_f11_handler);
-}
-
-module_init(rmi_f11_module_init);
-module_exit(rmi_f11_module_exit);
+module_rmi_driver(rmi_f11_handler);

  MODULE_AUTHOR(Christopher Heiny che...@synaptics.com);
  MODULE_DESCRIPTION(RMI F11 module);
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 8a74066..daca41b 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -600,4 +600,18 @@ int rmi_register_phys_device(struct rmi_phys_device *phys);
  void rmi_unregister_phys_device(struct rmi_phys_device *phys);
  int rmi_for_each_dev(void *data, int (*func)(struct device *dev, void *data));

+/**
+ * module_serio_driver() - Helper macro for registering a serio driver
+ * @__serio_driver: serio_driver struct
+ *
+ * Helper macro for serio drivers which do not do anything special in
+ * module init/exit. This eliminates a lot of boilerplate. Each module
+ * may only use this macro once, and calling it replaces module_init()
+ * and module_exit().
+ */
+#define module_rmi_driver(__rmi_driver)\
+   module_driver(__rmi_driver, \
+ rmi_register_function_handler,\
+ rmi_unregister_function_handler)
+
  #endif




--

Christopher Heiny
Senior Staff Firmware Engineer
Synaptics Incorporated
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 05/06] input/rmi4: F01 - device control

2012-11-27 Thread Christopher Heiny

On 11/27/2012 01:29 AM, Dmitry Torokhov wrote:

On Mon, Nov 26, 2012 at 02:31:27PM -0800, Christopher Heiny wrote:

On 11/26/2012 01:40 AM, Dmitry Torokhov wrote:

 Hi Christopher,
 
 On Fri, Nov 16, 2012 at 07:58:53PM -0800, Christopher Heiny wrote:

 RMI Function 01 implements basic device control and power management
 behaviors for the RMI4 sensor.
 
 rmi_f01.h exports definitions that we expect to be used by other 
functionality
 in the future (such as firmware reflash).

 
 Please see my comments below.


Hi Dmitry,

Thanks for the feedback and the patch.  I've got just one question,
included below, with a bunch of snipping).

Chris


 

 
 
 Signed-off-by: Christopher Heinyche...@synaptics.com
 
 Cc: Dmitry Torokhovdmitry.torok...@gmail.com
 Cc: Linus Walleijlinus.wall...@stericsson.com
 Cc: Naveen Kumar Gaddipatinaveen.gaddip...@stericsson.com
 Cc: Joeri de Gramj.de.g...@gmail.com
 
 
 ---
 
   drivers/input/rmi4/rmi_f01.c | 1348 
++
   drivers/input/rmi4/rmi_f01.h |  160 +
   2 files changed, 1508 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
 new file mode 100644
 index 000..038266c
 --- /dev/null
 +++ b/drivers/input/rmi4/rmi_f01.c
 @@ -0,0 +1,1348 @@
 +/*
 + * Copyright (c) 2011-2012 Synaptics Incorporated
 + * Copyright (c) 2011 Unixphere
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.


[snip]


 +/**
 + * @reset - set this bit to force a firmware reset of the sensor.
 + */
 +struct f01_device_commands {
 +  bool reset:1;
 +  u8 reserved:7;

 
 When specifying bitwise fields please use u8, u16, etc only.


Um, OK.  Previously patch feedback suggested to use bool instead of
u8 for single bit fields (see here:
http://www.spinics.net/lists/linux-input/msg22198.html).  So I'm a
little confused.  It's no big deal to change it back, but I'd like
confirmation that it is really what we should do.



I believe that it is better to specify exact bitness of the base type of
the bitfield so you do not surprised by the alignment.


OK, thanks!
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 02/06] input/rmi4: Core files

2012-11-26 Thread Christopher Heiny

On 11/26/2012 10:41 AM, Benjamin Tissoires wrote:

Hi Christopher,

On Sat, Nov 17, 2012 at 4:58 AM, Christopher Heiny  wrote:

rmi_bus.c implements the basic functionality of the RMI bus.  This file is
greatly simplified compared to the previous patch - we've switched from
"do it yourself" device/driver binding to using device_type to distinguish
between the two kinds of devices on the bus (sensor devices and function
specific devices) and using the standard bus implementation to manage devices
and drivers.


rmi_driver.c is a driver for the general functionality of the RMI sensor as a
whole, managing those behaviors (including IRQ handling) that are not specific
to any RMI4 function.  It has some unavoidable dependencies on F01 behavior,
though we have worked to minimize those as far as possible.


The header file rmi_driver.h provides definitions that are shared among
the modules of the RMI implementation, but not thought to be necessary
outside it.


Greg KH - Linus Walleij recommended that we seek your input on these core
files, particularly the bus implementation.


Signed-off-by: Christopher Heiny 

Cc: Greg Kroah-Hartman 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

---

  drivers/input/rmi4/rmi_bus.c|  248 ++
  drivers/input/rmi4/rmi_driver.c | 1663 +++
  drivers/input/rmi4/rmi_driver.h |  139 
  include/uapi/linux/input.h  |1 +
  4 files changed, 2051 insertions(+), 0 deletions(-)


[snipped]

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
new file mode 100644
index 000..05a73ae
--- /dev/null
+++ b/drivers/input/rmi4/rmi_driver.c

[snipped]

+/* extract product ID */
+void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
+{
+   struct device *dev = _dev->dev;
+   int retval;
+   int board = 0, rev = 0;
+   int i;
+   static const char * const pattern[] = {
+   "tm%4d-%d", "s%4d-%d", "s%4d-ver%1d"};
+   u8 product_id[RMI_PRODUCT_ID_LENGTH+1];
+
+   retval = rmi_read_block(rmi_dev,
+   drvdata->f01_container->fd.query_base_addr+
+   sizeof(struct f01_basic_queries),
+   product_id, RMI_PRODUCT_ID_LENGTH);
+   if (retval < 0) {
+   dev_err(dev, "Failed to read product id, code=%d!", retval);
+   return;
+   }
+   product_id[RMI_PRODUCT_ID_LENGTH] = '\0';
+
+   for (i = 0; i < sizeof(product_id); i++)
+   product_id[i] = tolower(product_id[i]);
+
+   for (i = 0; i < sizeof(pattern); i++) {


This should be ARRAY_SIZE(pattern).
It gave me a wonderful kernel oops :)


Yep, that's a bug!  Oddly enough, it runs without barfing on my systems 
(though who knows what horrible things are happening under the hood). 
Thanks for letting us know.


Chris



Cheers,
Benjamin


[snip]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 05/06] input/rmi4: F01 - device control

2012-11-26 Thread Christopher Heiny

On 11/26/2012 01:40 AM, Dmitry Torokhov wrote:

Hi Christopher,

On Fri, Nov 16, 2012 at 07:58:53PM -0800, Christopher Heiny wrote:

RMI Function 01 implements basic device control and power management
behaviors for the RMI4 sensor.

rmi_f01.h exports definitions that we expect to be used by other functionality
in the future (such as firmware reflash).


Please see my comments below.


Hi Dmitry,

Thanks for the feedback and the patch.  I've got just one question, 
included below, with a bunch of snipping).


Chris






Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 


---

  drivers/input/rmi4/rmi_f01.c | 1348 ++
  drivers/input/rmi4/rmi_f01.h |  160 +
  2 files changed, 1508 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
new file mode 100644
index 000..038266c
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -0,0 +1,1348 @@
+/*
+ * Copyright (c) 2011-2012 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.


[snip]


+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+struct f01_device_commands {
+   bool reset:1;
+   u8 reserved:7;


When specifying bitwise fields please use u8, u16, etc only.


Um, OK.  Previously patch feedback suggested to use bool instead of u8 
for single bit fields (see here: 
http://www.spinics.net/lists/linux-input/msg22198.html).  So I'm a 
little confused.  It's no big deal to change it back, but I'd like 
confirmation that it is really what we should do.


[snip]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 05/06] input/rmi4: F01 - device control

2012-11-26 Thread Christopher Heiny

On 11/26/2012 01:40 AM, Dmitry Torokhov wrote:

Hi Christopher,

On Fri, Nov 16, 2012 at 07:58:53PM -0800, Christopher Heiny wrote:

RMI Function 01 implements basic device control and power management
behaviors for the RMI4 sensor.

rmi_f01.h exports definitions that we expect to be used by other functionality
in the future (such as firmware reflash).


Please see my comments below.


Hi Dmitry,

Thanks for the feedback and the patch.  I've got just one question, 
included below, with a bunch of snipping).


Chris






Signed-off-by: Christopher Heiny che...@synaptics.com

Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Naveen Kumar Gaddipati naveen.gaddip...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com


---

  drivers/input/rmi4/rmi_f01.c | 1348 ++
  drivers/input/rmi4/rmi_f01.h |  160 +
  2 files changed, 1508 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
new file mode 100644
index 000..038266c
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -0,0 +1,1348 @@
+/*
+ * Copyright (c) 2011-2012 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.


[snip]


+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+struct f01_device_commands {
+   bool reset:1;
+   u8 reserved:7;


When specifying bitwise fields please use u8, u16, etc only.


Um, OK.  Previously patch feedback suggested to use bool instead of u8 
for single bit fields (see here: 
http://www.spinics.net/lists/linux-input/msg22198.html).  So I'm a 
little confused.  It's no big deal to change it back, but I'd like 
confirmation that it is really what we should do.


[snip]
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 02/06] input/rmi4: Core files

2012-11-26 Thread Christopher Heiny

On 11/26/2012 10:41 AM, Benjamin Tissoires wrote:

Hi Christopher,

On Sat, Nov 17, 2012 at 4:58 AM, Christopher Heiny che...@synaptics.com wrote:

rmi_bus.c implements the basic functionality of the RMI bus.  This file is
greatly simplified compared to the previous patch - we've switched from
do it yourself device/driver binding to using device_type to distinguish
between the two kinds of devices on the bus (sensor devices and function
specific devices) and using the standard bus implementation to manage devices
and drivers.


rmi_driver.c is a driver for the general functionality of the RMI sensor as a
whole, managing those behaviors (including IRQ handling) that are not specific
to any RMI4 function.  It has some unavoidable dependencies on F01 behavior,
though we have worked to minimize those as far as possible.


The header file rmi_driver.h provides definitions that are shared among
the modules of the RMI implementation, but not thought to be necessary
outside it.


Greg KH - Linus Walleij recommended that we seek your input on these core
files, particularly the bus implementation.


Signed-off-by: Christopher Heiny che...@synaptics.com

Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Cc: Linus Walleij linus.wall...@stericsson.com
Cc: Naveen Kumar Gaddipati naveen.gaddip...@stericsson.com
Cc: Joeri de Gram j.de.g...@gmail.com

---

  drivers/input/rmi4/rmi_bus.c|  248 ++
  drivers/input/rmi4/rmi_driver.c | 1663 +++
  drivers/input/rmi4/rmi_driver.h |  139 
  include/uapi/linux/input.h  |1 +
  4 files changed, 2051 insertions(+), 0 deletions(-)


[snipped]

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
new file mode 100644
index 000..05a73ae
--- /dev/null
+++ b/drivers/input/rmi4/rmi_driver.c

[snipped]

+/* extract product ID */
+void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
+{
+   struct device *dev = rmi_dev-dev;
+   int retval;
+   int board = 0, rev = 0;
+   int i;
+   static const char * const pattern[] = {
+   tm%4d-%d, s%4d-%d, s%4d-ver%1d};
+   u8 product_id[RMI_PRODUCT_ID_LENGTH+1];
+
+   retval = rmi_read_block(rmi_dev,
+   drvdata-f01_container-fd.query_base_addr+
+   sizeof(struct f01_basic_queries),
+   product_id, RMI_PRODUCT_ID_LENGTH);
+   if (retval  0) {
+   dev_err(dev, Failed to read product id, code=%d!, retval);
+   return;
+   }
+   product_id[RMI_PRODUCT_ID_LENGTH] = '\0';
+
+   for (i = 0; i  sizeof(product_id); i++)
+   product_id[i] = tolower(product_id[i]);
+
+   for (i = 0; i  sizeof(pattern); i++) {


This should be ARRAY_SIZE(pattern).
It gave me a wonderful kernel oops :)


Yep, that's a bug!  Oddly enough, it runs without barfing on my systems 
(though who knows what horrible things are happening under the hood). 
Thanks for letting us know.


Chris



Cheers,
Benjamin


[snip]
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 02/06] input/rmi4: Core files

2012-11-19 Thread Christopher Heiny

On 11/17/2012 01:54 PM, Greg Kroah-Hartman wrote:

On Fri, Nov 16, 2012 at 07:58:50PM -0800, Christopher Heiny wrote:

+static void release_rmidev_device(struct device *dev)
+{
+   device_unregister(dev);
+}


You just leaked memory here, right?

Also, you already unregistered the device, otherwise this function would
have never been called, so you just ended up in a loop?


Roger.  We'll fix that.



Have you ever tried removing a device?  Are you sure it's working
properly?


H.  If it leads to the loop you mention above, then the test I'm 
using must not be doing what I thought it was.  I'll fix that, too.




+EXPORT_SYMBOL(rmi_register_phys_device);


Just curious, but why not EXPORT_SYMBOL_GPL() on all of these new
symbols you are creating?


We'll change that.

Thanks very much!
Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 02/06] input/rmi4: Core files

2012-11-19 Thread Christopher Heiny

On 11/17/2012 01:54 PM, Greg Kroah-Hartman wrote:

On Fri, Nov 16, 2012 at 07:58:50PM -0800, Christopher Heiny wrote:

+static void release_rmidev_device(struct device *dev)
+{
+   device_unregister(dev);
+}


You just leaked memory here, right?

Also, you already unregistered the device, otherwise this function would
have never been called, so you just ended up in a loop?


Roger.  We'll fix that.



Have you ever tried removing a device?  Are you sure it's working
properly?


H.  If it leads to the loop you mention above, then the test I'm 
using must not be doing what I thought it was.  I'll fix that, too.




+EXPORT_SYMBOL(rmi_register_phys_device);


Just curious, but why not EXPORT_SYMBOL_GPL() on all of these new
symbols you are creating?


We'll change that.

Thanks very much!
Chris
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 02/06] input/rmi4: Core files

2012-11-16 Thread Christopher Heiny
rmi_bus.c implements the basic functionality of the RMI bus.  This file is
greatly simplified compared to the previous patch - we've switched from
"do it yourself" device/driver binding to using device_type to distinguish
between the two kinds of devices on the bus (sensor devices and function
specific devices) and using the standard bus implementation to manage devices
and drivers.


rmi_driver.c is a driver for the general functionality of the RMI sensor as a
whole, managing those behaviors (including IRQ handling) that are not specific
to any RMI4 function.  It has some unavoidable dependencies on F01 behavior,
though we have worked to minimize those as far as possible.


The header file rmi_driver.h provides definitions that are shared among
the modules of the RMI implementation, but not thought to be necessary
outside it.


Greg KH - Linus Walleij recommended that we seek your input on these core
files, particularly the bus implementation.


Signed-off-by: Christopher Heiny 

Cc: Greg Kroah-Hartman 
Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

---

 drivers/input/rmi4/rmi_bus.c|  248 ++
 drivers/input/rmi4/rmi_driver.c | 1663 +++
 drivers/input/rmi4/rmi_driver.h |  139 
 include/uapi/linux/input.h  |1 +
 4 files changed, 2051 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
new file mode 100644
index 000..a912349
--- /dev/null
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2011, 2012 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+DEFINE_MUTEX(rmi_bus_mutex);
+
+static struct attribute *function_dev_attrs[] = {
+   NULL,
+};
+
+static struct attribute_group function_dev_attr_group = {
+   .attrs = function_dev_attrs,
+};
+
+static const struct attribute_group *function_dev_attr_groups[] = {
+   _dev_attr_group,
+   NULL,
+};
+
+struct device_type rmi_function_type = {
+   .name = "rmi_function",
+   .groups = function_dev_attr_groups,
+};
+EXPORT_SYMBOL_GPL(rmi_function_type);
+
+static struct attribute *sensor_dev_attrs[] = {
+   NULL,
+};
+static struct attribute_group sensor_dev_attr_group = {
+   .attrs = sensor_dev_attrs,
+};
+
+static const struct attribute_group *sensor_dev_attr_groups[] = {
+   _dev_attr_group,
+   NULL,
+};
+
+struct device_type rmi_sensor_type = {
+   .name = "rmi_sensor",
+   .groups = sensor_dev_attr_groups,
+};
+EXPORT_SYMBOL_GPL(rmi_sensor_type);
+
+static atomic_t physical_device_count = ATOMIC_INIT(0);
+
+#ifdef CONFIG_RMI4_DEBUG
+static struct dentry *rmi_debugfs_root;
+#endif
+
+#ifdef CONFIG_PM
+static int rmi_bus_suspend(struct device *dev)
+{
+   struct device_driver *driver = dev->driver;
+   const struct dev_pm_ops *pm;
+
+   if (!driver)
+   return 0;
+
+   pm = driver->pm;
+   if (pm && pm->suspend)
+   return pm->suspend(dev);
+   if (driver->suspend)
+   return driver->suspend(dev, PMSG_SUSPEND);
+
+   return 0;
+}
+
+static int rmi_bus_resume(struct device *dev)
+{
+   struct device_driver *driver = dev->driver;
+   const struct dev_pm_ops *pm;
+
+   if (!driver)
+   return 0;
+
+   pm = driver->pm;
+   if (pm && pm->resume)
+   return pm->resume(dev);
+   if (driver->resume)
+   return driver->resume(dev);
+
+   return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(rmi_bus_pm_ops,
+rmi_bus_suspend, rmi_bus_resume);
+
+struct bus_type rmi_bus_type = {
+   .name   = "rmi",
+   .pm = _bus_pm_ops
+};
+EXPORT_SYMBOL_GPL(rmi_bus_type);
+
+static void release_rmidev_device(struct device *dev)
+{
+   device_unregister(dev);
+}
+
+/**
+ * rmi_register_phys_device - register a physical device connection on the RMI
+ * bus.  Physical drivers provide communication from the devices on the bus to
+ * the RMI4

[RFC PATCH 05/06] input/rmi4: F01 - device control

2012-11-16 Thread Christopher Heiny
RMI Function 01 implements basic device control and power management
behaviors for the RMI4 sensor.

rmi_f01.h exports definitions that we expect to be used by other functionality
in the future (such as firmware reflash).


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 


---

 drivers/input/rmi4/rmi_f01.c | 1348 ++
 drivers/input/rmi4/rmi_f01.h |  160 +
 2 files changed, 1508 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
new file mode 100644
index 000..038266c
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -0,0 +1,1348 @@
+/*
+ * Copyright (c) 2011-2012 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+#include "rmi_f01.h"
+
+#define FUNCTION_NUMBER 0x01
+
+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+struct f01_device_commands {
+   bool reset:1;
+   u8 reserved:7;
+};
+
+/**
+ * @ctrl0 - see documentation in rmi_f01.h.
+ * @interrupt_enable - A mask of per-function interrupts on the touch sensor.
+ * @doze_interval - controls the interval between checks for finger presence
+ * when the touch sensor is in doze mode, in units of 10ms.
+ * @wakeup_threshold - controls the capacitance threshold at which the touch
+ * sensor will decide to wake up from that low power state.
+ * @doze_holdoff - controls how long the touch sensor waits after the last
+ * finger lifts before entering the doze state, in units of 100ms.
+ */
+struct f01_device_control {
+   struct f01_device_control_0 ctrl0;
+   u8 *interrupt_enable;
+   u8 doze_interval;
+   u8 wakeup_threshold;
+   u8 doze_holdoff;
+};
+
+/**
+ * @has_ds4_queries - if true, the query registers relating to Design Studio 4
+ * features are present.
+ * @has_multi_phy - if true, multiple physical communications interfaces are
+ * supported.
+ * @has_guest - if true, a "guest" device is supported.
+ */
+struct f01_query_42 {
+   bool has_ds4_queries:1;
+   bool has_multi_phy:1;
+   bool has_guest:1;
+   u8 reserved:5;
+} __attribute__((__packed__));
+
+/**
+ * @length - the length of the remaining Query43.* register block, not
+ * including the first register.
+ * @has_package_id_query -  the package ID query data will be accessible from
+ * inside the ProductID query registers.
+ * @has_packrat_query -  the packrat query data will be accessible from inside
+ * the ProductID query registers.
+ * @has_reset_query - the reset pin related registers are valid.
+ * @has_maskrev_query - the silicon mask revision number will be reported.
+ * @has_i2c_control - the register F01_RMI_Ctrl6 will exist.
+ * @has_spi_control - the register F01_RMI_Ctrl7 will exist.
+ * @has_attn_control - the register F01_RMI_Ctrl8 will exist.
+ * @reset_enabled - the hardware reset pin functionality has been enabled
+ * for this device.
+ * @reset_polarity - If this bit reports as ‘0’, it means that the reset state
+ * is active low. A ‘1’ means that the reset state is active high.
+ * @pullup_enabled - If set, it indicates that a built-in weak pull up has
+ * been enabled on the Reset pin; clear means that no pull-up is present.
+ * @reset_pin_number - This field represents which GPIO pin number has been
+ * assigned the reset functionality.
+ */
+struct f01_ds4_queries {
+   u8 length:4;
+   u8 reserved_1:4;
+
+   bool has_package_id_query:1;
+   bool has_packrat_query:1;
+   bool has_reset_query:1;
+   bool has_maskrev_query:1;
+   u8 reserved_2:4;
+
+   bool has_i2c_control:1;
+   bool has_spi_control:1;
+   bool has_attn_control:1;
+   u8 reserved_3:5;
+
+   bool reset_enabled:1;
+   bool reset_polarity:1;
+   bool pullup_enabled:1;
+   u8 reserved_4:1;
+   u8 reset_pin_number:4;
+} __attribute__((__packed__));
+
+struct f01_data {
+   struct f01_device_control device_control;
+   struct f01_basic_queries basic_queries;
+   struct f01_device_status device_status;
+   u8 prod

[RFC PATCH 03/06] input/rmi4: I2C physical interface

2012-11-16 Thread Christopher Heiny

rmi_i2c.c abstracts an RMI4 device on some arbitrary I2C bus as a logical
device in the RMI bus.  It handles reads/writes from/to the RMI4 devices,
and manages the page select register setting (since the meaning of page
select is dependent on the physical layer used to communicate with the RMi4
device).


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_i2c.c |  490 ++
 1 files changed, 490 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
new file mode 100644
index 000..ca32101
--- /dev/null
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2011, 2012 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define BUFFER_SIZE_INCREMENT 32
+/**
+ * struct rmi_i2c_data - stores information for i2c communication
+ *
+ * @page_mutex: Locks current page to avoid changing pages in unexpected ways.
+ * @page: Keeps track of the current virtual page
+ * @phys: Pointer to the physical interface
+ *
+ * @tx_buf: Buffer used for transmitting data to the sensor over i2c.
+ * @tx_buf_size: Size of the buffer
+ * @debug_buf: Buffer used for exposing buffer contents using dev_dbg
+ * @debug_buf_size: Size of the debug buffer.
+ *
+ * @comms_debug: Latest data read/written for debugging I2C communications
+ * @debugfs_comms: Debugfs file for debugging I2C communications
+ *
+ */
+struct rmi_i2c_data {
+   struct mutex page_mutex;
+   int page;
+   struct rmi_phys_device *phys;
+
+   u8 *tx_buf;
+   int tx_buf_size;
+   u8 *debug_buf;
+   int debug_buf_size;
+
+   bool comms_debug;
+#ifdef CONFIG_RMI4_DEBUG
+   struct dentry *debugfs_comms;
+#endif
+};
+
+#ifdef CONFIG_RMI4_DEBUG
+
+
+/**
+ * struct i2c_debugfs_data - stores information for debugfs
+ *
+ * @done: Indicates that we are done reading debug data. Subsequent reads
+ * will return EOF.
+ * @i2c_data: Pointer to the i2c data
+ *
+ */
+struct i2c_debugfs_data {
+   bool done;
+   struct rmi_i2c_data *i2c_data;
+};
+
+static int debug_open(struct inode *inodep, struct file *filp)
+{
+   struct i2c_debugfs_data *data;
+
+   data = kzalloc(sizeof(struct i2c_debugfs_data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   data->i2c_data = inodep->i_private;
+   filp->private_data = data;
+   return 0;
+}
+
+static int debug_release(struct inode *inodep, struct file *filp)
+{
+   kfree(filp->private_data);
+   return 0;
+}
+
+static ssize_t comms_debug_read(struct file *filp, char __user *buffer,
+   size_t size, loff_t *offset) {
+   int retval;
+   char *local_buf;
+   struct i2c_debugfs_data *dfs = filp->private_data;
+   struct rmi_i2c_data *data = dfs->i2c_data;
+
+   if (dfs->done)
+   return 0;
+
+   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
+   if (!local_buf)
+   return -ENOMEM;
+
+   dfs->done = 1;
+
+   retval = snprintf(local_buf, PAGE_SIZE, "%u\n", data->comms_debug);
+
+   if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
+   retval = -EFAULT;
+   kfree(local_buf);
+
+   return retval;
+}
+
+static ssize_t comms_debug_write(struct file *filp, const char __user *buffer,
+  size_t size, loff_t *offset) {
+   int retval;
+   char *local_buf;
+   unsigned int new_value;
+   struct i2c_debugfs_data *dfs = filp->private_data;
+   struct rmi_i2c_data *data = dfs->i2c_data;
+
+   local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
+   if (!local_buf)
+   return -ENOMEM;
+   retval = copy_from_user(local_buf, buffer, size);
+   if (retval) {
+   kfree(local_buf);
+   return -EFAULT;
+   }
+
+   retval = sscanf(local_buf, "%u", _value);
+   kfree(local_buf);
+ 

  1   2   3   >