Linux Input/HID development
 help / color / mirror / Atom feed
* Re: Xpad Driver Replacement
From: Ken Phillis Jr @ 2013-12-14  5:16 UTC (permalink / raw)
  Cc: linux-input
In-Reply-To: <52A68A23.7050707@computerquip.com>

On Mon, Dec 9, 2013 at 9:27 PM, Zachary Lund <admin@computerquip.com> wrote:
>
>
> On 12/08/13 00:18, Zachary Lund wrote:
>>
>> Secondly, the Xbox 360 controllers claim to be HID compliant... this is not an HID driver. That's because the report descriptor is missing and I, unfortunately, do not know what to do about that. Some drivers like XBCD and the driver found at tattiebogle.net both provide their own report descriptor and work from there. While I'd like to do the same eventually, it will take me longer than a week to do that as I'd have to educate myself on HID and figure out what to do about the missing descriptors.
>
> I've run into an instant road block. The controller claims bInterfaceClass to be 0xFF (Vendor-specific) so usbhid won't probe it. I didn't think it would be so difficult to work around that but I've spent the better part of today trying to figure out just that. usbhid is a usb_driver that has only one requirement to be probed: bInterfaceClass be 0x03. Unfortunately, the device fails this requirement.
>
> Does anyone know of a way around this mechanism? Or perhaps I should take a different approach?
>

I agree that the XBOX 360 controller support should appear as a
separate driver. However the approach for detecting this should
instead rely on what microsoft has described as the "Xbox 360 Common
Controller class" (XUSB) [1]. The documentation surround the XINPUT
covers Audio and Joystick input. However I believe it is possible to
just cover the joystick input types ( and sub-controller types ) [2]
without overdoing the driver.

[1] MSDN Reference - DirectInput and XUSB
 http://msdn.microsoft.com/en-us/library/windows/desktop/hh405052%28v=vs.85%29.aspx

[2] MSDN Reference - XINPUT and sub-controller types.
http://msdn.microsoft.com/en-us/library/windows/desktop/hh405050%28v=vs.85%29.aspx

^ permalink raw reply

* Re: [PATCH 1/2] joydev: Map ABS_{THROTTLE,GAS,BREAK} to positive values.
From: Ken Phillis Jr @ 2013-12-14  5:13 UTC (permalink / raw)
  To: Benjamin Franzke; +Cc: linux-input
In-Reply-To: <1386749731-6500-1-git-send-email-benjaminfranzke@googlemail.com>

On Wed, Dec 11, 2013 at 2:15 AM, Benjamin Franzke
<benjaminfranzke@googlemail.com> wrote:
> Gamepads like XInput devices have triggers with a range from
> e.g. 0 to 255.
> When the conventional joydev AXES correction/mapping method is used,
> the default state 0 (i.e. when the user does not press a button or trigger)
> is mapped to -32767 (and 255 to 32767).
> You'll get 0 only when pressing the trigger half-way down.
> This has several drawbacks:
>  - A trigger is not usable at all when configured to have 2 directions
>    when there is physically only one.
>  - Applications that let the user configure joystick input assignments
>    may register the mapped non-zero default state as a press,
>    preventing the user from configuring any sensible value.
>
> Traditonal calibration e.g. with jscal does not help to get a usable
> experience either, it'll map the default state to -32767 as well.
> Only manually editing the calibration data does work currently.
>
> This patch tries to fix this issue by calculating a positive-only range for
> the throttle break and gas ABS bits.
> Maybe other ABS types need to be added to this scheme as well(?)
>
> Note:
> Although joydev is considered obsolete and people are encouraged to just
> use evdev, joydev should still be fixed, because
>  1. many applications still use it.
>  2. userspace already copies the joydev correction code to evdev (e.g. libSDL).
>
> This bug should be fixed here in joydev first, and when we have a good
> sensible state, this should be propagated to the application/libraries
> that copied the joydev correction code.
>
> Gamepad drivers will need to advertise triggers as THROTTLE,GAS,BREAK instead
> of e.g. ABS_{RZ,Z} where phyisically appropriate, to make use of this.
>
> I've considered changing the current joydev correction calculation for all ABS
> types, to have only a scaling functionality by default, no translation
> (all positive values remain positive, negatives negative and zero remains zero),
> so that drivers would need to expose zero-centered ABS values.
> It turned out to many drivers would need to be adjusted, which i cant
> test.
>
> Signed-off-by: Benjamin Franzke <benjaminfranzke@googlemail.com>


I have serious concerns that this Patch and the Next patch will the
input detection of the triggers on various games powered by SDL2. Have
you tested this against games listed on steam that have full
controller support?

^ permalink raw reply

* Re: [PATCHv4 0/2] twl4030-keypad DT binding
From: Sebastian Reichel @ 2013-12-13 18:47 UTC (permalink / raw)
  To: Dmitry Torokhov, Dmitry Torokhov, linux-input
In-Reply-To: <1385830416-12900-1-git-send-email-sre@debian.org>

[-- Attachment #1: Type: text/plain, Size: 170 bytes --]

Hi Dmitry,

> Add device tree support for the twl4030 keypad, which is
> for example used in the Nokia N900.

Can you add this to the input queue for 3.14?

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH] HID: remove SIS entries from hid_have_special_driver[]
From: Jiri Kosina @ 2013-12-13 14:45 UTC (permalink / raw)
  To: Emanuel Krenz, Wanlong Gao, AceLan Kao, Forest Bond; +Cc: linux-input

The entries are not needed, as hid-multitouch gets bound correctly 
automatically by contact ID.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---

I will be queuing for 3.14 if noone objects.

 drivers/hid/hid-core.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 48296c0..b0de258 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1822,9 +1822,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply related

* 3.12.3: Oops while hitting keyboard
From: Ortwin Glück @ 2013-12-12 19:10 UTC (permalink / raw)
  To: linux-input, linux-kernel

Hi,

My little son triggered the following Oops by hitting the Bluetooth keyboard 
like a little monkey:

Linux gandalf 3.12.3 #2 SMP PREEMPT Wed Dec 4 23:04:27 CET 2013 x86_64 Intel(R) 
Core(TM) i3 CPU 540 @ 3.07GHz GenuineIntel GNU/Linux


Dec 12 18:04:11 gandalf kernel: input: gandalf kbd as 
/devices/pci0000:00/0000:00:1a.7/usb1/1-1/1-1.
1/1-1.1.1/1-1.1.1:1.0/bluetooth/hci0/hci0:12/input45
Dec 12 18:04:11 gandalf kernel: apple 0005:05AC:023A.0025: input,hidraw2: 
BLUETOOTH HID v0.50 Keyboa
rd [gandalf kbd] on 7c:6d:62:9f:db:2d
Dec 12 18:04:28 gandalf kernel: BUG: unable to handle kernel paging request at 
ffffffff82450968
Dec 12 18:04:28 gandalf kernel: IP: [<ffffffff813450c7>] kbd_event+0x1d7/0x740
Dec 12 18:04:28 gandalf kernel: PGD 1c0c067 PUD 1c0d063 PMD 0
Dec 12 18:04:28 gandalf kernel: PGD 1c0c067 PUD 1c0d063 PMD 0
Dec 12 18:04:28 gandalf kernel: Oops: 0000 [#1] PREEMPT SMP
Dec 12 18:04:28 gandalf kernel: Modules linked in: fbcon radeon cfbfillrect 
cfbimgblt bitblit cfbcop
yarea softcursor font i2c_algo_bit drm_kms_helper ttm drm fb fbdev
Dec 12 18:04:28 gandalf kernel: CPU: 2 PID: 9153 Comm: khidpd_05ac023a Not 
tainted 3.12.3 #2
Dec 12 18:04:28 gandalf kernel: Hardware name: Apple Inc. iMac11,2/Mac-F2238AC8, 
BIOS    IM112.88Z.0057.B00.1005031455 05/03/10
Dec 12 18:04:28 gandalf kernel: task: ffff8800327e8000 ti: ffff880030858000 
task.ti: ffff880030858000
Dec 12 18:04:28 gandalf kernel: RIP: 0010:[<ffffffff813450c7>] 
[<ffffffff813450c7>] kbd_event+0x1d7/0x740
Dec 12 18:04:28 gandalf kernel: RSP: 0018:ffff880030859ba8  EFLAGS: 00010046
Dec 12 18:04:28 gandalf kernel: RAX: 000000000010000d RBX: 0000000000000038 RCX: 
ffffffff81e6cbde
Dec 12 18:04:28 gandalf kernel: RDX: ffff880030859bc0 RSI: 0000000000000001 RDI: 
ffffffff81e6cba0
Dec 12 18:04:28 gandalf kernel: RBP: 0000000000000000 R08: 0000000000000001 R09: 
0000000000000000
Dec 12 18:04:28 gandalf kernel: R10: 0000000000000000 R11: 0000000000000001 R12: 
ffff8800ba829800
Dec 12 18:04:28 gandalf kernel: R13: 000000000010000d R14: ffff880030b10500 R15: 
0000000000000038
Dec 12 18:04:28 gandalf kernel: FS:  0000000000000000(0000) 
GS:ffff88013bc80000(0000) knlGS:0000000000000000
Dec 12 18:04:28 gandalf kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
Dec 12 18:04:28 gandalf kernel: CR2: ffffffff82450968 CR3: 0000000001c0b000 CR4: 
00000000000007e0
Dec 12 18:04:28 gandalf kernel: CR2: ffffffff82450968 CR3: 0000000001c0b000 CR4: 
00000000000007e0
Dec 12 18:04:28 gandalf kernel: Stack:
Dec 12 18:04:28 gandalf kernel: ffffffff819db59b ffffffff8106e1b3 
0000000000000081 ffff8800ba829800
Dec 12 18:04:28 gandalf kernel: 0010000d00000000 0000003800000000 
0000000000000096 0000000000000003
Dec 12 18:04:28 gandalf kernel: ffff880030b103d8 ffffffff81c4e5e0 
ffff880030b103d8 ffff880030b105a0
Dec 12 18:04:28 gandalf kernel: Call Trace:
Dec 12 18:04:28 gandalf kernel: [<ffffffff8106e1b3>] ? __wake_up+0x43/0x70
Dec 12 18:04:28 gandalf kernel: [<ffffffff8145f3e3>] ? input_to_handler+0xd3/0xf0
Dec 12 18:04:28 gandalf kernel: [<ffffffff81461e72>] ? 
input_pass_values.part.8+0x162/0x170
Dec 12 18:04:28 gandalf kernel: [<ffffffff814625ad>] ? 
input_handle_event+0x12d/0x550
Dec 12 18:04:28 gandalf kernel: [<ffffffff81462afe>] ? input_event+0x5e/0xa0
Dec 12 18:04:28 gandalf kernel: [<ffffffff814e4d07>] ? 
hidinput_report_event+0x37/0x50
Dec 12 18:04:28 gandalf kernel: [<ffffffff814e3275>] ? 
hid_report_raw_event+0x285/0x460
Dec 12 18:04:28 gandalf kernel: [<ffffffff814e356d>] ? hid_input_report+0x11d/0x1b0
Dec 12 18:04:28 gandalf kernel: [<ffffffff816d589b>] ? 
hidp_session_thread+0x5eb/0x640
Dec 12 18:04:28 gandalf kernel: [<ffffffff810732d0>] ? try_to_wake_up+0x2a0/0x2a0
Dec 12 18:04:28 gandalf kernel: [<ffffffff810732d0>] ? try_to_wake_up+0x2a0/0x2a0
Dec 12 18:04:28 gandalf kernel: [<ffffffff816d52b0>] ? 
hidp_input_report.isra.9+0x2e0/0x2e0
Dec 12 18:04:28 gandalf kernel: [<ffffffff810653b3>] ? kthread+0xb3/0xc0
Dec 12 18:04:28 gandalf kernel: [<ffffffff81070000>] ? get_group+0x20/0x80
Dec 12 18:04:28 gandalf kernel: [<ffffffff81065300>] ? 
kthread_freezable_should_stop+0x60/0x60
Dec 12 18:04:28 gandalf kernel: [<ffffffff81065300>] ? 
kthread_freezable_should_stop+0x60/0x60
Dec 12 18:04:28 gandalf kernel: [<ffffffff81065300>] ? 
kthread_freezable_should_stop+0x60/0x60
Dec 12 18:04:28 gandalf kernel: [<ffffffff81773cfc>] ? ret_from_fork+0x7c/0xb0
Dec 12 18:04:28 gandalf kernel: [<ffffffff81773cfc>] ? ret_from_fork+0x7c/0xb0
Dec 12 18:04:28 gandalf kernel: [<ffffffff81065300>] ? 
kthread_freezable_should_stop+0x60/0x60
Dec 12 18:04:28 gandalf kernel: Code: e6 81 44 0f b6 68 01 44 0b 2d b6 7c b2 00 
41 31 d5 44 89 6c 24 24 48 8d 54 24 18 0f b6 40 02 d0 e8 83 e0 0f 89 44 24 28 49 
63 c5 <48> 8b 0c c5 00 09 c5 81 48 89 4c 24 08 e8 c7 59 d2 ff 48 8b 4c
Dec 12 18:04:28 gandalf kernel: RIP  [<ffffffff813450c7>] kbd_event+0x1d7/0x740
Dec 12 18:04:28 gandalf kernel: RSP <ffff880030859ba8>
Dec 12 18:04:28 gandalf kernel: CR2: ffffffff82450968
Dec 12 18:04:28 gandalf kernel: ---[ end trace edcf19cf8c005260 ]---

Thanks,

Ortwin

^ permalink raw reply

* [git pull] Input updates for 3.13-rc3
From: Dmitry Torokhov @ 2013-12-12 16:37 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-input

[-- Attachment #1: Type: text/plain, Size: 710 bytes --]

Hi Linus,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
	master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive more updates for the input subsystem. You will get a fix for
recent sysfs breakage in serio subsystem plus a fixup to adxl34x driver.

Changelog:
---------

Dmitry Torokhov (1):
      Input: serio - fix sysfs layout

Michael Hennerich (1):
      Input: adxl34x - Fix bug in definition of ADXL346_2D_ORIENT


Diffstat:
--------

 drivers/input/misc/adxl34x.c |  2 +-
 drivers/input/serio/serio.c  | 24 +++++++++++++++++-------
 2 files changed, 18 insertions(+), 8 deletions(-)


-- 
Dmitry


[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH 00/31] ARM: tegra: use common reset and DMA bindings
From: Stephen Warren @ 2013-12-12  0:11 UTC (permalink / raw)
  To: swarren
  Cc: Mark Rutland, alsa-devel, linux-usb, Wolfram Sang, David Airlie,
	linux-pci, dri-devel, linux-tegra, linux-i2c, ac100, devel,
	Stephen Warren, Alan Stern, linux-serial, linux-input,
	Terje Bergström, devicetree, Pawel Moll, Ian Campbell,
	Rob Herring, Mark Brown, Bjorn Helgaas, Mike Turquette,
	Dan Williams, linux-arm-kernel, treding
In-Reply-To: <1384548866-13141-1-git-send-email-swarren@wwwdotorg.org>

On 11/15/2013 01:53 PM, Stephen Warren wrote:
> From: Stephen Warren <swarren@nvidia.com>
> 
> This series implements a common reset framework driver for Tegra, and
> updates all relevant Tegra drivers to use it. It also removes the custom
> DMA bindings and replaced them with the standard DMA DT bindings.
> 
> Historically, the Tegra clock driver has exported a custom API for module
> reset. This series removes that API, and transitions DT and drivers to
> the new reset framework.
> 
> The custom API used a "struct clk" to identify which module to reset, and
> consequently some DT bindings and drivers required clocks to be provided
> where they really needed just a reset identifier instead. Due to this
> known deficiency, I have always considered most Tegra bindings to be
> unstable. This series removes this excuse for instability, although I
> still consider some Tegra bindings unstable due to the need to convert to
> the common DMA bindings.
> 
> Historically, Tegra DMA channels have been represented in DT using a
> custom nvidia,dma-request-selector property. Now that standard DMA DT
> bindings exist, convert all Tegra bindings, DTs, and drivers to use the
> standard instead.
> 
> This series makes a DT-ABI-incompatible change to:
> - Require reset specifiers in DT where relevant.
> - Require standard DMA specifiers.
> - Remove clock specifiers from DT where they were only needed for reset.
> - Remove legacy DMA specifier properties.
> 
> I anticipate merging this whole series into the Tegra and arm-soc trees
> as its own branch, due to internal dependencies. This branch will be
> stable and can then be merged into any other subsystem trees should any
> conflicts arise.
> 
> This series depends on Peter's Tegra clock driver rework, available at
> git://nv-tegra.nvidia.com/user/pdeschrijver/linux tegra-clk-tegra124-0
> (or whatever version of that gets included in 3.14)

I've applied this series (and pulled in the DMA/ASoC/clk dependencies
required) to Tegra's for-3.14/dmas-resets-rework branch.

^ permalink raw reply

* kernel panic on gpio-keys
From: Paul Cercueil @ 2013-12-11 19:17 UTC (permalink / raw)
  To: linux-input; +Cc: dmitry.torokhov

Hi there,

I am trying to use the gpio-keys driver to inject joystick events.
There seems to be some basic support of it, looking at <linux/gpio_keys.h>.

However, registering the following will trigger a kernel panic in the 
kernel:

static struct gpio_keys_button my_buttons[] {
	{
		.gpio = GPIO_FOO,
		.type = EV_ABS,
		.code = ABS_HAT0X,
		.value = 1,
	},
};

(tested on kernel 3.12).

I don't know well the input subsystem, so I have no idea of what is 
going wrong. Could anybody try to at least reproduce the issue?

Regards.

^ permalink raw reply

* Re: Sony DualShock4 - basic functions work, but looking to improve support
From: Jiri Kosina @ 2013-12-11 15:00 UTC (permalink / raw)
  To: David Herrmann; +Cc: Simon Wood, Linux Input, Antonio Ospite
In-Reply-To: <CANq1E4QxyKNbYCBAEUQN08dxz4YfYHfZQVHG0+w=cf5Fz1XpkQ@mail.gmail.com>

On Sun, 8 Dec 2013, David Herrmann wrote:

> >> Anyone here want to collaborate?
> >
> > I've decoded the majority of the HID stream including the multi-touch.
> 
> Nice! I already got my hands on one but will probably not find time
> for it until February. However, I will gladly test any patches!

Good work!

> Also, could you write your findings down and maybe put it into
> ./Documentation/hid/? I'm not sure whether we put protocol data there
> (Jiri?) but at least you could share the information on the list or
> github. I would appreciate that a lot!

We've never used Documentation/hid/ for this kind of purpose, especially 
as the driver doesn't exist yet. I am not really sure whether kernel tree 
is a proper collaboration method for this.

What we have for quite a few of the existing drivers is having the 
protocol described in comments directly in the driver, usually at its very 
beginning. Would that work in this case as well?

Thanks,

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* [PATCH 2/2] joystick/xpad: Advertise the triggers as throttle/break
From: Benjamin Franzke @ 2013-12-11  8:15 UTC (permalink / raw)
  To: linux-input; +Cc: Benjamin Franzke
In-Reply-To: <1386749731-6500-1-git-send-email-benjaminfranzke@googlemail.com>

They are considered positive only axes, so userspace and joydev can
handle them correctly.
It also fits semantically better, since these triggers are really intended
for throttle/break.

Signed-off-by: Benjamin Franzke <benjaminfranzke@googlemail.com>
---
 drivers/input/joystick/xpad.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 75e3b10..4e9de34 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -226,7 +226,7 @@ static const signed short xpad_abs_pad[] = {
 
 /* used when triggers are mapped to axes */
 static const signed short xpad_abs_triggers[] = {
-	ABS_Z, ABS_RZ,		/* triggers left/right */
+	ABS_BRAKE, ABS_THROTTLE, /* triggers left/right */
 	-1
 };
 
@@ -327,8 +327,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
 		input_report_key(dev, BTN_TL2, data[10]);
 		input_report_key(dev, BTN_TR2, data[11]);
 	} else {
-		input_report_abs(dev, ABS_Z, data[10]);
-		input_report_abs(dev, ABS_RZ, data[11]);
+		input_report_abs(dev, ABS_BRAKE, data[10]);
+		input_report_abs(dev, ABS_THROTTLE, data[11]);
 	}
 
 	/* digital pad */
@@ -429,8 +429,8 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
 		input_report_key(dev, BTN_TL2, data[4]);
 		input_report_key(dev, BTN_TR2, data[5]);
 	} else {
-		input_report_abs(dev, ABS_Z, data[4]);
-		input_report_abs(dev, ABS_RZ, data[5]);
+		input_report_abs(dev, ABS_BRAKE, data[4]);
+		input_report_abs(dev, ABS_THROTTLE, data[5]);
 	}
 
 	input_sync(dev);
