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&d=DwIBAg&c=7dfBJ8cXbWjhc0BhImu8wQ&r=veOxv1_7HLXIaWG-OKLqp-qvZc3r7ucT1d-68JSWqpM&m=3nNm4ob6G1wtf502YFuxorJVkSQvdBasje2RrZLxhTM&s=Z0nHSPAKhQLzdoENAZBYuDC6QmZNOliyiE7h1OOVkBA&e=
> 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 = &rmi_dev->dev;
> 
> mutex_lock(&data->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.

Anyway,

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
> > 
> > 
> > >
> 

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] rmi4_physic

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 = &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;
   

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(&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-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(&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 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(&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

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(&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) {
-  

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(&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) {
   

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(&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 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, &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 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(&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 contro

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(&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 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(&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 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(&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 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 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()

2014-01-14 Thread Christopher Heiny
;client->dev,
+   "read %zd bytes at %#06x: %d (%*ph)\n",
+   len, addr, 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(&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(&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 



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 = &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;
   

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 = &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++;
-   ret

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 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/


[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", &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 

[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(&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_se

[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&paste
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 de

[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(&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->t

[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(&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;
+  

[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&paste
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 (basicall

[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", &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->debug

[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 minimu

[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/


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_GENERIC) += rmi_driver.o rmi_f01.o
+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(&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 ");
-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: [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(&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 


--

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(&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: [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 = &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 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 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[] = {
+   &function_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[] = {
+   &sensor_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 = &rmi_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

[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", &new_value);
+   kfree(local_buf);
+ 

[RFC PATCH 04/06] input/rmi4: Config files and makefiles

2012-11-16 Thread Christopher Heiny

Infrastructure files for configuration and building.


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 


---

 drivers/input/Kconfig   |2 +
 drivers/input/Makefile  |3 ++
 drivers/input/rmi4/Kconfig  |   76 +++
 drivers/input/rmi4/Makefile |   22 
 4 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 55f7e57..2c543c0 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -188,6 +188,8 @@ source "drivers/input/touchscreen/Kconfig"

 source "drivers/input/misc/Kconfig"

+source "drivers/input/rmi4/Kconfig"
+
 endif

 menu "Hardware I/O ports"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 5ca3f63..88354fc 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -24,4 +24,7 @@ obj-$(CONFIG_INPUT_TABLET)+= tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)   += misc/

+obj-y += rmi4/
+
 obj-$(CONFIG_INPUT_APMPOWER)   += apm-power.o
+
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
new file mode 100644
index 000..41cbbee
--- /dev/null
+++ b/drivers/input/rmi4/Kconfig
@@ -0,0 +1,76 @@
+#
+# RMI4 configuration
+#
+config RMI4_BUS
+   bool "Synaptics RMI4 bus support"
+   help
+ Say Y here if you want to support the Synaptics RMI4 bus.  This is
+ required for all RMI4 device support.
+
+ If unsure, say Y.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_DEBUG
+   bool "RMI4 Debugging"
+   depends on RMI4_BUS
+   select DEBUG_FS
+   help
+ Say Y here to enable debug feature in the RMI4 driver.
+
+ Note that the RMI4 driver debug features can generate a lot of
+ output (potentially clogging up your dmesg output) and generally
+ slow down driver operation.  It's recommended to enable them only
+ if you are actively developing/debugging RMI4 features.
+
+ If unsure, say N.
+
+config RMI4_I2C
+   bool "RMI4 I2C Support"
+   depends on RMI4_BUS && I2C
+   help
+ Say Y here if you want to support RMI4 devices connected to an I2C
+ bus.
+
+ If unsure, say Y.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_GENERIC
+   bool "RMI4 Generic driver"
+   depends on RMI4_BUS
+   help
+ Say Y here if you want to support generic RMI4 devices.
+
+ This is pretty much required if you want to do anything useful with
+ your RMI device.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_F11
+   tristate "RMI4 Function 11 (2D pointing)"
+   depends on RMI4_BUS && RMI4_GENERIC
+   help
+ Say Y here if you want to add support for RMI4 function 11.
+
+ Function 11 provides 2D multifinger pointing for touchscreens and
+ touchpads.  For sensors that support relative pointing, F11 also
+ provides mouse input.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rmi-f11.
+
+config RMI4_F11_PEN
+   bool "RMI4 F11 Pen Support"
+   depends on RMI4_F11
+   help
+ Say Y here to add support for pen input to RMI4 function 11.
+
+ If this feature is enabled, when pen inputs are detected they
+ will be reported to the input stream as MT_TOOL_PEN.  Otherwise,
+ pens will be treated the same as fingers.
+
+ Not all UI implementations deal gracefully with pen discrimination.
+ If your system is not recognizing pen touches and you know your
+ sensor supports pen input, you probably want to turn this feature
+ off.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
new file mode 100644
index 000..8882c3d
--- /dev/null
+++ b/drivers/input/rmi4/Makefile
@@ -0,0 +1,22 @@
+obj-$(CONFIG_RMI4_BUS) += rmi_bus.o
+obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
+obj-$(CONFIG_RMI4_GENERIC) += rmi_driver.o rmi_f01.o
+obj-$(CONFIG_RMI4_F11) += rmi_f11.o
+
+ccflags-$(CONFIG_RMI4_DEBUG) += -DDEBUG
+
+ifeq ($(KERNELRELEASE),)
+
+# KERNELDIR ?= /home/
+PWD := $(shell pwd)
+
+.PHONY: build clean
+
+build:
+   $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+
+clean:
+   rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
+
+endif
+
--
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 01/06] input/rmi4: Public header and documentation

2012-11-16 Thread Christopher Heiny
rmi.h provides public definitions required by the RMI bus implementation and
modules that interact with it.

debugfs and sysfs attributes are documented in files in
Documentation/ABI/testing.  There's two files, one for debugfs and one for
sysfs.


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

---

 Documentation/ABI/testing/debugfs-rmi4 |   99 ++
 Documentation/ABI/testing/sysfs-rmi4   |  103 ++
 include/linux/rmi.h|  596 
 3 files changed, 798 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-rmi4 
b/Documentation/ABI/testing/debugfs-rmi4
new file mode 100644
index 000..ef0739d
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-rmi4
@@ -0,0 +1,99 @@
+What:  /sys/kernel/debug/rmi/devices
+Date:  October 2012
+KernelVersion: 3.x
+Contact:   Christopher Heiny 
+Description:
+
+  The RMI4 driver implementation exposes a set of informational and control
+  parameters via debugfs.  These parameters are those that typically are only
+  viewed or adjusted during product development, tuning, and debug.
+  For parameters that are  referenced and/or adjusted during normal operation,
+  please see sysfs-rmi4 in this directory.
+
+  General debugging parameters for a particular RMI4 sensor are found in
+  /sys/kernel/debug/rmi/sensorXX/, where XX is a the device's ID as a two
+  digit number (padded with leading zeros).  Function specific parameters
+  for an RMI4 sensor are found in /sys/kernel/debug/rmi/devices/FYY/, where
+  XX is a the device's ID as a two digit number (padded with leading zeros)
+  and YY is the hexdecimal function number (for example, F11 for RMI function
+  F11).
+
+  For RMI4 functions that support multiple sensor instances (such as F11),
+  the parameters for individual sensors have .Z appended to them, where Z is
+  the index of the sensor instance (for example, clip.0, clip.1, clip.2, and
+  so on).
+
+  Some of the parameters exposed here are described in detail in the
+  RMI4 Specification, which is found here:
+http://www.synaptics.com/sites/default/files/511-000136-01_revD.pdf
+  For such parameters, we'll reference you to that document, rather than
+  copying the contents here.
+
+  /sys/kernel/debug/rmi/
+  /sensorXX/
+  attn_count - (ro) Shows the number of ATTN interrupts handled so far.
+  comms_debug - (rw) Write 1 to this dump information about register
+  reads and writes to the console.  Write 0 to this to turn
+  this feature off.  WARNING: Imposes a major performance
+  penalty when turned on.
+  irq_debug - (rw) Write 1 to this dump information about interrupts
+  to the console.  Write 0 to this to turn this feature off.
+  WARNIG: Imposes a major performance penalty when turned on.
+  phys - (ro) Presents information about the physical connection of
+  this device.  It has one line, with the format:
+
+   prot tx_count tx_bytes tx_errors rx_count rx_bytes 
rx_errors attn
+
+  Where
+   prot is one of i2c, spi1, or spi2
+   tx_count is the number of write operations
+   tx_bytes is the number of bytes written
+   tx_errors is the number of write operations that 
encountered errors
+   rx_count is the number of read operations
+   rx_bytes is the total number of bytes read
+   rx_errors is the number of read operations that 
encountered errors
+
+  All counts are 64-bit unsigned values, and are set to zero
+  when the physical layer driver is initialized.
+
+  /sensorXX/F01/
+  interrupt_enable - (rw) allows you to read or modify the F01
+  interrupt enable mask (the F01_RMI_Ctrl1 register(s)).
+
+  /sensorXX/F11/
+  clip.Z - (rw) Controls in-driver coordinate clipping for the 2D
+  sensor Z.  This is a set of four unsigned values in the
+  range [0..65535], representing the lower bounds on X, the
+  upper bounds on X, the lower bounds on Y, and the upper
+  bounds on Y.  Coordinates will be clipped to these ranges.
+  If enabled, clip is the final transformation to be applied
+  to the coordinates. The default upper and lower bounds for
+  clip are 0 and 65535 respectively for both axes.
+  delta_threshold.Z - (rw) Controls the F11 distance thresholds. This
+  contains two values, corresponding to F11_2D_Ctrl2 and
+  F11_2D_Ctrl3.  Se the spec for more details.
+  flip.Z - (rw) This parameter is a pair of singl

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

2012-11-16 Thread Christopher Heiny
This patch implements a driver supporting Synaptics ClearPad and other
touchscreen sensors that use the RMI4 protocol, as defined here:


http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4%20Intrfacing%20Guide.pdf

as well as successor documents that haven't made their way through to
publication yet.

This code supersedes the patch submitted on 2012-10-05.  For all files
included in this patch, we believe that all outstanding issues arising
from the previous submissions have been addressed, except as follows:

* we've investigated using irq_chip to manage chip interrupt dispatch, and
that certainly is a good idea.  However, we need to support kernels back to
3.0.x, and the required functionality is not yet present in those older kernels.
Once we no longer need to support 3.0.x, we'll jump onto irq_chip right
away.

* some of the requested changes to rmi_f11.c are simply not possible while
still retaining general driver functionality.  We've clarified existing comments
and added new ones to explain why that is the case.


This patch is against the v3.7-rc5 tag of Linus' kernel tree, object
77b67063bb6bce6d475e910d3b886a606d0d91f7.  It should work fine with that kernel,
but will not work with earlier kernels due to changes in the input subsystem.



Included in this patch are:
- full support for an RMI virtual bus as a standard kernel bus

- physical layer implementation for I2C

- device driver for general RMI4 sensor functionality

- function implementations for the following RMI4 functions:
* F01 device control
* F11 multifinger pointing

The driver supports a system having one or more RMI sensors attached to it.
Most devices have just a single touch sensor, but some have more than one.
An example is the Fuse concept phone, which has 4 RMI sensors in it.

Each sensor is presented as a device on the RMI logical bus (/sys/bus/rmi).
Devices are named/numbered in the order they are discovered on the bus,
starting with /sys/bus/rmi/devices/sensor00 for the first once, .../sensor01
for the second one, and so on.

Individual RMI functions are presented as child devices of the sensor device.
For example, sensor00.fn01, sensor00.fn11, and so on.  Control of an RMI
function's operating parameters is implemented via sysfs or debugfs (depending
on whether the parameters are used during normal operation or system
development/prototyping).



The amount of feedback received on previous patches precludes addressing each
item individually.  However, major changes for this patch are:
- elimination of sysfs management macros
- elimination of roll-your-own bitmask management
- moved potentially large arrays and structs from the stack to the heap
- elimination of the union/struct idiom for mapping register groups
- corrected identification of input devices, including adding a BUS_RMI
  bus type.


We've broken this patch into 6 parts, as follows:
01 - public header files and documentation
02 - core sensor and bus implementation
03 - I2C physical layer driver
04 - Kconfigs and Makefiles
05..06 - drivers for individual RMI functions


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny 

Cc: Jean Delvare 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
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/


Re: [RFC PATCH 06/06] input/rmi4: F11 - 2D touch interface

2012-10-25 Thread Christopher Heiny

On 10/10/2012 11:21 AM, Henrik Rydberg wrote:

Hi Christopher,


rmi_f11.c is a driver for 2D touch sensors.  It has been updated to support
the MT-B specification, partition control attributes between debugfs andsysfs,
and to use the standard bus model for loading/unloading.


Please find comments inline.


Thanks very much.  I though I'd replied to this along with the other 
replies sent a couple of weeks ago, but don't see it in the archives. My 
apologies if this is a duplicate message.




Generally, if you want this merged as an input device sometime in the
future, you need to reduce the size and complexity of the whole
patchset. Given that you only need to feed the input subsystem with
raw data, you can make do without most of the sysfs nodes, debug
output, and internal gesture state.

The 2D sensor data, currently living in debugfs, might eventually find
a home in the input subsystem, based on the growing interest from
several directions. However, if you are just looking for a way to
transport the rmi data to userland, please consider implementing this
under a different subsystem.


I must disagree with some of this.  Feeding raw data to the input 
subsystem is not the only thing that needs to be done - there needs to 
be a way to configure and control the operation of the touch sensor, 
both during product prototyping/development (we've partitioned that 
stuff into debugfs) and during normal operation (we've put that stuff in 
sysfs).  If we remove the related code, that would not be possible.  If 
we move it to a different subsystem, where do you suggest it be moved to?


The gesture data is a different matter.  Although the most popular user 
space implementations may contain gesture recognition engines, not all 
of them do.  In that case, it is desirable to have the touch sensor 
firmware perform basic gesture recognition.  However, there is at this 
time no way standard way to transfer that via the input subsystem.  We 
chose to use sysfs for this, but alternatively we could investigate 
using a custom event stream in the input subsystem.  We'd also be quite 
happy to work with you to define a standard set of gesture events for 
basic gestures.






diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c


[snip]


+
+#define FINGER_STATE_MASK  0x03
+#define GET_FINGER_STATE(f_states, i) \
+   ((f_states[i / 4] >> (2 * (i % 4))) & FINGER_STATE_MASK)


These could be open-coded or put in a function instead.


We'll put that in a function.


+
+#define F11_CTRL_SENSOR_MAX_X_POS_OFFSET   6
+#define F11_CTRL_SENSOR_MAX_Y_POS_OFFSET   8
+
+#define F11_CEIL(x, y) (((x) + ((y)-1)) / (y))
+#define INBOX(x, y, box) (x >= box.x && x < (box.x + box.width) \
+   && y >= box.y && y < (box.y + box.height))
+
+#define DEFAULT_XY_MAX 
+#define DEFAULT_MAX_ABS_MT_PRESSURE 255
+#define DEFAULT_MAX_ABS_MT_TOUCH 15
+#define DEFAULT_MAX_ABS_MT_ORIENTATION 1
+#define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
+#define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
+#define MAX_NAME_LENGTH 256
+
+static ssize_t f11_relreport_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf);
+
+static ssize_t f11_relreport_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t count);
+
+static ssize_t f11_maxPos_show(struct device *dev,
+struct device_attribute *attr, char *buf);
+
+static ssize_t f11_rezero_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t count);
+
+static void rmi_f11_free_memory(struct rmi_function_container *fc);
+
+static int rmi_f11_initialize(struct rmi_function_container *fc);
+
+static int rmi_f11_create_sysfs(struct rmi_function_container *fc);
+
+static int rmi_f11_config(struct rmi_function_container *fc);
+
+static int rmi_f11_register_devices(struct rmi_function_container *fc);
+
+static void rmi_f11_free_devices(struct rmi_function_container *fc);
+
+static void f11_set_abs_params(struct rmi_function_container *fc, int index);


Please try to get rid of these.


OK

[snip]


+
+/**
+ * @rezero - writing 1 to this will cause the sensor to calibrate to the
+ * current capacitive state.
+ */
+union f11_2d_commands {
+   struct {
+   bool rezero:1;
+   u8 reserved:7;
+   } __attribute__((__packed__));
+   u8 reg;
+};


Maybe a constant would be more suitable here?


We're trying to use a single idiom for accessing registers (the 
union/struct mechanism you see here).  In a couple of cases, that means 
we use a struct to control a single bit, instead of a constant.  The end 
result is the same, and we find that not mixing our idioms makes the 
code a lot easier to maintain.





+
+/**

Re: [RFC PATCH 02/06] input/rmi4: Core files

2012-10-23 Thread Christopher Heiny

On 10/23/2012 05:11 PM, Dmitry Torokhov wrote:

On Tuesday, October 23, 2012 04:46:28 PM Christopher Heiny wrote:

On 10/11/2012 01:13 AM, Dmitry Torokhov wrote:

On Thu, Oct 11, 2012 at 04:15:56AM +, Christopher Heiny wrote:

On Thursday, October 11, 2012 02:21:53 AM you wrote:

On Sat, Oct 6, 2012 at 6:09 AM, Christopher Heiny 

wrote:


[snip]


+static int process_interrupt_requests(struct rmi_device *rmi_dev)
+{
+   struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+   struct device *dev = &rmi_dev->dev;
+   struct rmi_function_container *entry;
+   u8 irq_status[data->num_of_irq_regs];


Looking at this...

What does the data->num_of_irq_regs actually contain?

I just fear that it is something constant like always 2 or always 4,
so there is actually, in reality, a 16 or 32 bit register hiding in
there.

In that case what you should do is to represent it as a u16 or u32 here,
just or the bits into a status word, and then walk over that status
word with something like ffs(bitword); ...


Nope, it's not constant.  In theory, and RMI4 based sensor can have up
to 128 functions (in practice, it's far fewer), and each function can
have as many as 7 interrupts.  So the number of IRQ registers can vary
from RMI4 sensor to RMI4 sensor, and needs to be computed during the
scan of the product descriptor table.


Is it a good idea to have it on stack then? Should it be part of
rmi_device instead?


It's not coming off the stack.  We're allocating it via devm_kzalloc()
in rmi_driver_probe().


No, look at the part of the code that was quoted. "u8 irq_status[data-
num_of_irq_regs];" is on stack.


Sorry - I thought you were referring to data->num_of_irq_regs rather 
than irq_status.  We'll move that.

--
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-10-23 Thread Christopher Heiny

On 10/11/2012 01:13 AM, Dmitry Torokhov wrote:

On Thu, Oct 11, 2012 at 04:15:56AM +, Christopher Heiny wrote:

On Thursday, October 11, 2012 02:21:53 AM you wrote:

On Sat, Oct 6, 2012 at 6:09 AM, Christopher Heiny  wrote:





+
+/** This is here because all those casts made for some ugly code.
+ */
+static void u8_and(u8 *dest, u8 *target1, u8 *target2, int nbits)
+{
+   bitmap_and((long unsigned int *) dest,
+  (long unsigned int *) target1,
+  (long unsigned int *) target2,
+  nbits);
+}


Hm, getting rid of unreadable casts is a valid case.

I'll be OK with this but maybe the real solution is to introduce such
helpers into ?


Hmmm.  We'll give that some thought.  Thought I'd like to get the RMI4
driver nailed down, just to keep the area of change small.  Once we've
got all the kinks worked out here, we'll look at bitmap.h helpers.


The question is why you are using u8 for bitmaps instead of doing
DECALRE_BITMAP() and using it instead? Then you would not need silly
wrappers around existing APIs.


OK, we'll look into that.  My big concern is whether the bit-order in 
bitmask.h will be the same as the bit order in the RMI4 sensor 
registers.  If that works out OK, we'll switch.




(...)


+static int process_interrupt_requests(struct rmi_device *rmi_dev)
+{
+   struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+   struct device *dev = &rmi_dev->dev;
+   struct rmi_function_container *entry;
+   u8 irq_status[data->num_of_irq_regs];


Looking at this...

What does the data->num_of_irq_regs actually contain?

I just fear that it is something constant like always 2 or always 4,
so there is actually, in reality, a 16 or 32 bit register hiding in there.

In that case what you should do is to represent it as a u16 or u32 here,
just or the bits into a status word, and then walk over that status
word with something like ffs(bitword); ...


Nope, it's not constant.  In theory, and RMI4 based sensor can have up
to 128 functions (in practice, it's far fewer), and each function can
have as many as 7 interrupts.  So the number of IRQ registers can vary
from RMI4 sensor to RMI4 sensor, and needs to be computed during the
scan of the product descriptor table.


Is it a good idea to have it on stack then? Should it be part of
rmi_device instead?


It's not coming off the stack.  We're allocating it via devm_kzalloc() 
in rmi_driver_probe().




+#define simple_show_union_struct(regtype, propname, fmt)\
+static ssize_t tricat(rmi_fn_, FNUM, _##propname##_show)(struct device
*dev,\ +   struct device_attribute *attr,
char *buf) {\ +   struct rmi_function_container *fc;\
+   struct FUNCTION_DATA *data;\
+\
+   fc = to_rmi_function_container(dev);\
+   data = fc->data;\
+\
+   return snprintf(buf, PAGE_SIZE, fmt,\
+   data->regtype.propname);\
+}


OK I see the point, but is there really no other way to do this than
to #define huge static inlines like these? Is it really not possible to
create just generic functions instead of going this far?

(same comment for all)





We tried generic functions previously, and it wound up really really ugly.  
We'd be willing to look at it again, though, since this isn't real beautiful 
either.  If you've got an example implementation in mind. a pointer would help 
a great deal.


You just need to wrap around a custome structure around struct
device_attribute and then you shoudl be able to use generics. If you
look into trackpoint.c you should gett the idea.


That looks a lot tidier.  We'll work on it for sysfs (and maybe for 
debugfs, too).  It might not be applicable in all cases, but it promises 
to make a lot of things tidier.


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 01/06] input/rmi4: Public header and documentation

2012-10-23 Thread Christopher Heiny

On 10/15/2012 11:26 PM, Mark Brown wrote:

On Thu, Oct 11, 2012 at 05:32:59PM +0200, Linus Walleij wrote:

On Thu, Oct 11, 2012 at 5:41 AM, Christopher Heiny  wrote:



In previous patch submissions, we always used these warning functions.
But in the feedback on those patches, we were asked to just make
sysfs show/store NULL if the attribute is write/read only.  However,
during their development process, our customers want to see the
warnings if the attributes are accessed incorrectly.  So we made
these warnings a debug option.



Basically my stance is that you should not lower yourself to the
level of others not getting the point of your technical solution
by making unelegant compromises, what
you should do is to bring them up to your level so they
understand that your solution is elegant.


It seems like what you really want to do is add a debug feature to sysfs
which will optionally complain loudly at bad accesses; obviously it's
not something that should be there all the time as running then handling
an error is a perfectly legitimate thing to do.  As with the /CS
handling it'd mean it was handled at an appropriate level and could be
reused elsewhere (it might also help make it clear to your customers why
this is generally bad form).


See my reply to Dmitry of a bit ago.  These are no longer needed, and 
we'll be dropping them.

--
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 01/06] input/rmi4: Public header and documentation

2012-10-23 Thread Christopher Heiny

On 10/11/2012 08:32 AM, Linus Walleij wrote:

On Thu, Oct 11, 2012 at 5:41 AM, Christopher Heiny  wrote:

Linus Walleij wrote:



But please use arithmetic operators (I think I said this on the last
review):

dest[0] = src & 0xFF;
dest[1] = src >> 8;

Doing it the above way makes artithmetic look like maths, and it isn't.
Besides it's done this way in most parts of the kernel and we're
familiar with it.


Yes, you mentioned it previously.  I'm somewhat paranoid, though, and
don't trust the shift/mask method to work correctly on big-endian
machines.  If the shifts can be relied on to behave (I'm guessing the
answer is "yes", since you say this idiom is used widely in the
kernel), then I'll change it.


If the behaviour was not consistent across different endianness
it would not be part of the C language specification...

<< means shift left in the accumulator or whatever you have.
It will work the same no matter how bits are laid out in
memory.


OK, after reviewing the spec I'll accept that.  We'll make the change.


+static inline ssize_t rmi_store_error(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   dev_warn(dev,
+"WARNING: Attempt to write %d characters to read-only
attribute %s.", +   count, attr->attr.name);
+   return -EPERM;
+}


Here it looks like you're hiding a lot of stuff that should be dev_warn()?
Consider my earlier point about dynamic debug.


In previous patch submissions, we always used these warning functions.
But in the feedback on those patches, we were asked to just make
sysfs show/store NULL if the attribute is write/read only.  However,
during their development process, our customers want to see the
warnings if the attributes are accessed incorrectly.  So we made
these warnings a debug option.


See Dmitry's comment ...

Basically my stance is that you should not lower yourself to the
level of others not getting the point of your technical solution
by making unelegant compromises, what
you should do is to bring them up to your level so they
understand that your solution is elegant.

Maybe a bit utopist I know...


What's the old saying?  "I want to live in Theory.  Everything is always 
so nice there..."  :-)


Anyway, see my reply to Dmitry a bit ago.  These are no longer needed, 
so we'll drop them.

--
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 01/06] input/rmi4: Public header and documentation

2012-10-23 Thread Christopher Heiny

On 10/11/2012 01:24 AM, Dmitry Torokhov wrote:

On Thu, Oct 11, 2012 at 03:41:41AM +, Christopher Heiny wrote:

>Linus Walleij wrote:

> >On Sat, Oct 6, 2012 at 6:09 AM, Christopher Heiny  
wrote:
> >

> > >+#ifdef CONFIG_RMI4_DEBUG
> > >+/**
> > >+ * Utility routine to handle writes to read-only attributes.  Hopefully
> > >+ * this will never happen, but if the user does something stupid, we
> > >don't
> > >+ * want to accept it quietly (which is what can happen if you just put
> > >NULL + * for the attribute's store function).
> > >+ */
> > >+static inline ssize_t rmi_store_error(struct device *dev,
> > >+   struct device_attribute *attr,
> > >+   const char *buf, size_t count)
> > >+{
> > >+   dev_warn(dev,
> > >+"WARNING: Attempt to write %d characters to read-only
> > >attribute %s.", +   count, attr->attr.name);
> > >+   return -EPERM;
> > >+}

> >
> >Here it looks like you're hiding a lot of stuff that should be dev_warn()?
> >Consider my earlier point about dynamic debug.

>
>In previous patch submissions, we always used these warning functions.
>But in the feedback on those patches, we were asked to just make sysfs
>show/store NULL if the attribute is write/read only.  However, during
>their development process, our customers want to see the warnings if
>the attributes are accessed incorrectly.  So we made these warnings a
>debug option.

>

I think it is the case when customer is not always right. Given that
the attributes are created with S_IRUGO mask how will we even get these
methods to fire?


We were able to get those to fire in earlier kernels under some UIs 
(such as Android).  However, we no longer support those earlier version. 
 I have checked the behavior on up-to-date kernels and UI versions, and 
everyone seems to handle this correctly.  That means we can drop these 
definitions entirely, so we'll do that.

--
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 01/06] input/rmi4: Public header and documentation

2012-10-23 Thread Christopher Heiny

On 10/11/2012 01:20 AM, Dmitry Torokhov wrote:

On Fri, Oct 05, 2012 at 09:09:58PM -0700, Christopher Heiny wrote:

+
+   int (*write_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
+  int len);
+   int (*read_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
+ int len);
+


If you declare your buffer as [const] void * instead of u8 * I think you
will be able to get rid of most of your unions.


Good point.  We'll explore that.  If you see it in the next patch, 
you'll know it worked out.




+ * Helper fn to convert a byte array representing a 16 bit value in the RMI
+ * endian-ness to a 16-bit value in the native processor's specific endianness.
+ * We don't use ntohs/htons here because, well, we're not dealing with
+ * a pair of 16 bit values. Casting dest to u16* wouldn't work, because
+ * that would imply knowing the byte order of u16 in the first place.  The
+ * same applies for using shifts and masks.
+ */
+static inline u16 batohs(u8 *src)
+{
+   return src[1] * 0x100 + src[0];
+}
+
+/**
+ * Helper function to convert a 16 bit value (in host processor endianess) to
+ * a byte array in the RMI endianess for u16s.  See above comment for
+ * why we dont us htons or something like that.
+ */
+static inline void hstoba(u8 *dest, u16 src)
+{
+   dest[0] = src % 0x100;
+   dest[1] = src / 0x100;
+}


These are not used anymore, right?


There are function drivers that we chose not to include that depend on 
these.  We'll drop these from rmi.h until we're ready to submit those 
other function drivers.

--
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 01/06] input/rmi4: Public header and documentation

2012-10-23 Thread Christopher Heiny

On 10/11/2012 10:16 PM, Mark Brown wrote:

On Thu, Oct 11, 2012 at 03:56:22AM +, Christopher Heiny wrote:

Fix your mailer to word wrap within paragraphs.


Sorry - I was on the road and had to use a web interface.  It looked OK 
during composition.  Is this better?




>If this feature is a deal-breaker, we can take it out.  In the absence
>of a generic GPIO implementation for CS, though, I'd much rather leave
>it in.  Once generic GPIO CS arrives, we'll remove it pretty quickly.

>

Why not just implement this at an appropriate level in the SPI
subsystem?  One of the great things about Linux is that you can change
the core code...


At the moment, we're trying to keep our work focused on just the core 
RMI4 driver.  It's evident that we've still got a bit to learn, and I'd 
be more comfortable keeping our learning experiences confined as they 
are now.


However, a general capability in SPI core is a fine idea for future 
work, once we get the RMI4 driver ironed out.  Can we agree to defer 
that for now?


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: [RFC PATCH 02/06] input/rmi4: Core files

2012-10-22 Thread Christopher Heiny

On 10/10/2012 08:06 PM, Joe Perches wrote:

On Thu, 2012-10-11 at 02:49 +, Christopher Heiny wrote:

Joe Perches wrote:

[]

+ list_for_each_entry(entry, &data->rmi_functions.list, list)
+ if (entry->irq_mask)
+ process_one_interrupt(entry, irq_status,
+   data);


style nit, it'd be nicer with braces.


I agree with you, but checkpatch.pl doesn't. :-(


Sure it does.

$ cat t.c
{
list_for_each_entry(entry, &data->rmi_functions.list, list) {
if (entry->irq_mask)
process_one_interrupt(entry, irq_status, data);
}
}
$ ./scripts/checkpatch.pl --strict -f t.c
total: 0 errors, 0 warnings, 0 checks, 7 lines checked

t.c has no obvious style problems and is ready for submission.


I stand corrected.  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 06/06] input/rmi4: F11 - 2D touch interface

2012-10-10 Thread Christopher Heiny
Linus Walleij wrote:
> On Sat, Oct 6, 2012 at 6:10 AM, Christopher Heiny 
> wrote:
> 
> So looking closer at this one since we will use it. Maybe it's in such a
> good shape now that I should be able to actually test it with the hardware?

Well, it's been possible to test at least since the patch submitted last 
December.  The code might have been ugly, but it was working.

> 
> (...)
> 
> > diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c

[snip previously mentioned stuff]

> 
> > +#define F11_CTRL_SENSOR_MAX_X_POS_OFFSET   6
> > +#define F11_CTRL_SENSOR_MAX_Y_POS_OFFSET   8
> > +
> > +#define F11_CEIL(x, y) (((x) + ((y)-1)) / (y))
> 
> Use existing kernel macros in 
> 
> In this case:
> #define F11_CEIL(x, y) DIV_ROUND_UP(x, y)
> 
> Or just use DIV_ROUND_UP() directly in the code, your choice.

Use it directly is simpler.

> 
> > +#define MAX_NAME_LENGTH 256
> 
> Really? Are you sure there is not a null terminator or length byte
> included so it's actually 255?

We were assuming 255 + terminator.  Perhaps a better name such as 
NAME_BUFFER_SIZE would be clearer?


> 
> (...)
> 
> > +static int sensor_debug_open(struct inode *inodep, struct file *filp)
> > +{
> > +   struct sensor_debugfs_data *data;
> > +   struct f11_2d_sensor *sensor = inodep->i_private;
> > +   struct rmi_function_container *fc = sensor->fc;
> > +
> > +   data = devm_kzalloc(&fc->dev, sizeof(struct sensor_debugfs_data),
> > +   GFP_KERNEL);
> 
> Again I may have lead you astray. Check if this leaks memory, in that
> case use kzalloc()/kfree(). Sorry

No problem - will correct it.

> 
> (...)
> 
> > +static int f11_debug_open(struct inode *inodep, struct file *filp)
> > +{
> > +   struct f11_debugfs_data *data;
> > +   struct rmi_function_container *fc = inodep->i_private;
> > +
> > +   data = devm_kzalloc(&fc->dev, sizeof(struct f11_debugfs_data),
> > +   GFP_KERNEL);
> 
> Dito.
> 
> (...)
> 
> > +static void rmi_f11_abs_pos_report(struct f11_data *f11,
> > +  struct f11_2d_sensor *sensor,
> > +  u8 finger_state, u8 n_finger)
> 
> (...)
> 
> > +   if (axis_align->flip_y)
> > +   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.
> > +   */
> 
> This is a weird commenting style, what's wrong with a single star?
> (No big deal but it stands out...)

It's probably just someone's editor settings.  We can tidy it up.

> 
> (...)
> 
> > +static int f11_allocate_control_regs(struct rmi_device *rmi_dev,
> > +   struct f11_2d_device_query *device_query,
> > +   struct f11_2d_sensor_query *sensor_query,
> > +   struct f11_2d_ctrl *ctrl,
> > +   u16 ctrl_base_addr) {
> > +
> > +   struct rmi_driver_data *driver_data =
> > dev_get_drvdata(&rmi_dev->dev); +   struct rmi_function_container *fc
> > = driver_data->f01_container; +
> > +   ctrl->ctrl0_9 = devm_kzalloc(&fc->dev, sizeof(union
> > f11_2d_ctrl0_9), +  GFP_KERNEL);
> 
> If this is called from .probe() only, this is correct.
> 
> So the rule is: use devm_* for anything that is allocated at .probe()
> and released on .remove(). Any other dynamic buffers etc need to
> use common kzalloc()/kfree().

OK - we'll review to make sure that rule is followed, and change as required.

[snip a bunch of the same]

> 
> > +
> > +   return f11_read_control_regs(rmi_dev, ctrl, ctrl_base_addr);
> 
> Hey why are you ending with a call to that function?
> The function name gets misleading.
> 
> Instead call both functions in succession at the call site on
> .probe().

OK.


> 
> (...)
> 
> > +static int f11_device_init(struct rmi_function_container *fc)
> > +{
> > +   int rc;
> > +
> > +   rc = rmi_f11_initialize(fc);
> > +   if (rc < 0)
> > +   goto err_free_data;
>

RE: [RFC PATCH 05/06] input/rmi4: F01 - device control

2012-10-10 Thread Christopher Heiny
Linus Walleij wrote:
> On Sat, Oct 6, 2012 at 6:10 AM, Christopher Heiny  
> wrote:
> > RMI Function 01 implements basic device control and power management
> > behaviors for the RMI4 sensor.  Since the last patch, we've decoupled
> > rmi_f01.c implementation from rmi_driver.c, so rmi_f01.c acts as a
> > standard driver module to handle F01 devices on the RMI bus.
> > 
> > Like other modules, a number of attributes have been moved from sysfs to
> > debugfs, depending on their expected use.
> > 
> > 
> > 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 
> > 
> > ---
> 
> There is liberal whitespacing above. (No big deal, but anyway.)
> 
> (...)
> 
> > +/**
> > + * @reset - set this bit to force a firmware reset of the sensor.
> > + */
> > +union f01_device_commands {
> > +   struct {
> > +   bool reset:1;
> > +   u8 reserved:7;
> > +   } __attribute__((__packed__));
> > +   u8 reg;
> > +};
> 
> I'm still scared by these unions. I see what you're doing but my
> preferred style of driver writing is to use a simple u8 if you just treat
> it the right way with some |= and &= ...
> 
> #include 
> 
> #define F01_RESET BIT(0)
> 
> u8 my_command = F01_RESET;
> 
> send(&my_command);
> 
> I will not insist on this because it's a bit about programming style.
> For memory-mapped devices we usually do it my way, but this
> is more like some protocol and I know protocols like to do things
> with structs and stuff so no big deal.

That's a good summary of what we're trying to do.  Our original version did 
more of the traditional mask+shift approach to manipulating the fields in the 
various registers, but in the case of complicated functions such as F11 this 
rapidly became unreadable.  We found the unions worked a lot better - the code 
was more readable and less error prone.  For consistency we decided to apply 
them throughout the code.

> 
> > +#ifdef CONFIG_RMI4_DEBUG
> > +struct f01_debugfs_data {
> > +   bool done;
> > +   struct rmi_function_container *fc;
> > +};
> > +
> > +static int f01_debug_open(struct inode *inodep, struct file *filp)
> > +{
> > +   struct f01_debugfs_data *data;
> > +   struct rmi_function_container *fc = inodep->i_private;
> > +
> > +   data = devm_kzalloc(&fc->dev, sizeof(struct f01_debugfs_data),
> > +   GFP_KERNEL);
> 
> Wait, you probably did this because I requested it, but I was maybe
> wrong?
> 
> Will this not re-allocate a chunk every time you look at a debugfs
> file? So it leaks memory?
> 
> In that case common kzalloc() and kfree() is the way to go, as it
> is for dynamic buffers. Sorry for screwing things up for you.

No problem - we'll fix it.  Or unfix it.  Or something like that. :-)


> 
> > +   for (i = 0; i < f01->irq_count && *local_buf != 0;
> > +i++, local_buf += 2) {
> > +   int irq_shift;
> > +   int interrupt_enable;
> > +   int result;
> > +
> > +   irq_reg = i / 8;
> > +   irq_shift = i % 8;
> 
> Please stop doing these arithmetics-turned-maths things.
> 
> irq_reg = i >> 8;
> irq_shift = i & 0xFF;

See note on this in a previous email.

> 
> (...)
> 
> > +static ssize_t rmi_fn_01_interrupt_enable_show(struct device *dev,
> > +   struct device_attribute *attr, char *buf)
> > +{
> > +   struct rmi_function_container *fc;
> > +   struct f01_data *data;
> > +   int i, len, total_len = 0;
> > +   char *current_buf = buf;
> > +
> > +   fc = to_rmi_function_container(dev);
> > +   data = fc->data;
> > +   /* loop through each irq value and copy its
> > +* string representation into buf */
> > +   for (i = 0; i < data->irq_count; i++) {
> > +   int irq_reg;
> > +   int irq_shift;
> > +   int interrupt_enable;
> > +
> > +   irq_reg = i / 8;
> > +   irq_shift = i % 8;
> 
> Dito.
> 
> (...)
> 
> > +static int f01_probe(struct device *dev);
> 
> Do you really need to forward-declare this?

It's a leftover from

RE: [RFC PATCH 04/06] input/rmi4: Config files and makefiles

2012-10-10 Thread Christopher Heiny
Linus Walleij wrote:
> On Sat, Oct 6, 2012 at 6:10 AM, Christopher Heiny 
> wrote:
> 
> (...)
> 
> > diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> 
> (...)
> 
> > +config RMI4_DEBUG
> > +   bool "RMI4 Debugging"
> > +   depends on RMI4_BUS
> 
> select DEBUG_FS
> 
> This has been illustrated many times in the review. You definatley
> have code depending on debugfs when this is selected.

Agreed.--
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 03/06] input/rmi4: I2C physical interface

2012-10-10 Thread Christopher Heiny
Linus Walleij wrote:
> On Sat, Oct 6, 2012 at 6:10 AM, Christopher Heiny  
> wrote:
> > The I2C physical driver is not extensively changed in terms of
> > functionality since the previous patch.  Management of the attention GPIO
> > has been moved to rmi_driver.c (see previous email), and most of the
> > debug related interfaces have been moved from sysfs to debugfs.  Control
> > of the debug features has been moved from compile-time to runtime
> > switches available via debugfs.
> > 
> > The core I2C functionality was previously ACKed by Jean Delvare.  I don't
> > believe that portion of the code has changed much since then, but we'd
> > appreciate a second glance at this.
> 
> The above commit blurb looks more like a changelog than a description
> of the actual patch. Nothing wrong with that but begin by describing
> the patch first.

Good point.  I was describing the patch, but not from the correct point of 
view. :-)

[snip some items covered in a previous email]

> 
> > +static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data
> > *data); +static void teardown_debugfs(struct rmi_i2c_data *data);
> 
> Why do you need to forward-declare these? Can't you just move them
> up above the functions using them?

Probably.  We'll do that if possible.

> 
> > +struct i2c_debugfs_data {
> > +   bool done;
> 
> Done with what? ... needs some doc.

OK.

> 
> > +   struct rmi_i2c_data *i2c_data;
> > +};
> 
> (...)
> 
> > +static int __devinit rmi_i2c_probe(struct i2c_client *client,
> > + const struct i2c_device_id *id)
> 
> (...)
> 
> > +   rmi_phys = kzalloc(sizeof(struct rmi_phys_device), GFP_KERNEL);
> 
> (...)
> 
> > +   data = kzalloc(sizeof(struct rmi_i2c_data), GFP_KERNEL);
> 
> Can you use devm_kzalloc(&client->dev, ...) for these so you don't
> need to free() them explicitly?

Hmm.  That looks like a merge regression - I'm pretty sure we implemented 
devm_kzalloc there.

> 
> (...)
> 
> > +static int __devexit rmi_i2c_remove(struct i2c_client *client)
> > +{
> > +   struct rmi_phys_device *phys = i2c_get_clientdata(client);
> > +   struct rmi_device_platform_data *pd = client->dev.platform_data;
> > +
> > +   /* Can I remove this disable_device */
> > +   /*disable_device(phys); */
> 
> So just delete these two lines then?

Yes.--
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-10-10 Thread Christopher Heiny
On Thursday, October 11, 2012 02:21:53 AM you wrote:
> On Sat, Oct 6, 2012 at 6:09 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.
> 
> So I think you really want Greg KH to look at this bus implementation
> now. Please include Greg on future mailings...
> 
> It looks much improved from previous versions, and sorry if I am now
> adding even more comments, but it's because you cleared out some
> noise that was disturbing my perception so I can cleanly review
> the architecture of this thing now. (I'm impressed by your work and
> new high-speed turnaround time!)

Thanks for the praise - it means a lot to me and my team.

We'll cc Greg on the next patch drop.

[snip some items covered in a previous email]

> 
> (...)
> 
> > diff --git a/drivers/input/rmi4/rmi_driver.c
> > b/drivers/input/rmi4/rmi_driver.c

[snip some items covered in a previous email]

> 
> > +#define DELAY_NAME "delay"
> 
> This is only used in one place, why not just use the string
> "delay" there?
> 
> (...)
> 
> > +   if (IS_ENABLED(CONFIG_RMI4_SPI) && !strncmp("spi", info->proto,
> > 3)) { +   data->debugfs_delay =
> > debugfs_create_file(DELAY_NAME,
> > +   RMI_RW_ATTR, rmi_dev->debugfs_root,
> > rmi_dev, +   &delay_fops);
> 
> i.e. there.

That's a left-over.  We'll consolidate it.

> 
> (...)
> 
> > +/* Useful helper functions for u8* */
> > +
> > +static bool u8_is_any_set(u8 *target, int size)
> > +{
> > +   int i;
> > +   /* We'd like to use find_first_bit, but it ALWAYS returns 1,
> > +   *  no matter what we pass it.  So we have to do this the hard way.
> > +   *  return find_first_bit((long unsigned int *)  target, size) !=
> > 0;
> > +   */
> > +   for (i = 0; i < size; i++) {
> > +   if (target[i])
> > +   return true;
> > +   }
> > +   return false;
> > +}
> 
> Instead of:
> 
> if (u8_is_any_set(foo, 128) {}
> 
> Why can't you use:
> 
> if (!bitmap_empty(foo, 128*8) {}
> 
> ?
> 
> If you look at the implementation in the  header
> and __bitmap_empty() in lib/bitmap.c you will realize that this
> function is already optimized like this (and I actually don't think
> the RMI4 code is performance-critical for these functions anyway,
> but prove me wrong!)

We'll give !bitmap_empty a try.

> 
> > +
> > +/** This is here because all those casts made for some ugly code.
> > + */
> > +static void u8_and(u8 *dest, u8 *target1, u8 *target2, int nbits)
> > +{
> > +   bitmap_and((long unsigned int *) dest,
> > +  (long unsigned int *) target1,
> > +  (long unsigned int *) target2,
> > +  nbits);
> > +}
> 
> Hm, getting rid of unreadable casts is a valid case.
> 
> I'll be OK with this but maybe the real solution is to introduce such
> helpers into ?

Hmmm.  We'll give that some thought.  Thought I'd like to get the RMI4 driver 
nailed down, just to keep the area of change small.  Once we've got all the 
kinks worked out here, we'll look at bitmap.h helpers.

> 
> (...)
> 
> > +static int process_interrupt_requests(struct rmi_device *rmi_dev)
> > +{
> > +   struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > +   struct device *dev = &rmi_dev->dev;
> > +   struct rmi_function_container *entry;
> > +   u8 irq_status[data->num_of_irq_regs];
> 
> Looking at this...
> 
> What does the data->num_of_irq_regs actually contain?
> 
> I just fear that it is something constant like always 2 or always 4,
> so there is actually, in reality, a 16 or 32 bit register hiding in there.
> 
> In that case what you should do is to represent it as a u16 or u32 here,
> just or the bits into a status word, and then walk over that status
> word with something like ffs(bitword); ...

Nope, it's not constant.  In theory, and RMI4 based sensor can have up to 128 
functions (in practice, it's far fewer), and each function can have

RE: [RFC PATCH 01/06] input/rmi4: Public header and documentation

2012-10-10 Thread Christopher Heiny
Mark Brown wrote:
> On Tue, Oct 09, 2012 at 09:43:13AM +0200, Linus Walleij wrote:
> > On Sat, Oct 6, 2012 at 6:09 AM, Christopher Heiny  
> > wrote:
> > > + * @cs_assert - For systems where the SPI subsystem does not control
> > > the CS/SSB + * line, or where such control is broken, you can provide a
> > > custom routine to + * handle a GPIO as CS/SSB.  This routine will be
> > > called at the beginning and + * end of each SPI transaction.  The RMI
> > > SPI implementation will wait + * pre_delay_us after this routine
> > > returns before starting the SPI transfer; + * and post_delay_us after
> > > completion of the SPI transfer(s) before calling it + * with
> > > assert==FALSE.
> > 
> > Hm hm, can you describe the case where this happens?
> > 
> > Usually we don't avoid fixes for broken drivers by duct-taping
> > solutions into other drivers, instead we fix the SPI driver.
> > 
> > I can think of systems where CS is asserted not by using
> > GPIO but by poking some special register for example, which
> > is a valid reason for including this, but working around broken
> > SPI drivers is not a valid reason to include this.
> > 
> > (Paging Mark about it.)
> 
> Yeah, this seems silly - by this logic we'd have to go round implementing
> manual /CS control in every single SPI client driver which isn't
> terribly sensible.  The driver should just assume that the SPI
> controller does what it's told.  As you say if there's an issue the
> relevant controller driver should take care of things.
> 
> We should also have generic support in the SPI framework for GPIO based
> /CS, there's enough drivers open coding this already either due to
> hardware limitations or to support extra chip selects.
> 
> The ability of SPI hardware and driver authors to get /CS right is
> pretty depressing :/

You will get no argument at all from me on that point.  I'll even add board 
layout engineers to the list ("it wasn't convenient to run CS, so we just used 
a different pin.  You can just mux it, right?").  Basically this feature exists 
to help get prototype systems up and running while the SPI 
hardware/driver/layout matures.

If this feature is a deal-breaker, we can take it out.  In the absence of a 
generic GPIO implementation for CS, though, I'd much rather leave it in.  Once 
generic GPIO CS arrives, we'll remove it pretty quickly.  

--
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 01/06] input/rmi4: Public header and documentation

2012-10-10 Thread Christopher Heiny
Linus Walleij wrote:
> On Sat, Oct 6, 2012 at 6:09 AM, Christopher Heiny  
> wrote:
> > As requested in the feedback from the previous patch, we've documented the
> > debugfs and sysfs attributes in files in
> > Documentation/ABI/testing.  There's two files, one for debugfs and one
> > for sysfs.
> 
> This is a massive improvement! Atleast as far as I've read... If you fix the
> below remarks I think I'm ready to accept this file, but that's just me and
> doesn't say anything about what Dmitry et al will comment on...

Thanks!  See my comments below.

> 
> (...)
> 
> > +  The RMI4 driver implementation exposes a set of informational and
> > control +  parameters via debugs.  These parameters are those that
> > typically are only
> s/debugs/debugfs
> 
> (...)
> 
> > +  comms_debug - (rw) Write 1 to this dump information about
> > register +  reads and writes to the console.  Write 0 to
> > this to turn +  this feature off.  WARNING: Imposes a
> > major performance +  penalty when turned on.
> > +  irq_debug - (rw) Write 1 to this dump information about
> > interrupts +  to the console.  Write 0 to this to turn
> > this feature off. +  WARNIG: Imposes a major performance
> > penalty when turned on.
> Hm. Usually we control dynamic debug prints by standard kernel
> frameworks, can you tell what is wrong with this and why you need
> a custom mechanism? See the following:
> Documentation/dynamic-debug-howto.txt
> http://lwn.net/Articles/434833/

The current arrangement was arrived at after some discussion with customers.  
Originally we went with the Kconfig based approach you suggested in August.  
However, the response from our guinea pigs, um, very helpful test customers, 
was "AAAggh! Too complicated and too static!!"  As a result we explored 
alternatives.  The dynamic debug interface was considered, but it is usually 
disabled in our customer's kernel configurations, even during development.  In 
the end, we arrived at some simple debugfs on/off switches for the more verbose 
features (like comms_debug and irq_debug, above).

If this is a deal-breaker, I can go back to the customers and see if they are 
willing to consider enabling dynamic debug during prototyping and development.

> 
> (...)
> 
> > +++ b/Documentation/ABI/testing/sysfs-rmi4
> 
> (...)
> 
> > +  chargerinput ... (rw) User space programs can use this to tell
> > the +  sensor that the system is plugged into an external
> > power +  source (as opposed to running on
> > batteries).  This allows +  the sensor firmware to make
> > necessary adjustments for the +  current capacitence
> > regime.  Write 1 to this when the +  system is using
> > external power, write 0 to this when the +  system is
> > running on batteries.  See spec for full details.
> I remember discussing in-kernel notifiers for this. I don't
> really see the point in tunnelling a notification from the drivers/power
> subsystem to the drivers/input subsystem through userspace for
> no good.
> 
> It's no blocker though, I don't expect you to fix this as part of
> this driver submission.
> 
> Maybe Anton can comment?

Hmmm.  I agree that it'd be good to avoid looping through userspace.  But

I found ways to notfiy the kernel that the charger is plugged/unplugged, but 
that's only useful if you're a battery charger device driver.  I also found 
ways for userspace to get notification of charger events.  I didn't spot any 
way for in-kernel drivers to get notification of such events.  Perhaps I'm not 
looking the right places, though - can you provide a pointer?

> 
> (...)
> 
> > +  interrupt_enable ... (ro) This represents the current RMI4
> > interrupt +  mask (F01_RMI_Ctrl1 registers).  See spec
> > for full details.
> What does the userspace have to do with this stuff? Seems way
> too low-level, but whatever.

It's primarily used in hardware prototyping and bring up.  Perhaps it belongs 
in debugfs in that case.

> 
> (...)
> 
> > +  sleepmode ... (rw) Controls power management on the
> > device.  Writing +  0 to this parameter puts the device
> > into its normal operating +  mode.  Writing 1 to this
> > parameter fully disables touch +  sensors and similar
> > inputs - no touch data will be reported +  from the
> > device in this mode.  Writing 2 or 3 to this device

RE: [RFC PATCH 02/06] input/rmi4: Core files

2012-10-10 Thread Christopher Heiny
Joe Perches wrote:
> On Fri, 2012-10-05 at 21:09 -0700, Christopher Heiny wrote:
> []
> 
> Just some trivial comments:

Thanks - see below for responses.

> > diff --git a/drivers/input/rmi4/rmi_driver.c
> > b/drivers/input/rmi4/rmi_driver.c
> []
> 
> > @@ -0,0 +1,1529 @@
> 
> []
> 
> > +static ssize_t delay_write(struct file *filp, const char __user *buffer,
> > +size_t size, loff_t *offset) {
> > + struct driver_debugfs_data *data = filp->private_data;
> > + struct rmi_device_platform_data *pdata =
> > + data->rmi_dev->phys->dev->platform_data;
> > + int retval;
> > + char local_buf[size];
> > + unsigned int new_read_delay;
> > + unsigned int new_write_delay;
> > + unsigned int new_block_delay;
> > + unsigned int new_pre_delay;
> > + unsigned int new_post_delay;
> > +
> > + retval = copy_from_user(local_buf, buffer, size);
> > + if (retval)
> > + return -EFAULT;
> > +
> > + retval = sscanf(local_buf, "%u %u %u %u %u", &new_read_delay,
> > + &new_write_delay, &new_block_delay,
> > + &new_pre_delay, &new_post_delay);
> > + if (retval != 5) {
> > + dev_err(&data->rmi_dev->dev,
> > + "Incorrect number of values provided for delay.");
> > + return -EINVAL;
> > + }
> > + if (new_read_delay < 0) {
> 
> These are unnecessary tests as unsigned values are never < 0.

Right.  Thought we'd taken care of most of the silliness like that, but 
obviously missed some.  We'll recheck the codebase.

[snip]


> > +static ssize_t phys_read(struct file *filp, char __user *buffer, size_t
> > size, + loff_t *offset) {
> > + struct driver_debugfs_data *data = filp->private_data;
> > + struct rmi_phys_info *info = &data->rmi_dev->phys->info;
> > + int retval;
> > + char local_buf[size];
> 
> size comes from where?  possible stack overflow?

H.  Good point.  We'll look at this.

[snip]

> []
> 
> > + list_for_each_entry(entry, &data->rmi_functions.list, list)
> > + if (entry->irq_mask)
> > + process_one_interrupt(entry, irq_status,
> > +   data);
> 
> style nit, it'd be nicer with braces.

I agree with you, but checkpatch.pl doesn't. :-(

> 
> > diff --git a/drivers/input/rmi4/rmi_driver.h
> > b/drivers/input/rmi4/rmi_driver.h
> []
> 
> > @@ -0,0 +1,438 @@
> > 
> > +
> > +#define tricat(x, y, z) tricat_(x, y, z)
> > +
> > +#define tricat_(x, y, z) x##y##z
> 
> I think these tricat macros are merely obfuscating
> and don't need to be used.

tricat is used internally by another collection of macros that helps generate 
sysfs files.  In particular, it's used to generate the RMI4 register name 
symbols.--
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 04/06] input/rmi4: Config files and makefiles

2012-10-05 Thread Christopher Heiny
Not much to say here, except that we've reduced the number of different
Kconfig options, which will hopefully make it easier to configure RMI4
support in kernels.


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

---

 drivers/input/Kconfig   |2 +
 drivers/input/Makefile  |2 +
 drivers/input/rmi4/Kconfig  |   86 +++
 drivers/input/rmi4/Makefile |   26 +
 4 files changed, 116 insertions(+), 0 deletions(-)

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 55f7e57..2c543c0 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -188,6 +188,8 @@ source "drivers/input/touchscreen/Kconfig"

 source "drivers/input/misc/Kconfig"

+source "drivers/input/rmi4/Kconfig"
+
 endif

 menu "Hardware I/O ports"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 5ca3f63..571515a 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -24,4 +24,6 @@ obj-$(CONFIG_INPUT_TABLET)+= tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)   += misc/

+obj-y += rmi4/
+
 obj-$(CONFIG_INPUT_APMPOWER)   += apm-power.o
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
new file mode 100644
index 000..fa12638
--- /dev/null
+++ b/drivers/input/rmi4/Kconfig
@@ -0,0 +1,86 @@
+#
+# RMI4 configuration
+#
+config RMI4_BUS
+   bool "Synaptics RMI4 bus support"
+   help
+ Say Y here if you want to support the Synaptics RMI4 bus.  This is
+ required for all RMI4 device support.
+
+ If unsure, say Y.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_DEBUG
+   bool "RMI4 Debugging"
+   depends on RMI4_BUS
+   help
+ Say Y here to enable debug feature in the RMI4 driver.
+
+ Note that the RMI4 driver debug features can generate a lot of
+ output (potentially clogging up your dmesg output) and generally
+ slow down driver operation.  It's recommended to enable them only
+ if you are actively developing/debugging RMI4 features.
+
+ If unsure, say N.
+
+config RMI4_I2C
+   bool "RMI4 I2C Support"
+   depends on RMI4_BUS && I2C
+   help
+ Say Y here if you want to support RMI4 devices connected to an I2C
+ bus.
+
+ If unsure, say Y.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_GENERIC
+   bool "RMI4 Generic driver"
+   depends on RMI4_BUS
+   help
+ Say Y here if you want to support generic RMI4 devices.
+
+ This is pretty much required if you want to do anything useful with
+ your RMI device.
+
+ This feature is not currently available as a loadable module.
+
+config RMI4_F11
+   tristate "RMI4 Function 11 (2D pointing)"
+   depends on RMI4_BUS && RMI4_GENERIC
+   help
+ Say Y here if you want to add support for RMI4 function 11.
+
+ Function 11 provides 2D multifinger pointing for touchscreens and
+ touchpads.  For sensors that support relative pointing, F11 also
+ provides mouse input.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rmi-f11.
+
+config RMI4_F11_PEN
+   bool "RMI4 F11 Pen Support"
+   depends on RMI4_F11
+   help
+ Say Y here to add support for pen input to RMI4 function 11.
+
+ If this feature is enabled, when pen inputs are detected they
+ will be reported to the input stream as MT_TOOL_PEN.  Otherwise,
+ pens will be treated the same as fingers.
+
+ Not all UI implementations deal gracefully with pen discrimination.
+ If your system is not recognizing pen touches and you know your
+ sensor supports pen input, you probably want to turn this feature
+ off.
+
+config RMI4_VIRTUAL_BUTTON
+   tristate "RMI4 Vitual Button"
+   depends on RMI4_F11
+   help
+ Say Y here if you want to add support for RMI4 virtual button to F11.
+
+ The virtual button feature implement the virtual button device in
+ certain RMI4 touch sensors.
+
+ This works only if your sensor supports F11 gestures.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
new file mode 100644
index 000..1480689
--- /dev/null
+++ b/drivers/input/rmi4/Makefile
@@ -0,0 +1,26 @@
+obj-$(CONFIG_RMI4_BUS) += rmi_bus.o
+obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
+obj-$(CONFIG_RMI4_GENERIC) += rmi_driver.o rmi_f01.o
+obj-$(CONFIG_RMI4_F11) += rmi_f11.o
+
+ccflags-$(CONFIG_RMI4_DEBUG) += -DDEBUG
+
+ifeq ($(KERNELRELEASE),)
+
+# KERNELDIR ?= /home/
+PWD := $(shell pwd)
+
+.PHONY: build clean
+
+build:
+  

[RFC PATCH 05/06] input/rmi4: F01 - device control

2012-10-05 Thread Christopher Heiny
RMI Function 01 implements basic device control and power management
behaviors for the RMI4 sensor.  Since the last patch, we've decoupled rmi_f01.c
implementation from rmi_driver.c, so rmi_f01.c acts as a standard driver
module to handle F01 devices on the RMI bus.

Like other modules, a number of attributes have been moved from sysfs to
debugfs, depending on their expected use.


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 | 1463 ++
 drivers/input/rmi4/rmi_f01.h |  136 
 2 files changed, 1599 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..d734f46
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -0,0 +1,1463 @@
+/*
+ * 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"
+
+/**
+ * @reset - set this bit to force a firmware reset of the sensor.
+ */
+union f01_device_commands {
+   struct {
+   bool reset:1;
+   u8 reserved:7;
+   } __attribute__((__packed__));
+   u8 reg;
+};
+
+/**
+ * @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 {
+   union 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.
+ */
+union f01_query_42 {
+   struct {
+   bool has_ds4_queries:1;
+   bool has_multi_phy:1;
+   bool has_guest:1;
+   u8 reserved:5;
+   } __attribute__((__packed__));
+   u8 regs[1];
+};
+
+/**
+ * @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.
+ */
+union f01_ds4_queries {
+   struct {
+   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_

[RFC PATCH 01/06] input/rmi4: Public header and documentation

2012-10-05 Thread Christopher Heiny
As requested in the feedback from the previous patch, we've documented the
debugfs and sysfs attributes in files in Documentation/ABI/testing.  There's
two files, one for debugfs and one for sysfs.


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

---

 Documentation/ABI/testing/debugfs-rmi4 |   99 +
 Documentation/ABI/testing/sysfs-rmi4   |  103 +
 include/linux/rmi.h|  696 
 3 files changed, 898 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/debugfs-rmi4 
b/Documentation/ABI/testing/debugfs-rmi4
new file mode 100644
index 000..cf1aa2d
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-rmi4
@@ -0,0 +1,99 @@
+What:  /sys/kernel/debug/rmi/devices
+Date:  October 2012
+KernelVersion: 3.x
+Contact:   Christopher Heiny 
+Description:
+
+  The RMI4 driver implementation exposes a set of informational and control
+  parameters via debugs.  These parameters are those that typically are only
+  viewed or adjusted during product development, tuning, and debug.
+  For parameters that are  referenced and/or adjusted during normal operation,
+  please see sysfs-rmi4 in this directory.
+
+  General debugging parameters for a particular RMI4 sensor are found in
+  /sys/kernel/debug/rmi/sensorXX/, where XX is a the device's ID as a two
+  digit number (padded with leading zeros).  Function specific parameters
+  for an RMI4 sensor are found in /sys/kernel/debug/rmi/devices/FYY/, where
+  XX is a the device's ID as a two digit number (padded with leading zeros)
+  and YY is the hexdecimal function number (for example, F11 for RMI function
+  F11).
+
+  For RMI4 functions that support multiple sensor instances (such as F11),
+  the parameters for individual sensors have .Z appended to them, where Z is
+  the index of the sensor instance (for example, clip.0, clip.1, clip.2, and
+  so on).
+
+  Some of the parameters exposed here are described in detail in the
+  RMI4 Specification, which is found here:
+http://www.synaptics.com/sites/default/files/511-000136-01_revD.pdf
+  For such parameters, we'll reference you to that document, rather than
+  copying the contents here.
+
+  /sys/kernel/debug/rmi/
+  /sensorXX/
+  attn_count - (ro) Shows the number of ATTN interrupts handled so far.
+  comms_debug - (rw) Write 1 to this dump information about register
+  reads and writes to the console.  Write 0 to this to turn
+  this feature off.  WARNING: Imposes a major performance
+  penalty when turned on.
+  irq_debug - (rw) Write 1 to this dump information about interrupts
+  to the console.  Write 0 to this to turn this feature off.
+  WARNIG: Imposes a major performance penalty when turned on.
+  phys - (ro) Presents information about the physical connection of
+  this device.  It has one line, with the format:
+
+   prot tx_count tx_bytes tx_errors rx_count rx_bytes 
rx_errors attn
+
+  Where
+   prot is one of i2c, spi1, or spi2
+   tx_count is the number of write operations
+   tx_bytes is the number of bytes written
+   tx_errors is the number of write operations that 
encountered errors
+   rx_count is the number of read operations
+   rx_bytes is the total number of bytes read
+   rx_errors is the number of read operations that 
encountered errors
+
+  All counts are 64-bit unsigned values, and are set to zero
+  when the physical layer driver is initialized.
+
+  /sensorXX/F01/
+  interrupt_enable - (rw) allows you to read or modify the F01
+  interrupt enable mask (the F01_RMI_Ctrl1 register(s)).
+
+  /sensorXX/F11/
+  clip.Z - (rw) Controls in-driver coordinate clipping for the 2D
+  sensor Z.  This is a set of four unsigned values in the
+  range [0..65535], representing the lower bounds on X, the
+  upper bounds on X, the lower bounds on Y, and the upper
+  bounds on Y.  Coordinates will be clipped to these ranges.
+  If enabled, clip is the final transformation to be applied
+  to the coordinates. The default upper and lower bounds for
+  clip are 0 and 65535 respectively for both axes.
+  delta_threshold.Z - (rw) Controls the F11 distance thresholds. This
+  contains two values, corresponding to F11_2D_Ctrl2 and
+  F11_2D_Ctrl3.  Se the spec for more details.
+  flip.Z - (rw) This parameter is a pair of single binary digits (for
+  example, "0 0" or

[RFC PATCH 03/06] input/rmi4: I2C physical interface

2012-10-05 Thread Christopher Heiny
The I2C physical driver is not extensively changed in terms of functionality
since the previous patch.  Management of the attention GPIO has been moved to
rmi_driver.c (see previous email), and most of the debug related interfaces
have been moved from sysfs to debugfs.  Control of the debug features has been
moved from compile-time to runtime switches available via debugfs.

The core I2C functionality was previously ACKed by Jean Delvare.  I don't
believe that portion of the code has changed much since then, but we'd
appreciate a second glance at this.


Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 
Cc: Jean Delvare 

Acked-by: Jean Delvare 

---

 drivers/input/rmi4/rmi_i2c.c |  455 ++
 1 files changed, 455 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..c21a27c
--- /dev/null
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -0,0 +1,455 @@
+/*
+ * 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 "rmi_driver.h"
+
+struct rmi_i2c_data {
+   struct mutex page_mutex;
+   int page;
+   struct rmi_phys_device *phys;
+
+   bool comms_debug;
+#ifdef CONFIG_RMI4_DEBUG
+   struct dentry *debugfs_comms;
+#endif
+};
+
+#ifdef CONFIG_RMI4_DEBUG
+
+#include 
+#include 
+
+static int setup_debugfs(struct rmi_device *rmi_dev, struct rmi_i2c_data 
*data);
+static void teardown_debugfs(struct rmi_i2c_data *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[size];
+   struct i2c_debugfs_data *dfs = filp->private_data;
+   struct rmi_i2c_data *data = dfs->i2c_data;
+
+   if (dfs->done)
+   return 0;
+
+   dfs->done = 1;
+
+   retval = snprintf(local_buf, PAGE_SIZE, "%u\n", data->comms_debug);
+
+   if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
+   return -EFAULT;
+
+   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[size];
+   unsigned int new_value;
+   struct i2c_debugfs_data *dfs = filp->private_data;
+   struct rmi_i2c_data *data = dfs->i2c_data;
+
+   retval = copy_from_user(local_buf, buffer, size);
+   if (retval)
+   return -EFAULT;
+
+   retval = sscanf(local_buf, "%u", &new_value);
+   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);
+   if (!data->debugfs_comms || IS_ERR(data->debugfs_comms)) {
+   dev_warn(&rmi_dev->dev, "Failed to create debugfs 
comms_debug.\n");
+ 

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

2012-10-05 Thread Christopher Heiny
This patch implements a driver supporting Synaptics ClearPad and other
touchscreen sensors that use the RMI4 protocol, as defined here:


http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4%20Intrfacing%20Guide.pdf

as well as successor documents that haven't made their way through to
publication yet.

This code supersedes the patch submitted on 2012-08-17.  For all files
included in this patch, we believe that all outstanding issues arising
from the previous submissions have been addressed, except for looking into
using irq_chip to manage chip interrupt dispatch - was passed on that mainly
to limit the amount of major structural change since the previous patch.  We
will continue to pursue the irq_chip request, however.

Also, at the request of several maintainers, we have reduced the number of
files included in this patch.  Hopefully this is much less of a patch bomb
(perhaps just a patch firecracker).  The files provided are sufficient to
fully drive an RMI4 2D sensor, handling full multifinger reporting and device
and power management.


This patch is against the v3.6 tag of Linus' kernel tree, commit
a0d271cbfed1dd50278c6b06bead3d00ba0a88f9.  It should work fine with kernels
back to 3.1.



Included in this patch are:
- full support for an RMI virtual bus as a standard kernel bus

- physical layer implementation for I2C

- device driver for general RMI4 sensor functionality

- function implementations for the following RMI4 functions:
* F01 device control
* F11 multifinger pointing

The driver supports a system having one or more RMI sensors attached to it.
Most devices have just a single touch sensor, but some have more than one.
An example is the Fuse concept phone, which has 4 RMI sensors in it.

Each sensor is presented as a device on the RMI logical bus (/sys/bus/rmi).
Devices are named/numbered in the order they are discovered on the bus,
starting with /sys/bus/rmi/devices/sensor00 for the first once, .../sensor01
for the second one, and so on.

Individual RMI functions are presented as child devices of the sensor device.
For example, sensor00.fn01, sensor00.fn11, and so on.  Control of an RMI
function's operating parameters is implemented via sysfs or debugfs (depending
on whether the parameters are used during normal operation or system
development/prototyping).



The amount of feedback received on previous patches precludes addressing each
item individually.  However, major changes for this patch are:
- elimination of ad-hoc bus matching/binding and reliance on standard bus
  implementation.
- elimination of out-of-tree features such as EARLY_SUSPEND
- use of devm_kzalloc where appropriate
- partition of control parameters between sysfs and debugfs
- simplified configuration and control of debugging related features
- IRQ management consolidated in once place


We've broken this patch into 6 parts, as follows:
01 - public header files and documentation
02 - core sensor and bus implementation
03 - I2C physical layer driver
04 - Kconfigs and Makefiles
05..06 - drivers for individual RMI functions


Comments and other feedback on this driver are welcomed.

Christopher Heiny and the Synaptics RMI4 driver team

Signed-off-by: Christopher Heiny 

Cc: Jean Delvare 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
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/


Re: [RFC PATCH 2/17] input: RMI4 core bus and sensor drivers.

2012-09-25 Thread Christopher Heiny
Sorry about the delay in following up on this one - we're going over the 
feedback, and realized we'd missed this comment.



On 08/23/2012 01:55 AM, Linus Walleij wrote:

+/* Create templates for given types */
>+#define simple_show_union_struct_unsigned(regtype, propname)\
>+simple_show_union_struct(regtype, propname, "%u\n")
>+
>+#define simple_show_union_struct_unsigned2(regtype, reg_group, propname)\
>+simple_show_union_struct2(regtype, reg_group, propname, "%u\n")
>+
>+#define show_union_struct_unsigned(regtype, reg_group, propname)\
>+show_union_struct(regtype, reg_group, propname, "%u\n")
>+
>+#define show_store_union_struct_unsigned(regtype, reg_group, propname)\
>+show_store_union_struct(regtype, reg_group, propname, "%u\n")
>+
>+#define show_repeated_union_struct_unsigned(regtype, reg_group, propname)\
>+show_repeated_union_struct(regtype, reg_group, propname, "%u")
>+
>+#define show_store_repeated_union_struct_unsigned(regtype, reg_group, 
propname)\
>+show_store_repeated_union_struct(regtype, reg_group, propname, "%u")
>+
>+/* Remove access to raw format string versions */
>+/*#undef simple_show_union_struct
>+#undef show_union_struct_unsigned
>+#undef show_store_union_struct
>+#undef show_repeated_union_struct
>+#undef show_store_repeated_union_struct*/

This looks like trying to reimplement ioctl() in sysfs.

If what you want is to send big structs in/out of the kernel,
use either ioctl() on device nodes (should be trivial since input
is using real device nodes) or use configfs.


I'm a little confused.  There's repeated emphasis in the kernel doc that 
you shouldn't use ioctl() anymore - use sysfs instead.  So we've been 
using sysfs, though it seems somewhat klutzy.  If it's actually OK to 
use ioctl(), that could simplify things.  On the other hand, using 
configfs might be more appropriate.

--
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] Input: Add new driver into Input Subsystem for Synaptics DS4 touchscreen I2C devices

2012-09-19 Thread Christopher Heiny

On 09/16/2012 03:33 PM, Linus Walleij wrote:

On Sun, Sep 16, 2012 at 11:56 AM, Alexandra Chin
 wrote:


Synaptics DS4 touchscreen driver implements a generic driver supporting I2C
protocol for Synaptics Design Studio 4 (DS4) family of Touchscreen Controllers
which include the following:

- S32xX series
- S730X series
- S22xx series

The driver supports multifinger pointing functionality and power management.
The driver is based on the original work submitted by
Linus Walleij  and
Naveen Kumar Gaddipati .


Naveen's driver is sitting in drivers/staging/ste_rmi4 right now because
Christopher Heiny is working on a RMI4 bus driver, and wanted to
merge that.

I am happy with this being merged for now if the plan is
to eventually replace it with Christopher's (et al) driver,
if it's not going to disturb the other driver in the end.

How are Synaptics planning to handle the transition?
(I assume you are coordinated... not always the case in
big companies, I know from experience :-)

Remember to keep Henrik Rydberg in the loop on touch
controllers.


Hi Linus,

The RMI4 bus driver will continue to be developed by my team, with the 
intent that it will support all RMI4 functions as well as all Synaptics 
RMI4 products, and the goal of eventual inclusion in the kernel. 
However, as you've noted elsewhere, this is taking a while. :-)


In the meantime, there is a perceived customer pull for a limited 
functionality product/platform specific "thin driver".  Alexandra's team 
has been working on such a driver, resulting in her patch submission 
from a couple of days ago.  They really would like to see both our 
drivers being adopted into the kernel. This will enable them to support 
all our customers effectively and provide our customers with the best 
flexibility possible. Going forward, Synaptics will continue to 
maintain, support and upgrade these drivers for future touch controller 
platforms as well.


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 17/17] input: RMI4 F54 analog data reporting

2012-09-04 Thread Christopher Heiny

On 08/27/2012 04:01 PM, Linus Walleij wrote:



>Signed-off-by: Christopher Heiny
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 

This is not using the existing in-kernel framework for ADC (which I think is
what you're doing), in this case use the IIO subsystem so consult
drivers/iio/adc and be inspired.

Just exposing a set of weird sysfs files to userspace is not proper.


I don't think the Industrial I/O ADC framework is appropriate for this. 
 F54 isn't intended to provide access to a general purpose ADC feature, 
but rather for diagnostic access to the touchscreen's capacitive sense 
features, which results in a fairly weird (as you noticed) interface. 
Trying to hammer on it to fit into iio/adc would require a lot of 
effort, and wind up making it look like something it really isn't.


However, it makes sense to move this whole interface to debugfs, given 
its intended model of use.



--
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 14/17] input: RMI4 F30 GPIO/LED control

2012-09-04 Thread Christopher Heiny

On 08/27/2012 03:58 PM, Linus Walleij wrote:

GPIO/LED, nice since I'm a GPIO maintainer I'll take a closer look.

If the bus will start doing a lot of non-input business it should live under
drivers/mfd but I think this is just one exception, right?

On Fri, Aug 17, 2012 at 3:17 PM, Christopher Heiny  wrote:

(...)

diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c



+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"


The non-existance of  and  tells us that something
is very wrong.

You should not model these GPIOs and LEDs by a set of obscure
sysfs attributes, instead use the proper kernel subsystems that
already exist for handling this! LEDs and GPIOs already have their
own (standardized) userspace sysfs interfaces.

Reading the code I see that this is what happens here, so please rewrite
this to be a real GPIO+LED driver using struct gpio_chip and
the same for LEDs.

Be inspired by drivers/gpio/* and drivers/leds/*


Roger.  We'll rework this and resubmit at a later date.
--
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 5/17] input: rmidev character driver for RMI4 sensors

2012-09-04 Thread Christopher Heiny

On 08/27/2012 11:49 AM, Linus Walleij wrote:

On Fri, Aug 17, 2012 at 3:17 PM, Christopher Heiny  wrote:


Driver for Synaptics touchscreens using RMI4 protocol.


Really? This looks more like some custom char driver to get a pipe
into the device from userspace. Put in a proper description of what this
is for.

If the purpose is to read/write arbitrary addresses in the device,
you should use regmap's debugfs interface for this instead,
it is much better suited for the task.


We'll look into using regmap not only for that, but possibly for general 
register access.  It has the potential to greatly simply both the 
arbitrary register access, as well as the driver itself.




(...)

+#define RMI_CHAR_DEV_TMPBUF_SZ 128
+#define RMI_REG_ADDR_PAGE_SELECT 0xFF
+#define REG_ADDR_LIMIT 0x
+
+struct rmidev_data {
+   /* mutex for file operation*/
+   struct mutex file_mutex;
+   /* main char dev structure */
+   struct cdev main_dev;
+
+   /* pointer to the corresponding RMI4 device.  We use this to do */
+   /* read, write, etc. */
+   struct rmi_device *rmi_dev;
+   /* reference count */
+   int ref_count;


Something tells me you should atleast use  for this.
It also solves a few atomicity problems in a good standard way.
See Documentation/kref.txt


Roger.



+/*store dynamically allocated major number of char device*/
+static int rmidev_major_num;


You need to patch your desired major number into
Documentation/devices.txt'


We were going by the recommendation in Linux Device Drivers (3rd 
edition) to use dynamic major number allocation via alloc_chrdev_region. 
 In particular in section 3.2.3 it says "new numbers are not being 
assigned".  I guess at this point we need to know whether the info in 
LDD3 is authoritative or not.  We can always add a number to 
Documentation/devices.txt if that's the right thing to do, but I'd like 
to make sure our next submission isn't bounced because we did that, 
turning the process into Patch Ping-Pong :-).


In any case, it's likely that switching to the regmap interface would 
make this question irrelevant.




+static struct class *rmidev_device_class;


Last time discussed with Greg, class devices were deprecated,
and you should just use a bus instead. (But not sure.)


The references I found online weren't clear on this, so more 
investigation is required.  We'll defer that till we find out if the 
regmap changes eliminate the need for this.


--
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 8/17] input: RMI4 F09 Built-In Self Test

2012-09-04 Thread Christopher Heiny

On 08/27/2012 03:07 PM, Linus Walleij wrote:
[snip]

>+static struct device_attribute attrs[] = {
>+   __ATTR(status, RMI_RW_ATTR,
>+  rmi_f09_status_show, rmi_f09_status_store),
>+   __ATTR(limitRegisterCount, RMI_RO_ATTR,
>+  rmi_f09_limit_register_count_show, rmi_store_error),
>+   __ATTR(hostTestEnable, RMI_RW_ATTR,
>+  rmi_f09_host_test_enable_show, rmi_f09_host_test_enable_store),
>+   __ATTR(internalLimits, RMI_RO_ATTR,
>+  rmi_f09_internal_limits_show, rmi_store_error),
>+   __ATTR(resultRegisterCount, RMI_RO_ATTR,
>+  rmi_f09_result_register_count_show, rmi_store_error),
>+   __ATTR(overall_bist_result, RMI_RO_ATTR,
>+  rmi_f09_overall_bist_result_show, rmi_store_error),
>+   __ATTR(test_number_control, RMI_RW_ATTR,
>+  rmi_f09_test_number_control_show,
>+  rmi_f09_test_number_control_store),
>+   __ATTR(test_result1, RMI_RO_ATTR,
>+  rmi_f09_test_result1_show, rmi_store_error),
>+   __ATTR(test_result2, RMI_RO_ATTR,
>+  rmi_f09_test_result2_show, rmi_store_error),
>+   __ATTR(run_bist, RMI_RW_ATTR,
>+  rmi_f09_run_bist_show, rmi_f09_run_bist_store),
>+   __ATTR(f09_control_test1, RMI_RW_ATTR,
>+  rmi_f09_control_test1_show, rmi_f09_control_test1_store),
>+   __ATTR(f09_control_test2, RMI_RW_ATTR,
>+  rmi_f09_control_test2_show, rmi_f09_control_test2_store),
>+};

If this is*only*  for tests, then for sure this should be in debugfs?


F09 is used in the final product (for example, a phone or tablet) both 
on the production line and to diagnose failures in returned products. 
We can't be certain that the phone/tablet/whatever manufacturer will 
include debugfs in their production kernel, and if they don't they 
almost certainly won't want to install a different kernel on the 
production line to run a test, so we provided a sysfs interface to this.





>+static int rmi_f09_alloc_memory(struct rmi_function_container *fc)

(...)

>+static void rmi_f09_free_memory(struct rmi_function_container *fc)

Why do you need separate functions for these two?

If they are only used from one place (which I suspect) then just
put the code at that site.


Some of the other modules have fairly large and complicated 
alloc_memory() and free_memory() implementations, so we adopted this as 
a general convention in all the RMI function implementations.  But as 
you suggested elsewhere, using devm_kzalloc could tidy things up a lot, 
in which case the functions could be merged back into their callers.


[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 00/11] input: Synaptics RMI4 Touchscreen Driver

2012-08-27 Thread Christopher Heiny

On 08/22/2012 05:50 AM, Linus Walleij wrote:

On Sat, Aug 18, 2012 at 12:17 AM, Christopher Heiny
  wrote:


>This patch implements a driver supporting Synaptics ClearPad and other
>touchscreen sensors that use the RMI4 protocol, as defined here:

Nice!


>This patch is against the v2.6.38 tag of Linus' kernel tree, commit
>521cb40b0c44418a4fd36dc633f575813d59a43d.  This will be our last patch against
>such an old kernel version, future patches will be against 3.x kernels.

Please use the head of the subsystem tree to do this work.
In this case, use Dmitry's git.

Currently I just cannot test this because we have no such old codebase
around.

But I will attempt to review the patch set!


Thanks for all the feedback so far - it has been quite valuable.  I'm 
not going to try to respond to every comment, especially since most of 
it will be of a "Yeah - good idea" nature.


A couple of general things:


The "phys" debugfs interface is intended to tell you about the physical 
interface a particular RMI4 sensor is using (either SPI or I2C or 
whatever), including the name of the interface, the number of 
reads/writes done, number of bytes that have been read/written, number 
of errors, and so on.


We chose to to call name it phys so that the debug tools would be able 
to find this interface no matter what the physical connection was, even 
when new physical layer support (for example, SMbus) is introduced.




EARLY_SUSPEND/LATE_RESUME and other power management stuff.  We're 
caught in a bind here.  Most of our customers are using some flavor of 
Android.  They have the expectation that our driver will (a) support the 
Android power management model, and (b) be contributed into the mainline 
kernel without change.  Yes, I know these are contradictory 
requirements, given that Android specific features are not in the mainline.


With the upcoming rebase of the code to more modern kernels, we'll be 
able to eliminate a bunch of those dependencies.  But the only way to 
eliminate them entirely would be to maintain mainline and Android 
versions of the driver, which would drain resources from developing core 
features and fixing bugs.  So for now we've got a single code base. 
When we finally submit a patch and the only response is "everything is 
fine but that Android stuff", we'll probably change that policy within 
48 hours (to include time needed for celebration and subsequent hangover 
recovery :-) ).


Cheers,
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 1/17] input: RMI4 public header file and documentation.

2012-08-22 Thread Christopher Heiny

On 08/22/2012 02:45 PM, Dmitry Torokhov wrote:

On Wednesday, August 22, 2012 09:08:00 PM Linus Walleij wrote:

>On Sat, Aug 18, 2012 at 12:17 AM, Christopher Heiny
>  wrote:
>

> >+/* Helper fn to convert a byte array representing a short in the RMI
> >+ * endian-ness to a short in the native processor's specific endianness.

Is RMI-endiannes different from BE and LE (joking)? Please simply state what
on-wire endianness is and use xx_to_cpu() or cpu_to_xx() as needed. I think I
mentioned it about a year ago already...


Gronk. I thought I'd killed that.  But obviously didn't do a thorough job.

[Slinks off in embarrassment.]
--
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 00/11] input: Synaptics RMI4 Touchscreen Driver

2012-08-22 Thread Christopher Heiny

On 08/22/2012 05:50 AM, Linus Walleij wrote:

On Sat, Aug 18, 2012 at 12:17 AM, Christopher Heiny
 wrote:


This patch implements a driver supporting Synaptics ClearPad and other
touchscreen sensors that use the RMI4 protocol, as defined here:


Nice!


This patch is against the v2.6.38 tag of Linus' kernel tree, commit
521cb40b0c44418a4fd36dc633f575813d59a43d.  This will be our last patch against
such an old kernel version, future patches will be against 3.x kernels.


Please use the head of the subsystem tree to do this work.
In this case, use Dmitry's git.

Currently I just cannot test this because we have no such old codebase
around.


Yeah, we've been in a bind in that regard, mostly due to customer 
requirements to support Android Gingerbread.  At least we were able to 
drop Froyo support this time around. :-P


Going forward, though, we'll be tracking much newer kernels for our 
development, and hopefully getting patches out more frequently as well.




But I will attempt to review the patch set!


Thanks!  We look forward to your input.

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 14/17] input: RMI4 F30 GPIO/LED control

2012-08-17 Thread Christopher Heiny
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_f30.c | 1247 ++
 1 files changed, 1247 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
new file mode 100644
index 000..4bc2932
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f30.c
@@ -0,0 +1,1247 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+#define FUNCTION_DATA rmi_fn_30_data
+#define FNUM 30
+
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+
+#define MAX_LEN 256
+
+/* data specific to fn $30 that needs to be kept around */
+union f30_query {
+   struct {
+   u8 extended_patterns:1;
+   u8 has_mappable_buttons:1;
+   u8 has_led:1;
+   u8 has_gpio:1;
+   u8 has_haptic:1;
+   u8 has_gpio_driver_control:1;
+   u8 gpio_led_count:5;
+   };
+   struct {
+   u8 regs[2];
+   u16 address;
+   };
+};
+
+struct f30_gpio_ctrl_0n {
+   u8 led_sel;
+};
+
+struct f30_gpio_ctrl_0 {
+   struct f30_gpio_ctrl_0n *regs;
+   u16 address;
+   u8 length;
+};
+
+union f30_gpio_ctrl_1 {
+   struct {
+   u8 gpio_debounce:1;
+   u8 reserved:3;
+   u8 halt:1;
+   u8 halted:1;
+   u8 reserved2:2;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   };
+};
+
+struct f30_gpio_ctrl_2n {
+   u8 dir;
+};
+
+struct f30_gpio_ctrl_2 {
+   struct f30_gpio_ctrl_2n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_gpio_ctrl_3n {
+   u8 gpiodata;
+};
+
+struct f30_gpio_ctrl_3 {
+   struct f30_gpio_ctrl_3n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_gpio_ctrl_4n {
+   u8 led_act;
+};
+
+struct f30_gpio_ctrl_4 {
+   struct f30_gpio_ctrl_4n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_gpio_ctrl_5n {
+   u8 ramp_period_a;
+   u8 ramp_period_b;
+};
+
+struct f30_gpio_ctrl_5 {
+   struct f30_gpio_ctrl_5n *regs;
+   u16 address;
+   u8 length;
+};
+
+union f30_gpio_ctrl_6n {
+   struct {
+   u8 reserved:1;
+   u8 SPCTRL:3;
+   u8 STRPD:1;
+   u8 reserved2:1;
+   u8 STRPU:1;
+   u8 reserved3:1;
+   };
+   struct {
+   u8 brightness:4;
+   u8 pattern:4;
+   };
+};
+
+struct f30_gpio_ctrl_6 {
+   union f30_gpio_ctrl_6n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_gpio_ctrl_7n {
+   u8 capacity_btn_nbr:5;
+   u8 valid:1;
+   u8 invert:1;
+   u8 open_drain:1;
+};
+
+struct f30_gpio_ctrl_7 {
+   struct f30_gpio_ctrl_7n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_gpio_ctrl_8n {
+   u8 gpio_ctrl8_0;
+   u8 gpio_ctrl8_1;
+};
+
+struct f30_gpio_ctrl_8 {
+   struct f30_gpio_ctrl_8n *regs;
+   u16 address;
+   u8 length;
+};
+
+union f30_gpio_ctrl_9 {
+   struct {
+   u8 haptic_duration;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   };
+};
+
+struct f30_control {
+   struct f30_gpio_ctrl_0 *reg_0;
+   union f30_gpio_ctrl_1 *reg_1;
+   struct f30_gpio_ctrl_2 *reg_2;
+   struct f30_gpio_ctrl_3 *reg_3;
+   struct f30_gpio_ctrl_4 *reg_4;
+   struct f30_gpio_ctrl_5 *reg_5;
+   struct f30_gpio_ctrl_6 *reg_6;
+   struct f30_gpio_ctrl_7 *reg_7;
+   struct f30_gpio_ctrl_8 *reg_8;
+   union f30_gpio_ctrl_9 *reg_9;
+};
+
+struct f30_data_0n {
+   u8 gpi_led_data:1;
+};
+
+struct f30_data_0 {
+   struct f30_data_0n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f30_data {
+   struct f30_data_0 *datareg_0;
+   u16 address;
+   u8 length;
+};
+
+struct rmi_fn_30_data {
+   union f30_query query;
+   struct f30_data data;
+   struct f30_control control;
+   unsigned char gpioled_count;
+   unsigned char gpioled_bitmask_size;
+   unsigned char gpioled_byte_size;
+   uns

[RFC PATCH 12/17] input: RMI4 F1A simple capacitive buttons

2012-08-17 Thread Christopher Heiny
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_f1a.c | 1025 ++
 1 files changed, 1025 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f1a.c b/drivers/input/rmi4/rmi_f1a.c
new file mode 100644
index 000..a7cccfa
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f1a.c
@@ -0,0 +1,1025 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+#define FUNCTION_DATA f1a_data
+#define FNUM 1a
+
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define QUERY_BASE_INDEX 1
+#define MAX_NAME_LEN 256
+#define MAX_BUFFER_LEN 80
+
+#define FILTER_MODE_MIN0
+#define FILTER_MODE_MAX3
+#define MULTI_BUTTON_REPORT_MIN0
+#define MULTI_BUTTON_REPORT_MAX3
+#define TX_RX_BUTTON_MIN   0
+#define TX_RX_BUTTON_MAX   255
+#define THREADHOLD_BUTTON_MIN  0
+#define THREADHOLD_BUTTON_MAX  255
+#define RELEASE_THREADHOLD_BUTTON_MIN  0
+#define RELEASE_THREADHOLD_BUTTON_MAX  255
+#define STRONGEST_BUTTON_HYSTERESIS_MIN0
+#define STRONGEST_BUTTON_HYSTERESIS_MAX255
+#define FILTER_STRENGTH_MIN0
+#define FILTER_STRENGTH_MAX255
+
+union f1a_0d_query {
+   struct {
+   u8 max_button_count:3;
+   u8 reserved:5;
+
+   u8 has_general_control:1;
+   u8 has_interrupt_enable:1;
+   u8 has_multibutton_select:1;
+   u8 has_tx_rx_map:1;
+   u8 has_perbutton_threshold:1;
+   u8 has_release_threshold:1;
+   u8 has_strongestbtn_hysteresis:1;
+   u8 has_filter_strength:1;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[2];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f1a_0d_control_0 {
+   struct {
+   u8 multibutton_report:2;
+   u8 filter_mode:2;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f1a_0d_control_1n {
+   u8 interrupt_enabled_button;
+};
+
+struct f1a_0d_control_1 {
+   struct f1a_0d_control_1n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f1a_0d_control_2n {
+   u8 multi_button;
+};
+
+struct f1a_0d_control_2 {
+   struct f1a_0d_control_2n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f1a_0d_control_3_4n {
+   u8 transmitterbtn;
+   u8 receiverbtn;
+} __attribute__((__packed__));
+
+struct f1a_0d_control_3_4 {
+   struct f1a_0d_control_3_4n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f1a_0d_control_5n {
+   u8 threshold_button;
+};
+
+struct f1a_0d_control_5 {
+   struct f1a_0d_control_5n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+union f1a_0d_control_6 {
+   struct {
+   u8 button_release_threshold;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f1a_0d_control_7 {
+   struct {
+   u8 strongest_button_hysteresis;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f1a_0d_control_8 {
+   struct {
+   u8 filter_strength;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f1a_0d_control {
+   union f1a_0d_control_0 *reg_0;
+   struct f1a_0d_control_1 *reg_1;
+   struct f1a_0d_control_2 *reg_2;
+   struct f1a_0d_control_3_4 *reg_3_4;
+   struct f1a_0d_control_5 *reg_5;
+   union f1a_0d_control_6 *reg_6;
+   union f1a_0d_control_7 *reg_7;
+   union f1a_0d_control_8 *reg_8;
+};
+
+/* data spec

[RFC PATCH 16/17] input: RMI4 F41 Active pen 2D input

2012-08-17 Thread Christopher Heiny
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_f41.c | 1020 ++
 1 files changed, 1020 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f41.c b/drivers/input/rmi4/rmi_f41.c
new file mode 100644
index 000..1bac4e3
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f41.c
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+
+#define FUNCTION_DATA rmi_fn_41_data
+#define FNUM 41
+
+
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define MAX_STR_LEN 256
+
+union f41_ap_query {
+   struct {
+   /* Query 0 */
+   u8 has_reduced_reporting:1;
+   u8 has_modal_control:1;
+   u8 has_force:1;
+   u8 has_orientation:1;
+   u8 has_serial_number:1;
+   u8 has_battery:1;
+   u8 has_z:1;
+   u8 has_single_tap:1;
+
+   /* Query 1 */
+   u8 number_of_buttons:3;
+   u8 f41_ap_query1_b3__7:5;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[2];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+
+union f41_ap_control_0 {
+   struct {
+   /* control 0 */
+   u8 reporting_mode:2;
+   u8 modal_ctrl:1;
+   u8 f41_ap_control0_b3__4:2;
+   u8 single_tap_interrupt_enable:1;
+   u8 in_range_interrupt_enable:1;
+   u8 new_sn_interrupt_enable:1;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f41_ap_control_1 {
+   struct {
+   /* control 1 */
+   u8 button_1_interrupt_enable:1;
+   u8 button_2_interrupt_enable:1;
+   u8 button_3_interrupt_enable:1;
+   u8 button_4_interrupt_enable:1;
+   u8 button_5_interrupt_enable:1;
+   u8 button_6_interrupt_enable:1;
+   u8 button_7_interrupt_enable:1;
+   u8 f41_ap_control1_b7:1;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f41_ap_control_2__5 {
+   struct {
+   u16 max_x_position;
+   u16 max_y_position;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[4];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f41_ap_control_6__9 {
+   struct {
+   u16 x_reduced_reporting_distance;
+   u16 y_reduced_reporting_distance;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[4];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f41_ap_control_10 {
+   struct {
+   u8 max_tap_time;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f41_ap_control {
+   union f41_ap_control_0 *reg_0;
+   union f41_ap_control_1 *reg_1;
+   union f41_ap_control_2__5 *reg_2__5;
+   union f41_ap_control_6__9 *reg_6__9;
+   union f41_ap_control_10 *reg_10;
+};
+
+
+union f41_ap_data_0__3 {
+   struct {
+   /* data 0-1 */
+   u16 x_position;
+
+   /* data 2-3 */
+   u16 y_position;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[4];
+   } __attribute__((__packed__));
+};
+
+union f41_ap_data_4 {
+   struct {
+   /* data 4 */
+   u8 force;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   } __attribute__((__packed__));
+};
+
+union f41_ap_data_5 {
+   struct {
+   /* data 5 */
+   u8 button_1_state:1;
+   u8 button_2_state:1;
+   u8 button_3_state:1;
+   u8 button_4_state:1;
+   u8 button_5_state:1;
+   

[RFC PATCH 15/17] input: RMI4 F34 device reflash

2012-08-17 Thread Christopher Heiny
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_f34.c |  917 ++
 drivers/input/rmi4/rmi_f34.h |   74 
 2 files changed, 991 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
new file mode 100644
index 000..a07f7f9
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f34.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2011, 2012 Synaptics Incorporated
+ *
+ * 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 "rmi_driver.h"
+#include "rmi_f34.h"
+
+#define BLK_SZ_OFF 3
+#define IMG_BLK_CNT_OFF5
+#define CFG_BLK_CNT_OFF7
+
+#define BLK_NUM_OFF 2
+
+/* data specific to fn $34 that needs to be kept around */
+struct rmi_fn_34_data {
+   unsigned char status;
+   unsigned char cmd;
+   unsigned short bootloaderid;
+   unsigned short blocksize;
+   unsigned short imageblockcount;
+   unsigned short configblockcount;
+   unsigned short blocknum;
+   bool inflashprogmode;
+   struct mutex attn_mutex;
+};
+
+static ssize_t rmi_fn_34_status_show(struct device *dev,
+struct device_attribute *attr, char *buf);
+
+
+static ssize_t rmi_fn_34_status_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_fn_34_cmd_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_fn_34_cmd_store(struct device *dev,
+  struct device_attribute *attr,
+  const char *buf, size_t count);
+
+static ssize_t rmi_fn_34_data_read(struct file *data_file, struct kobject 
*kobj,
+  struct bin_attribute *attributes,
+  char *buf, loff_t pos, size_t count);
+
+static ssize_t rmi_fn_34_data_write(struct file *data_file,
+   struct kobject *kobj,
+   struct bin_attribute *attributes, char *buf,
+   loff_t pos, size_t count);
+
+static ssize_t rmi_fn_34_bootloaderid_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf);
+
+static ssize_t rmi_fn_34_bootloaderid_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count);
+
+static ssize_t rmi_fn_34_blocksize_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf);
+
+static ssize_t rmi_fn_34_imageblockcount_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t rmi_fn_34_configblockcount_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf);
+
+static ssize_t rmi_fn_34_blocknum_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf);
+
+static ssize_t rmi_fn_34_blocknum_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count);
+
+static ssize_t rmi_fn_34_rescanPDT_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count);
+
+
+static int rmi_f34_alloc_memory(struct rmi_function_container *fc);
+
+static void rmi_f34_free_memory(struct rmi_function_container *fc);
+
+static int rmi_f34_initialize(struct rmi_function_container *fc);
+
+static int rmi_f34_config(struct rmi_function_container *fc);
+
+static int rmi_f34_reset(struct rm

[RFC PATCH 5/17] input: rmidev character driver for RMI4 sensors

2012-08-17 Thread Christopher Heiny
Driver for Synaptics touchscreens using RMI4 protocol.

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_dev.c |  448 ++
 1 files changed, 448 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_dev.c b/drivers/input/rmi4/rmi_dev.c
new file mode 100644
index 000..080db55
--- /dev/null
+++ b/drivers/input/rmi4/rmi_dev.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2011 Synaptics Incorporated
+ *
+ * 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 "rmi_driver.h"
+
+#define CHAR_DEVICE_NAME "rmi"
+#define DEVICE_CLASS_NAME "rmidev"
+
+#define RMI_CHAR_DEV_TMPBUF_SZ 128
+#define RMI_REG_ADDR_PAGE_SELECT 0xFF
+#define REG_ADDR_LIMIT 0x
+
+struct rmidev_data {
+   /* mutex for file operation*/
+   struct mutex file_mutex;
+   /* main char dev structure */
+   struct cdev main_dev;
+
+   /* pointer to the corresponding RMI4 device.  We use this to do */
+   /* read, write, etc. */
+   struct rmi_device *rmi_dev;
+   /* reference count */
+   int ref_count;
+
+   struct class *device_class;
+};
+
+/*store dynamically allocated major number of char device*/
+static int rmidev_major_num;
+
+
+static struct class *rmidev_device_class;
+
+
+/* file operations for RMI char device */
+
+/*
+ * rmidev_llseek: - use to setup register address
+ *
+ * @filp: file structure for seek
+ * @off: offset
+ *   if whence == SEEK_SET,
+ *   high 16 bits: page address
+ *   low 16 bits: register address
+ *
+ *   if whence == SEEK_CUR,
+ *   offset from current position
+ *
+ *   if whence == SEEK_END,
+ *   offset from END(0x)
+ *
+ * @whence: SEEK_SET , SEEK_CUR or SEEK_END
+ */
+static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
+{
+   loff_t newpos;
+   struct rmidev_data *data = filp->private_data;
+
+   if (IS_ERR(data)) {
+   pr_err("%s: pointer of char device is invalid", __func__);
+   return -EBADF;
+   }
+
+   mutex_lock(&(data->file_mutex));
+
+   switch (whence) {
+   case SEEK_SET:
+   newpos = off;
+   break;
+
+   case SEEK_CUR:
+   newpos = filp->f_pos + off;
+   break;
+
+   case SEEK_END:
+   newpos = REG_ADDR_LIMIT + off;
+   break;
+
+   default:/* can't happen */
+   newpos = -EINVAL;
+   goto clean_up;
+   }
+
+   if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
+   dev_err(&data->rmi_dev->dev, "newpos 0x%04x is invalid.\n",
+   (unsigned int)newpos);
+   newpos = -EINVAL;
+   goto clean_up;
+   }
+
+   filp->f_pos = newpos;
+
+clean_up:
+   mutex_unlock(&(data->file_mutex));
+   return newpos;
+}
+
+/*
+ *  rmidev_read: - use to read data from RMI stream
+ *
+ *  @filp: file structure for read
+ *  @buf: user-level buffer pointer
+ *
+ *  @count: number of byte read
+ *  @f_pos: offset (starting register address)
+ *
+ * @return number of bytes read into user buffer (buf) if succeeds
+ *  negative number if error occurs.
+ */
+static ssize_t rmidev_read(struct file *filp, char __user *buf,
+   size_t count, loff_t *f_pos)
+{
+   struct rmidev_data *data = filp->private_data;
+   ssize_t retval  = 0;
+   unsigned char tmpbuf[count+1];
+
+   /* limit offset to REG_ADDR_LIMIT-1 */
+   if (count > (REG_ADDR_LIMIT - *f_pos))
+   count = REG_ADDR_LIMIT - *f_pos;
+
+   if (count == 0)
+   return 0;
+
+   if (IS_ERR(data)) {
+   pr_err("%s: pointer of char device is invalid", __func__);
+   return -EBADF;
+   }
+
+   mutex_lock(&(data->file_mutex));
+
+   retval = rmi_read_block(data->rmi_dev, *f_pos, tmpbuf, count);
+
+   if (retval < 0)
+   goto clean_up;
+
+   if (copy_to_user(buf, tmpbuf, c

[RFC PATCH 1/17] input: RMI4 public header file and documentation.

2012-08-17 Thread Christopher Heiny
Signed-off-by: Christopher Heiny 

Cc: Dmitry Torokhov 
Cc: Linus Walleij 
Cc: Naveen Kumar Gaddipati 
Cc: Joeri de Gram 

Acked-by: Jean Delvare 

---

 Documentation/input/rmi4.txt |   25 ++
 Documentation/input/rmidev.txt   |  144 +
 Documentation/input/rmisysfs.txt |  200 
 include/linux/rmi.h  |  652 ++
 4 files changed, 1021 insertions(+), 0 deletions(-)

diff --git a/Documentation/input/rmi4.txt b/Documentation/input/rmi4.txt
new file mode 100644
index 000..4e033ff
--- /dev/null
+++ b/Documentation/input/rmi4.txt
@@ -0,0 +1,25 @@
+RMI4 Touchscreen Driver
+===
+
+TBD
+
+Firmware Update Function
+
+
+The RMI4 driver uses the kernel's request_firmware() feature to obtain
+firmware for the touch sensor.  The firmware is expected to live in
+the file firmware/rmi4/.img, where  is the Product ID
+found in the F01 query registers (F01_RMI_QUERY11 through F01_RMI_QUERY20).
+
+To prepare Synaptics provided .img file for reflashing, convert it to .ihex
+format using the following command:
+
+objcopy -I binary -O ihex .img 
firmware/rmi4/.img.ihex
+
+Then make sure to add the image file name to the CONFIG_RMI4_FWLIB entry in
+firmware/Makefile.  If you don't do this, the image file won't be included, and
+the firmware loader class will delay for 60 seconds waiting for a non-existent
+userspace response to the firmware load request.
+
+Firmware updates for multichip solutions (aka LTS) are not supported.
+
diff --git a/Documentation/input/rmidev.txt b/Documentation/input/rmidev.txt
new file mode 100644
index 000..73473ee
--- /dev/null
+++ b/Documentation/input/rmidev.txt
@@ -0,0 +1,144 @@
+RMI4 devices are typically handled by kernel drivers attached to devices on
+/sys/bus/rmi.  However, user space programs can access the RMI4 devices
+through a /dev interface.
+
+Each registered RMI4 device is assigned a number, starting from 0.  The rmidev
+module (if present and loaded) creates a corresponding /dev/rmiX device.  This
+device is a flat binary character file that allows you to read, write, and seek
+within the register space of the corresponding RMI4 device.
+
+Opening the rmidev file is done just like opening any other file.  For example,
+in C you might do the following to open the device file for the first RMI4
+device:
+int file;
+
+file = open("/dev/rmi0", O_RDWR);
+if (file < 0) {
+/* ERROR HANDLING; you can check errno to see what went wrong */
+exit(1);
+}
+
+Once the file is open, you can use read() and write() to access registers in
+the RMI4 register map.  Use lseek() to specify the address at which the
+read() or write() operation will begin.
+
+
+NOTES ON ADDRESSING
+---
+
+The RMI4 register space is 16 bits wide, supporting 65536 available 8-bit
+registers.  This means the range of valid positions within the file is 0
+through 65535 (0x).
+
+Attempting to lseek() to an address of 65536 or higher will return EINVAL.
+read() and write() operations that begin at 65536 or higher will return EINVAL.
+The result of read() and write() operations that begine at 65535 or below, and
+then extend beyond that boundary are undefined.
+
+Although the RMI4 register space supports 65536 registers, not all registers
+are defined or mapped on all products.  Undefined or unmapped registers will
+usually return zero, but you should not rely on this behavior.  The register
+map for a given device may contain 'holes' of unimplemented registers.
+
+If you're not sure what the register map for a given RMI4 device looks like,
+you can use the self describing features of RMI4 to determine the register
+map (this is what the RMI4 touchscreen driver does), or consult the product
+spec and documentation for your product.
+
+
+BUFFERED REGISTERS
+--
+
+The RMI4 specification also defines certain special registers, sometimes
+referred to as "buffered registers".  Buffered registers allow large amounts
+of data to be read or written at a single address in a single read or write
+operation.  Reads from (or writes to) buffered registers DO NOT increment the
+RMI4 device's internal register pointer.  When reading/writing a buffered
+register, you MUST follow these steps:
+(1) lseek() to the buffered register's address
+(2) read/write all data in a single read() or write() call
+(3) lseek() to the address of the next register you wish to read/write
+
+The result of a read or write that extends across a buffered register is
+undefined.  It probably won't do what you expect.
+
+The result of trying to use multiple read() or write() calls to access the
+data in a buffered register is undefined.  It most certainly won't do what
+you expect.
+
+The result of failing to lseek() after reading or writing a buffered register
+is undefined.  It probably won&#x

[RFC PATCH 7/17] input: RMI4 F01 device control

2012-08-17 Thread Christopher Heiny
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_f01.c | 1331 ++
 drivers/input/rmi4/rmi_f01.h |   88 +++
 2 files changed, 1419 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..312ad13
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -0,0 +1,1331 @@
+/*
+ * 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 "rmi_driver.h"
+#include "rmi_f01.h"
+
+union f01_device_commands {
+   struct {
+   u8 reset:1;
+   u8 reserved:1;
+   };
+   u8 reg;
+};
+
+struct f01_device_control {
+   union f01_device_control_0 ctrl0;
+   u8 *interrupt_enable;
+   u8 doze_interval;
+   u8 wakeup_threshold;
+   u8 doze_holdoff;
+};
+
+union f01_query_42 {
+   struct {
+   u8 has_ds4_queries:1;
+   u8 has_multi_phy:1;
+   u8 has_guest:1;
+   u8 reserved:5;
+   };
+   u8 regs[1];
+};
+
+union f01_ds4_queries {
+   struct {
+   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;
+   };
+   u8 regs[4];
+};
+
+struct f01_data {
+   struct f01_device_control device_control;
+   union f01_basic_queries basic_queries;
+   union f01_device_status device_status;
+   u8 product_id[RMI_PRODUCT_ID_LENGTH+1];
+
+   u16 interrupt_enable_addr;
+   u16 doze_interval_addr;
+   u16 wakeup_threshold_addr;
+   u16 doze_holdoff_addr;
+
+   int irq_count;
+   int num_of_irq_regs;
+
+#ifdef CONFIG_PM
+   bool suspended;
+   bool old_nosleep;
+#endif
+};
+
+
+static ssize_t rmi_fn_01_productinfo_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t rmi_fn_01_productid_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf);
+
+static ssize_t rmi_fn_01_manufacturer_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf);
+
+static ssize_t rmi_fn_01_datecode_show(struct device *dev,
+  struct device_attribute *attr,
+  char *buf);
+
+static ssize_t rmi_fn_01_reportrate_show(struct device *dev,
+struct device_attribute *attr,
+char *buf);
+
+static ssize_t rmi_fn_01_reportrate_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_fn_01_interrupt_enable_show(struct device *dev,
+struct device_attribute *attr,
+char *buf);
+
+static ssize_t rmi_fn_01_interrupt_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_fn_01_doze_interval_show(struct device *dev,
+struct device_attribute *attr,
+char *buf);
+
+static ssize_t rmi_fn_01_doze_interval_store(struct device *dev,
+ struct de

[RFC PATCH 3/17] input: RMI4 physical layer drivers for I2C and SPI

2012-08-17 Thread Christopher Heiny
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 |  452 +
 drivers/input/rmi4/rmi_spi.c |  911 ++
 2 files changed, 1363 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..1da8d96
--- /dev/null
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * 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.
+ */
+
+#define COMMS_DEBUG 0
+
+#define IRQ_DEBUG 0
+
+#if COMMS_DEBUG || IRQ_DEBUG
+#define DEBUG
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define RMI_PAGE_SELECT_REGISTER 0xff
+#define RMI_I2C_PAGE(addr) (((addr) >> 8) & 0xff)
+
+static char *phys_proto_name = "i2c";
+
+struct rmi_i2c_data {
+   struct mutex page_mutex;
+   int page;
+   int enabled;
+   int irq;
+   int irq_flags;
+   struct rmi_phys_device *phys;
+};
+
+static irqreturn_t rmi_i2c_irq_thread(int irq, void *p)
+{
+   struct rmi_phys_device *phys = p;
+   struct rmi_device *rmi_dev = phys->rmi_dev;
+   struct rmi_driver *driver = rmi_dev->driver;
+   struct rmi_device_platform_data *pdata = phys->dev->platform_data;
+
+#if IRQ_DEBUG
+   dev_dbg(phys->dev, "ATTN gpio, value: %d.\n",
+   gpio_get_value(pdata->attn_gpio));
+#endif
+   if (gpio_get_value(pdata->attn_gpio) == pdata->attn_polarity) {
+   phys->info.attn_count++;
+   if (driver && driver->irq_handler && rmi_dev)
+   driver->irq_handler(rmi_dev, irq);
+   }
+
+   return IRQ_HANDLED;
+}
+
+/*
+ * rmi_set_page - Set RMI page
+ * @phys: The pointer to the rmi_phys_device struct
+ * @page: The new page address.
+ *
+ * RMI devices have 16-bit addressing, but some of the physical
+ * implementations (like SMBus) only have 8-bit addressing. So RMI implements
+ * a page address at 0xff of every page so we can reliable page addresses
+ * every 256 registers.
+ *
+ * The page_mutex lock must be held when this function is entered.
+ *
+ * Returns zero on success, non-zero on failure.
+ */
+static int rmi_set_page(struct rmi_phys_device *phys, unsigned int page)
+{
+   struct i2c_client *client = to_i2c_client(phys->dev);
+   struct rmi_i2c_data *data = phys->data;
+   char txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page};
+   int retval;
+
+#if COMMS_DEBUG
+   dev_dbg(&client->dev, "RMI4 I2C writes 3 bytes: %02x %02x\n",
+   txbuf[0], txbuf[1]);
+#endif
+   phys->info.tx_count++;
+   phys->info.tx_bytes += sizeof(txbuf);
+   retval = i2c_master_send(client, txbuf, sizeof(txbuf));
+   if (retval != sizeof(txbuf)) {
+   phys->info.tx_errs++;
+   dev_err(&client->dev,
+   "%s: set page failed: %d.", __func__, retval);
+   return (retval < 0) ? retval : -EIO;
+   }
+   data->page = page;
+   return 0;
+}
+
+static int rmi_i2c_write_block(struct rmi_phys_device *phys, u16 addr, u8 *buf,
+  int len)
+{
+   struct i2c_client *client = to_i2c_client(phys->dev);
+   struct rmi_i2c_data *data = phys->data;
+   u8 txbuf[len + 1];
+   int retval;
+#ifCOMMS_DEBUG
+   char debug_buf[len*3 + 1];
+   int i, n;
+#endif
+
+   txbuf[0] = addr & 0xff;
+   memcpy(txbuf + 1, buf, len);
+
+   mutex_lock(&data->page_mutex);
+
+   if (RMI_I2C_PAGE(addr) != data->page) {
+   retval = rmi_set_page(phys, RMI_I2C_PAGE(addr));
+   if (retval < 0)
+   goto exit;
+   }
+
+#if COMMS_DEBUG
+   n = 0;
+   for (i = 0; i < len; i++)
+   n = snprintf(debug_buf+n, 4, "%02x ", buf[i]);
+   dev_dbg(&client->dev, "RMI4 I2C writes %d bytes at %#06x: %

[RFC PATCH 13/17] input: RMI4 F21 Force sensing

2012-08-17 Thread Christopher Heiny
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_f21.c |  832 ++
 1 files changed, 832 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f21.c b/drivers/input/rmi4/rmi_f21.c
new file mode 100644
index 000..2e37c75
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f21.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright (c) 2012-2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+
+#define FUNCTION_DATA rmi_fn_21_data
+#define FNUM 21
+
+
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+union f21_2df_query {
+   struct {
+   /* Query 0 */
+   u8 max_force_sensor_count:3;
+   u8 f21_2df_query0_b3__6:4;
+   u8 has_high_resolution:1;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f21_2df_control_0__3 {
+   struct {
+   /* Control 0 */
+   u8 reporting_mode:3;
+   u8 no_rezero:1;
+   u8 ctl0_reserved:4;
+
+   /* Control 1 */
+   u8 force_click_threshold:8;
+
+   /* Control 2 */
+   u8 int_en_force_0:1;
+   u8 int_en_force_1:1;
+   u8 int_en_force_2:1;
+   u8 int_en_force_3:1;
+   u8 int_en_force_4:1;
+   u8 int_en_force_5:1;
+   u8 int_en_force_6:1;
+   u8 int_en_click:1;
+
+   /* Control 3 */
+   u8 force_interrupt_threshold:8;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[4];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f21_2df_control_4n {
+   /*Control 4.* */
+   u8 one_newton_linear_calibration:7;
+   u8 use_cfg_cal:1;
+} __attribute__((__packed__));
+
+struct f21_2df_control_4 {
+   struct f21_2df_control_4n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f21_2df_control_5n {
+   /* Control 5 */
+   u8 one_newton_nonlinear_calibration;
+};
+
+struct f21_2df_control_5 {
+   struct f21_2df_control_5n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f21_2df_control_6n {
+   /*Control 6.* */
+   u8 x_location;
+};
+
+struct f21_2df_control_6 {
+   struct f21_2df_control_6n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f21_2df_control_7n {
+   /*Control 7.* */
+   u8 y_location;
+};
+
+struct f21_2df_control_7 {
+   struct f21_2df_control_7n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f21_2df_control_8n {
+   /*Control 8.* */
+   u8 transmitter_force_sensor;
+};
+
+struct f21_2df_control_8 {
+   struct f21_2df_control_8n *regs;
+   u16 address;
+   u8 length;
+};
+
+struct f21_2df_control_9n {
+   /*Control 9.* */
+   u8 receiver_force_sensor;
+};
+
+struct f21_2df_control_9 {
+   struct f21_2df_control_9n *regs;
+   u16 address;
+   u8 length;
+};
+
+
+#define RMI_F21_NUM_CTRL_REGS 8
+struct f21_2df_control {
+   /* Control 0-3 */
+   union f21_2df_control_0__3 *reg_0__3;
+
+   /* Control 4 */
+   struct f21_2df_control_4 *reg_4;
+
+   /* Control 5 */
+   struct f21_2df_control_5 *reg_5;
+
+   /* Control 6 */
+   struct f21_2df_control_6 *reg_6;
+
+   /* Control 7 */
+   struct f21_2df_control_7 *reg_7;
+
+   /* Control 8 */
+   struct f21_2df_control_8 *reg_8;
+
+   /* Control 9 */
+   struct f21_2df_control_9 *reg_9;
+};
+
+union f21_2df_data_2 {
+   struct {
+   /* Data 2 */
+   u8 force_click:1;
+   u8 f21_2df_control0_b2__7:7;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f21_2df_data {
+   /* Data 0 */
+   struct {
+   u8 *force_hi_lo;
+

[RFC PATCH 11/17] input: RMI4 F19 capacitive buttons

2012-08-17 Thread Christopher Heiny
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_f19.c |  869 ++
 1 files changed, 869 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f19.c b/drivers/input/rmi4/rmi_f19.c
new file mode 100644
index 000..9e9ea93
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f19.c
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+#define FUNCTION_DATA f19_data
+#define FNUM 19
+
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define QUERY_BASE_INDEX 1
+#define MAX_LEN 256
+#define MAX_BUFFER_LEN 80
+
+#define SENSOR_MAP_MIN 0
+#define SENSOR_MAP_MAX 127
+#define SENSITIVITY_ADJ_MIN0
+#define SENSITIVITY_ADJ_MAX31
+#define HYSTERESIS_THRESHOLD_MIN   0
+#define HYSTERESIS_THRESHOLD_MAX   15
+
+union f19_0d_query {
+   struct {
+   u8 configurable:1;
+   u8 has_sensitivity_adjust:1;
+   u8 has_hysteresis_threshold:1;
+   u8 reserved_1:5;
+
+   u8 button_count:5;
+   u8 reserved_2:3;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[2];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f19_0d_control_0 {
+   struct {
+   u8 button_usage:2;
+   u8 filter_mode:2;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+/* rewrite control regs */
+struct f19_0d_control_1n {
+   u8 int_enabled_button;
+};
+
+struct f19_0d_control_1 {
+   struct f19_0d_control_1n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f19_0d_control_2n {
+   u8 single_button;
+};
+
+struct f19_0d_control_2 {
+   struct f19_0d_control_2n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f19_0d_control_3n {
+   u8 sensor_map_button:7;
+};
+
+struct f19_0d_control_3 {
+   struct f19_0d_control_3n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+struct f19_0d_control_4n {
+   u8 sensitivity_button:7;
+};
+
+struct f19_0d_control_4 {
+   struct f19_0d_control_4n *regs;
+   u16 address;
+   u8 length;
+} __attribute__((__packed__));
+
+union f19_0d_control_5 {
+   struct {
+   u8 sensitivity_adj:5;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+union f19_0d_control_6 {
+   struct {
+   u8 hysteresis_threshold:4;
+   };
+   struct {
+   u8 regs[1];
+   u16 address;
+   } __attribute__((__packed__));
+};
+
+struct f19_0d_control {
+   union f19_0d_control_0 *reg_0;
+   struct f19_0d_control_1 *reg_1;
+   struct f19_0d_control_2 *reg_2;
+   struct f19_0d_control_3 *reg_3;
+   struct f19_0d_control_4 *reg_4;
+   union f19_0d_control_5 *reg_5;
+   union f19_0d_control_6 *reg_6;
+};
+
+/* data specific to fn $19 that needs to be kept around */
+struct f19_data {
+   struct f19_0d_control control;
+   union f19_0d_query query;
+   u8 button_rezero;
+   unsigned char button_count;
+   unsigned char button_bitmask_size;
+   unsigned char *button_data_buffer;
+   unsigned short *button_map;
+   char input_name[MAX_LEN];
+   char input_phys[MAX_LEN];
+   struct input_dev *input;
+   struct mutex control_mutex;
+   struct mutex data_mutex;
+};
+
+
+static int rmi_f19_alloc_memory(struct rmi_function_container *fc);
+
+static void rmi_f19_free_memory(struct rmi_function_container *fc);
+
+static int rmi_f19_initialize(struct rmi_function_container *fc);
+
+static int rmi_f19_register_device(struct rmi_function_container *fc);
+
+static int rmi_f19_create_sysfs(struct rmi_function_container *fc);
+
+static int rmi_f19_config(struct rmi_function_container *fc);
+
+static int rmi_f19_reset(struct rmi_function_container *fc);
+
+/* Query s

[RFC PATCH 8/17] input: RMI4 F09 Built-In Self Test

2012-08-17 Thread Christopher Heiny
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_f09.c |  772 ++
 1 files changed, 772 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f09.c b/drivers/input/rmi4/rmi_f09.c
new file mode 100644
index 000..ee3058e
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f09.c
@@ -0,0 +1,772 @@
+/*
+ * Copyright (c) 2011, 2012 Synaptics Incorporated
+ *
+ * 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 "rmi_driver.h"
+
+#define QUERY_BASE_INDEX 1
+
+/* data specific to fn $09 that needs to be kept around */
+struct f09_query {
+   u8 limit_register_count;
+   union {
+   struct {
+   u8 result_register_count:3;
+   u8 reserved:3;
+   u8 internal_limits:1;
+   u8 host_test_enable:1;
+   };
+   u8 f09_bist_query1;
+   };
+};
+
+struct f09_control {
+   union {
+   struct {
+   u8 test1_limit_low:8;
+   u8 test1_limit_high:8;
+   u8 test1_limit_diff:8;
+   };
+   u8 f09_control_test1[3];
+   };
+   union {
+   struct {
+   u8 test2_limit_low:8;
+   u8 test2_limit_high:8;
+   u8 test2_limit_diff:8;
+   };
+   u8 f09_control_test2[3];
+   };
+};
+
+struct f09_data {
+   u8 test_number_control;
+   u8 overall_bist_result;
+   u8 test_result1;
+   u8 test_result2;
+   u8 transmitter_number;
+
+   union {
+   struct {
+   u8 receiver_number:6;
+   u8 limit_failure_code:2;
+   };
+   u8 f09_bist_data2;
+   };
+};
+
+struct f09_cmd {
+   union {
+   struct {
+   u8 run_bist:1;
+   };
+   u8 f09_bist_cmd0;
+   };
+};
+
+struct rmi_fn_09_data {
+   struct f09_query query;
+   struct f09_data data;
+   struct f09_cmd cmd;
+   struct f09_control control;
+   signed char status;
+};
+
+
+static ssize_t rmi_f09_status_show(struct device *dev,
+struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_status_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count);
+
+static ssize_t rmi_f09_limit_register_count_show(struct device *dev,
+   struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_host_test_enable_show(struct device *dev,
+   struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_host_test_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_internal_limits_show(struct device *dev,
+   struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_result_register_count_show(struct device *dev,
+   struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_overall_bist_result_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_test_number_control_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_test_number_control_store(struct device *dev,
+ struct device_attribute *attr,
+   const char *buf, size_t count);
+
+static ssize_t rmi_f09_run_bist_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_run_bist_store(struct device *dev,
+ struct device_attribute *attr,
+   const char *buf, si

[RFC PATCH 6/17] input: RMI4 firmware update

2012-08-17 Thread Christopher Heiny
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_fw_update.c |  724 
 1 files changed, 724 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_fw_update.c 
b/drivers/input/rmi4/rmi_fw_update.c
new file mode 100644
index 000..7f6c315
--- /dev/null
+++ b/drivers/input/rmi4/rmi_fw_update.c
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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.
+ */
+
+#define DEBUG
+
+#define RIM_HACK 1
+
+#include 
+#include 
+#include 
+#include 
+#include
+#include 
+#include 
+#include "rmi_driver.h"
+#include "rmi_f01.h"
+#include "rmi_f34.h"
+
+#define HAS_BSR_MASK 0x20
+
+#define CHECKSUM_OFFSET 0
+#define BOOTLOADER_VERSION_OFFSET 0x07
+#define IMAGE_SIZE_OFFSET 0x08
+#define CONFIG_SIZE_OFFSET 0x0C
+#define PRODUCT_ID_OFFSET 0x10
+#define PRODUCT_ID_SIZE 10
+#define PRODUCT_INFO_OFFSET 0x1E
+#define PRODUCT_INFO_SIZE 2
+
+#define F01_RESET_MASK 0x01
+
+#define ENABLE_WAIT_US (300 * 1000)
+
+/** Image file V5, Option 0
+ */
+struct image_header {
+   u32 checksum;
+   unsigned int image_size;
+   unsigned int config_size;
+   unsigned char options;
+   unsigned char bootloader_version;
+   u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
+   unsigned char product_info[PRODUCT_INFO_SIZE];
+};
+
+static u32 extract_u32(const u8 *ptr)
+{
+   return (u32)ptr[0] +
+   (u32)ptr[1] * 0x100 +
+   (u32)ptr[2] * 0x1 +
+   (u32)ptr[3] * 0x100;
+}
+
+struct reflash_data {
+   struct rmi_device *rmi_dev;
+   struct pdt_entry *f01_pdt;
+   union f01_basic_queries f01_queries;
+   union f01_device_control_0 f01_controls;
+   char product_id[RMI_PRODUCT_ID_LENGTH+1];
+   struct pdt_entry *f34_pdt;
+   u8 bootloader_id[2];
+   union f34_query_regs f34_queries;
+   union f34_control_status f34_controls;
+   const u8 *firmware_data;
+   const u8 *config_data;
+};
+
+/* If this parameter is true, we will update the firmware regardless of
+ * the versioning info.
+ */
+static bool force = 1;
+module_param(force, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(param, "Force reflash of RMI4 devices");
+
+/* If this parameter is not NULL, we'll use that name for the firmware image,
+ * instead of getting it from the F01 queries.
+ */
+static char *img_name;
+module_param(img_name, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(param, "Name of the RMI4 firmware image");
+
+#define RMI4_IMAGE_FILE_REV1_OFFSET 30
+#define RMI4_IMAGE_FILE_REV2_OFFSET 31
+#define IMAGE_FILE_CHECKSUM_SIZE 4
+#define FIRMWARE_IMAGE_AREA_OFFSET 0x100
+
+static void extract_header(const u8 *data, int pos, struct image_header 
*header)
+{
+   header->checksum = extract_u32(&data[pos + CHECKSUM_OFFSET]);
+   header->bootloader_version = data[pos + BOOTLOADER_VERSION_OFFSET];
+   header->image_size = extract_u32(&data[pos + IMAGE_SIZE_OFFSET]);
+   header->config_size = extract_u32(&data[pos + CONFIG_SIZE_OFFSET]);
+   memcpy(header->product_id, &data[pos + PRODUCT_ID_OFFSET],
+  RMI_PRODUCT_ID_LENGTH);
+   header->product_id[PRODUCT_ID_SIZE] = 0;
+   memcpy(header->product_info, &data[pos + PRODUCT_INFO_OFFSET],
+  RMI_PRODUCT_ID_LENGTH);
+}
+
+static int rescan_pdt(struct reflash_data *data)
+{
+   int retval;
+   bool f01_found;
+   bool f34_found;
+   struct pdt_entry pdt_entry;
+   int i;
+   struct rmi_device *rmi_dev = data->rmi_dev;
+   struct pdt_entry *f34_pdt = data->f34_pdt;
+   struct pdt_entry *f01_pdt = data->f01_pdt;
+
+   /* Per spec, once we're in reflash we only need to look at the first
+* PDT page for potentially changed F01 and F34 information.
+*/
+   for (i = PDT_START_SCAN_LOCATION; i >= PDT_END_SCAN_LOCATION;
+   i -= sizeof(pdt_entry)) {
+   retval = rmi_read_block(rmi_dev, i, (u8 *)&pdt_entry,
+   sizeof(pdt_entry));
+   if (retval != sizeof(

[RFC PATCH 10/17] input: RM4 F17 Pointing sticks

2012-08-17 Thread Christopher Heiny
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_f17.c |  713 ++
 1 files changed, 713 insertions(+), 0 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f17.c b/drivers/input/rmi4/rmi_f17.c
new file mode 100644
index 000..006a716
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f17.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2012 Synaptics Incorporated
+ *
+ * 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 "rmi_driver.h"
+
+#define QUERY_BASE_INDEX 1
+#define MAX_NAME_LENGTH 256
+
+union f17_device_query {
+   struct {
+   u8 number_of_sticks:3;
+   };
+   u8 regs[1];
+};
+
+#define F17_MANUFACTURER_SYNAPTICS 0
+#define F17_MANUFACTURER_NMB 1
+#define F17_MANUFACTURER_ALPS 2
+
+struct f17_stick_query {
+   union {
+   struct {
+   u8 manufacturer:4;
+   u8 resistive:1;
+   u8 ballistics:1;
+   u8 reserved1:2;
+   u8 has_relative:1;
+   u8 has_absolute:1;
+   u8 has_gestures:1;
+   u8 has_dribble:1;
+   u8 reserved2:4;
+   };
+   u8 regs[2];
+   } general;
+
+   union {
+   struct {
+   u8 has_single_tap:1;
+   u8 has_tap_and_hold:1;
+   u8 has_double_tap:1;
+   u8 has_early_tap:1;
+   u8 has_press:1;
+   };
+   u8 regs[1];
+   } gestures;
+};
+
+union f17_device_controls {
+   struct {
+   u8 reporting_mode:3;
+   u8 dribble:1;
+   };
+   u8 regs[1];
+};
+
+struct f17_stick_controls {
+   union {
+   struct {
+   u8 z_force_threshold;
+   u8 radial_force_threshold;
+   };
+   u8 regs[3];
+   } general;
+
+   union {
+   struct {
+   u8 motion_sensitivity:4;
+   u8 antijitter:1;
+   };
+   u8 regs[1];
+   } relative;
+
+   union {
+   struct {
+   u8 single_tap:1;
+   u8 tap_and_hold:1;
+
+   u8 double_tap:1;
+   u8 early_tap:1;
+   u8 press:1;
+   };
+   u8 regs[1];
+   } enable;
+
+   u8 maximum_tap_time;
+   u8 minimum_press_time;
+   u8 maximum_radial_force;
+};
+
+
+union f17_device_commands {
+   struct {
+   u8 rezero:1;
+   };
+   u8 regs[1];
+};
+
+struct f17_stick_data {
+   union {
+   struct {
+   u8 x_force_high:8;
+   u8 y_force_high:8;
+   u8 y_force_low:4;
+   u8 x_force_low:4;
+   u8 z_force:8;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[4];
+   u16 address;
+   };
+   } abs;
+   union {
+   struct {
+   s8 x_delta:8;
+   s8 y_delta:8;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[2];
+   u16 address;
+   };
+   } rel;
+   union {
+   struct {
+   u8 single_tap:1;
+   u8 tap_and_hold:1;
+   u8 double_tap:1;
+   u8 early_tap:1;
+   u8 press:1;
+   u8 reserved:3;
+   } __attribute__((__packed__));
+   struct {
+   u8 regs[1];
+   u16 address;
+   };
+   } gestures;
+};
+
+
+/* data specific to f17 that needs to be kept around */
+
+struct rmi_f17_stick_data {
+   struct f17_stick_query query;
+   struct f17_stick_controls controls;
+   struct f17_stick_data data;
+
+

  1   2   >