@@ -824,8 +824,8 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
 	case ABS_RY:	/* the two sticks */
 		input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
 		break;
-	case ABS_Z:
-	case ABS_RZ:	/* the triggers (if mapped to axes) */
+	case ABS_BRAKE:
+	case ABS_THROTTLE: /* the triggers (if mapped to axes) */
 		input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
 		break;
 	case ABS_HAT0X:
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 1/2] joydev: Map ABS_{THROTTLE,GAS,BREAK} to positive values.
From: Benjamin Franzke @ 2013-12-11  8:15 UTC (permalink / raw)
  To: linux-input; +Cc: Benjamin Franzke

Gamepads like XInput devices have triggers with a range from
e.g. 0 to 255.
When the conventional joydev AXES correction/mapping method is used,
the default state 0 (i.e. when the user does not press a button or trigger)
is mapped to -32767 (and 255 to 32767).
You'll get 0 only when pressing the trigger half-way down.
This has several drawbacks:
 - A trigger is not usable at all when configured to have 2 directions
   when there is physically only one.
 - Applications that let the user configure joystick input assignments
   may register the mapped non-zero default state as a press,
   preventing the user from configuring any sensible value.

Traditonal calibration e.g. with jscal does not help to get a usable
experience either, it'll map the default state to -32767 as well.
Only manually editing the calibration data does work currently.

This patch tries to fix this issue by calculating a positive-only range for
the throttle break and gas ABS bits.
Maybe other ABS types need to be added to this scheme as well(?)

Note:
Although joydev is considered obsolete and people are encouraged to just
use evdev, joydev should still be fixed, because
 1. many applications still use it.
 2. userspace already copies the joydev correction code to evdev (e.g. libSDL).

This bug should be fixed here in joydev first, and when we have a good
sensible state, this should be propagated to the application/libraries
that copied the joydev correction code.

Gamepad drivers will need to advertise triggers as THROTTLE,GAS,BREAK instead
of e.g. ABS_{RZ,Z} where phyisically appropriate, to make use of this.

I've considered changing the current joydev correction calculation for all ABS
types, to have only a scaling functionality by default, no translation
(all positive values remain positive, negatives negative and zero remains zero),
so that drivers would need to expose zero-centered ABS values.
It turned out to many drivers would need to be adjusted, which i cant
test.

Signed-off-by: Benjamin Franzke <benjaminfranzke@googlemail.com>
---
 drivers/input/joydev.c | 59 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index f362883..8352bee 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -761,11 +761,50 @@ static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 	return true;
 }
 
+static void joydev_calculate_correction(struct input_dev *dev, __u8 abs,
+					struct js_corr *corr)
+{
+	int t;
+
+	corr->type = JS_CORR_BROKEN;
+	corr->prec = input_abs_get_fuzz(dev, abs);
+
+	switch (abs) {
+	/* Map [min - max] => [0 - 32767]. */
+	case ABS_THROTTLE:
+	case ABS_GAS:
+	case ABS_BRAKE:
+		corr->coef[0] = input_abs_get_min(dev, abs);
+		corr->coef[1] = corr->coef[0] + input_abs_get_flat(dev, abs);
+		corr->coef[2] = 0;
+
+		t = input_abs_get_max(dev, abs) - input_abs_get_min(dev, abs)
+			- input_abs_get_flat(dev, abs);
+		if (t)
+			corr->coef[3] = (1 << 29) / t;
+		break;
+	/* Map [min - max] => [-32768 - 32767]. */
+	default:
+		t = (input_abs_get_max(dev, abs) +
+		     input_abs_get_min(dev, abs)) / 2;
+		corr->coef[0] = t - input_abs_get_flat(dev, abs);
+		corr->coef[1] = t + input_abs_get_flat(dev, abs);
+		t = (input_abs_get_max(dev, abs) -
+		     input_abs_get_min(dev, abs)) / 2
+			- 2 * input_abs_get_flat(dev, abs);
+		if (t) {
+			corr->coef[2] = (1 << 29) / t;
+			corr->coef[3] = (1 << 29) / t;
+		}
+		break;
+	}
+}
+
 static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
 			  const struct input_device_id *id)
 {
 	struct joydev *joydev;
-	int i, j, t, minor, dev_no;
+	int i, j, minor, dev_no;
 	int error;
 
 	minor = input_get_new_minor(JOYDEV_MINOR_BASE, JOYDEV_MINORS, true);
@@ -826,23 +865,13 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
 			joydev->abs[i] = input_abs_get_val(dev, j);
 			continue;
 		}
-		joydev->corr[i].type = JS_CORR_BROKEN;
-		joydev->corr[i].prec = input_abs_get_fuzz(dev, j);
 
-		t = (input_abs_get_max(dev, j) + input_abs_get_min(dev, j)) / 2;
-		joydev->corr[i].coef[0] = t - input_abs_get_flat(dev, j);
-		joydev->corr[i].coef[1] = t + input_abs_get_flat(dev, j);
+		joydev_calculate_correction(dev, j, &joydev->corr[i]);
 
-		t = (input_abs_get_max(dev, j) - input_abs_get_min(dev, j)) / 2
-			- 2 * input_abs_get_flat(dev, j);
-		if (t) {
-			joydev->corr[i].coef[2] = (1 << 29) / t;
-			joydev->corr[i].coef[3] = (1 << 29) / t;
+		joydev->abs[i] =
+			joydev_correct(input_abs_get_val(dev, j),
+				       joydev->corr + i);
 
-			joydev->abs[i] =
-				joydev_correct(input_abs_get_val(dev, j),
-					       joydev->corr + i);
-		}
 	}
 
 	joydev->dev.devt = MKDEV(INPUT_MAJOR, minor);
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH] input synaptics-rmi4: Eliminate packed structs in PDT handling
From: Christopher Heiny @ 2013-12-11  3:10 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
	Vivian Ly, Daniel Rosenberg, Jean Delvare, Joerie de Gram,
	Linus Walleij, Benjamin Tissoires

This converts the PDT handling routines from using bitfields in packed structs,
converting to bitmasks and shifts to parse out bitfields, nibbles, and so on.

Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Joerie de Gram <j.de.gram@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

This patch implements changes to the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patch is commit
f154022b208a59b048f52b7b5d58a5ec1949b96e.

 drivers/input/rmi4/rmi_driver.c | 45 +++++++++++++++++++++++++++-------------
 drivers/input/rmi4/rmi_driver.h | 46 +++++++++++++++--------------------------
 2 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index dffbfa0..a30c7d3 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -483,6 +483,31 @@ int rmi_driver_irq_get_mask(struct rmi_device *rmi_dev,
 		return -ENOMEM;
 }
 
+int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry *entry,
+			u16 pdt_address)
+{
+	u8 buf[RMI_PDT_ENTRY_SIZE];
+	int error;
+
+	error = rmi_read_block(rmi_dev, pdt_address, buf, RMI_PDT_ENTRY_SIZE);
+	if (error < 0) {
+		dev_err(&rmi_dev->dev, "Read PDT entry at %#06x failed, code: %d.\n",
+				pdt_address, error);
+		return error;
+	}
+
+	entry->query_base_addr = buf[0];
+	entry->command_base_addr = buf[1];
+	entry->control_base_addr = buf[2];
+	entry->data_base_addr = buf[3];
+	entry->interrupt_source_count = buf[4] & RMI_PDT_INT_SOURCE_COUNT_MASK;
+	entry->function_version = (buf[4] & RMI_PDT_FUNCTION_VERSION_MASK) >> 5;
+	entry->function_number = buf[5];
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rmi_read_pdt_entry);
+
 static void rmi_driver_copy_pdt_to_fd(struct pdt_entry *pdt,
 				      struct rmi_function_descriptor *fd,
 				      u16 page_start)
@@ -572,14 +597,10 @@ static int reset_and_reflash(struct rmi_device *rmi_dev)
 		u16 pdt_end = page_start + PDT_END_SCAN_LOCATION;
 
 		done = true;
-		for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) {
-			retval = rmi_read_block(rmi_dev, i, &pdt_entry,
-					       sizeof(pdt_entry));
-			if (retval != sizeof(pdt_entry)) {
-				dev_err(dev, "Read PDT entry at %#06x failed, code = %d.\n",
-						i, retval);
+		for (i = pdt_start; i >= pdt_end; i -= RMI_PDT_ENTRY_SIZE) {
+			retval = rmi_read_pdt_entry(rmi_dev, &pdt_entry, i);
+			if (retval < 0)
 				return retval;
-			}
 
 			if (RMI4_END_OF_PDT(pdt_entry.function_number))
 				break;
@@ -634,14 +655,10 @@ static int rmi_scan_pdt(struct rmi_device *rmi_dev)
 		u16 pdt_end = page_start + PDT_END_SCAN_LOCATION;
 
 		done = true;
-		for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) {
-			retval = rmi_read_block(rmi_dev, i, &pdt_entry,
-					       sizeof(pdt_entry));
-			if (retval != sizeof(pdt_entry)) {
-				dev_err(dev, "Read of PDT entry at %#06x failed.\n",
-					i);
+		for (i = pdt_start; i >= pdt_end; i -= RMI_PDT_ENTRY_SIZE) {
+			retval = rmi_read_pdt_entry(rmi_dev, &pdt_entry, i);
+			if (retval < 0)
 				goto error_exit;
-			}
 
 			if (RMI4_END_OF_PDT(pdt_entry.function_number))
 				break;
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index f8d87e9..5e3c4d4 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -29,11 +29,7 @@
 #define PDT_PROPERTIES_LOCATION 0x00EF
 #define BSR_LOCATION 0x00FE
 
-struct pdt_properties {
-	u8 reserved_1:6;
-	u8 has_bsr:1;
-	u8 reserved_2:1;
-} __attribute__((__packed__));
+#define RMI_PDT_PROPS_HAS_BSR 0x02
 
 struct rmi_driver_data {
 	struct list_head function_list;
@@ -61,7 +57,7 @@ struct rmi_driver_data {
 	ktime_t poll_interval;
 
 	struct mutex pdt_mutex;
-	struct pdt_properties pdt_props;
+	u8 pdt_props;
 	u8 bsr;
 
 	bool enabled;
@@ -90,34 +86,26 @@ struct rmi_driver_data {
 	void *data;
 };
 
+#define RMI_PDT_ENTRY_SIZE 6
+#define RMI_PDT_FUNCTION_VERSION_MASK   0x60
+#define RMI_PDT_INT_SOURCE_COUNT_MASK   0x07
+
 #define PDT_START_SCAN_LOCATION 0x00e9
 #define PDT_END_SCAN_LOCATION	0x0005
 #define RMI4_END_OF_PDT(id) ((id) == 0x00 || (id) == 0xff)
 
 struct pdt_entry {
-	u8 query_base_addr:8;
-	u8 command_base_addr:8;
-	u8 control_base_addr:8;
-	u8 data_base_addr:8;
-	u8 interrupt_source_count:3;
-	u8 bits3and4:2;
-	u8 function_version:2;
-	u8 bit7:1;
-	u8 function_number:8;
-} __attribute__((__packed__));
-
-static inline void copy_pdt_entry_to_fd(struct pdt_entry *pdt,
-				 struct rmi_function_descriptor *fd,
-				 u16 page_start)
-{
-	fd->query_base_addr = pdt->query_base_addr + page_start;
-	fd->command_base_addr = pdt->command_base_addr + page_start;
-	fd->control_base_addr = pdt->control_base_addr + page_start;
-	fd->data_base_addr = pdt->data_base_addr + page_start;
-	fd->function_number = pdt->function_number;
-	fd->interrupt_source_count = pdt->interrupt_source_count;
-	fd->function_version = pdt->function_version;
-}
+	u8 query_base_addr;
+	u8 command_base_addr;
+	u8 control_base_addr;
+	u8 data_base_addr;
+	u8 interrupt_source_count;
+	u8 function_version;
+	u8 function_number;
+};
+
+int rmi_read_pdt_entry(struct rmi_device *rmi_dev, struct pdt_entry *entry,
+			u16 pdt_address);
 
 bool rmi_is_physical_driver(struct device_driver *);
 int rmi_register_physical_driver(void);

^ permalink raw reply related

* [PATCH] input synaptics-rmi4: Eliminate packed structs in rmi_f11.c
From: Christopher Heiny @ 2013-12-11  2:39 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
	Vivian Ly, Daniel Rosenberg, Jean Delvare, Joerie de Gram,
	Linus Walleij, Benjamin Tissoires

This converts rmi_f11.c from using bitfields in packed structs, converting
to bitmasks and shifts to parse out bitfields, nibbles, and so on.

Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Joerie de Gram <j.de.gram@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

This patch implements changes to the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patch is commit
f154022b208a59b048f52b7b5d58a5ec1949b96e.

 drivers/input/rmi4/rmi_f11.c | 1526 +++++++++++++++---------------------------
 1 file changed, 553 insertions(+), 973 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index d3a9ba8..d63ef31 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -69,33 +69,124 @@
  */
 
 /**
- * @rezero - writing 1 to this will cause the sensor to calibrate to the
- * current capacitive state.
+ * @rezero - writing this to the F11 command register will cause the sensor to
+ * calibrate to the current capacitive state.
  */
-struct f11_2d_commands {
-	u8 rezero:1;
-	u8 reserved:7;
-} __attribute__((__packed__));
+#define RMI_F11_REZERO  0x01
+
+#define RMI_F11_HAS_QUERY9              (1 << 3)
+#define RMI_F11_HAS_QUERY11             (1 << 4)
+#define RMI_F11_HAS_QUERY12             (1 << 5)
+#define RMI_F11_HAS_QUERY27             (1 << 6)
+#define RMI_F11_HAS_QUERY28             (1 << 7)
+
+/** Defs for Query 1 */
+
+#define RMI_F11_NR_FINGERS_MASK 0x07
+#define RMI_F11_HAS_REL                 (1 << 3)
+#define RMI_F11_HAS_ABS                 (1 << 4)
+#define RMI_F11_HAS_GESTURES            (1 << 5)
+#define RMI_F11_HAS_SENSITIVITY_ADJ     (1 << 6)
+#define RMI_F11_CONFIGURABLE            (1 << 7)
+
+/** Defs for Query 2, 3, and 4. */
+#define RMI_F11_NR_ELECTRODES_MASK      0x7F
+
+/** Defs for Query 5 */
+
+#define RMI_F11_ABS_DATA_SIZE_MASK      0x03
+#define RMI_F11_HAS_ANCHORED_FINGER     (1 << 2)
+#define RMI_F11_HAS_ADJ_HYST            (1 << 3)
+#define RMI_F11_HAS_DRIBBLE             (1 << 4)
+#define RMI_F11_HAS_BENDING_CORRECTION  (1 << 5)
+#define RMI_F11_HAS_LARGE_OBJECT_SUPPRESSION    (1 << 6)
+#define RMI_F11_HAS_JITTER_FILTER       (1 << 7)
+
+/** Defs for Query 7 */
+#define RMI_F11_HAS_SINGLE_TAP                  (1 << 0)
+#define RMI_F11_HAS_TAP_AND_HOLD                (1 << 1)
+#define RMI_F11_HAS_DOUBLE_TAP                  (1 << 2)
+#define RMI_F11_HAS_EARLY_TAP                   (1 << 3)
+#define RMI_F11_HAS_FLICK                       (1 << 4)
+#define RMI_F11_HAS_PRESS                       (1 << 5)
+#define RMI_F11_HAS_PINCH                       (1 << 6)
+#define RMI_F11_HAS_CHIRAL                      (1 << 7)
+
+/** Defs for Query 8 */
+#define RMI_F11_HAS_PALM_DET                    (1 << 0)
+#define RMI_F11_HAS_ROTATE                      (1 << 1)
+#define RMI_F11_HAS_TOUCH_SHAPES                (1 << 2)
+#define RMI_F11_HAS_SCROLL_ZONES                (1 << 3)
+#define RMI_F11_HAS_INDIVIDUAL_SCROLL_ZONES     (1 << 4)
+#define RMI_F11_HAS_MF_SCROLL                   (1 << 5)
+#define RMI_F11_HAS_MF_EDGE_MOTION              (1 << 6)
+#define RMI_F11_HAS_MF_SCROLL_INERTIA           (1 << 7)
+
+/** Defs for Query 9. */
+#define RMI_F11_HAS_PEN                         (1 << 0)
+#define RMI_F11_HAS_PROXIMITY                   (1 << 1)
+#define RMI_F11_HAS_PALM_DET_SENSITIVITY        (1 << 2)
+#define RMI_F11_HAS_SUPPRESS_ON_PALM_DETECT     (1 << 3)
+#define RMI_F11_HAS_TWO_PEN_THRESHOLDS          (1 << 4)
+#define RMI_F11_HAS_CONTACT_GEOMETRY            (1 << 5)
+#define RMI_F11_HAS_PEN_HOVER_DISCRIMINATION    (1 << 6)
+#define RMI_F11_HAS_PEN_FILTERS                 (1 << 7)
+
+/** Defs for Query 10. */
+#define RMI_F11_NR_TOUCH_SHAPES_MASK            0x1F
+
+/** Defs for Query 11 */
+
+#define RMI_F11_HAS_Z_TUNING                    (1 << 0)
+#define RMI_F11_HAS_ALGORITHM_SELECTION         (1 << 1)
+#define RMI_F11_HAS_W_TUNING                    (1 << 2)
+#define RMI_F11_HAS_PITCH_INFO                  (1 << 3)
+#define RMI_F11_HAS_FINGER_SIZE                 (1 << 4)
+#define RMI_F11_HAS_SEGMENTATION_AGGRESSIVENESS (1 << 5)
+#define RMI_F11_HAS_XY_CLIP                     (1 << 6)
+#define RMI_F11_HAS_DRUMMING_FILTER             (1 << 7)
+
+/** Defs for Query 12. */
+
+#define RMI_F11_HAS_GAPLESS_FINGER              (1 << 0)
+#define RMI_F11_HAS_GAPLESS_FINGER_TUNING       (1 << 1)
+#define RMI_F11_HAS_8BIT_W                      (1 << 2)
+#define RMI_F11_HAS_ADJUSTABLE_MAPPING          (1 << 3)
+#define RMI_F11_HAS_INFO2                       (1 << 4)
+#define RMI_F11_HAS_PHYSICAL_PROPS              (1 << 5)
+#define RMI_F11_HAS_FINGER_LIMIT                (1 << 6)
+#define RMI_F11_HAS_LINEAR_COEFF                (1 << 7)
+
+/** Defs for Query 13. */
+
+#define RMI_F11_JITTER_WINDOW_MASK              0x1F
+#define RMI_F11_JITTER_FILTER_MASK              0x60
+#define RMI_F11_JITTER_FILTER_SHIFT             5
+
+/** Defs for Query 14. */
+#define RMI_F11_LIGHT_CONTROL_MASK              0x03
+#define RMI_F11_IS_CLEAR                        (1 << 2)
+#define RMI_F11_CLICKPAD_PROPS_MASK             0x18
+#define RMI_F11_CLICKPAD_PROPS_SHIFT            3
+#define RMI_F11_MOUSE_BUTTONS_MASK              0x60
+#define RMI_F11_MOUSE_BUTTONS_SHIFT             5
+#define RMI_F11_HAS_ADVANCED_GESTURES           (1 << 7)
+
+#define RMI_F11_QUERY_SIZE                      4
+#define RMI_F11_QUERY_GESTURE_SIZE              2
 
-/** This query is always present, and is on a per device basis.  All other
- * queries are on a per-sensor basis.
+#define F11_LIGHT_CTL_NONE 0x00
+#define F11_LUXPAD	   0x01
+#define F11_DUAL_MODE      0x02
+
+#define F11_NOT_CLICKPAD     0x00
+#define F11_HINGED_CLICKPAD  0x01
+#define F11_UNIFORM_CLICKPAD 0x02
+
+/**
+ * Query registers 1 through 4 are always present.
  *
- * @nbr_of_sensors - the number of 2D sensors on the touch device.
- * @has_query9 - indicates the F11_2D_Query9 register exists.
- * @has_query11 - indicates the F11_2D_Query11 register exists.
- * @has_query12 - indicates the F11_2D_Query12 register exists.
- */
-struct f11_2d_device_query {
-	u8 nbr_of_sensors:3;
-	u8 has_query9:1;
-	u8 has_query11:1;
-	u8 has_query12:1;
-	u8 has_query27:1;
-	u8 has_query28:1;
-} __attribute__((__packed__));
-
-/** Query registers 1 through 4 are always present.
- * @number_of_fingers - describes the maximum number of fingers the 2-D sensor
+ * @nr_fingers - describes the maximum number of fingers the 2-D sensor
  * supports.
  * @has_rel - the sensor supports relative motion reporting.
  * @has_abs - the sensor supports absolute poition reporting.
@@ -109,27 +200,8 @@ struct f11_2d_device_query {
  * supports on the Y axis.
  * @max_electrodes - the total number of X and Y electrodes that may be
  * configured.
- */
-struct f11_2d_sensor_info {
-	/* query1 */
-	u8 number_of_fingers:3;
-	u8 has_rel:1;
-	u8 has_abs:1;
-	u8 has_gestures:1;
-	u8 has_sensitivity_adjust:1;
-	u8 configurable:1;
-	/* query2 */
-	u8 num_of_x_electrodes:7;
-	u8 reserved_1:1;
-	/* query3 */
-	u8 num_of_y_electrodes:7;
-	u8 reserved_2:1;
-	/* query4 */
-	u8 max_electrodes:7;
-	u8 reserved_3:1;
-} __attribute__((__packed__));
-
-/** Query 5 - this is present if the has_abs bit is set.
+ *
+ * Query 5 is present if the has_abs bit is set.
  *
  * @abs_data_size - describes the format of data reported by the absolute
  * data source.  Only one format (the kind used here) is supported at this
@@ -146,18 +218,8 @@ struct f11_2d_sensor_info {
  * @has_large_object_suppression - control register 58 and data register 28
  * exist.
  * @has_jitter_filter - query 13 and control 73..76 exist.
- */
-struct f11_2d_abs_info {
-	u8 abs_data_size:2;
-	u8 has_anchored_finger:1;
-	u8 has_adj_hyst:1;
-	u8 has_dribble:1;
-	u8 has_bending_correction:1;
-	u8 has_large_object_suppression:1;
-	u8 has_jitter_filter:1;
-} __attribute__((__packed__));
-
-/** Gesture information queries 7 and 8 are present if has_gestures bit is set.
+ *
+ * Gesture information queries 7 and 8 are present if has_gestures bit is set.
  *
  * @has_single_tap - a basic single-tap gesture is supported.
  * @has_tap_n_hold - tap-and-hold gesture is supported.
@@ -176,38 +238,17 @@ struct f11_2d_abs_info {
  * @has_scroll_zones - scrolling areas near the sensor edges are supported.
  * @has_individual_scroll_zones - if 1, then 4 scroll zones are supported;
  * if 0, then only two are supported.
- * @has_multi_finger_scroll - the multifinger_scrolling bit will be set when
+ * @has_mf_scroll - the multifinger_scrolling bit will be set when
  * more than one finger is involved in a scrolling action.
- */
-struct f11_2d_gesture_info {
-	u8 has_single_tap:1;
-	u8 has_tap_n_hold:1;
-	u8 has_double_tap:1;
-	u8 has_early_tap:1;
-	u8 has_flick:1;
-	u8 has_press:1;
-	u8 has_pinch:1;
-	u8 has_chiral:1;
-
-	u8 has_palm_det:1;
-	u8 has_rotate:1;
-	u8 has_touch_shapes:1;
-	u8 has_scroll_zones:1;
-	u8 has_individual_scroll_zones:1;
-	u8 has_multi_finger_scroll:1;
-	u8 has_mf_edge_motion:1;
-	u8 has_mf_scroll_inertia:1;
-} __attribute__((__packed__));
-
-/** Utility for checking bytes in the gesture info registers.  This is done
- * often enough that we put it here to declutter the conditionals.
- */
-static bool has_gesture_bits(const struct f11_2d_gesture_info *info,
-			     const u8 byte) {
-	return ((u8 *) info)[byte] != 0;
-}
-
-/**
+ *
+ * Convenience for checking bytes in the gesture info registers.  This is done
+ * often enough that we put it here to declutter the conditionals
+ *
+ * @query7_nonzero - true if none of the query 7 bits are set
+ * @query8_nonzero - true if none of the query 8 bits are set
+ *
+ * Query 9 is present if the has_query9 is set.
+ *
  * @has_pen - detection of a stylus is supported and registers F11_2D_Ctrl20
  * and F11_2D_Ctrl21 exist.
  * @has_proximity - detection of fingers near the sensor is supported and
@@ -216,30 +257,14 @@ static bool has_gesture_bits(const struct f11_2d_gesture_info *info,
  * feature and register F11_2D_Ctrl27 exists.
  * @has_two_pen_thresholds - is has_pen is also set, then F11_2D_Ctrl35 exists.
  * @has_contact_geometry - the sensor supports the use of contact geometry to
- * map absolute X and Y target positions and registers F11_2D_Data18.* through
- * F11_2D_Data27 exist.
- */
-struct f11_2d_query9 {
-	u8 has_pen:1;
-	u8 has_proximity:1;
-	u8 has_palm_det_sensitivity:1;
-	u8 has_suppress_on_palm_detect:1;
-	u8 has_two_pen_thresholds:1;
-	u8 has_contact_geometry:1;
-	u8 has_pen_hover_discrimination:1;
-	u8 has_pen_filters:1;
-} __attribute__((__packed__));
-
-/** Touch shape info (query 10) is present if has_touch_shapes is set.
+ * map absolute X and Y target positions and registers F11_2D_Data18
+ * through F11_2D_Data27 exist.
  *
- * @nbr_touch_shapes - the total number of touch shapes supported.
- */
-struct f11_2d_ts_info {
-	u8 nbr_touch_shapes:5;
-	u8 reserved:3;
-} __attribute__((__packed__));
-
-/** Query 11 is present if the has_query11 bit is set in query 0.
+ * Touch shape info (query 10) is present if has_touch_shapes is set.
+ *
+ * @nr_touch_shapes - the total number of touch shapes supported.
+ *
+ * Query 11 is present if the has_query11 bit is set in query 0.
  *
  * @has_z_tuning - if set, the sensor supports Z tuning and registers
  * F11_2D_Ctrl29 through F11_2D_Ctrl33 exist.
@@ -259,19 +284,9 @@ struct f11_2d_ts_info {
  * @has_drumming_filter - the sensor can be configured to distinguish
  * between a fast flick and a quick drumming movement and registers
  * F11_2D_Ctrl50 and F11_2D_Ctrl51 exist.
- */
-struct f11_2d_query11 {
-	u8 has_z_tuning:1;
-	u8 has_algorithm_selection:1;
-	u8 has_w_tuning:1;
-	u8 has_pitch_info:1;
-	u8 has_finger_size:1;
-	u8 has_segmentation_aggressiveness:1;
-	u8 has_XY_clip:1;
-	u8 has_drumming_filter:1;
-} __attribute__((__packed__));
-
-/**
+ *
+ * Query 12 is present if hasQuery12 bit is set.
+ *
  * @has_gapless_finger - control registers relating to gapless finger are
  * present.
  * @has_gapless_finger_tuning - additional control and data registers relating
@@ -283,29 +298,12 @@ struct f11_2d_query11 {
  * of the sensor are present.
  * @has_finger_limit - indicates that F11 Ctrl 80 exists.
  * @has_linear_coeff - indicates that F11 Ctrl 81 exists.
- */
-struct f11_2d_query12 {
-	u8 has_gapless_finger:1;
-	u8 has_gapless_finger_tuning:1;
-	u8 has_8bit_w:1;
-	u8 has_adjustable_mapping:1;
-	u8 has_info2:1;
-	u8 has_physical_props:1;
-	u8 has_finger_limit:1;
-	u8 has_linear_coeff_2:1;
-} __attribute__((__packed__));
-
-/** This register is present if Query 5's has_jitter_filter bit is set.
+ *
+ * Query 13 is present if Query 5's has_jitter_filter bit is set.
  * @jitter_window_size - used by Design Studio 4.
  * @jitter_filter_type - used by Design Studio 4.
- */
-struct f11_2d_query13 {
-	u8 jtter_window_size:5;
-	u8 jitter_filter_type:2;
-	u8 reserved:1;
-} __attribute__((__packed__));
-
-/** This register is present if query 12's has_general_info2 flag is set.
+ *
+ * Query 14 is present if query 12's has_general_info2 flag is set.
  *
  * @light_control - Indicates what light/led control features are present, if
  * any.
@@ -316,422 +314,174 @@ struct f11_2d_query13 {
  * @mouse_buttons - specifies the number of mouse buttons present (if any).
  * @has_advanced_gestures - advanced driver gestures are supported.
  */
-struct f11_2d_query14 {
-	u8 light_control:2;
-	u8 is_clear:1;
-	u8 clickpad_props:2;
-	u8 mouse_buttons:2;
-	u8 has_advanced_gestures:1;
-} __attribute__((__packed__));
-
-#define F11_LIGHT_CTL_NONE 0x00
-#define F11_LUXPAD	   0x01
-#define F11_DUAL_MODE      0x02
-
-#define F11_NOT_CLICKPAD     0x00
-#define F11_HINGED_CLICKPAD  0x01
-#define F11_UNIFORM_CLICKPAD 0x02
-
-/** See notes above for information about specific query register sets.
- */
 struct f11_2d_sensor_queries {
-	struct f11_2d_sensor_info info;
-	struct f11_2d_abs_info abs_info;
-	u8 f11_2d_query6;
-	struct f11_2d_gesture_info gesture_info;
-	struct f11_2d_query9 query9;
-	struct f11_2d_ts_info ts_info;
-	struct f11_2d_query11 features_1;
-	struct f11_2d_query12 features_2;
-	struct f11_2d_query13 jitter_filter;
-	struct f11_2d_query14 info_2;
-};
-
-/**
- * @reporting_mode - controls how often finger position data is reported.
- * @abs_pos_filt - when set, enables various noise and jitter filtering
- * algorithms for absolute reports.
- * @rel_pos_filt - when set, enables various noise and jitter filtering
- * algorithms for relative reports.
- * @rel_ballistics - enables ballistics processing for the relative finger
- * motion on the 2-D sensor.
- * @dribble - enables the dribbling feature.
- * @report_beyond_clip - when this is set, fingers outside the active area
- * specified by the x_clip and y_clip registers will be reported, but with
- * reported finger position clipped to the edge of the active area.
- * @palm_detect_thresh - the threshold at which a wide finger is considered a
- * palm. A value of 0 inhibits palm detection.
- * @motion_sensitivity - specifies the threshold an anchored finger must move
- * before it is considered no longer anchored.  High values mean more
- * sensitivity.
- * @man_track_en - for anchored finger tracking, whether the host (1) or the
- * device (0) determines which finger is the tracked finger.
- * @man_tracked_finger - when man_track_en is 1, specifies whether finger 0 or
- * finger 1 is the tracked finger.
- * @delta_x_threshold - 2-D position update interrupts are inhibited unless
- * the finger moves more than a certain threshold distance along the X axis.
- * @delta_y_threshold - 2-D position update interrupts are inhibited unless
- * the finger moves more than a certain threshold distance along the Y axis.
- * @velocity - When rel_ballistics is set, this register defines the
- * velocity ballistic parameter applied to all relative motion events.
- * @acceleration - When rel_ballistics is set, this register defines the
- * acceleration ballistic parameter applied to all relative motion events.
- * @sensor_max_x_pos - the maximum X coordinate reported by the sensor.
- * @sensor_max_y_pos - the maximum Y coordinate reported by the sensor.
- */
-struct f11_2d_ctrl0_9 {
-	/* F11_2D_Ctrl0 */
-	u8 reporting_mode:3;
-	u8 abs_pos_filt:1;
-	u8 rel_pos_filt:1;
-	u8 rel_ballistics:1;
-	u8 dribble:1;
-	u8 report_beyond_clip:1;
-	/* F11_2D_Ctrl1 */
-	u8 palm_detect_thres:4;
-	u8 motion_sensitivity:2;
-	u8 man_track_en:1;
-	u8 man_tracked_finger:1;
-	/* F11_2D_Ctrl2 and 3 */
-	u8 delta_x_threshold:8;
-	u8 delta_y_threshold:8;
-	/* F11_2D_Ctrl4 and 5 */
-	u8 velocity:8;
-	u8 acceleration:8;
-	/* F11_2D_Ctrl6 thru 9 */
-	u16 sensor_max_x_pos:12;
-	u8 ctrl7_reserved:4;
-	u16 sensor_max_y_pos:12;
-	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__));
+	/* query1 */
+	u8 nr_fingers;
+	bool has_rel;
+	bool has_abs;
+	bool has_gestures;
+	bool has_sensitivity_adjust;
+	bool configurable;
 
-/**
- * @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__));
+	/* query2 */
+	u8 nr_x_electrodes;
 
-/**
- * @min_flick_distance - the minimum finger movement for a flick gesture,
- * in 1-millimeter units.
- * @min_flick_speed - the minimum finger speed for a flick gesture, in
- * 10-millimeter/second units.
- */
-struct f11_2d_ctrl18_19 {
-	u8 min_flick_distance:8;
-	u8 min_flick_speed:8;
-} __attribute__((__packed__));
+	/* query3 */
+	u8 nr_y_electrodes;
 
-/**
- * @pen_detect_enable - enable reporting of stylus activity.
- * @pen_jitter_filter_enable - Setting this enables the stylus anti-jitter
- * filter.
- * @pen_z_threshold - This is the stylus-detection lower threshold. Smaller
- * values result in higher sensitivity.
- */
-struct f11_2d_ctrl20_21 {
-	u8 pen_detect_enable:1;
-	u8 pen_jitter_filter_enable:1;
-	u8 ctrl20_reserved:6;
-	u8 pen_z_threshold:8;
-} __attribute__((__packed__));
+	/* query4 */
+	u8 max_electrodes;
 
-/**
- * These are not accessible through sysfs yet.
- *
- * @proximity_detect_int_en - enable proximity detection feature.
- * @proximity_jitter_filter_en - enables an anti-jitter filter on proximity
- * data.
- * @proximity_detection_z_threshold - the threshold for finger-proximity
- * detection.
- * @proximity_delta_x_threshold - In reduced-reporting modes, this is the
- * threshold for proximate-finger movement in the direction parallel to the
- * X-axis.
- * @proximity_delta_y_threshold - In reduced-reporting modes, this is the
- * threshold for proximate-finger movement in the direction parallel to the
- * Y-axis.
- * * @proximity_delta_Z_threshold - In reduced-reporting modes, this is the
- * threshold for proximate-finger movement in the direction parallel to the
- * Z-axis.
- */
-struct f11_2d_ctrl22_26 {
-	/* control 22 */
-	u8 proximity_detect_int_en:1;
-	u8 proximity_jitter_filter_en:1;
-	u8 f11_2d_ctrl6_b3__7:6;
+	/* query5 */
+	u8 abs_data_size;
+	bool has_anchored_finger;
+	bool has_adj_hyst;
+	bool has_dribble;
+	bool has_bending_correction;
+	bool has_large_object_suppression;
+	bool has_jitter_filter;
 
-	/* control 23 */
-	u8 proximity_detection_z_threshold;
+	u8 f11_2d_query6;
 
-	/* control 24 */
-	u8 proximity_delta_x_threshold;
+	/* query 7 */
+	bool has_single_tap;
+	bool has_tap_n_hold;
+	bool has_double_tap;
+	bool has_early_tap;
+	bool has_flick;
+	bool has_press;
+	bool has_pinch;
+	bool has_chiral;
+
+	bool query7_nonzero;
+
+	/* query 8 */
+	bool has_palm_det;
+	bool has_rotate;
+	bool has_touch_shapes;
+	bool has_scroll_zones;
+	bool has_individual_scroll_zones;
+	bool has_mf_scroll;
+	bool has_mf_edge_motion;
+	bool has_mf_scroll_inertia;
+
+	bool query8_nonzero;
+
+	/* Query 9 */
+	bool has_pen;
+	bool has_proximity;
+	bool has_palm_det_sensitivity;
+	bool has_suppress_on_palm_detect;
+	bool has_two_pen_thresholds;
+	bool has_contact_geometry;
+	bool has_pen_hover_discrimination;
+	bool has_pen_filters;
+
+	/* Query 10 */
+	u8 nr_touch_shapes;
+
+	/* Query 11. */
+	bool has_z_tuning;
+	bool has_algorithm_selection;
+	bool has_w_tuning;
+	bool has_pitch_info;
+	bool has_finger_size;
+	bool has_segmentation_aggressiveness;
+	bool has_XY_clip;
+	bool has_drumming_filter;
+
+	/* Query 12 */
+	bool has_gapless_finger;
+	bool has_gapless_finger_tuning;
+	bool has_8bit_w;
+	bool has_adjustable_mapping;
+	bool has_info2;
+	bool has_physical_props;
+	bool has_finger_limit;
+	bool has_linear_coeff_2;
+
+	/* Query 13 */
+	u8 jitter_window_size;
+	u8 jitter_filter_type;
+
+	/* Query 14 */
+	u8 light_control;
+	bool is_clear;
+	u8 clickpad_props;
+	u8 mouse_buttons;
+	bool has_advanced_gestures;
+};
 
-	/* control 25 */
-	u8 proximity_delta_y_threshold;
+/* Defs for Ctrl0. */
+#define RMI_F11_REPORT_MODE_MASK        0x07
+#define RMI_F11_ABS_POS_FILT            (1 << 3)
+#define RMI_F11_REL_POS_FILT            (1 << 4)
+#define RMI_F11_REL_BALLISTICS          (1 << 5)
+#define RMI_F11_DRIBBLE                 (1 << 6)
+#define RMI_F11_REPORT_BEYOND_CLIP      (1 << 7)
 
-	/* control 26 */
-	u8 proximity_delta_z_threshold;
-} __attribute__((__packed__));
+/* Defs for Ctrl1. */
+#define RMI_F11_PALM_DETECT_THRESH_MASK 0x0F
+#define RMI_F11_MOTION_SENSITIVITY_MASK 0x30
+#define RMI_F11_MANUAL_TRACKING         (1 << 6)
+#define RMI_F11_MANUAL_TRACKED_FINGER   (1 << 7)
 
-/**
- * @palm_detecy_sensitivity - When this value is small, smaller objects will
- * be identified as palms; when this value is large, only larger objects will
- * be identified as palms. 0 represents the factory default.
- * @suppress_on_palm_detect - when set, all F11 interrupts except palm_detect
- * are suppressed while a palm is detected.
- */
-struct f11_2d_ctrl27 {
-	s8 palm_detect_sensitivity:4;
-	u8 suppress_on_palm_detect:1;
-	u8 f11_2d_ctrl27_b5__7:3;
-} __attribute__((__packed__));
-
-/**
- * @multi_finger_scroll_mode - allows choice of multi-finger scroll mode and
- * determines whether and how X or Y displacements are reported.
- * @edge_motion_en - enables the edge_motion feature.
- * @multi_finger_scroll_momentum - controls the length of time that scrolling
- * continues after fingers have been lifted.
- */
-struct f11_2d_ctrl28 {
-	u8 multi_finger_scroll_mode:2;
-	u8 edge_motion_en:1;
-	u8 f11_2d_ctrl28b_3:1;
-	u8 multi_finger_scroll_momentum:4;
-} __attribute__((__packed__));
-
-/**
- * @z_touch_threshold - Specifies the finger-arrival Z threshold. Large values
- * may cause smaller fingers to be rejected.
- * @z_touch_hysteresis - Specifies the difference between the finger-arrival
- * Z threshold and the finger-departure Z threshold.
- */
-struct f11_2d_ctrl29_30 {
-	u8 z_touch_threshold;
-	u8 z_touch_hysteresis;
-} __attribute__((__packed__));
+#define RMI_F11_DELTA_X_THRESHOLD       2
+#define RMI_F11_DELTA_Y_THRESHOLD       3
 
+#define RMI_F11_CTRL_REG_COUNT          10
 
 struct f11_2d_ctrl {
-	struct f11_2d_ctrl0_9		 *ctrl0_9;
-	u16				ctrl0_9_address;
-	struct f11_2d_ctrl10		*ctrl10;
-	struct f11_2d_ctrl11		*ctrl11;
-	u8				ctrl12_size;
-	struct f11_2d_ctrl14		*ctrl14;
-	struct f11_2d_ctrl15		*ctrl15;
-	struct f11_2d_ctrl16		*ctrl16;
-	struct f11_2d_ctrl17		*ctrl17;
-	struct f11_2d_ctrl18_19		*ctrl18_19;
-	struct f11_2d_ctrl20_21		*ctrl20_21;
-	struct f11_2d_ctrl22_26		*ctrl22_26;
-	struct f11_2d_ctrl27		*ctrl27;
-	struct f11_2d_ctrl28		*ctrl28;
-	struct f11_2d_ctrl29_30		*ctrl29_30;
+	u8              ctrl0_9[RMI_F11_CTRL_REG_COUNT];
+	u16             ctrl0_9_address;
 };
 
-/**
- * @x_msb - top 8 bits of X finger position.
- * @y_msb - top 8 bits of Y finger position.
- * @x_lsb - bottom 4 bits of X finger position.
- * @y_lsb - bottom 4 bits of Y finger position.
- * @w_y - contact patch width along Y axis.
- * @w_x - contact patch width along X axis.
- * @z - finger Z value (proxy for pressure).
- */
-struct f11_2d_data_1_5 {
-	u8 x_msb;
-	u8 y_msb;
-	u8 x_lsb:4;
-	u8 y_lsb:4;
-	u8 w_y:4;
-	u8 w_x:4;
-	u8 z;
-} __attribute__((__packed__));
-
-/**
- * @delta_x - relative motion along X axis.
- * @delta_y - relative motion along Y axis.
- */
-struct f11_2d_data_6_7 {
-	s8 delta_x;
-	s8 delta_y;
-} __attribute__((__packed__));
-
-/**
- * @single_tap - a single tap was recognized.
- * @tap_and_hold - a tap-and-hold gesture was recognized.
- * @double_tap - a double tap gesture was recognized.
- * @early_tap - a tap gesture might be happening.
- * @flick - a flick gesture was detected.
- * @press - a press gesture was recognized.
- * @pinch - a pinch gesture was detected.
- */
-struct f11_2d_data_8 {
-	bool single_tap:1;
-	bool tap_and_hold:1;
-	bool double_tap:1;
-	bool early_tap:1;
-	bool flick:1;
-	bool press:1;
-	bool pinch:1;
-} __attribute__((__packed__));
-
-/**
- * @palm_detect - a palm or other large object is in contact with the sensor.
- * @rotate - a rotate gesture was detected.
- * @shape - a TouchShape has been activated.
- * @scrollzone - scrolling data is available.
- * @finger_count - number of fingers involved in the reported gesture.
- */
-struct f11_2d_data_9 {
-	bool palm_detect:1;
-	bool rotate:1;
-	bool shape:1;
-	bool scrollzone:1;
-	u8 finger_count:3;
-} __attribute__((__packed__));
-
-/**
- * @pinch_motion - when a pinch gesture is detected, this is the change in
- * distance between the two fingers since this register was last read.
- */
-struct f11_2d_data_10 {
-	s8 pinch_motion;
-} __attribute__((__packed__));
+#define RMI_F11_ABS_BYTES 5
+#define RMI_F11_REL_BYTES 2
 
-/**
- * @x_flick_dist - when a flick gesture is detected,  the distance of flick
- * gesture in X direction.
- * @y_flick_dist - when a flick gesture is detected,  the distance of flick
- * gesture in Y direction.
- * @flick_time - the total time of the flick gesture, in 10ms units.
- */
-struct f11_2d_data_10_12 {
-	s8 x_flick_dist;
-	s8 y_flick_dist;
-	u8 flick_time;
-} __attribute__((__packed__));
+/* Defs for Data 8 */
 
-/**
- * @motion - when a rotate gesture is detected, the accumulated distance
- * of the rotate motion. Clockwise motion is positive and counterclockwise
- * motion is negative.
- * @finger_separation - when a rotate gesture is detected, the distance
- * between the fingers.
- */
-struct f11_2d_data_11_12 {
-	s8 motion;
-	u8 finger_separation;
-} __attribute__((__packed__));
+#define RMI_F11_SINGLE_TAP              (1 << 0)
+#define RMI_F11_TAP_AND_HOLD            (1 << 1)
+#define RMI_F11_DOUBLE_TAP              (1 << 2)
+#define RMI_F11_EARLY_TAP               (1 << 3)
+#define RMI_F11_FLICK                   (1 << 4)
+#define RMI_F11_PRESS                   (1 << 5)
+#define RMI_F11_PINCH                   (1 << 6)
 
-/**
- * @shape_n - a bitmask of the currently activate TouchShapes (if any).
- */
-struct f11_2d_data_13 {
-	u8 shape_n;
-} __attribute__((__packed__));
+/* Defs for Data 9 */
 
-/**
- * @horizontal - chiral scrolling distance in the X direction.
- * @vertical - chiral scrolling distance in the Y direction.
- */
-struct f11_2d_data_14_15 {
-	s8 horizontal;
-	s8 vertical;
-} __attribute__((__packed__));
+#define RMI_F11_PALM_DETECT                     (1 << 0)
+#define RMI_F11_ROTATE                          (1 << 1)
+#define RMI_F11_SHAPE                           (1 << 2)
+#define RMI_F11_SCROLLZONE                      (1 << 3)
+#define RMI_F11_GESTURE_FINGER_COUNT_MASK       0x70
 
-/**
- * @x_low - scroll zone motion along the lower edge of the sensor.
- * @y_right - scroll zone motion along the right edge of the sensor.
- * @x_upper - scroll zone motion along the upper edge of the sensor.
- * @y_left - scroll zone motion along the left edge of the sensor.
+/** Handy pointers into our data buffer.
+ *
+ * @f_state - start of finger state registers.
+ * @abs_pos - start of absolute position registers (if present).
+ * @rel_pos - start of relative data registers (if present).
+ * @gest_1  - gesture flags (if present).
+ * @gest_2  - gesture flags & finger count (if present).
+ * @pinch   - pinch motion register (if present).
+ * @flick   - flick distance X & Y, flick time (if present).
+ * @rotate  - rotate motion and finger separation.
+ * @multi_scroll - chiral deltas for X and Y (if present).
+ * @scroll_zones - scroll deltas for 4 regions (if present).
  */
-struct f11_2d_data_14_17 {
-	s8 x_low;
-	s8 y_right;
-	s8 x_upper;
-	s8 y_left;
-} __attribute__((__packed__));
-
 struct f11_2d_data {
-	u8				*f_state;
-	const struct f11_2d_data_1_5	*abs_pos;
-	const struct f11_2d_data_6_7	*rel_pos;
-	const struct f11_2d_data_8	*gest_1;
-	const struct f11_2d_data_9	*gest_2;
-	const struct f11_2d_data_10	*pinch;
-	const struct f11_2d_data_10_12	*flick;
-	const struct f11_2d_data_11_12	*rotate;
-	const struct f11_2d_data_13	*shapes;
-	const struct f11_2d_data_14_15	*multi_scroll;
-	const struct f11_2d_data_14_17	*scroll_zones;
+	u8	*f_state;
+	u8	*abs_pos;
+	s8	*rel_pos;
+	u8	*gest_1;
+	u8	*gest_2;
+	s8	*pinch;
+	u8	*flick;
+	u8	*rotate;
+	u8	*shapes;
+	s8	*multi_scroll;
+	s8	*scroll_zones;
 };
 
 /**
@@ -785,11 +535,13 @@ struct f11_2d_sensor {
  * poor electrical behavior on resume, where the initial calibration of the
  * sensor(s) coming out of sleep state may be bogus.
  * @sensors - per sensor data structures.
- * @debugfs_rezero_wait - allows control of the rezero_wait value.  Useful
- * during system prototyping.
  */
 struct f11_data {
-	struct f11_2d_device_query dev_query;
+	bool has_query9;
+	bool has_query11;
+	bool has_query12;
+	bool has_query27;
+	bool has_query28;
 	struct f11_2d_ctrl dev_controls;
 	struct mutex dev_controls_mutex;
 	u16 rezero_wait_ms;
@@ -809,7 +561,7 @@ enum finger_state_values {
 static int get_tool_type(struct f11_2d_sensor *sensor, u8 finger_state)
 {
 	if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
-			sensor->sens_query.query9.has_pen &&
+			sensor->sens_query.has_pen &&
 			finger_state == F11_PEN)
 		return MT_TOOL_PEN;
 	return MT_TOOL_FINGER;
@@ -822,8 +574,8 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor *sensor, u8 n_finger)
 	s8 x, y;
 	s8 temp;
 
-	x = data->rel_pos[n_finger].delta_x;
-	y = data->rel_pos[n_finger].delta_y;
+	x = data->rel_pos[n_finger * 2];
+	y = data->rel_pos[n_finger * 2 + 1];
 
 	x = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)x));
 	y = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)y));
@@ -856,17 +608,18 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
 	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;
 
 	if (finger_state) {
-		x = ((data->abs_pos[n_finger].x_msb << 4) |
-			data->abs_pos[n_finger].x_lsb);
-		y = ((data->abs_pos[n_finger].y_msb << 4) |
-			data->abs_pos[n_finger].y_lsb);
-		z = data->abs_pos[n_finger].z;
-		w_x = data->abs_pos[n_finger].w_x;
-		w_y = data->abs_pos[n_finger].w_y;
+		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;
@@ -976,38 +729,36 @@ static int f11_2d_construct_data(struct f11_2d_sensor *sensor)
 	struct f11_2d_data *data = &sensor->data;
 	int i;
 
-	sensor->nbr_fingers = (query->info.number_of_fingers == 5 ? 10 :
-				query->info.number_of_fingers + 1);
+	sensor->nbr_fingers = (query->nr_fingers == 5 ? 10 :
+				query->nr_fingers + 1);
 
 	sensor->pkt_size = DIV_ROUND_UP(sensor->nbr_fingers, 4);
 
-	if (query->info.has_abs)
+	if (query->has_abs)
 		sensor->pkt_size += (sensor->nbr_fingers * 5);
 
-	if (query->info.has_rel)
+	if (query->has_rel)
 		sensor->pkt_size +=  (sensor->nbr_fingers * 2);
 
 	/* Check if F11_2D_Query7 is non-zero */
-	if (has_gesture_bits(&query->gesture_info, 0))
+	if (query->query7_nonzero)
 		sensor->pkt_size += sizeof(u8);
 
 	/* Check if F11_2D_Query7 or F11_2D_Query8 is non-zero */
-	if (has_gesture_bits(&query->gesture_info, 0) ||
-				has_gesture_bits(&query->gesture_info, 1))
+	if (query->query7_nonzero || query->query8_nonzero)
 		sensor->pkt_size += sizeof(u8);
 
-	if (query->gesture_info.has_pinch || query->gesture_info.has_flick
-			|| query->gesture_info.has_rotate) {
+	if (query->has_pinch || query->has_flick || query->has_rotate) {
 		sensor->pkt_size += 3;
-		if (!query->gesture_info.has_flick)
+		if (!query->has_flick)
 			sensor->pkt_size--;
-		if (!query->gesture_info.has_rotate)
+		if (!query->has_rotate)
 			sensor->pkt_size--;
 	}
 
-	if (query->gesture_info.has_touch_shapes)
+	if (query->has_touch_shapes)
 		sensor->pkt_size +=
-			DIV_ROUND_UP(query->ts_info.nbr_touch_shapes + 1, 8);
+			DIV_ROUND_UP(query->nr_touch_shapes + 1, 8);
 
 	sensor->data_pkt = kzalloc(sensor->pkt_size, GFP_KERNEL);
 	if (!sensor->data_pkt)
@@ -1016,58 +767,52 @@ static int f11_2d_construct_data(struct f11_2d_sensor *sensor)
 	data->f_state = sensor->data_pkt;
 	i = DIV_ROUND_UP(sensor->nbr_fingers, 4);
 
-	if (query->info.has_abs) {
-		data->abs_pos = (struct f11_2d_data_1_5 *)
-				&sensor->data_pkt[i];
-		i += (sensor->nbr_fingers * 5);
+	if (query->has_abs) {
+		data->abs_pos = &sensor->data_pkt[i];
+		i += (sensor->nbr_fingers * RMI_F11_ABS_BYTES);
 	}
 
-	if (query->info.has_rel) {
-		data->rel_pos = (struct f11_2d_data_6_7 *)
-				&sensor->data_pkt[i];
-		i += (sensor->nbr_fingers * 2);
+	if (query->has_rel) {
+		data->rel_pos = &sensor->data_pkt[i];
+		i += (sensor->nbr_fingers * RMI_F11_REL_BYTES);
 	}
 
-	if (has_gesture_bits(&query->gesture_info, 0)) {
-		data->gest_1 = (struct f11_2d_data_8 *)&sensor->data_pkt[i];
+	if (query->query7_nonzero) {
+		data->gest_1 = &sensor->data_pkt[i];
 		i++;
 	}
 
-	if (has_gesture_bits(&query->gesture_info, 0) ||
-				has_gesture_bits(&query->gesture_info, 1)) {
-		data->gest_2 = (struct f11_2d_data_9 *)&sensor->data_pkt[i];
+	if (query->query7_nonzero || query->query8_nonzero) {
+		data->gest_2 = &sensor->data_pkt[i];
 		i++;
 	}
 
-	if (query->gesture_info.has_pinch) {
-		data->pinch = (struct f11_2d_data_10 *)&sensor->data_pkt[i];
+	if (query->has_pinch) {
+		data->pinch = &sensor->data_pkt[i];
 		i++;
 	}
 
-	if (query->gesture_info.has_flick) {
-		if (query->gesture_info.has_pinch) {
-			data->flick = (struct f11_2d_data_10_12 *)data->pinch;
+	if (query->has_flick) {
+		if (query->has_pinch) {
+			data->flick = data->pinch;
 			i += 2;
 		} else {
-			data->flick = (struct f11_2d_data_10_12 *)
-					&sensor->data_pkt[i];
+			data->flick = &sensor->data_pkt[i];
 			i += 3;
 		}
 	}
 
-	if (query->gesture_info.has_rotate) {
-		if (query->gesture_info.has_flick) {
-			data->rotate = (struct f11_2d_data_11_12 *)
-					(data->flick + 1);
+	if (query->has_rotate) {
+		if (query->has_flick) {
+			data->rotate = data->flick + 1;
 		} else {
-			data->rotate = (struct f11_2d_data_11_12 *)
-					&sensor->data_pkt[i];
+			data->rotate = &sensor->data_pkt[i];
 			i += 2;
 		}
 	}
 
-	if (query->gesture_info.has_touch_shapes)
-		data->shapes = (struct f11_2d_data_13 *)&sensor->data_pkt[i];
+	if (query->has_touch_shapes)
+		data->shapes = &sensor->data_pkt[i];
 
 	return 0;
 }
@@ -1075,213 +820,16 @@ static int f11_2d_construct_data(struct f11_2d_sensor *sensor)
 static int f11_read_control_regs(struct rmi_function *fn,
 				struct f11_2d_ctrl *ctrl, u16 ctrl_base_addr) {
 	struct rmi_device *rmi_dev = fn->rmi_dev;
-	u16 read_address = ctrl_base_addr;
 	int error = 0;
 
-	ctrl->ctrl0_9_address = read_address;
-	error = rmi_read_block(rmi_dev, read_address, ctrl->ctrl0_9,
-		sizeof(*ctrl->ctrl0_9));
+	ctrl->ctrl0_9_address = ctrl_base_addr;
+	error = rmi_read_block(rmi_dev, ctrl_base_addr, ctrl->ctrl0_9,
+				RMI_F11_CTRL_REG_COUNT);
 	if (error < 0) {
 		dev_err(&fn->dev, "Failed to read ctrl0, code: %d.\n", error);
 		return error;
 	}
-	read_address += sizeof(*ctrl->ctrl0_9);
 
-	if (ctrl->ctrl10) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl10, sizeof(*ctrl->ctrl10));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl10, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl10);
-	}
-
-	if (ctrl->ctrl11) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl11, sizeof(*ctrl->ctrl11));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl11, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl11);
-	}
-
-	if (ctrl->ctrl14) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl14, sizeof(*ctrl->ctrl14));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl14, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl14);
-	}
-
-	if (ctrl->ctrl15) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl15, sizeof(*ctrl->ctrl15));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl15, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl15);
-	}
-
-	if (ctrl->ctrl16) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl16, sizeof(*ctrl->ctrl16));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl16, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl16);
-	}
-
-	if (ctrl->ctrl17) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl17, sizeof(*ctrl->ctrl17));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl17, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl17);
-	}
-
-	if (ctrl->ctrl18_19) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl18_19, sizeof(*ctrl->ctrl18_19));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl18_19, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl18_19);
-	}
-
-	if (ctrl->ctrl20_21) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl20_21, sizeof(*ctrl->ctrl20_21));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl20_21, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl20_21);
-	}
-
-	if (ctrl->ctrl22_26) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl22_26, sizeof(*ctrl->ctrl22_26));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl22_26, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl22_26);
-	}
-
-	if (ctrl->ctrl27) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl27, sizeof(*ctrl->ctrl27));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl27, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl27);
-	}
-
-	if (ctrl->ctrl28) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl28, sizeof(*ctrl->ctrl28));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl28, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl28);
-	}
-
-	if (ctrl->ctrl29_30) {
-		error = rmi_read_block(rmi_dev, read_address,
-			ctrl->ctrl29_30, sizeof(*ctrl->ctrl29_30));
-		if (error < 0) {
-			dev_err(&fn->dev,
-				"Failed to read ctrl29_30, code: %d.\n", error);
-			return error;
-		}
-		read_address += sizeof(*ctrl->ctrl29_30);
-	}
-	return 0;
-}
-
-static int f11_allocate_control_regs(struct rmi_function *fn,
-				struct f11_2d_device_query *device_query,
-				struct f11_2d_sensor_queries *sensor_query,
-				struct f11_2d_ctrl *ctrl,
-				u16 ctrl_base_addr) {
-
-	ctrl->ctrl0_9 = devm_kzalloc(&fn->dev, sizeof(struct f11_2d_ctrl0_9),
-				       GFP_KERNEL);
-	if (!ctrl->ctrl0_9)
-		return -ENOMEM;
-	if (has_gesture_bits(&sensor_query->gesture_info, 0)) {
-		ctrl->ctrl10 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl10), GFP_KERNEL);
-		if (!ctrl->ctrl10)
-			return -ENOMEM;
-	}
-
-	if (has_gesture_bits(&sensor_query->gesture_info, 1)) {
-		ctrl->ctrl11 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl11), GFP_KERNEL);
-		if (!ctrl->ctrl11)
-			return -ENOMEM;
-	}
-
-	if (device_query->has_query9 && sensor_query->query9.has_pen) {
-		ctrl->ctrl20_21 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl20_21), GFP_KERNEL);
-		if (!ctrl->ctrl20_21)
-			return -ENOMEM;
-	}
-
-	if (device_query->has_query9 && sensor_query->query9.has_proximity) {
-		ctrl->ctrl22_26 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl22_26), GFP_KERNEL);
-		if (!ctrl->ctrl22_26)
-			return -ENOMEM;
-	}
-
-	if (device_query->has_query9 &&
-		(sensor_query->query9.has_palm_det_sensitivity ||
-		sensor_query->query9.has_suppress_on_palm_detect)) {
-		ctrl->ctrl27 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl27), GFP_KERNEL);
-		if (!ctrl->ctrl27)
-			return -ENOMEM;
-	}
-
-	if (sensor_query->gesture_info.has_multi_finger_scroll) {
-		ctrl->ctrl28 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl28), GFP_KERNEL);
-		if (!ctrl->ctrl28)
-			return -ENOMEM;
-	}
-
-	if (device_query->has_query11 &&
-			sensor_query->features_1.has_z_tuning) {
-		ctrl->ctrl29_30 = devm_kzalloc(&fn->dev,
-			sizeof(struct f11_2d_ctrl29_30), GFP_KERNEL);
-		if (!ctrl->ctrl29_30)
-			return -ENOMEM;
-	}
 
 	return 0;
 }
@@ -1292,139 +840,71 @@ static int f11_write_control_regs(struct rmi_function *fn,
 					u16 ctrl_base_addr)
 {
 	struct rmi_device *rmi_dev = fn->rmi_dev;
-	u16 write_address = ctrl_base_addr;
 	int error;
 
-	error = rmi_write_block(rmi_dev, write_address,
-				ctrl->ctrl0_9,
-				 sizeof(*ctrl->ctrl0_9));
+	error = rmi_write_block(rmi_dev, ctrl_base_addr, ctrl->ctrl0_9,
+				RMI_F11_CTRL_REG_COUNT);
 	if (error < 0)
 		return error;
-	write_address += sizeof(ctrl->ctrl0_9);
-
-	if (ctrl->ctrl10) {
-		error = rmi_write_block(rmi_dev, write_address,
-					ctrl->ctrl10, sizeof(*ctrl->ctrl10));
-		if (error < 0)
-			return error;
-		write_address++;
-	}
-
-	if (ctrl->ctrl11) {
-		error = rmi_write_block(rmi_dev, write_address,
-					ctrl->ctrl11, sizeof(*ctrl->ctrl11));
-		if (error < 0)
-			return error;
-		write_address++;
-	}
-
-	if (ctrl->ctrl14) {
-		error = rmi_write_block(rmi_dev, write_address,
-				ctrl->ctrl14, sizeof(ctrl->ctrl14));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl15);
-	}
 
-	if (ctrl->ctrl15) {
-		error = rmi_write_block(rmi_dev, write_address,
-				ctrl->ctrl15, sizeof(*ctrl->ctrl15));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl15);
-	}
-
-	if (ctrl->ctrl16) {
-		error = rmi_write_block(rmi_dev, write_address,
-				ctrl->ctrl16, sizeof(*ctrl->ctrl16));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl16);
-	}
-
-	if (ctrl->ctrl17) {
-		error = rmi_write_block(rmi_dev, write_address,
-				ctrl->ctrl17, sizeof(*ctrl->ctrl17));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl17);
-	}
-
-	if (ctrl->ctrl18_19) {
-		error = rmi_write_block(rmi_dev, write_address,
-			ctrl->ctrl18_19, sizeof(*ctrl->ctrl18_19));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl18_19);
-	}
-
-	if (ctrl->ctrl20_21) {
-		error = rmi_write_block(rmi_dev, write_address,
-			ctrl->ctrl20_21, sizeof(*ctrl->ctrl20_21));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl20_21);
-	}
-
-	if (ctrl->ctrl22_26) {
-		error = rmi_write_block(rmi_dev, write_address,
-			ctrl->ctrl22_26, sizeof(*ctrl->ctrl22_26));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl22_26);
-	}
-
-	if (ctrl->ctrl27) {
-		error = rmi_write_block(rmi_dev, write_address,
-			ctrl->ctrl27, sizeof(*ctrl->ctrl27));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl27);
-	}
-
-	if (ctrl->ctrl28) {
-		error = rmi_write_block(rmi_dev, write_address,
-			ctrl->ctrl28, sizeof(*ctrl->ctrl28));
-		if (error < 0)
-			return error;
-		write_address += sizeof(*ctrl->ctrl28);
-	}
-
-	if (ctrl->ctrl29_30) {
-		error = rmi_write_block(rmi_dev, write_address,
-					ctrl->ctrl29_30,
-					sizeof(struct f11_2d_ctrl29_30));
-		if (error < 0)
-			return error;
-		write_address += sizeof(struct f11_2d_ctrl29_30);
-	}
 
 	return 0;
 }
 
 static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
-			struct f11_2d_device_query *dev_query,
+			struct f11_data *f11,
 			struct f11_2d_sensor_queries *sensor_query,
 			u16 query_base_addr)
 {
 	int query_size;
 	int rc;
+	u8 query_buf[RMI_F11_QUERY_SIZE];
 
-	rc = rmi_read_block(rmi_dev, query_base_addr,
-			    &sensor_query->info, sizeof(sensor_query->info));
+	rc = rmi_read_block(rmi_dev, query_base_addr, query_buf,
+				RMI_F11_QUERY_SIZE);
 	if (rc < 0)
 		return rc;
-	query_size = sizeof(sensor_query->info);
 
-	if (sensor_query->info.has_abs) {
-		rc = rmi_read(rmi_dev, query_base_addr + query_size,
-					&sensor_query->abs_info);
+	sensor_query->nr_fingers = query_buf[0] & RMI_F11_NR_FINGERS_MASK;
+	sensor_query->has_rel = !!(query_buf[0] & RMI_F11_HAS_REL);
+	sensor_query->has_abs = !!(query_buf[0] & RMI_F11_HAS_ABS);
+	sensor_query->has_gestures = !!(query_buf[0] & RMI_F11_HAS_GESTURES);
+	sensor_query->has_sensitivity_adjust =
+		!!(query_buf[0] && RMI_F11_HAS_SENSITIVITY_ADJ);
+	sensor_query->configurable = !!(query_buf[0] & RMI_F11_CONFIGURABLE);
+
+	sensor_query->nr_x_electrodes =
+				query_buf[1] & RMI_F11_NR_ELECTRODES_MASK;
+	sensor_query->nr_y_electrodes =
+				query_buf[2] & RMI_F11_NR_ELECTRODES_MASK;
+	sensor_query->max_electrodes =
+				query_buf[3] & RMI_F11_NR_ELECTRODES_MASK;
+
+	query_size = RMI_F11_QUERY_SIZE;
+
+	if (sensor_query->has_abs) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
+
+		sensor_query->abs_data_size =
+			query_buf[0] & RMI_F11_ABS_DATA_SIZE_MASK;
+		sensor_query->has_anchored_finger =
+			!!(query_buf[0] & RMI_F11_HAS_ANCHORED_FINGER);
+		sensor_query->has_adj_hyst =
+			!!(query_buf[0] & RMI_F11_HAS_ADJ_HYST);
+		sensor_query->has_dribble =
+			!!(query_buf[0] & RMI_F11_HAS_DRIBBLE);
+		sensor_query->has_bending_correction =
+			!!(query_buf[0] & RMI_F11_HAS_BENDING_CORRECTION);
+		sensor_query->has_large_object_suppression =
+		!!(query_buf[0] && RMI_F11_HAS_LARGE_OBJECT_SUPPRESSION);
+		sensor_query->has_jitter_filter =
+			!!(query_buf[0] & RMI_F11_HAS_JITTER_FILTER);
 		query_size++;
 	}
 
-	if (sensor_query->info.has_rel) {
+	if (sensor_query->has_rel) {
 		rc = rmi_read(rmi_dev, query_base_addr + query_size,
 					&sensor_query->f11_2d_query6);
 		if (rc < 0)
@@ -1432,67 +912,173 @@ static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
 		query_size++;
 	}
 
-	if (sensor_query->info.has_gestures) {
+	if (sensor_query->has_gestures) {
 		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->gesture_info,
-					sizeof(sensor_query->gesture_info));
+					query_buf, RMI_F11_QUERY_GESTURE_SIZE);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->gesture_info);
-	}
 
-	if (dev_query->has_query9) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->query9,
-					sizeof(sensor_query->query9));
+		sensor_query->has_single_tap =
+			!!(query_buf[0] & RMI_F11_HAS_SINGLE_TAP);
+		sensor_query->has_tap_n_hold =
+			!!(query_buf[0] & RMI_F11_HAS_TAP_AND_HOLD);
+		sensor_query->has_double_tap =
+			!!(query_buf[0] & RMI_F11_HAS_DOUBLE_TAP);
+		sensor_query->has_early_tap =
+			!!(query_buf[0] & RMI_F11_HAS_EARLY_TAP);
+		sensor_query->has_flick =
+			!!(query_buf[0] & RMI_F11_HAS_FLICK);
+		sensor_query->has_press =
+			!!(query_buf[0] & RMI_F11_HAS_PRESS);
+		sensor_query->has_pinch =
+			!!(query_buf[0] & RMI_F11_HAS_PINCH);
+		sensor_query->has_chiral =
+			!!(query_buf[0] & RMI_F11_HAS_CHIRAL);
+
+		/* query 8 */
+		sensor_query->has_palm_det =
+			!!(query_buf[1] & RMI_F11_HAS_PALM_DET);
+		sensor_query->has_rotate =
+			!!(query_buf[1] & RMI_F11_HAS_ROTATE);
+		sensor_query->has_touch_shapes =
+			!!(query_buf[1] & RMI_F11_HAS_TOUCH_SHAPES);
+		sensor_query->has_scroll_zones =
+			!!(query_buf[1] & RMI_F11_HAS_SCROLL_ZONES);
+		sensor_query->has_individual_scroll_zones =
+			!!(query_buf[1] & RMI_F11_HAS_INDIVIDUAL_SCROLL_ZONES);
+		sensor_query->has_mf_scroll =
+			!!(query_buf[1] & RMI_F11_HAS_MF_SCROLL);
+		sensor_query->has_mf_edge_motion =
+			!!(query_buf[1] & RMI_F11_HAS_MF_EDGE_MOTION);
+		sensor_query->has_mf_scroll_inertia =
+			!!(query_buf[1] & RMI_F11_HAS_MF_SCROLL_INERTIA);
+
+		sensor_query->query7_nonzero = !!(query_buf[0]);
+		sensor_query->query8_nonzero = !!(query_buf[1]);
+
+		query_size += 2;
+	}
+
+	if (f11->has_query9) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->query9);
+
+		sensor_query->has_pen =
+			!!(query_buf[0] & RMI_F11_HAS_PEN);
+		sensor_query->has_proximity =
+			!!(query_buf[0] & RMI_F11_HAS_PROXIMITY);
+		sensor_query->has_palm_det_sensitivity =
+			!!(query_buf[0] & RMI_F11_HAS_PALM_DET_SENSITIVITY);
+		sensor_query->has_suppress_on_palm_detect =
+			!!(query_buf[0] & RMI_F11_HAS_SUPPRESS_ON_PALM_DETECT);
+		sensor_query->has_two_pen_thresholds =
+			!!(query_buf[0] & RMI_F11_HAS_TWO_PEN_THRESHOLDS);
+		sensor_query->has_contact_geometry =
+			!!(query_buf[0] & RMI_F11_HAS_CONTACT_GEOMETRY);
+		sensor_query->has_pen_hover_discrimination =
+			!!(query_buf[0] & RMI_F11_HAS_PEN_HOVER_DISCRIMINATION);
+		sensor_query->has_pen_filters =
+			!!(query_buf[0] & RMI_F11_HAS_PEN_FILTERS);
+
+		query_size++;
 	}
 
-	if (sensor_query->gesture_info.has_touch_shapes) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->ts_info,
-					sizeof(sensor_query->ts_info));
+	if (sensor_query->has_touch_shapes) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->ts_info);
+
+		sensor_query->nr_touch_shapes = query_buf[0] &
+				RMI_F11_NR_TOUCH_SHAPES_MASK;
+
+		query_size++;
 	}
 
-	if (dev_query->has_query11) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->features_1,
-					sizeof(sensor_query->features_1));
+	if (f11->has_query11) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->features_1);
+
+		sensor_query->has_z_tuning =
+			!!(query_buf[0] & RMI_F11_HAS_Z_TUNING);
+		sensor_query->has_algorithm_selection =
+			!!(query_buf[0] & RMI_F11_HAS_ALGORITHM_SELECTION);
+		sensor_query->has_w_tuning =
+			!!(query_buf[0] & RMI_F11_HAS_W_TUNING);
+		sensor_query->has_pitch_info =
+			!!(query_buf[0] & RMI_F11_HAS_PITCH_INFO);
+		sensor_query->has_finger_size =
+			!!(query_buf[0] & RMI_F11_HAS_FINGER_SIZE);
+		sensor_query->has_segmentation_aggressiveness =
+			!!(query_buf[0] &
+				RMI_F11_HAS_SEGMENTATION_AGGRESSIVENESS);
+		sensor_query->has_XY_clip =
+			!!(query_buf[0] & RMI_F11_HAS_XY_CLIP);
+		sensor_query->has_drumming_filter =
+			!!(query_buf[0] & RMI_F11_HAS_DRUMMING_FILTER);
+
+		query_size++;
 	}
 
-	if (dev_query->has_query12) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->features_2,
-					sizeof(sensor_query->features_2));
+	if (f11->has_query12) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->features_2);
+
+		sensor_query->has_gapless_finger =
+			!!(query_buf[0] & RMI_F11_HAS_GAPLESS_FINGER);
+		sensor_query->has_gapless_finger_tuning =
+			!!(query_buf[0] & RMI_F11_HAS_GAPLESS_FINGER_TUNING);
+		sensor_query->has_8bit_w =
+			!!(query_buf[0] & RMI_F11_HAS_8BIT_W);
+		sensor_query->has_adjustable_mapping =
+			!!(query_buf[0] & RMI_F11_HAS_ADJUSTABLE_MAPPING);
+		sensor_query->has_info2 =
+			!!(query_buf[0] & RMI_F11_HAS_INFO2);
+		sensor_query->has_physical_props =
+			!!(query_buf[0] & RMI_F11_HAS_PHYSICAL_PROPS);
+		sensor_query->has_finger_limit =
+			!!(query_buf[0] & RMI_F11_HAS_FINGER_LIMIT);
+		sensor_query->has_linear_coeff_2 =
+			!!(query_buf[0] & RMI_F11_HAS_LINEAR_COEFF);
+
+		query_size++;
 	}
 
-	if (sensor_query->abs_info.has_jitter_filter) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-					&sensor_query->jitter_filter,
-					sizeof(sensor_query->jitter_filter));
+	if (sensor_query->has_jitter_filter) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->jitter_filter);
+
+		sensor_query->jitter_window_size = query_buf[0] &
+			RMI_F11_JITTER_WINDOW_MASK;
+		sensor_query->jitter_filter_type = (query_buf[0] &
+			RMI_F11_JITTER_FILTER_MASK) >>
+			RMI_F11_JITTER_FILTER_SHIFT;
+
+		query_size++;
 	}
 
-	if (dev_query->has_query12 && sensor_query->features_2.has_info2) {
-		rc = rmi_read_block(rmi_dev, query_base_addr + query_size,
-				    &sensor_query->info_2,
-					sizeof(sensor_query->info_2));
+	if (f11->has_query12 && sensor_query->has_info2) {
+		rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
 		if (rc < 0)
 			return rc;
-		query_size += sizeof(sensor_query->info_2);
+
+		sensor_query->light_control =
+			query_buf[0] & RMI_F11_LIGHT_CONTROL_MASK;
+		sensor_query->is_clear =
+			!!(query_buf[0] & RMI_F11_IS_CLEAR);
+		sensor_query->clickpad_props =
+			(query_buf[0] & RMI_F11_CLICKPAD_PROPS_MASK) >>
+			RMI_F11_CLICKPAD_PROPS_SHIFT;
+		sensor_query->mouse_buttons =
+			(query_buf[0] & RMI_F11_MOUSE_BUTTONS_MASK) >>
+			RMI_F11_MOUSE_BUTTONS_SHIFT;
+		sensor_query->has_advanced_gestures =
+			!!(query_buf[0] & RMI_F11_HAS_ADVANCED_GESTURES);
+
+		query_size++;
 	}
 
 	return query_size;
@@ -1506,10 +1092,15 @@ static void f11_set_abs_params(struct rmi_function *fn)
 	struct f11_data *f11 = fn->data;
 	struct f11_2d_sensor *sensor = &f11->sensor;
 	struct input_dev *input = sensor->input;
-	u16 device_x_max =
-		f11->dev_controls.ctrl0_9->sensor_max_x_pos;
-	u16 device_y_max =
-		f11->dev_controls.ctrl0_9->sensor_max_y_pos;
+	/* These two lines are not doing what we want them to.  So we use
+	 * some shifts instead.
+	int device_x_max = le16_to_cpu(*(f11->dev_controls.ctrl0_9 + 6));
+	int device_y_max = le16_to_cpu(*(f11->dev_controls.ctrl0_9 + 8));
+	 */
+	u16 device_x_max = f11->dev_controls.ctrl0_9[6] |
+			((f11->dev_controls.ctrl0_9[7] & 0x0F) << 8);
+	u16 device_y_max = f11->dev_controls.ctrl0_9[8] |
+			((f11->dev_controls.ctrl0_9[9] & 0x0F) << 8);
 	u16 x_min, x_max, y_min, y_max;
 	unsigned int input_flags;
 
@@ -1517,8 +1108,8 @@ static void f11_set_abs_params(struct rmi_function *fn)
 	 * as a touchpad in the platform data
 	 */
 	if (sensor->sensor_type == rmi_f11_sensor_touchpad ||
-			(sensor->sens_query.features_2.has_info2 &&
-				!sensor->sens_query.info_2.is_clear))
+			(sensor->sens_query.has_info2 &&
+				!sensor->sens_query.is_clear))
 		input_flags = INPUT_PROP_POINTER;
 	else
 		input_flags = INPUT_PROP_DIRECT;
@@ -1567,8 +1158,7 @@ static void f11_set_abs_params(struct rmi_function *fn)
 			y_min, y_max, 0, 0);
 	if (!sensor->type_a)
 		input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
-	if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
-			sensor->sens_query.query9.has_pen)
+	if (IS_ENABLED(CONFIG_RMI4_F11_PEN) && sensor->sens_query.has_pen)
 		input_set_abs_params(input, ABS_MT_TOOL_TYPE,
 				     0, MT_TOOL_MAX, 0, 0);
 	else
@@ -1588,6 +1178,7 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	int rc;
 	struct rmi_device_platform_data *pdata = to_rmi_platform_data(rmi_dev);
 	struct f11_2d_sensor *sensor;
+	u8 buf;
 
 	dev_dbg(&fn->dev, "Initializing F11 values for %s.\n",
 		 pdata->sensor_name);
@@ -1605,29 +1196,26 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	query_base_addr = fn->fd.query_base_addr;
 	control_base_addr = fn->fd.control_base_addr;
 
-	rc = rmi_read(rmi_dev, query_base_addr, &f11->dev_query);
+	rc = rmi_read(rmi_dev, query_base_addr, &buf);
 	if (rc < 0)
 		return rc;
 
+	f11->has_query9 = !!(buf & RMI_F11_HAS_QUERY9);
+	f11->has_query11 = !!(buf & RMI_F11_HAS_QUERY11);
+	f11->has_query12 = !!(buf & RMI_F11_HAS_QUERY12);
+	f11->has_query27 = !!(buf & RMI_F11_HAS_QUERY27);
+	f11->has_query28 = !!(buf & RMI_F11_HAS_QUERY28);
+
 	query_offset = (query_base_addr + 1);
 	sensor = &f11->sensor;
 	sensor->fn = fn;
 
-	rc = rmi_f11_get_query_parameters(rmi_dev, &f11->dev_query,
+	rc = rmi_f11_get_query_parameters(rmi_dev, f11,
 			&sensor->sens_query, query_offset);
 	if (rc < 0)
 		return rc;
 	query_offset += rc;
 
-	rc = f11_allocate_control_regs(fn,
-			&f11->dev_query, &sensor->sens_query,
-			&f11->dev_controls, control_base_addr);
-	if (rc < 0) {
-		dev_err(&fn->dev,
-			"Failed to allocate F11 control params.\n");
-		return rc;
-	}
-
 	rc = f11_read_control_regs(fn, &f11->dev_controls,
 			control_base_addr);
 	if (rc < 0) {
@@ -1670,12 +1258,11 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 
 	ctrl = &f11->dev_controls;
 	if (sensor->axis_align.delta_x_threshold) {
-		ctrl->ctrl0_9->delta_x_threshold =
+		ctrl->ctrl0_9[RMI_F11_DELTA_X_THRESHOLD] =
 			sensor->axis_align.delta_x_threshold;
-		rc = rmi_write_block(rmi_dev,
-				ctrl->ctrl0_9_address,
+		rc = rmi_write_block(rmi_dev, ctrl->ctrl0_9_address,
 				ctrl->ctrl0_9,
-				sizeof(*ctrl->ctrl0_9));
+				RMI_F11_CTRL_REG_COUNT);
 		if (rc < 0)
 			dev_warn(&fn->dev, "Failed to write to delta_x_threshold. Code: %d.\n",
 				rc);
@@ -1683,12 +1270,10 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	}
 
 	if (sensor->axis_align.delta_y_threshold) {
-		ctrl->ctrl0_9->delta_y_threshold =
+		ctrl->ctrl0_9[RMI_F11_DELTA_Y_THRESHOLD] =
 			sensor->axis_align.delta_y_threshold;
-		rc = rmi_write_block(rmi_dev,
-				ctrl->ctrl0_9_address,
-				ctrl->ctrl0_9,
-				sizeof(*ctrl->ctrl0_9));
+		rc = rmi_write_block(rmi_dev, ctrl->ctrl0_9_address,
+				ctrl->ctrl0_9, RMI_F11_CTRL_REG_COUNT);
 		if (rc < 0)
 			dev_warn(&fn->dev, "Failed to write to delta_y_threshold. Code: %d.\n",
 				rc);
@@ -1737,7 +1322,7 @@ static int rmi_f11_register_devices(struct rmi_function *fn)
 
 	f11_set_abs_params(fn);
 
-	if (sensor->sens_query.info.has_rel) {
+	if (sensor->sens_query.has_rel) {
 		set_bit(EV_REL, input_dev->evbit);
 		set_bit(REL_X, input_dev->relbit);
 		set_bit(REL_Y, input_dev->relbit);
@@ -1749,7 +1334,7 @@ static int rmi_f11_register_devices(struct rmi_function *fn)
 		goto error_unregister;
 	}
 
-	if (sensor->sens_query.info.has_rel) {
+	if (sensor->sens_query.has_rel) {
 		/*create input device for mouse events  */
 		input_dev_mouse = input_allocate_device();
 		if (!input_dev_mouse) {
@@ -1857,10 +1442,6 @@ static int rmi_f11_resume(struct device *dev)
 	struct rmi_function *fn = to_rmi_function(dev);
 	struct rmi_device *rmi_dev = fn->rmi_dev;
 	struct f11_data *data = fn->data;
-	/* Command register always reads as 0, so we can just use a local. */
-	struct f11_2d_commands commands = {
-		.rezero = true,
-	};
 	int error;
 
 	dev_dbg(&fn->dev, "Resuming...\n");
@@ -1869,8 +1450,7 @@ static int rmi_f11_resume(struct device *dev)
 
 	mdelay(data->rezero_wait_ms);
 
-	error = rmi_write_block(rmi_dev, fn->fd.command_base_addr,
-				&commands, sizeof(commands));
+	error = rmi_write(rmi_dev, fn->fd.command_base_addr, RMI_F11_REZERO);
 	if (error < 0) {
 		dev_err(&fn->dev,
 			"%s: failed to issue rezero command, error = %d.",

^ permalink raw reply related

* [PATCH] input synaptics-rmi4: Debugfs initialization fixes
From: Christopher Heiny @ 2013-12-11  2:12 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
	Vivian Ly, Daniel Rosenberg, Jean Delvare, Joerie de Gram,
	Linus Walleij, Benjamin Tissoires

This fixes the broken #ifdefs on CONFIG_RMI4_DEBUG.  Per device debugfs
setup is reordered to ensure that the debugfs tree for a given device is
created before it is registered (since the action of registering a device
may cause other things to happen that depend on debugfs being initialized
already).

Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Joerie de Gram <j.de.gram@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>

---

This patch implements changes to the synaptics-rmi4 branch of
Dmitry's input tree.  The base for the patch is commit
f154022b208a59b048f52b7b5d58a5ec1949b96e.

 drivers/input/rmi4/rmi_bus.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index cb14cf6..173f6be 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -47,7 +47,7 @@ bool rmi_is_physical_device(struct device *dev)
 	return dev->type == &rmi_device_type;
 }
 
-#if CONFIG_RMI4_DEBUG
+#ifdef CONFIG_RMI4_DEBUG
 
 static void rmi_physical_setup_debugfs(struct rmi_device *rmi_dev)
 {
@@ -109,12 +109,12 @@ int rmi_register_physical_device(struct rmi_phys_device *phys)
 
 	phys->rmi_dev = rmi_dev;
 
+	rmi_physical_setup_debugfs(rmi_dev);
+
 	error = device_register(&rmi_dev->dev);
 	if (error)
 		return error;
 
-	rmi_physical_setup_debugfs(rmi_dev);
-
 	dev_dbg(phys->dev, "%s: Registered %s as %s.\n", __func__,
 		pdata->sensor_name, dev_name(&rmi_dev->dev));
 
@@ -155,7 +155,7 @@ bool rmi_is_function_device(struct device *dev)
 	return dev->type == &rmi_function_type;
 }
 
-#if CONFIG_RMI4_DEBUG
+#ifdef CONFIG_RMI4_DEBUG
 
 static void rmi_function_setup_debugfs(struct rmi_function *fn)
 {
@@ -233,18 +233,23 @@ int rmi_register_function(struct rmi_function *fn)
 	fn->dev.type = &rmi_function_type;
 	fn->dev.bus = &rmi_bus_type;
 
+	rmi_function_setup_debugfs(fn);
+
 	error = device_register(&fn->dev);
 	if (error) {
 		dev_err(&rmi_dev->dev,
 			"Failed device_register function device %s\n",
 			dev_name(&fn->dev));
-		return error;
+		goto error_exit;
 	}
 
 	dev_dbg(&rmi_dev->dev, "Registered F%02X.\n", fn->fd.function_number);
 
-	rmi_function_setup_debugfs(fn);
 	return 0;
+
+error_exit:
+	rmi_function_teardown_debugfs(fn);
+	return error;
 }
 
 void rmi_unregister_function(struct rmi_function *fn)
@@ -357,6 +362,8 @@ static int __init rmi_bus_init(void)
 		return error;
 	}
 
+	rmi_bus_setup_debugfs();
+
 	error = rmi_register_f01_handler();
 	if (error) {
 		pr_err("%s: error registering the RMI F01 handler: %d\n",
@@ -371,13 +378,12 @@ static int __init rmi_bus_init(void)
 		goto err_unregister_f01;
 	}
 
-	rmi_bus_setup_debugfs();
-
 	return 0;
 
 err_unregister_f01:
 	rmi_unregister_f01_handler();
 err_unregister_bus:
+	rmi_bus_teardown_debugfs();
 	bus_unregister(&rmi_bus_type);
 	return error;
 }
@@ -390,9 +396,9 @@ static void __exit rmi_bus_exit(void)
 	 * all we have to do at this point is unregister ourselves.
 	 */
 
-	rmi_bus_teardown_debugfs();
 	rmi_unregister_physical_driver();
 	rmi_unregister_f01_handler();
+	rmi_bus_teardown_debugfs();
 	bus_unregister(&rmi_bus_type);
 }
 module_exit(rmi_bus_exit);

^ permalink raw reply related

* [PATCH] input: egalax: Send touch end event when is about to suspend
From: Felipe F. Tonello @ 2013-12-11  0:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-input, Andy Shevchenko, Sachin Kamat, Heiko Abraham,
	Dmitry Torokhov, Felipe F. Tonello

From: "Felipe F. Tonello" <eu@felipetonello.com>

This is useful to report for users of this device that don't know anything
about the suspension of the device. So users will receive a touch end event
when the device is about to suspend, making it more user friendly.

One example of users is the X Server with the evdev input driver. This patch
make sure that the X server will propagate a touch end event to its windows.

Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
---
 drivers/input/touchscreen/egalax_ts.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 054d225..1f21f0d 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -63,6 +63,7 @@
 struct egalax_ts {
 	struct i2c_client		*client;
 	struct input_dev		*input_dev;
+	bool					ids_in_use[MAX_SUPPORT_POINTS];
 };
 
 static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
@@ -117,6 +118,8 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
 	input_mt_report_pointer_emulation(input_dev, true);
 	input_sync(input_dev);
 
+	ts->ids_in_use[id] = down;
+
 	return IRQ_HANDLED;
 }
 
@@ -247,9 +250,22 @@ static int egalax_ts_suspend(struct device *dev)
 		0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0
 	};
 	struct i2c_client *client = to_i2c_client(dev);
-	int ret;
+	struct egalax_ts *ts = i2c_get_clientdata(client);
+	int ret, id;
 
 	ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN);
+
+	/* We send a touch end event (for the ids in use) if the egalax module is
+	   about to be turned off. */
+	for (id = 0; id < MAX_SUPPORT_POINTS; ++id) {
+		if (ts->ids_in_use[id]) {
+			input_mt_slot(ts->input_dev, id);
+			input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
+			input_mt_report_pointer_emulation(ts->input_dev, true);
+			input_sync(ts->input_dev);
+		}
+	}
+
 	return ret > 0 ? 0 : ret;
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 7/7] Input: pmic8xxx-keypad - Migrate to regmap APIs
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Use the regmap APIs for this driver instead of custom pm8xxx
APIs. This breaks this driver's dependency on the pm8xxx APIs and
allows us to easily port it to other bus protocols in the future.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/keyboard/pmic8xxx-keypad.c | 81 ++++++++++++--------------------
 1 file changed, 29 insertions(+), 52 deletions(-)

diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index 4e6bfbf..c6d3d21 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -19,8 +19,8 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/regmap.h>
 
-#include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/gpio.h>
 #include <linux/input/pmic8xxx-keypad.h>
 
@@ -87,6 +87,7 @@
  * struct pmic8xxx_kp - internal keypad data structure
  * @pdata - keypad platform data pointer
  * @input - input device pointer for keypad
+ * @regmap - regmap handle
  * @key_sense_irq - key press/release irq number
  * @key_stuck_irq - key stuck notification irq number
  * @keycodes - array to hold the key codes
@@ -98,6 +99,7 @@
 struct pmic8xxx_kp {
 	const struct pm8xxx_keypad_platform_data *pdata;
 	struct input_dev *input;
+	struct regmap *regmap;
 	int key_sense_irq;
 	int key_stuck_irq;
 
@@ -110,33 +112,6 @@ struct pmic8xxx_kp {
 	u8 ctrl_reg;
 };
 
-static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp,
-				 u8 data, u16 reg)
-{
-	int rc;
-
-	rc = pm8xxx_writeb(kp->dev->parent, reg, data);
-	return rc;
-}
-
-static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp,
-				 u8 *data, u16 reg, unsigned num_bytes)
-{
-	int rc;
-
-	rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes);
-	return rc;
-}
-
-static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp,
-				 u8 *data, u16 reg)
-{
-	int rc;
-
-	rc = pmic8xxx_kp_read(kp, data, reg, 1);
-	return rc;
-}
-
 static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col)
 {
 	/* all keys pressed on that particular row? */
@@ -161,9 +136,9 @@ static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col)
 static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp)
 {
 	int rc;
-	u8 scan_val;
+	unsigned int scan_val;
 
-	rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN);
+	rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val);
 	if (rc < 0) {
 		dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc);
 		return rc;
@@ -171,7 +146,7 @@ static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp)
 
 	scan_val |= 0x1;
 
-	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val);
 	if (rc < 0) {
 		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
 		return rc;
@@ -187,26 +162,24 @@ static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state,
 					u16 data_reg, int read_rows)
 {
 	int rc, row;
-	u8 new_data[PM8XXX_MAX_ROWS];
+	unsigned int val;
 
-	rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows);
-	if (rc)
-		return rc;
-
-	for (row = 0; row < kp->pdata->num_rows; row++) {
-		dev_dbg(kp->dev, "new_data[%d] = %d\n", row,
-					new_data[row]);
-		state[row] = pmic8xxx_col_state(kp, new_data[row]);
+	for (row = 0; row < read_rows; row++) {
+		rc = regmap_read(kp->regmap, data_reg, &val);
+		if (rc)
+			return rc;
+		dev_dbg(kp->dev, "%d = %d\n", row, val);
+		state[row] = pmic8xxx_col_state(kp, val);
 	}
 
-	return rc;
+	return 0;
 }
 
 static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
 					 u16 *old_state)
 {
 	int rc, read_rows;
-	u8 scan_val;
+	unsigned int scan_val;
 
 	if (kp->pdata->num_rows < PM8XXX_MIN_ROWS)
 		read_rows = PM8XXX_MIN_ROWS;
@@ -236,14 +209,14 @@ static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
 	/* 4 * 32KHz clocks */
 	udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
 
-	rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN);
+	rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val);
 	if (rc < 0) {
 		dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc);
 		return rc;
 	}
 
 	scan_val &= 0xFE;
-	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val);
 	if (rc < 0)
 		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
 
@@ -379,10 +352,10 @@ static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data)
 static irqreturn_t pmic8xxx_kp_irq(int irq, void *data)
 {
 	struct pmic8xxx_kp *kp = data;
-	u8 ctrl_val, events;
+	unsigned int ctrl_val, events;
 	int rc;
 
-	rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1);
+	rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val);
 	if (rc < 0) {
 		dev_err(kp->dev, "failed to read keyp_ctrl register\n");
 		return IRQ_HANDLED;
@@ -421,7 +394,7 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp)
 
 	ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT);
 
-	rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL);
+	rc = regmap_write(kp->regmap, KEYP_CTRL, ctrl_val);
 	if (rc < 0) {
 		dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc);
 		return rc;
@@ -439,7 +412,7 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp)
 
 	scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT);
 
-	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val);
 	if (rc)
 		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
 
@@ -474,7 +447,7 @@ static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp)
 
 	kp->ctrl_reg |= KEYP_CTRL_KEYP_EN;
 
-	rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL);
+	rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg);
 	if (rc < 0)
 		dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc);
 
@@ -487,7 +460,7 @@ static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp)
 
 	kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN;
 
-	rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL);
+	rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg);
 	if (rc < 0)
 		return rc;
 
@@ -525,7 +498,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 	const struct matrix_keymap_data *keymap_data;
 	struct pmic8xxx_kp *kp;
 	int rc;
-	u8 ctrl_val;
+	unsigned int ctrl_val;
 
 	struct pm_gpio kypd_drv = {
 		.direction	= PM_GPIO_DIR_OUT,
@@ -590,6 +563,10 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 	if (!kp)
 		return -ENOMEM;
 
+	kp->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!kp->regmap)
+		return -ENODEV;
+
 	platform_set_drvdata(pdev, kp);
 
 	kp->pdata	= pdata;
@@ -678,7 +655,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 		return rc;
 	}
 
-	rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
+	rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
 		return rc;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related

* [PATCH 3/7] Input: pm8xxx-vibrator - Migrate to devm_* APIs
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Simplify the error paths and reduce the lines of code in this
driver by using the devm_* APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/misc/pm8xxx-vibrator.c | 44 +++++++++++-------------------------
 1 file changed, 13 insertions(+), 31 deletions(-)

diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c
index ec086f6..2a92ab0 100644
--- a/drivers/input/misc/pm8xxx-vibrator.c
+++ b/drivers/input/misc/pm8xxx-vibrator.c
@@ -186,13 +186,13 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
 	int error;
 	u8 val;
 
-	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!vib || !input_dev) {
-		dev_err(&pdev->dev, "couldn't allocate memory\n");
-		error = -ENOMEM;
-		goto err_free_mem;
-	}
+	vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
+	if (!vib)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
 
 	INIT_WORK(&vib->work, pm8xxx_work_handler);
 	vib->dev = &pdev->dev;
@@ -201,17 +201,17 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
 	/* operate in manual mode */
 	error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
 	if (error < 0)
-		goto err_free_mem;
+		return error;
+
 	val &= ~VIB_DRV_EN_MANUAL_MASK;
 	error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
 	if (error < 0)
-		goto err_free_mem;
+		return error;
 
 	vib->reg_vib_drv = val;
 
 	input_dev->name = "pm8xxx_vib_ffmemless";
 	input_dev->id.version = 1;
-	input_dev->dev.parent = &pdev->dev;
 	input_dev->close = pm8xxx_vib_close;
 	input_set_drvdata(input_dev, vib);
 	input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
@@ -221,35 +221,18 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
 	if (error) {
 		dev_err(&pdev->dev,
 			"couldn't register vibrator as FF device\n");
-		goto err_free_mem;
+		return error;
 	}
 
 	error = input_register_device(input_dev);
 	if (error) {
 		dev_err(&pdev->dev, "couldn't register input device\n");
-		goto err_destroy_memless;
+		input_ff_destroy(input_dev);
+		return error;
 	}
 
 	platform_set_drvdata(pdev, vib);
 	return 0;
-
-err_destroy_memless:
-	input_ff_destroy(input_dev);
-err_free_mem:
-	input_free_device(input_dev);
-	kfree(vib);
-
-	return error;
-}
-
-static int pm8xxx_vib_remove(struct platform_device *pdev)
-{
-	struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
-
-	input_unregister_device(vib->vib_input_dev);
-	kfree(vib);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -268,7 +251,6 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
 
 static struct platform_driver pm8xxx_vib_driver = {
 	.probe		= pm8xxx_vib_probe,
-	.remove		= pm8xxx_vib_remove,
 	.driver		= {
 		.name	= "pm8xxx-vib",
 		.owner	= THIS_MODULE,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related

* [PATCH 0/7] Use regmap+devm in pm8xxx input drivers
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input,
	Thomas Gleixner

These patches move the pm8xxx input drivers over to use devm_* APIs
and regmap. This breaks the dependency of these drivers on the pm8xxx
specific read/write calls and also simplifies the probe code a bit.

There was no devm_request_any_context_irq() available, so I've added
it here.

Stephen Boyd (7):
  Input: pmic8xxx-pwrkey - Pass input device directly to interrupt
  Input: pmic8xxx-pwrkey - Migrate to regmap APIs
  Input: pm8xxx-vibrator - Migrate to devm_* APIs
  Input: pm8xxx-vibrator - Migrate to regmap APIs
  genirq: Add devm_request_any_context_irq()
  Input: pmic8xxx-keypad - Migrate to devm_* APIs
  Input: pmic8xxx-keypad - Migrate to regmap APIs

 drivers/input/keyboard/pmic8xxx-keypad.c | 143 ++++++++++---------------------
 drivers/input/misc/pm8xxx-vibrator.c     | 107 ++++++-----------------
 drivers/input/misc/pmic8xxx-pwrkey.c     |  35 ++++----
 include/linux/interrupt.h                |   5 ++
 kernel/irq/devres.c                      |  45 ++++++++++
 5 files changed, 141 insertions(+), 194 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply

* [PATCH 6/7] Input: pmic8xxx-keypad - Migrate to devm_* APIs
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Simplify the error paths and reduce the lines of code in this
driver by using the devm_* APIs.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/keyboard/pmic8xxx-keypad.c | 62 +++++++++-----------------------
 1 file changed, 17 insertions(+), 45 deletions(-)

diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index 2c9f19a..4e6bfbf 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -586,7 +586,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	kp = kzalloc(sizeof(*kp), GFP_KERNEL);
+	kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL);
 	if (!kp)
 		return -ENOMEM;
 
@@ -595,32 +595,27 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 	kp->pdata	= pdata;
 	kp->dev		= &pdev->dev;
 
-	kp->input = input_allocate_device();
+	kp->input = devm_input_allocate_device(&pdev->dev);
 	if (!kp->input) {
 		dev_err(&pdev->dev, "unable to allocate input device\n");
-		rc = -ENOMEM;
-		goto err_alloc_device;
+		return -ENOMEM;
 	}
 
 	kp->key_sense_irq = platform_get_irq(pdev, 0);
 	if (kp->key_sense_irq < 0) {
 		dev_err(&pdev->dev, "unable to get keypad sense irq\n");
-		rc = -ENXIO;
-		goto err_get_irq;
+		return kp->key_sense_irq;
 	}
 
 	kp->key_stuck_irq = platform_get_irq(pdev, 1);
 	if (kp->key_stuck_irq < 0) {
 		dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
-		rc = -ENXIO;
-		goto err_get_irq;
+		return kp->key_stuck_irq;
 	}
 
 	kp->input->name = pdata->input_name ? : "PMIC8XXX keypad";
 	kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0";
 
-	kp->input->dev.parent	= &pdev->dev;
-
 	kp->input->id.bustype	= BUS_I2C;
 	kp->input->id.version	= 0x0001;
 	kp->input->id.product	= 0x0001;
@@ -634,7 +629,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 					kp->keycodes, kp->input);
 	if (rc) {
 		dev_err(&pdev->dev, "failed to build keymap\n");
-		goto err_get_irq;
+		return rc;
 	}
 
 	if (pdata->rep)
@@ -650,7 +645,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 	rc = pmic8xxx_kpd_init(kp);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "unable to initialize keypad controller\n");
-		goto err_get_irq;
+		return rc;
 	}
 
 	rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start,
@@ -667,24 +662,26 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 		goto err_gpio_config;
 	}
 
-	rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq,
-				 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
+	rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq,
+			pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad",
+			kp);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to request keypad sense irq\n");
-		goto err_get_irq;
+		return rc;
 	}
 
-	rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq,
-				 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
+	rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq,
+			pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING,
+			"pmic-keypad-stuck", kp);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
-		goto err_req_stuck_irq;
+		return rc;
 	}
 
 	rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
-		goto err_pmic_reg_read;
+		return rc;
 	}
 
 	kp->ctrl_reg = ctrl_val;
@@ -692,36 +689,12 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
 	rc = input_register_device(kp->input);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "unable to register keypad input device\n");
-		goto err_pmic_reg_read;
+		return rc;
 	}
 
 	device_init_wakeup(&pdev->dev, pdata->wakeup);
 
 	return 0;
-
-err_pmic_reg_read:
-	free_irq(kp->key_stuck_irq, kp);
-err_req_stuck_irq:
-	free_irq(kp->key_sense_irq, kp);
-err_gpio_config:
-err_get_irq:
-	input_free_device(kp->input);
-err_alloc_device:
-	kfree(kp);
-	return rc;
-}
-
-static int pmic8xxx_kp_remove(struct platform_device *pdev)
-{
-	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
-
-	device_init_wakeup(&pdev->dev, 0);
-	free_irq(kp->key_stuck_irq, kp);
-	free_irq(kp->key_sense_irq, kp);
-	input_unregister_device(kp->input);
-	kfree(kp);
-
-	return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -771,7 +744,6 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
 
 static struct platform_driver pmic8xxx_kp_driver = {
 	.probe		= pmic8xxx_kp_probe,
-	.remove		= pmic8xxx_kp_remove,
 	.driver		= {
 		.name = PM8XXX_KEYPAD_DEV_NAME,
 		.owner = THIS_MODULE,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH 5/7] genirq: Add devm_request_any_context_irq()
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input,
	Thomas Gleixner
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Some drivers use request_any_context_irq() but there isn't a
devm_* function for it. Add one so that these drivers don't need
to explicitly free the irq on driver detach.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 include/linux/interrupt.h |  5 +++++
 kernel/irq/devres.c       | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index c9e831d..8334f9b 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -160,6 +160,11 @@ devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
 					 devname, dev_id);
 }
 
+extern int __must_check
+devm_request_any_context_irq(struct device *dev, unsigned int irq,
+		 irq_handler_t handler, unsigned long irqflags,
+		 const char *devname, void *dev_id);
+
 extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
 
 /*
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index bd8e788..f71e9ff 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -73,6 +73,51 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
 EXPORT_SYMBOL(devm_request_threaded_irq);
 
 /**
+ *	devm_request_any_context_irq - allocate an interrupt line for a managed device
+ *	@dev: device to request interrupt for
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@thread_fn: function to be called in a threaded interrupt context. NULL
+ *		    for devices which handle everything in @handler
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	Except for the extra @dev argument, this function takes the
+ *	same arguments and performs the same function as
+ *	request_any_context_irq().  IRQs requested with this function will be
+ *	automatically freed on driver detach.
+ *
+ *	If an IRQ allocated with this function needs to be freed
+ *	separately, devm_free_irq() must be used.
+ */
+int devm_request_any_context_irq(struct device *dev, unsigned int irq,
+			      irq_handler_t handler, unsigned long irqflags,
+			      const char *devname, void *dev_id)
+{
+	struct irq_devres *dr;
+	int rc;
+
+	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
+			  GFP_KERNEL);
+	if (!dr)
+		return -ENOMEM;
+
+	rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
+	if (rc) {
+		devres_free(dr);
+		return rc;
+	}
+
+	dr->irq = irq;
+	dr->dev_id = dev_id;
+	devres_add(dev, dr);
+
+	return 0;
+}
+EXPORT_SYMBOL(devm_request_any_context_irq);
+
+/**
  *	devm_free_irq - free an interrupt
  *	@dev: device to free interrupt for
  *	@irq: Interrupt line to free
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH 4/7] Input: pm8xxx-vibrator - Migrate to regmap APIs
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Use the regmap APIs for this driver instead of custom pm8xxx
APIs. This breaks this driver's dependency on the pm8xxx APIs and
allows us to easily port it to other bus protocols in the future.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/misc/pm8xxx-vibrator.c | 61 +++++++++---------------------------
 1 file changed, 14 insertions(+), 47 deletions(-)

diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c
index 2a92ab0..cb5a8e8f 100644
--- a/drivers/input/misc/pm8xxx-vibrator.c
+++ b/drivers/input/misc/pm8xxx-vibrator.c
@@ -17,7 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/slab.h>
-#include <linux/mfd/pm8xxx/core.h>
+#include <linux/regmap.h>
 
 #define VIB_DRV			0x4A
 
@@ -35,7 +35,7 @@
  * struct pm8xxx_vib - structure to hold vibrator data
  * @vib_input_dev: input device supporting force feedback
  * @work: work structure to set the vibration parameters
- * @dev: device supporting force feedback
+ * @regmap: regmap for register read/write
  * @speed: speed of vibration set from userland
  * @active: state of vibrator
  * @level: level of vibration to set in the chip
@@ -44,7 +44,7 @@
 struct pm8xxx_vib {
 	struct input_dev *vib_input_dev;
 	struct work_struct work;
-	struct device *dev;
+	struct regmap *regmap;
 	int speed;
 	int level;
 	bool active;
@@ -52,42 +52,6 @@ struct pm8xxx_vib {
 };
 
 /**
- * pm8xxx_vib_read_u8 - helper to read a byte from pmic chip
- * @vib: pointer to vibrator structure
- * @data: placeholder for data to be read
- * @reg: register address
- */
-static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
-				 u8 *data, u16 reg)
-{
-	int rc;
-
-	rc = pm8xxx_readb(vib->dev->parent, reg, data);
-	if (rc < 0)
-		dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
-				reg, rc);
-	return rc;
-}
-
-/**
- * pm8xxx_vib_write_u8 - helper to write a byte to pmic chip
- * @vib: pointer to vibrator structure
- * @data: data to write
- * @reg: register address
- */
-static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
-				 u8 data, u16 reg)
-{
-	int rc;
-
-	rc = pm8xxx_writeb(vib->dev->parent, reg, data);
-	if (rc < 0)
-		dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
-				reg, rc);
-	return rc;
-}
-
-/**
  * pm8xxx_vib_set - handler to start/stop vibration
  * @vib: pointer to vibrator structure
  * @on: state to set
@@ -95,14 +59,14 @@ static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
 {
 	int rc;
-	u8 val = vib->reg_vib_drv;
+	unsigned int val = vib->reg_vib_drv;
 
 	if (on)
 		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
 	else
 		val &= ~VIB_DRV_SEL_MASK;
 
-	rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
+	rc = regmap_write(vib->regmap, VIB_DRV, val);
 	if (rc < 0)
 		return rc;
 
@@ -118,9 +82,9 @@ static void pm8xxx_work_handler(struct work_struct *work)
 {
 	struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
 	int rc;
-	u8 val;
+	unsigned int val;
 
-	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
+	rc = regmap_read(vib->regmap, VIB_DRV, &val);
 	if (rc < 0)
 		return;
 
@@ -184,27 +148,30 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
 	struct pm8xxx_vib *vib;
 	struct input_dev *input_dev;
 	int error;
-	u8 val;
+	unsigned int val;
 
 	vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
 	if (!vib)
 		return -ENOMEM;
 
+	vib->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!vib->regmap)
+		return -ENODEV;
+
 	input_dev = devm_input_allocate_device(&pdev->dev);
 	if (!input_dev)
 		return -ENOMEM;
 
 	INIT_WORK(&vib->work, pm8xxx_work_handler);
-	vib->dev = &pdev->dev;
 	vib->vib_input_dev = input_dev;
 
 	/* operate in manual mode */
-	error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
+	error = regmap_read(vib->regmap, VIB_DRV, &val);
 	if (error < 0)
 		return error;
 
 	val &= ~VIB_DRV_EN_MANUAL_MASK;
-	error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
+	error = regmap_write(vib->regmap, VIB_DRV, val);
 	if (error < 0)
 		return error;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH 2/7] Input: pmic8xxx-pwrkey - Migrate to regmap APIs
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Use the regmap APIs for this driver instead of custom pm8xxx
APIs. This breaks this driver's dependency on the pm8xxx APIs and
allows us to easily port it to other bus protocols in the future.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/misc/pmic8xxx-pwrkey.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index 233b216..a4de105 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -18,9 +18,9 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/log2.h>
 
-#include <linux/mfd/pm8xxx/core.h>
 #include <linux/input/pmic8xxx-pwrkey.h>
 
 #define PON_CNTL_1 0x1C
@@ -83,7 +83,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 	int key_press_irq = platform_get_irq(pdev, 1);
 	int err;
 	unsigned int delay;
-	u8 pon_cntl;
+	unsigned int pon_cntl;
+	struct regmap *regmap;
 	struct pmic8xxx_pwrkey *pwrkey;
 	const struct pm8xxx_pwrkey_platform_data *pdata =
 					dev_get_platdata(&pdev->dev);
@@ -108,6 +109,10 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 		err = -ENOMEM;
 	}
 
+	regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
 	input_set_capability(pwr, EV_KEY, KEY_POWER);
 
 	pwr->name = "pmic8xxx_pwrkey";
@@ -116,7 +121,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 	delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC;
 	delay = 1 + ilog2(delay);
 
-	err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl);
+	err = regmap_read(regmap, PON_CNTL_1, &pon_cntl);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err);
 		return err;
@@ -129,7 +134,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 	else
 		pon_cntl &= ~PON_CNTL_PULL_UP;
 
-	err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl);
+	err = regmap_write(regmap, PON_CNTL_1, pon_cntl);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err);
 		return err;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [PATCH 1/7] Input: pmic8xxx-pwrkey - Pass input device directly to interrupt
From: Stephen Boyd @ 2013-12-10 23:43 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input
In-Reply-To: <1386718996-3733-1-git-send-email-sboyd@codeaurora.org>

Instead of passing the pointer to the container structure just
pass the input device here. This saves a dereference in the fast
path.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/input/misc/pmic8xxx-pwrkey.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index ce3c426..233b216 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -32,26 +32,21 @@
  * @key_press_irq: key press irq number
  */
 struct pmic8xxx_pwrkey {
-	struct input_dev *pwr;
 	int key_press_irq;
 };
 
-static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey)
+static irqreturn_t pwrkey_press_irq(int irq, void *pwr)
 {
-	struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
-
-	input_report_key(pwrkey->pwr, KEY_POWER, 1);
-	input_sync(pwrkey->pwr);
+	input_report_key(pwr, KEY_POWER, 1);
+	input_sync(pwr);
 
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey)
+static irqreturn_t pwrkey_release_irq(int irq, void *pwr)
 {
-	struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
-
-	input_report_key(pwrkey->pwr, KEY_POWER, 0);
-	input_sync(pwrkey->pwr);
+	input_report_key(pwr, KEY_POWER, 0);
+	input_sync(pwr);
 
 	return IRQ_HANDLED;
 }
@@ -147,12 +142,11 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 	}
 
 	pwrkey->key_press_irq = key_press_irq;
-	pwrkey->pwr = pwr;
 
 	platform_set_drvdata(pdev, pwrkey);
 
 	err = devm_request_irq(&pdev->dev, key_press_irq, pwrkey_press_irq,
-		IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey);
+		IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwr);
 	if (err < 0) {
 		dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
 				 key_press_irq, err);
@@ -160,7 +154,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
 	}
 
 	err = devm_request_irq(&pdev->dev, key_release_irq, pwrkey_release_irq,
-		 IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey);
+		 IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwr);
 	if (err < 0) {
 		dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
 				 key_release_irq, err);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* Re: [PATCH V2] Input: define KEY_WWAN for Wireless WAN
From: Jiri Kosina @ 2013-12-10 19:36 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: linux-input, Hauke Mehrtens, Dmitry Torokhov
In-Reply-To: <1386671349-16337-1-git-send-email-zajec5@gmail.com>

On Tue, 10 Dec 2013, Rafał Miłecki wrote:

> Some devices with support for mobile networks may have buttons for
> enabling/disabling such connection. An example can be Linksys router
> 54G3G.
> We already have KEY_BLUETOOTH, KEY_WLAN and KEY_UWB so it makes sense
> to add KEY_WWAN as well.
> As we already have KEY_WIMAX, use it's value for KEY_WWAN and make it an
> alias.
> 
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
> V2: Re-use 246 value for WWAN and make WIMAX an aliast to WWAN
> ---
>  include/uapi/linux/input.h |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
> index a372627..7c69941 100644
> --- a/include/uapi/linux/input.h
> +++ b/include/uapi/linux/input.h
> @@ -464,7 +464,8 @@ struct input_keymap_entry {
>  #define KEY_BRIGHTNESS_ZERO	244	/* brightness off, use ambient */
>  #define KEY_DISPLAY_OFF		245	/* display device to off state */
>  
> -#define KEY_WIMAX		246
> +#define KEY_WWAN		246	/* Wireless WAN (LTE, UMTS, GSM, etc.) */
> +#define KEY_WIMAX		KEY_WWAN
>  #define KEY_RFKILL		247	/* Key that controls all radios */
>  
>  #define KEY_MICMUTE		248	/* Mute / unmute the microphone */

Adding Dmitry to CC

-- 
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V2] input synaptics-rmi4: Reorder declarations in rmi_bus.c
From: Christopher Heiny @ 2013-12-10 17:41 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Benjamin Tissoires, Linux Input, Andrew Duggan, Vincent Huang,
	Vivian Ly, Daniel Rosenberg, Jean Delvare, Joerie de Gram,
	Linus Walleij
In-Reply-To: <20131210064624.GE12524@core.coreip.homeip.net>

On 12/09/2013 10:46 PM, Dmitry Torokhov wrote:
> On Mon, Dec 09, 2013 at 10:39:14PM -0800, Dmitry Torokhov wrote:
>> On Mon, Dec 09, 2013 at 03:14:26PM -0500, Benjamin Tissoires wrote:
>>> Hi Chris,
>>>
>>> On 05/12/13 19:29, Christopher Heiny wrote:
>>>> This patch implements changes to the synaptics-rmi4 branch of
>>>> Dmitry's input tree.  The base for the patch is commit
>>>> 8ca01dc61a42b6f7bcba052a8c084000f7057a34.
>>>>
>>>> This patch primarily reorders the various declarations in rmi_bus.c in order to
>>>> group related elements together, along with some typo fixes.  The code is still
>>>> horribly broken, but this change should make the following fixes easier to
>>>>  review.
>>>>
>>>> Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
>>>> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>>>> Cc: Jean Delvare <khali@linux-fr.org>
>>>> Cc: Linus Walleij <linus.walleij@stericsson.com>
>>>> Cc: Joerie de Gram <j.de.gram@gmail.com>
>>>> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>>>>
>>>> ---
>>>
>>> FWIW, I made a review of the patch.
>>> The patches does not only reorder the functions, but also fix some few
>>> things I will detail later (plus fixes of whitespace/comments issues).
>>> It also changes the exported functions as GPL.
>>>
>>> Dmitry, given the current state of the driver (which does not work at
>>> all if I understood correctly), maybe you can pick this one in its
>>> current state.
>>
>> Applied, thank you.
> 
> Well, I had to pull up rmi_debugfs_root declaration to avoid:
> 
>   CC [M]  drivers/input/rmi4/rmi_driver.o
> drivers/input/rmi4/rmi_bus.c: In function ‘rmi_physical_setup_debugfs’:
> drivers/input/rmi4/rmi_bus.c:51:10: error: ‘rmi_debugfs_root’ undeclared
> (first use in this function)
>           rmi_debugfs_root);
> 
> Guys, a bit better compile coverage would be appreciated.

Um, well, OK.  As mentioned in a previous patch, the code is still
horribly broken, although it's getting better.  I should have included
that previous patch's disclaimer with this one.

There's a bunch of debugfs problems in the branch as it stands, such as
failure to compile in certain configurations, kernel panics in others,
problematic initialization sequence, and so on. I was planning to fix
all that in a separate patch following this one, rather than putting
changes in piece meal, or piggybacking the changes onto another patch.

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

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox