* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Benjamin Tissoires @ 2014-07-25 14:54 UTC (permalink / raw)
To: Przemo Firszt
Cc: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
linux-kernel, linux-input
In-Reply-To: <1406295035.2664.43.camel@fedora-lan>
On Jul 25 2014 or thereabouts, Przemo Firszt wrote:
> Dnia 2014-07-25, pią o godzinie 08:58 -0400, Benjamin Tissoires pisze:
> > Hi Przemo,
> Hi Benjamin,
> > On Jul 25 2014 or thereabouts, Przemo Firszt wrote:
> > > Dnia 2014-07-24, czw o godzinie 14:13 -0400, Benjamin Tissoires pisze:
> > > [..]
> > > > Hi Przemo,
> > > Hi Benjamin,
> > > > Normally, this series contains all the bits of hid-wacom (except the custom
> > > > LED/OLED API). Please tell me if I am missing anything and if you like the
> > > > change.
> > >
> > > I can't cleanly apply your set yet to test it, so:
> >
> > Hmm, you need to apply the first series I sent on July 15th, on top of
> > Dmitry's next branch.
> >
> > http://www.spinics.net/lists/linux-input/msg32385.html
> >
> OK, thnaks!
> > > Acked-by: Przemo Firszt <przemo@firszt.eu>
> >
> > Thanks!
> >
> > >
> > > What's your plan about LED/OLED API?
> >
> > I thought I would only preserve the current, wider used, LED/OLED API and
> > just drop the one in hid-wacom. This way, g-s-d will access both
> > bluetooth and USB the same way.
> >
> > My decision was mostly guided because the support of BT in g-s-d was
> > only added recently (3.12 and backported to gnome 3.10 IIRC). And as
> > soon as these patches hit Dmitry's tree, I'll send the g-s-d patches to
> > fix all that.
>
> If I understand you correctly we cannot have the same entry point in
> sysfs for OLEDs unless we can tell userspace somehow if the tablet is
> conected over USB or over bluetooth. The hardware of Intuos4 Wireless
> over bluetooth allows only 1-bit images. The same hardware over USB
> allows 4-bit images. Formatting of the images is also completely
Holy crap! I missed that. I did not noticed the 1-bit vs 4-bits
difference :(
> different and it's not "plain". Check [1] for usb and exisitng
> hid-wacom.c/wacom_scramble function for bluetooth.
Maybe I overlooked it, but I thought that in case of USB, the scrambling
is done in user space, and in case of BT, the same scrambling made in the
kernel. They looks very similar so I thought the user-space scramble for
USB would have fit. However, the 4-bits/1-bits kills that assumption.
>
> If we want to make it consistent single entry on kernel level we
> probably have to implement image conversion in the kernel. The user land
> would always use 4-bit, plain formatted images and kernel driver would
> convert them to 4-bit, wacom usb format or 1-bit wacom bluetooth format
> depending on how the tablet is connected.
>
> The downside of this approach is that the user land wouldn't have 100%
> control over 1-bit images for bluetooth as kernel would have to create
> them from 4-bit images.
The USB interface is *very* simple:
- if incoming data != 1024 -> reject
- forward everything to the device without in kernel treatment*
How about just changing the expected size to 256 in case of a BT tablet,
and let the user-space scramble in both cases and forward proper raw
data?
This way, user space will still have control over 1-bit vs 4-bits, and
the changes required in the kernel will be small enough.
My concern is that I'd like to have this series in 3.17 and I will not
have access to the hardware until next week :/
Having all of the user-spaces breakages in the same kernel release will
I think simplify the user space work.
Cheers,
Benjamin
* speaking about that: I just noticed that hid-wacom sent the
WAC_CMD_ICON_START_STOP message twice with 0 as the second parameter.
However, the USB spec tells that you have to use 1 for 'start' and 0
for 'stop'. Rather weird that this is working with both 0 in BT mode.
>
> [1] https://lkml.org/lkml/2012/9/9/80
> --
> Kind regards,
> Przemo Firszt
>
>
--
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: Linux 3.16-rc6
From: Peter Zijlstra @ 2014-07-25 16:10 UTC (permalink / raw)
To: Waiman Long
Cc: Linus Torvalds, Borislav Petkov, Ingo Molnar,
Linux Kernel Mailing List, USB list, linux-input@vger.kernel.org
In-Reply-To: <53D16EC4.1000801@hp.com>
[-- Attachment #1: Type: text/plain, Size: 1296 bytes --]
On Thu, Jul 24, 2014 at 04:38:28PM -0400, Waiman Long wrote:
> Yes, I think I may have a solution for that.
>
> Borislav, can you apply the following patch on top of the lockdep patch to
> see if it can fix the problem?
>
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index d24e433..507a8ce 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -3595,6 +3595,12 @@ void lock_acquire(struct lockdep_map *lock, unsigned int
> raw_local_irq_save(flags);
> check_flags(flags);
>
> + /*
> + * An interrupt recursive read in interrupt context can be considered
> + * to be the same as a recursive read from checking perspective.
> + */
> + if ((read == 3) && in_interrupt())
> + read = 2;
> current->lockdep_recursion = 1;
> trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
> __lock_acquire(lock, subclass, trylock, read, check,
Just had another look at the initial patch and it cannot be right, even
with the above.
The problem is you cannot use in_interrupt() in check_deadlock().
Check_deadlock() must be context invariant, it should only test the
chain state and not rely on where or when its called.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2] Input: soc_button_array: Remove kfree on data allocated with devm_zalloc
From: Dmitry Torokhov @ 2014-07-25 16:22 UTC (permalink / raw)
To: pramod.gurav.etc
Cc: linux-input, linux-kernel, Pramod Gurav, Lejun Zhu, Sachin Kamat
In-Reply-To: <1406288074-28725-1-git-send-email-pramod.gurav@smartplayin.com>
Hi Pramod,
On Fri, Jul 25, 2014 at 05:04:34PM +0530, pramod.gurav.etc@gmail.com wrote:
> From: Pramod Gurav <pramod.gurav@smartplayin.com>
>
> This patch does below:
> - Removes kfree done on data allocated with devm_zalloc in probe
> path of the driver.
> - Adds a check on return value from devm_kzalloc which was missing
>
> CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> CC: Lejun Zhu <lejun.zhu@linux.intel.com>
> CC: Sachin Kamat <sachin.kamat@linaro.org>
>
> Signed-off-by: Pramod Gurav <pramod.gurav@smartplayin.com>
> ---
> drivers/input/misc/soc_button_array.c | 17 +++++++----------
> 1 file changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
> index 5a6334b..fc64ec6 100644
> --- a/drivers/input/misc/soc_button_array.c
> +++ b/drivers/input/misc/soc_button_array.c
> @@ -83,6 +83,9 @@ soc_button_device_create(struct pnp_dev *pdev,
> sizeof(*gpio_keys_pdata) +
> sizeof(*gpio_keys) * MAX_NBUTTONS,
> GFP_KERNEL);
> + if (!gpio_keys_pdata)
> + return ERR_PTR(-ENOMEM);
OK, that makes sense.
> +
> gpio_keys = (void *)(gpio_keys_pdata + 1);
>
> for (info = button_info; info->name; info++) {
> @@ -102,20 +105,16 @@ soc_button_device_create(struct pnp_dev *pdev,
> n_buttons++;
> }
>
> - if (n_buttons == 0) {
> - error = -ENODEV;
> - goto err_free_mem;
> - }
> + if (n_buttons == 0)
> + return ERR_PTR(-ENODEV);
But that one and the rest don't, because failure in
soc_button_device_create() does not necessarily mean that binding for
the whole device will fail. In this case we do not want unused memory
hang around.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: Linux 3.16-rc6
From: Waiman Long @ 2014-07-25 17:23 UTC (permalink / raw)
To: Borislav Petkov
Cc: Peter Zijlstra, Linus Torvalds, Ingo Molnar,
Linux Kernel Mailing List, USB list, linux-input@vger.kernel.org
In-Reply-To: <20140724214549.GU19239@pd.tnic>
On 07/24/2014 05:45 PM, Borislav Petkov wrote:
> On Thu, Jul 24, 2014 at 04:38:28PM -0400, Waiman Long wrote:
>> Borislav, can you apply the following patch on top of the lockdep
>> patch to see if it can fix the problem?
> It is too late here for me to test anything but the ingridients to
> reproduce are nothing special. Just grab a kvm guest and pick out the
> locking or so options out of the .config I sent previously. Then boot it
> a couple of times, it triggers pretty easy after a couple of tries.
>
Thank for the reply.
I was not able to reproduce the read_lock lockdep problem that you see
in your test machine. However, I saw the following lockdep warning on a
mutex when I enabled CONFIG_PROVE_LOCKING=y and CONFIG_LOCKDEP=y. My
virtual machine is based on RHEL 7 beta with xfs filesystem, and the
error happens for both plain 3.16-rc6 and tip/master+3.16-rc6.
[ 7.821723] ======================================================
[ 7.821725] [ INFO: possible circular locking dependency detected ]
[ 7.821727] 3.16.0-rc6 #4 Not tainted
[ 7.821727] -------------------------------------------------------
[ 7.821728] kworker/3:1/276 is trying to acquire lock:
[ 7.821747] (&qdev->release_mutex){+.+.+.}, at: [<ffffffffa0151a2c>]
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.821749]
[ 7.821749] but task is already holding lock:
[ 7.821763] (&fbdefio->lock){+.+.+.}, at: [<ffffffff8135ea65>]
fb_deferred_io_work+0x35/0xd0
[ 7.821765]
[ 7.821765] which lock already depends on the new lock.
[ 7.821765]
[ 7.821766]
[ 7.821766] the existing dependency chain (in reverse order) is:
[ 7.821770]
[ 7.821770] -> #4 (&fbdefio->lock){+.+.+.}:
[ 7.821781] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.821785] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.821793] [<ffffffff81636add>] mutex_lock_nested+0x5d/0x4d0
[ 7.821796] [<ffffffff8135e866>] fb_deferred_io_mkwrite+0x46/0x120
[ 7.821803] [<ffffffff8118534d>] do_page_mkwrite+0x3d/0x70
[ 7.821807] [<ffffffff81188376>]
do_shared_fault.isra.52+0x66/0x1d0
[ 7.821811] [<ffffffff81189524>] handle_mm_fault+0x474/0x1080
[ 7.821819] [<ffffffff81048ea1>] __do_page_fault+0x191/0x530
[ 7.821822] [<ffffffff810492f1>] trace_do_page_fault+0x41/0x100
[ 7.821828] [<ffffffff81043569>] do_async_page_fault+0x29/0xe0
[ 7.821834] [<ffffffff8163d608>] async_page_fault+0x28/0x30
[ 7.821841]
[ 7.821841] -> #3 (&mm->mmap_sem){++++++}:
[ 7.821844] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.821846] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.821849] [<ffffffff81185220>] might_fault+0x70/0xa0
[ 7.821858] [<ffffffff811e4ad1>] filldir+0x91/0x120
[ 7.821904] [<ffffffffa018253e>]
xfs_dir2_block_getdents.isra.12+0x1ae/0x200 [xfs]
[ 7.821916] [<ffffffffa01826f9>] xfs_readdir+0x109/0x150 [xfs]
[ 7.821928] [<ffffffffa018436b>] xfs_file_readdir+0x2b/0x40 [xfs]
[ 7.821931] [<ffffffff811e48be>] iterate_dir+0xae/0x140
[ 7.821933] [<ffffffff811e4dba>] SyS_getdents+0x8a/0x120
[ 7.821935] [<ffffffff8163b6e9>] system_call_fastpath+0x16/0x1b
[ 7.821937]
[ 7.821937] -> #2 (&xfs_dir_ilock_class){++++.+}:
[ 7.821940] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.821942] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.821945] [<ffffffff810abd74>] down_read_nested+0x44/0x90
[ 7.821965] [<ffffffffa01c8d82>] xfs_ilock+0xd2/0x100 [xfs]
[ 7.821982] [<ffffffffa01c8e24>]
xfs_ilock_attr_map_shared+0x34/0x40 [xfs]
[ 7.821997] [<ffffffffa019e5a7>] xfs_attr_get+0xb7/0x160 [xfs]
[ 7.822013] [<ffffffffa01986a7>] xfs_xattr_get+0x37/0x50 [xfs]
[ 7.822013] [<ffffffff811f6a7f>] generic_getxattr+0x4f/0x70
[ 7.822013] [<ffffffff8127ce60>]
inode_doinit_with_dentry+0x150/0x640
[ 7.822013] [<ffffffff8127d428>] sb_finish_set_opts+0xd8/0x270
[ 7.822013] [<ffffffff8127d84f>] selinux_set_mnt_opts+0x28f/0x5e0
[ 7.822013] [<ffffffff8127dc08>] superblock_doinit+0x68/0xd0
[ 7.822013] [<ffffffff8127dc80>] delayed_superblock_init+0x10/0x20
[ 7.822013] [<ffffffff811d45c2>] iterate_supers+0xb2/0x110
[ 7.822013] [<ffffffff8127e713>] selinux_complete_init+0x33/0x40
[ 7.822013] [<ffffffff8128cea4>] security_load_policy+0xf4/0x600
[ 7.822013] [<ffffffff8128008c>] sel_write_load+0xac/0x750
[ 7.822013] [<ffffffff811d0b9a>] vfs_write+0xba/0x1f0
[ 7.822013] [<ffffffff811d1749>] SyS_write+0x49/0xb0
[ 7.822013] [<ffffffff8163b6e9>] system_call_fastpath+0x16/0x1b
[ 7.822013]
[ 7.822013] -> #1 (&isec->lock){+.+.+.}:
[ 7.822013] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.822013] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.822013] [<ffffffff81636add>] mutex_lock_nested+0x5d/0x4d0
[ 7.822013] [<ffffffff8127cdb5>]
inode_doinit_with_dentry+0xa5/0x640
[ 7.822013] [<ffffffff8127defc>] selinux_d_instantiate+0x1c/0x20
[ 7.822013] [<ffffffff812732fb>] security_d_instantiate+0x1b/0x30
[ 7.822013] [<ffffffff811e8810>] d_instantiate+0x50/0x70
[ 7.822013] [<ffffffff811747f0>] __shmem_file_setup+0xe0/0x1d0
[ 7.822013] [<ffffffff811748f0>] shmem_file_setup+0x10/0x20
[ 7.822013] [<ffffffffa00d718b>] drm_gem_object_init+0x2b/0x40
[drm]
[ 7.822013] [<ffffffffa014cfce>] qxl_bo_create+0x7e/0x1a0 [qxl]
[ 7.822013] [<ffffffffa0151b50>]
qxl_alloc_release_reserved+0x190/0x200 [qxl]
[ 7.822013] [<ffffffffa014f6ec>] qxl_draw_opaque_fb+0x7c/0x390
[qxl]
[ 7.822013] [<ffffffffa014bc8e>]
qxl_fb_imageblit_internal+0x3e/0x40 [qxl]
[ 7.822013] [<ffffffffa014c17e>] qxl_fb_imageblit+0x6e/0x1a0 [qxl]
[ 7.822013] [<ffffffff813522a4>] soft_cursor+0x1b4/0x250
[ 7.822013] [<ffffffff81351b63>] bit_cursor+0x623/0x660
[ 7.822013] [<ffffffff8134df5b>] fbcon_cursor+0x13b/0x1c0
[ 7.822013] [<ffffffff813b5c98>] hide_cursor+0x28/0xa0
[ 7.822013] [<ffffffff813b77a8>] redraw_screen+0x168/0x240
[ 7.822013] [<ffffffff813b8181>] vc_do_resize+0x481/0x4b0
[ 7.822013] [<ffffffff813b81cf>] vc_resize+0x1f/0x30
[ 7.822013] [<ffffffff8134fb1c>] fbcon_init+0x35c/0x590
[ 7.822013] [<ffffffff813b5ef8>] visual_init+0xb8/0x120
[ 7.822013] [<ffffffff813b85a3>] do_bind_con_driver+0x163/0x330
[ 7.822013] [<ffffffff813b8d44>] do_take_over_console+0x114/0x1c0
[ 7.822013] [<ffffffff8134b3c3>] do_fbcon_takeover+0x63/0xd0
[ 7.822013] [<ffffffff813507a5>] fbcon_event_notify+0x6b5/0x800
[ 7.822013] [<ffffffff8108628c>] notifier_call_chain+0x4c/0x70
[ 7.822013] [<ffffffff81086553>]
__blocking_notifier_call_chain+0x53/0x70
[ 7.822013] [<ffffffff81086586>]
blocking_notifier_call_chain+0x16/0x20
[ 7.822013] [<ffffffff81356e0b>] fb_notifier_call_chain+0x1b/0x20
[ 7.822013] [<ffffffff8135905c>] register_framebuffer+0x1ec/0x330
[ 7.822013] [<ffffffffa013cb9e>]
drm_fb_helper_initial_config+0x2fe/0x4b0 [drm_kms_helper]
[ 7.822013] [<ffffffffa014ccfb>] qxl_fbdev_init+0xab/0xd0 [qxl]
[ 7.822013] [<ffffffffa014aded>] qxl_modeset_init+0x1fd/0x240
[qxl]
[ 7.822013] [<ffffffffa0148ca8>] qxl_driver_load+0x88/0xc0 [qxl]
[ 7.822013] [<ffffffffa00db90d>] drm_dev_register+0xad/0x100 [drm]
[ 7.822013] [<ffffffffa00de46f>] drm_get_pci_dev+0x8f/0x1f0 [drm]
[ 7.822013] [<ffffffffa01482ab>] qxl_pci_probe+0x1b/0x40 [qxl]
[ 7.822013] [<ffffffff8132ad65>] local_pci_probe+0x45/0xa0
[ 7.822013] [<ffffffff8132c031>] pci_device_probe+0xd1/0x130
[ 7.822013] [<ffffffff813e6f80>] driver_probe_device+0x90/0x3c0
[ 7.822013] [<ffffffff813e7383>] __driver_attach+0x93/0xa0
[ 7.822013] [<ffffffff813e4f2b>] bus_for_each_dev+0x6b/0xb0
[ 7.822013] [<ffffffff813e69ee>] driver_attach+0x1e/0x20
[ 7.822013] [<ffffffff813e65f8>] bus_add_driver+0x188/0x260
[ 7.822013] [<ffffffff813e7b54>] driver_register+0x64/0xf0
[ 7.822013] [<ffffffff8132a6f0>] __pci_register_driver+0x60/0x70
[ 7.822013] [<ffffffffa00de6da>] drm_pci_init+0x10a/0x140 [drm]
[ 7.822013] [<ffffffffa015b03e>]
cdrom_dummy_generic_packet+0x3e/0x40 [cdrom]
[ 7.822013] [<ffffffff810002fc>] do_one_initcall+0xbc/0x200
[ 7.822013] [<ffffffff810e714d>] load_module+0x162d/0x1a90
[ 7.822013] [<ffffffff810e7746>] SyS_finit_module+0x86/0xb0
[ 7.822013] [<ffffffff8163b6e9>] system_call_fastpath+0x16/0x1b
[ 7.822013]
[ 7.822013] -> #0 (&qdev->release_mutex){+.+.+.}:
[ 7.822013] [<ffffffff810b030c>]
validate_chain.isra.36+0x110c/0x11b0
[ 7.822013] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.822013] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.822013] [<ffffffff81636add>] mutex_lock_nested+0x5d/0x4d0
[ 7.822013] [<ffffffffa0151a2c>]
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.822013] [<ffffffffa014f6ec>] qxl_draw_opaque_fb+0x7c/0x390
[qxl]
[ 7.822013] [<ffffffffa014bdb1>]
qxl_fb_dirty_flush+0x121/0x160 [qxl]
[ 7.822013] [<ffffffffa014be90>] qxl_deferred_io+0xa0/0xb0 [qxl]
[ 7.822013] [<ffffffff8135eaae>] fb_deferred_io_work+0x7e/0xd0
[ 7.822013] [<ffffffff8107a0b5>] process_one_work+0x1f5/0x510
[ 7.822013] [<ffffffff8107ab4d>] worker_thread+0x11d/0x520
[ 7.822013] [<ffffffff81081760>] kthread+0xf0/0x110
[ 7.822013] [<ffffffff8163b63c>] ret_from_fork+0x7c/0xb0
[ 7.822013]
[ 7.822013] other info that might help us debug this:
[ 7.822013]
[ 7.822013] Chain exists of:
[ 7.822013] &qdev->release_mutex --> &mm->mmap_sem --> &fbdefio->lock
[ 7.822013]
[ 7.822013] Possible unsafe locking scenario:
[ 7.822013]
[ 7.822013] CPU0 CPU1
[ 7.822013] ---- ----
[ 7.822013] lock(&fbdefio->lock);
[ 7.822013] lock(&mm->mmap_sem);
[ 7.822013] lock(&fbdefio->lock);
[ 7.822013] lock(&qdev->release_mutex);
[ 7.822013]
[ 7.822013] *** DEADLOCK ***
[ 7.822013]
[ 7.822013] 3 locks held by kworker/3:1/276:
[ 7.822013] #0: ("events"){.+.+.+}, at: [<ffffffff8107a053>]
process_one_work+0x193/0x510
[ 7.822013] #1: ((&(&info->deferred_work)->work)){+.+.+.}, at:
[<ffffffff8107a053>] process_one_work+0x193/0x510
[ 7.822013] #2: (&fbdefio->lock){+.+.+.}, at: [<ffffffff8135ea65>]
fb_deferred_io_work+0x35/0xd0
[ 7.822013]
[ 7.822013] stack backtrace:
[ 7.822013] CPU: 3 PID: 276 Comm: kworker/3:1 Not tainted 3.16.0-rc6 #4
[ 7.822013] Hardware name: Red Hat KVM, BIOS Bochs 01/01/2011
[ 7.822013] Workqueue: events fb_deferred_io_work
[ 7.822013] ffffffff8268aa90 ffff8807df2ff8e8 ffffffff8163182a
ffffffff826ba5f0
[ 7.822013] ffff8807df2ff928 ffffffff8162b0d5 ffff8807df2ff960
ffff8807df2ddb50
[ 7.822013] ffff8807df2ddb50 0000000000000002 ffff8807df2dcec0
0000000000000003
[ 7.822013] Call Trace:
[ 7.822013] [<ffffffff8163182a>] dump_stack+0x45/0x56
[ 7.822013] [<ffffffff8162b0d5>] print_circular_bug+0x1f9/0x207
[ 7.822013] [<ffffffff810b030c>] validate_chain.isra.36+0x110c/0x11b0
[ 7.822013] [<ffffffff810ad89b>] ?
add_lock_to_list.isra.22.constprop.43+0x7b/0xf0
[ 7.822013] [<ffffffff8100c1b9>] ? sched_clock+0x9/0x10
[ 7.822013] [<ffffffff810b2078>] __lock_acquire+0x3a8/0xc40
[ 7.822013] [<ffffffff810b29c0>] lock_acquire+0xb0/0x140
[ 7.822013] [<ffffffffa0151a2c>] ?
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.822013] [<ffffffff81636add>] mutex_lock_nested+0x5d/0x4d0
[ 7.822013] [<ffffffffa0151a2c>] ?
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.822013] [<ffffffffa0151a2c>] ?
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.822013] [<ffffffff8163a957>] ? _raw_spin_unlock+0x27/0x30
[ 7.822013] [<ffffffffa0151598>] ? qxl_release_alloc+0x98/0x100 [qxl]
[ 7.822013] [<ffffffffa0151a2c>]
qxl_alloc_release_reserved+0x6c/0x200 [qxl]
[ 7.822013] [<ffffffffa014f6ec>] qxl_draw_opaque_fb+0x7c/0x390 [qxl]
[ 7.822013] [<ffffffffa014e3e3>] ? qxl_io_log+0x63/0x70 [qxl]
[ 7.822013] [<ffffffffa014bdb1>] qxl_fb_dirty_flush+0x121/0x160 [qxl]
[ 7.822013] [<ffffffffa014be90>] qxl_deferred_io+0xa0/0xb0 [qxl]
[ 7.822013] [<ffffffff8135eaae>] fb_deferred_io_work+0x7e/0xd0
[ 7.822013] [<ffffffff8107a0b5>] process_one_work+0x1f5/0x510
[ 7.822013] [<ffffffff8107a053>] ? process_one_work+0x193/0x510
[ 7.822013] [<ffffffff8107ab4d>] worker_thread+0x11d/0x520
[ 7.822013] [<ffffffff8107aa30>] ? create_and_start_worker+0x60/0x60
[ 7.822013] [<ffffffff81081760>] kthread+0xf0/0x110
[ 7.822013] [<ffffffff81081670>] ? kthread_create_on_node+0x220/0x220
[ 7.822013] [<ffffffff8163b63c>] ret_from_fork+0x7c/0xb0
[ 7.822013] [<ffffffff81081670>] ? kthread_create_on_node+0x220/0x220
[ 7.988039] hardirqs last enabled at (361): [<ffffffff81048f85>]
__do_page_fault+0x275/0x530
[ 7.988039] hardirqs last disabled at (360): [<ffffffff8163d826>]
error_sti+0x5/0x6
[ 7.988039] softirqs last enabled at (0): [<ffffffff8105ad8b>]
copy_process.part.22+0x66b/0x1d40
[ 7.988039] softirqs last disabled at (0): [<
(null)>] (null)
^ permalink raw reply
* Re: [PATCH v2] Input: add i2c/smbus driver for elan touchpad
From: cheng wei Lin @ 2014-07-25 18:05 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-kernel, linux-input, bleung, agnescheng,
"SRD1 �蝬踐��?都����",
jeff.chuang
In-Reply-To: <20140724180516.GA26752@core.coreip.homeip.net>
Hi Dmitry,
Sorry for late to reply you and thanks for your command
Yes, I also agree, it looks great than my original code.
So, should I modify this and upstream v3 patch for you?
thank you,
duson
Dmitry Torokhov <dmitry.torokhov@gmail.com> 於 2014/7/25 上午2:05 寫道:
> Hi,
>
> On Tue, Jan 07, 2014 at 11:08:03AM +0800, Duson Lin wrote:
>> +/*
>> + ******************************************************************
>> + * General functions
>> + ******************************************************************
>> + */
>> +/*
>> + * (value from firmware) * 10 + 790 = dpi
>> + * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
>> + */
>> +static unsigned int elan_convert_res(char val)
>> +{
>> + int res;
>> + if (val & 0x80) {
>> + val = ~val + 1;
>> + res = (790 - val * 10) * 10 / 254;
>> + } else
>> + res = (val * 10 + 790) * 10 / 254;
>> + return res;
>> +}
>
> Why isn't this simply:
>
> res = ((int)val * 10 + 790) * 10 / 254;
>
> ?
>
> If high bit is 1 you basically do the 2 complement by hand to get to
> positive and then subtract. Which shoudl be the same as adding positive
> value.
>
> Thanks.
>
> --
> Dmitry
>
--
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] input: drv260x: Introduce TI drv260x haptics driver
From: Murphy, Dan @ 2014-07-25 18:18 UTC (permalink / raw)
To: linux-input@vger.kernel.org
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1406228875-21539-1-git-send-email-dmurphy@ti.com>
On 07/24/2014 02:07 PM, Murphy, Dan wrote:
> Add the TI drv260x haptics/vibrator driver.
> This device uses the input force feedback
> to produce a wave form to driver an
> ERM or LRA actuator device.
>
> The initial driver supports the devices
> real time playback mode. But the device
> has additional wave patterns in ROM.
>
> This functionality will be added in
> future patchsets.
>
> Product data sheet is located here:
> http://www.ti.com/product/drv2605
>
> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> ---
> .../devicetree/bindings/input/ti,drv260x.txt | 44 ++
> drivers/input/misc/Kconfig | 9 +
> drivers/input/misc/Makefile | 1 +
> drivers/input/misc/drv260x.c | 537 ++++++++++++++++++++
> include/dt-bindings/input/ti-drv260x.h | 30 ++
> include/linux/input/drv260x.h | 181 +++++++
> 6 files changed, 802 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/ti,drv260x.txt
> create mode 100644 drivers/input/misc/drv260x.c
> create mode 100644 include/dt-bindings/input/ti-drv260x.h
> create mode 100644 include/linux/input/drv260x.h
>
> diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt
> new file mode 100644
> index 0000000..0860661
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/ti,drv260x.txt
> @@ -0,0 +1,44 @@
> +Texas Instruments - drv260x Haptics driver family
> +
> +The drv260x family serial control bus communicates through I2C protocols
> +
> +Required properties:
> + - compatible - One of:
> + "ti,drv2604" - DRV2604
> + "ti,drv2605" - DRV2605
> + "ti,drv2605l" - DRV2605L
> + - reg - I2C slave address
> + - mode - Power up mode of the chip (defined in include/dt-bindings/input/ti-drv260x.h)
> + DRV260X_RTP_MODE - Real time playback mode
> + DRV260X_LRA_MODE - Linear Resonance Actuator mode (Piezoelectric)
> + DRV260X_ERM_MODE - Eccentric Rotating Mass mode (Rotary vibrator)
> + - library_sel - Library to use at power up (defined in include/dt-bindings/input/ti-drv260x.h)
> + DRV260X_LIB_A - Pre-programmed Library
> + DRV260X_LIB_B - Pre-programmed Library
> + DRV260X_LIB_C - Pre-programmed Library
> + DRV260X_LIB_D - Pre-programmed Library
> + DRV260X_LIB_E - Pre-programmed Library
> + DRV260X_LIB_F - Pre-programmed Library
> +
> +Optional properties:
> + - enable-gpio - gpio pin to enable/disable the device.
> + - vib_rated_voltage - The rated voltage of the actuator. If this is not
> + set then the value will be defaulted to 0x90 in the
> + driver.
> + - vib_overdrive_voltage - The overdrive voltage of the actuator.
> + If this is not set then the value
> + will be defaulted to 0x90 in the driver.
> +Example:
> +
> +drv2605l: drv2605l@41 {
This needs to be updated
> + compatible = "ti,drv2605l";
> + reg = <0x5a>;
> + enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; /* GPIO 60 */
> + mode = <DRV260X_RTP_MODE>;
> + library_sel = <DRV260X_LIB_SEL_DEFAULT>;
> + vib_rated_voltage = <3200>;
> + vib_overdriver_voltage = <3200>;
> +};
> +
> +For more product information please see the link below:
> +http://www.ti.com/product/drv2605
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 2ff4425..99f6762 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -676,4 +676,13 @@ config INPUT_SOC_BUTTON_ARRAY
> To compile this driver as a module, choose M here: the
> module will be called soc_button_array.
>
> +config INPUT_DRV260X_HAPTICS
> + tristate "TI DRV260X haptics support"
> + depends on INPUT && I2C
> + help
> + Say Y to enable support for the TI DRV260X haptics driver.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called drv260x-haptics.
> +
> endif
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 4955ad3..d8ef3c7 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -64,3 +64,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
> obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
> obj-$(CONFIG_INPUT_YEALINK) += yealink.o
> obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o
> +obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o
> diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
> new file mode 100644
> index 0000000..aadfd57
> --- /dev/null
> +++ b/drivers/input/misc/drv260x.c
> @@ -0,0 +1,537 @@
> +/*
> + * drv260x.c - DRV260X haptics driver family
> + *
> + * Author: Dan Murphy <dmurphy@ti.com>
> + *
> + * Copyright: (C) 2014 Texas Instruments, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/input.h>
> +#include <linux/module.h>
> +#include <linux/of_gpio.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include <linux/input/drv260x.h>
> +#include <dt-bindings/input/ti-drv260x.h>
> +
> +#define DRV260X_MAX_EFFECTS 255
> +
> +/**
> + * struct drv260x_data -
> + * @input_dev - Pointer to the input device
> + * @client - Pointer to the I2C client
> + * @timer - High res timer used to turn on/off vibration
> + * @regmap - Register map of the device
> + * @lock - Lock for device access
> + * @work - Work item used to off load the enable/disable of the vibration
> + * @enable_gpio - Pointer to the gpio used for enable/disabling
> + * @regulator - Pointer to the regulator for the IC
> + * @upload_effects - Vibration effect data array
> + * @runtime_left - Indicates how much runtime is remaining in the timer
> + * @effect_id - The ID of the vibration effect requested to be played
> + * @mode - The operating mode of the IC (RTP, ERM or LRA)
> + * @library - The vibration library to be used
> + * @rated_voltage - The rated_voltage of the actuator
> + * @overdriver_voltage - The over drive voltage of the actuator
> +**/
> +struct drv260x_data {
> + struct input_dev *input_dev;
> + struct i2c_client *client;
> + struct hrtimer timer;
> + struct regmap *regmap;
> + struct mutex lock;
> + struct work_struct work;
> + struct gpio_desc *enable_gpio;
> + struct regulator *regulator;
> + struct ff_effect upload_effects[DRV260X_MAX_EFFECTS];
> + u32 runtime_left;
> + u32 effect_id;
> + int mode;
> + int library;
> + int rated_voltage;
> + int overdrive_voltage;
> +};
> +
> +static struct reg_default drv260x_reg_defs[] = {
> + { DRV260X_STATUS, 0xe0 },
> + { DRV260X_MODE, 0x40 },
> + { DRV260X_RT_PB_IN, 0x00},
> + { DRV260X_LIB_SEL, 0x00},
> + { DRV260X_WV_SEQ_1, 0x01},
> + { DRV260X_WV_SEQ_2, 0x00},
> + { DRV260X_WV_SEQ_3, 0x00},
> + { DRV260X_WV_SEQ_4, 0x00},
> + { DRV260X_WV_SEQ_5, 0x00},
> + { DRV260X_WV_SEQ_6, 0x00},
> + { DRV260X_WV_SEQ_7, 0x00},
> + { DRV260X_WV_SEQ_8, 0x00},
> + { DRV260X_GO, 0x00},
> + { DRV260X_OVERDRIVE_OFF, 0x00},
> + { DRV260X_SUSTAIN_P_OFF, 0x00},
> + { DRV260X_SUSTAIN_N_OFF, 0x00},
> + { DRV260X_BRAKE_OFF , 0x00},
> + { DRV260X_A_TO_V_CTRL , 0x05},
> + { DRV260X_A_TO_V_MIN_INPUT, 0x19},
> + { DRV260X_A_TO_V_MAX_INPUT, 0xff},
> + { DRV260X_A_TO_V_MIN_OUT, 0x19},
> + { DRV260X_A_TO_V_MAX_OUT, 0xff},
> + { DRV260X_RATED_VOLT, 0x3e},
> + { DRV260X_OD_CLAMP_VOLT, 0x8c},
> + { DRV260X_CAL_COMP, 0x0c},
> + { DRV260X_CAL_BACK_EMF, 0x6c},
> + { DRV260X_FEEDBACK_CTRL, 0x36},
> + { DRV260X_CTRL1, 0x93},
> + { DRV260X_CTRL2, 0xfa},
> + { DRV260X_CTRL3, 0xa0},
> + { DRV260X_CTRL4, 0x20},
> + { DRV260X_CTRL5, 0x80},
> + { DRV260X_LRA_LOOP_PERIOD, 0x33},
> + { DRV260X_VBAT_MON, 0x00},
> + { DRV260X_LRA_RES_PERIOD, 0x00},
> +};
> +
> +/**
> + * Rated and Overdriver Voltages:
> + * Calculated using the formula r = v * 255 / 5.6
> + * where r is what will be written to the register
> + * and v is the rated or overdriver voltage of the actuator
> + **/
> +#define DRV260X_DEF_RATED_VOLT 0x90
> +#define DRV260X_DEF_OD_CLAMP_VOLT 0x90
> +
> +static int drv260x_calculate_voltage(int voltage)
> +{
> + return (voltage * 255 / 5600);
> +}
> +
> +static void drv260x_worker(struct work_struct *work)
> +{
> + struct drv260x_data *haptics = container_of(work, struct drv260x_data, work);
> + int effect_id = haptics->effect_id;
> + int magnitude;
> +
> + mutex_lock(&haptics->lock);
> +
> + if (haptics->upload_effects[effect_id].u.rumble.strong_magnitude > 0)
> + magnitude = haptics->upload_effects[effect_id].u.rumble.strong_magnitude;
> + else if (haptics->upload_effects[effect_id].u.rumble.weak_magnitude > 0)
> + magnitude = haptics->upload_effects[effect_id].u.rumble.weak_magnitude;
> + else
> + goto out;
> +
> + if (haptics->runtime_left > 0)
> + regmap_write(haptics->regmap, DRV260X_RT_PB_IN, magnitude);
> + else
> + regmap_write(haptics->regmap, DRV260X_RT_PB_IN, 0x0);
> +
> +out:
> + mutex_unlock(&haptics->lock);
> +}
> +
> +static enum hrtimer_restart drv260x_timer(struct hrtimer *timer)
> +{
> + struct drv260x_data *data = container_of(timer, struct drv260x_data, timer);
> +
> + data->runtime_left = 0;
> + schedule_work(&data->work);
> +
> + return HRTIMER_NORESTART;
> +}
> +
> +static int drv260x_playback(struct input_dev *input, int effect_id, int value)
> +{
> + struct drv260x_data *haptics = input_get_drvdata(input);
> + unsigned long time_ms;
> +
> + gpiod_set_value(haptics->enable_gpio, 1);
> + /* Data sheet says to wait 250us before trying to communicate */
> + udelay(250);
> +
> + regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_RT_PLAYBACK);
> +
> + haptics->mode = DRV260X_RTP_MODE;
> + haptics->runtime_left = haptics->upload_effects[effect_id].replay.length;
> + haptics->effect_id = effect_id;
> +
> + time_ms = haptics->runtime_left * NSEC_PER_MSEC;
> +
> + schedule_work(&haptics->work);
> + hrtimer_start(&haptics->timer, ktime_set(0, time_ms), HRTIMER_MODE_REL);
> +
> + return 0;
> +}
> +
> +static int drv260x_upload_effect(struct input_dev *input,
> + struct ff_effect *effect,
> + struct ff_effect *old)
> +{
> + struct drv260x_data *haptics = input_get_drvdata(input);
> +
> + haptics->upload_effects[effect->id] = *effect;
> +
> + return 0;
> +}
> +
> +static void drv260x_close(struct input_dev *input)
> +{
> + struct drv260x_data *haptics = input_get_drvdata(input);
> +
> + cancel_work_sync(&haptics->work);
> + regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_STANDBY);
> + gpiod_set_value(haptics->enable_gpio, 0);
> +}
> +
> +static const struct reg_default drv260x_lra_cal_regs[] = {
> + { DRV260X_MODE, DRV260X_AUTO_CAL },
> + { DRV260X_CTRL3, DRV260X_NG_THRESH_2},
> + { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH },
> +};
> +
> +static const struct reg_default drv260x_lra_init_regs[] = {
> + { DRV260X_MODE, DRV260X_RT_PLAYBACK},
> + { DRV260X_LIB_SEL, DRV260X_LIB_F },
> + { DRV260X_A_TO_V_CTRL, DRV260X_AUDIO_HAPTICS_PEAK_20MS | DRV260X_AUDIO_HAPTICS_FILTER_125HZ},
> + { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
> + { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
> + { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT },
> + { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT },
> + { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | DRV260X_BRAKE_FACTOR_2X | DRV260X_LOOP_GAIN_MED | DRV260X_BEMF_GAIN_3 },
> + { DRV260X_CTRL1, DRV260X_STARTUP_BOOST },
> + { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 },
> + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANANLOG_IN },
> + { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
> +};
> +
> +static const struct reg_default drv260x_erm_cal_regs[] = {
> + { DRV260X_MODE, DRV260X_AUTO_CAL },
> + { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
> + { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
> + { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT },
> + { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT },
> + { DRV260X_FEEDBACK_CTRL, DRV260X_BRAKE_FACTOR_3X | DRV260X_LOOP_GAIN_MED | DRV260X_BEMF_GAIN_2 },
> + { DRV260X_CTRL1, DRV260X_STARTUP_BOOST },
> + { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 | DRV260X_BLANK_TIME_75 | DRV260X_SAMP_TIME_250 | DRV260X_IDISS_TIME_75 },
> + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ERM_OPEN_LOOP },
> + { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
> +};
> +
> +static int drv260x_init(struct drv260x_data *haptics)
> +{
> + int ret;
> + unsigned int cal_buf;
> +
> + ret = regmap_write(haptics->regmap,
> + DRV260X_RATED_VOLT, haptics->rated_voltage);
> + if (ret != 0)
> + goto write_failure;
> +
> + ret = regmap_write(haptics->regmap,
> + DRV260X_OD_CLAMP_VOLT, haptics->overdrive_voltage);
> + if (ret != 0)
> + goto write_failure;
> +
> + if (haptics->mode == DRV260X_LRA_MODE) {
> + ret = regmap_register_patch(haptics->regmap,
> + drv260x_lra_cal_regs,
> + ARRAY_SIZE(drv260x_lra_cal_regs));
> + if (ret != 0)
> + goto write_failure;
> +
> + } else if (haptics->mode == DRV260X_ERM_MODE) {
> + ret = regmap_register_patch(haptics->regmap,
> + drv260x_erm_cal_regs,
> + ARRAY_SIZE(drv260x_erm_cal_regs));
> + if (ret != 0)
> + goto write_failure;
> +
> + ret = regmap_update_bits(haptics->regmap, DRV260X_LIB_SEL,
> + DRV260X_LIB_SEL_MASK,
> + haptics->library);
> + if (ret != 0)
> + goto write_failure;
> +
> + } else {
> + ret = regmap_register_patch(haptics->regmap,
> + drv260x_lra_init_regs,
> + ARRAY_SIZE(drv260x_lra_init_regs));
> + if (ret != 0)
> + goto write_failure;
> +
> + goto skip_go_bit;
> + }
> +
> + if (ret != 0) {
> + dev_err(&haptics->client->dev,
> + "Failed to write init registers: %d\n",
> + ret);
> + goto write_failure;
> + }
> +
> + ret = regmap_write(haptics->regmap, DRV260X_GO, DRV260X_GO_BIT);
> + if (ret != 0)
> + goto write_failure;
> +
> + do {
> + ret = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf);
> + if (ret != 0)
> + goto write_failure;
> + } while (cal_buf == DRV260X_GO_BIT || ret != 0);
> +
> + return ret;
> +
> +write_failure:
> + dev_err(&haptics->client->dev,
> + "Failed to write init registers: %d\n",
> + ret);
> +skip_go_bit:
> + return ret;
> +}
> +
> +static const struct regmap_config drv260x_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> +
> + .max_register = DRV260X_MAX_REG,
> + .reg_defaults = drv260x_reg_defs,
> + .num_reg_defaults = ARRAY_SIZE(drv260x_reg_defs),
> + .cache_type = REGCACHE_NONE,
> +};
> +
> +static int drv260x_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct drv260x_data *haptics;
> + struct device_node *np = client->dev.of_node;
> + struct drv260x_platform_data *pdata = client->dev.platform_data;
> + struct ff_device *ff;
> + int ret;
> + int voltage;
> +
> + haptics = devm_kzalloc(&client->dev, sizeof(*haptics), GFP_KERNEL);
> + if (!haptics)
> + return -ENOMEM;
> +
> + haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT;
> + haptics->rated_voltage = DRV260X_DEF_RATED_VOLT;
> +
> + if (np) {
> + ret = of_property_read_u32(np, "mode", &haptics->mode);
> + if (ret < 0) {
> + dev_err(&client->dev,
> + "%s: No entry for mode\n", __func__);
> +
> + return ret;
> + }
> + ret = of_property_read_u32(np, "library_sel",
> + &haptics->library);
> + if (ret < 0) {
> + dev_err(&client->dev,
> + "%s: No entry for library selection\n", __func__);
> +
> + return ret;
> + }
> + ret = of_property_read_u32(np, "vib_rated_voltage",
> + &voltage);
> + if (!ret)
> + haptics->rated_voltage = drv260x_calculate_voltage(voltage);
> +
> +
> + ret = of_property_read_u32(np, "vib_overdrive_voltage",
> + &voltage);
> + if (!ret)
> + haptics->overdrive_voltage = drv260x_calculate_voltage(voltage);
> +
> + } else if (pdata) {
> + haptics->mode = pdata->mode;
> + haptics->library = pdata->library_selection;
> + if (pdata->vib_overdrive_voltage)
> + haptics->overdrive_voltage = drv260x_calculate_voltage(pdata->vib_overdrive_voltage);
> + if (pdata->vib_rated_voltage)
> + haptics->rated_voltage = drv260x_calculate_voltage(pdata->vib_rated_voltage);
> + } else {
> + dev_err(&client->dev, "Platform data not set\n");
> + return -ENODEV;
> + }
> +
> + haptics->regulator = regulator_get(&client->dev, "vbat");
> + if (IS_ERR(haptics->regulator)) {
> + ret = PTR_ERR(haptics->regulator);
> + dev_err(&client->dev,
> + "unable to get regulator, error: %d\n", ret);
> + goto err_regulator;
> + }
> +
> + haptics->enable_gpio = devm_gpiod_get(&client->dev, "enable");
> + if (IS_ERR(haptics->enable_gpio)) {
> + ret = PTR_ERR(haptics->enable_gpio);
> + if (ret != -ENOENT && ret != -ENOSYS)
> + goto err_gpio;
> +
> + haptics->enable_gpio = NULL;
> + } else {
> + gpiod_direction_output(haptics->enable_gpio, 1);
> + }
> +
> + haptics->input_dev = input_allocate_device();
> + if (haptics->input_dev == NULL) {
> + dev_err(&client->dev, "Failed to allocate input device\n");
> + ret = -ENOMEM;
> + goto err_input_alloc;
> + }
> +
> + haptics->input_dev->name = "drv260x:haptics";
> + haptics->input_dev->dev.parent = client->dev.parent;
> + haptics->input_dev->close = drv260x_close;
> + input_set_drvdata(haptics->input_dev, haptics);
> + input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);
> +
> + ret = input_ff_create(haptics->input_dev, DRV260X_MAX_EFFECTS);
> + if (ret < 0) {
> + dev_err(&client->dev, "input_ff_create() failed: %d\n",
> + ret);
> + goto err_ff_create;
> + }
> +
> + ff = haptics->input_dev->ff;
> + ff->playback = drv260x_playback;
> + ff->upload = drv260x_upload_effect;
> +
> + mutex_init(&haptics->lock);
> + INIT_WORK(&haptics->work, drv260x_worker);
> + hrtimer_init(&haptics->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> + haptics->timer.function = drv260x_timer;
> +
> + haptics->client = client;
> + i2c_set_clientdata(client, haptics);
> +
> + haptics->regmap = devm_regmap_init_i2c(client, &drv260x_regmap_config);
> + if (IS_ERR(haptics->regmap)) {
> + ret = PTR_ERR(haptics->regmap);
> + dev_err(&client->dev, "Failed to allocate register map: %d\n",
> + ret);
> + goto err_regmap;
> + }
> +
> + drv260x_init(haptics);
> +
> + ret = input_register_device(haptics->input_dev);
> + if (ret < 0) {
> + dev_err(&client->dev, "couldn't register input device: %d\n",
> + ret);
> + goto err_iff;
> + }
> + return 0;
> +
> +err_iff:
> +err_regmap:
> + if (haptics->input_dev)
> + input_ff_destroy(haptics->input_dev);
> +err_ff_create:
> + input_free_device(haptics->input_dev);
> +err_input_alloc:
> +err_gpio:
> + regulator_put(haptics->regulator);
> +err_regulator:
> + return ret;
> +}
> +
> +static int drv260x_remove(struct i2c_client *client)
> +{
> + struct drv260x_data *haptics = i2c_get_clientdata(client);
> +
> + cancel_work_sync(&haptics->work);
> +
> + regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_STANDBY);
> + gpiod_set_value(haptics->enable_gpio, 0);
> +
> + input_unregister_device(haptics->input_dev);
> + regulator_put(haptics->regulator);
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int drv260x_suspend(struct device *dev)
> +{
> + struct drv260x_data *haptics = dev_get_drvdata(dev);
> +
> + regmap_update_bits(haptics->regmap,
> + DRV260X_MODE,
> + DRV260X_STANDBY_MASK,
> + DRV260X_STANDBY);
> + gpiod_set_value(haptics->enable_gpio, 0);
> +
> + regulator_disable(haptics->regulator);
> +
> + return 0;
> +}
> +
> +static int drv260x_resume(struct device *dev)
> +{
> + struct drv260x_data *haptics = dev_get_drvdata(dev);
> + int ret;
> +
> + ret = regulator_enable(haptics->regulator);
> + if (ret) {
> + dev_err(dev, "Failed to enable regulator\n");
> + return ret;
> + }
> + regmap_update_bits(haptics->regmap,
> + DRV260X_MODE,
> + DRV260X_STANDBY_MASK, 0);
> +
> + gpiod_set_value(haptics->enable_gpio, 1);
> +
> + return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume);
> +
> +static const struct i2c_device_id drv260x_id[] = {
> + { "drv2605l", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, drv260x_id);
> +
> +#if IS_ENABLED(CONFIG_OF)
> +static const struct of_device_id drv260x_of_match[] = {
> + { .compatible = "ti,drv2604", },
> + { .compatible = "ti,drv2605", },
> + { .compatible = "ti,drv2605l", },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, drv260x_of_match);
> +#endif
> +
> +static struct i2c_driver drv260x_driver = {
> + .probe = drv260x_probe,
> + .remove = drv260x_remove,
> + .driver = {
> + .name = "drv260x-haptics",
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(drv260x_of_match),
> + .pm = &drv260x_pm_ops,
> + },
> + .id_table = drv260x_id,
> +};
> +module_i2c_driver(drv260x_driver);
> +
> +MODULE_ALIAS("platform:drv260x-haptics");
> +MODULE_DESCRIPTION("TI DRV260x haptics driver");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
> diff --git a/include/dt-bindings/input/ti-drv260x.h b/include/dt-bindings/input/ti-drv260x.h
> new file mode 100644
> index 0000000..28f1dfa
> --- /dev/null
> +++ b/include/dt-bindings/input/ti-drv260x.h
> @@ -0,0 +1,30 @@
> +/*
> + * ti-drv260x.h - DRV260X haptics driver family
> + *
> + * Author: Dan Murphy <dmurphy@ti.com>
> + *
> + * Copyright: (C) 2014 Texas Instruments, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + */
> +
> +/* Calibration Types */
> +#define DRV260X_RTP_MODE 0x00
> +#define DRV260X_LRA_MODE 0x01
> +#define DRV260X_ERM_MODE 0x02
> +
> +/* Library Selection */
> +#define DRV260X_LIB_SEL_DEFAULT 0x00
> +#define DRV260X_LIB_A 0x01
> +#define DRV260X_LIB_B 0x02
> +#define DRV260X_LIB_C 0x03
> +#define DRV260X_LIB_D 0x04
> +#define DRV260X_LIB_E 0x05
> +#define DRV260X_LIB_F 0x06
> diff --git a/include/linux/input/drv260x.h b/include/linux/input/drv260x.h
> new file mode 100644
> index 0000000..709395e
> --- /dev/null
> +++ b/include/linux/input/drv260x.h
> @@ -0,0 +1,181 @@
> +/*
> + * drv260x.h - DRV260X haptics driver family
> + *
> + * Author: Dan Murphy <dmurphy@ti.com>
> + *
> + * Copyright: (C) 2014 Texas Instruments, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + */
> +
> +#ifndef _LINUX_DRV260X_I2C_H
> +#define _LINUX_DRV260X_I2C_H
> +
> +#define DRV260X_STATUS 0x0
> +#define DRV260X_MODE 0x1
> +#define DRV260X_RT_PB_IN 0x2
> +#define DRV260X_LIB_SEL 0x3
> +#define DRV260X_WV_SEQ_1 0x4
> +#define DRV260X_WV_SEQ_2 0x5
> +#define DRV260X_WV_SEQ_3 0x6
> +#define DRV260X_WV_SEQ_4 0x7
> +#define DRV260X_WV_SEQ_5 0x8
> +#define DRV260X_WV_SEQ_6 0x9
> +#define DRV260X_WV_SEQ_7 0xa
> +#define DRV260X_WV_SEQ_8 0xb
> +#define DRV260X_GO 0xc
> +#define DRV260X_OVERDRIVE_OFF 0xd
> +#define DRV260X_SUSTAIN_P_OFF 0xe
> +#define DRV260X_SUSTAIN_N_OFF 0xf
> +#define DRV260X_BRAKE_OFF 0x10
> +#define DRV260X_A_TO_V_CTRL 0x11
> +#define DRV260X_A_TO_V_MIN_INPUT 0x12
> +#define DRV260X_A_TO_V_MAX_INPUT 0x13
> +#define DRV260X_A_TO_V_MIN_OUT 0x14
> +#define DRV260X_A_TO_V_MAX_OUT 0x15
> +#define DRV260X_RATED_VOLT 0x16
> +#define DRV260X_OD_CLAMP_VOLT 0x17
> +#define DRV260X_CAL_COMP 0x18
> +#define DRV260X_CAL_BACK_EMF 0x19
> +#define DRV260X_FEEDBACK_CTRL 0x1a
> +#define DRV260X_CTRL1 0x1b
> +#define DRV260X_CTRL2 0x1c
> +#define DRV260X_CTRL3 0x1d
> +#define DRV260X_CTRL4 0x1e
> +#define DRV260X_CTRL5 0x1f
> +#define DRV260X_LRA_LOOP_PERIOD 0x20
> +#define DRV260X_VBAT_MON 0x21
> +#define DRV260X_LRA_RES_PERIOD 0x22
> +#define DRV260X_MAX_REG 0x23
> +
> +#define DRV260X_ALLOWED_R_BYTES 25
> +#define DRV260X_ALLOWED_W_BYTES 2
> +#define DRV260X_MAX_RW_RETRIES 5
> +#define DRV260X_I2C_RETRY_DELAY 10
> +
> +#define DRV260X_GO_BIT 0x01
> +
> +/* Library Selection */
> +#define DRV260X_LIB_SEL_MASK 0x07
> +#define DRV260X_LIB_SEL_RAM 0x0
> +#define DRV260X_LIB_SEL_OD 0x1
> +#define DRV260X_LIB_SEL_40_60 0x2
> +#define DRV260X_LIB_SEL_60_80 0x3
> +#define DRV260X_LIB_SEL_100_140 0x4
> +#define DRV260X_LIB_SEL_140_PLUS 0x5
> +
> +#define DRV260X_LIB_SEL_HIZ_MASK 0x10
> +#define DRV260X_LIB_SEL_HIZ_EN 0x01
> +#define DRV260X_LIB_SEL_HIZ_DIS 0
> +
> +/* Mode register */
> +#define DRV260X_STANDBY (1 << 6)
> +#define DRV260X_STANDBY_MASK 0x40
> +#define DRV260X_INTERNAL_TRIGGER 0x00
> +#define DRV260X_EXT_TRIGGER_EDGE 0x01
> +#define DRV260X_EXT_TRIGGER_LEVEL 0x02
> +#define DRV260X_PWM_ANALOG_IN 0x03
> +#define DRV260X_AUDIOHAPTIC 0x04
> +#define DRV260X_RT_PLAYBACK 0x05
> +#define DRV260X_DIAGNOSTICS 0x06
> +#define DRV260X_AUTO_CAL 0x07
> +
> +/* Audio to Haptics Control */
> +#define DRV260X_AUDIO_HAPTICS_PEAK_10MS (0 << 2)
> +#define DRV260X_AUDIO_HAPTICS_PEAK_20MS (1 << 2)
> +#define DRV260X_AUDIO_HAPTICS_PEAK_30MS (2 << 2)
> +#define DRV260X_AUDIO_HAPTICS_PEAK_40MS (3 << 2)
> +
> +#define DRV260X_AUDIO_HAPTICS_FILTER_100HZ 0x00
> +#define DRV260X_AUDIO_HAPTICS_FILTER_125HZ 0x01
> +#define DRV260X_AUDIO_HAPTICS_FILTER_150HZ 0x02
> +#define DRV260X_AUDIO_HAPTICS_FILTER_200HZ 0x03
> +
> +/* Min/Max Input/Output Voltages */
> +#define DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT 0x19
> +#define DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT 0x64
> +#define DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT 0x19
> +#define DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT 0xFF
> +
> +/* Feedback register */
> +#define DRV260X_FB_REG_ERM_MODE 0x7f
> +#define DRV260X_FB_REG_LRA_MODE (1 << 7)
> +
> +#define DRV260X_BRAKE_FACTOR_MASK 0x1f
> +#define DRV260X_BRAKE_FACTOR_2X (1 << 0)
> +#define DRV260X_BRAKE_FACTOR_3X (2 << 4)
> +#define DRV260X_BRAKE_FACTOR_4X (3 << 4)
> +#define DRV260X_BRAKE_FACTOR_6X (4 << 4)
> +#define DRV260X_BRAKE_FACTOR_8X (5 << 4)
> +#define DRV260X_BRAKE_FACTOR_16 (6 << 4)
> +#define DRV260X_BRAKE_FACTOR_DIS (7 << 4)
> +
> +#define DRV260X_LOOP_GAIN_LOW 0xf3
> +#define DRV260X_LOOP_GAIN_MED (1 << 2)
> +#define DRV260X_LOOP_GAIN_HIGH (2 << 2)
> +#define DRV260X_LOOP_GAIN_VERY_HIGH (3 << 2)
> +
> +#define DRV260X_BEMF_GAIN_0 0xfc
> +#define DRV260X_BEMF_GAIN_1 (1 << 0)
> +#define DRV260X_BEMF_GAIN_2 (2 << 0)
> +#define DRV260X_BEMF_GAIN_3 (3 << 0)
> +
> +/* Control 1 register */
> +#define DRV260X_AC_CPLE_EN (1 << 5)
> +#define DRV260X_STARTUP_BOOST (1 << 7)
> +
> +/* Control 2 register */
> +
> +#define DRV260X_IDISS_TIME_45 0
> +#define DRV260X_IDISS_TIME_75 (1 << 0)
> +#define DRV260X_IDISS_TIME_150 (1 << 1)
> +#define DRV260X_IDISS_TIME_225 0x03
> +
> +#define DRV260X_BLANK_TIME_45 (0 << 2)
> +#define DRV260X_BLANK_TIME_75 (1 << 2)
> +#define DRV260X_BLANK_TIME_150 (2 << 2)
> +#define DRV260X_BLANK_TIME_225 (3 << 2)
> +
> +#define DRV260X_SAMP_TIME_150 (0 << 4)
> +#define DRV260X_SAMP_TIME_200 (1 << 4)
> +#define DRV260X_SAMP_TIME_250 (2 << 4)
> +#define DRV260X_SAMP_TIME_300 (3 << 4)
> +
> +#define DRV260X_BRAKE_STABILIZER (1 << 6)
> +#define DRV260X_UNIDIR_IN (0 << 7)
> +#define DRV260X_BIDIR_IN (1 << 7)
> +
> +/* Control 3 Register */
> +#define DRV260X_LRA_OPEN_LOOP (1 << 0)
> +#define DRV260X_ANANLOG_IN (1 << 1)
> +#define DRV260X_LRA_DRV_MODE (1 << 2)
> +#define DRV260X_RTP_UNSIGNED_DATA (1 << 3)
> +#define DRV260X_SUPPLY_COMP_DIS (1 << 4)
> +#define DRV260X_ERM_OPEN_LOOP (1 << 5)
> +#define DRV260X_NG_THRESH_0 (0 << 6)
> +#define DRV260X_NG_THRESH_2 (1 << 6)
> +#define DRV260X_NG_THRESH_4 (2 << 6)
> +#define DRV260X_NG_THRESH_8 (3 << 6)
> +
> +/* Control 4 Register */
> +#define DRV260X_AUTOCAL_TIME_150MS (0 << 4)
> +#define DRV260X_AUTOCAL_TIME_250MS (1 << 4)
> +#define DRV260X_AUTOCAL_TIME_500MS (2 << 4)
> +#define DRV260X_AUTOCAL_TIME_1000MS (3 << 4)
> +
> +struct drv260x_platform_data {
> + int enable_gpio;
> + int library_selection;
> + int mode;
> + int vib_rated_voltage;
> + int vib_overdrive_voltage;
> +};
> +
> +#endif
--
------------------
Dan Murphy
^ permalink raw reply
* Re: [PATCH v2] Input: add i2c/smbus driver for elan touchpad
From: Dmitry Torokhov @ 2014-07-25 18:20 UTC (permalink / raw)
To: cheng wei Lin
Cc: linux-kernel, linux-input, bleung, agnescheng,
"SRD1 �蝬踐��?都����",
jeff.chuang
In-Reply-To: <73E9FA09-55D6-409D-A902-29CC3F414CBF@emc.com.tw>
Hi Duson,
On Sat, Jul 26, 2014 at 02:05:02AM +0800, cheng wei Lin wrote:
> Hi Dmitry,
>
> Sorry for late to reply you and thanks for your command
>
> Yes, I also agree, it looks great than my original code.
Thank you for confirming.
> So, should I modify this and upstream v3 patch for you?
No, that is fine, I'll fix it up on my end.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: wacom_serial4 - prepare for wacom USB moving to HID
From: Hans de Goede @ 2014-07-25 19:06 UTC (permalink / raw)
To: Dmitry Torokhov, Julian Squires, Benjamin Tissoires
Cc: linux-input, linux-kernel
In-Reply-To: <20140724203108.GA9191@core.coreip.homeip.net>
Hi,
On 07/24/2014 10:31 PM, Dmitry Torokhov wrote:
> wacom_wac.h will be moving to drivers/hid. Since we only need 3 definitions
> from it let's simply copy them over.
>
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Ack, but you will want to drop the #include of wacom_wac.h yoo.
Regards,
Hans
> ---
> drivers/input/tablet/wacom_serial4.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/input/tablet/wacom_serial4.c b/drivers/input/tablet/wacom_serial4.c
> index d3d251e..deef50e 100644
> --- a/drivers/input/tablet/wacom_serial4.c
> +++ b/drivers/input/tablet/wacom_serial4.c
> @@ -149,6 +149,11 @@ MODULE_LICENSE("GPL");
> #define F_HAS_STYLUS2 0x02
> #define F_HAS_SCROLLWHEEL 0x04
>
> +/* device IDs */
> +#define STYLUS_DEVICE_ID 0x02
> +#define CURSOR_DEVICE_ID 0x06
> +#define ERASER_DEVICE_ID 0x0A
> +
> enum { STYLUS = 1, ERASER, CURSOR };
>
> static const struct {
>
^ permalink raw reply
* Re: [PATCH] hid: usbhid: Use flag HID_DISCONNECTED when a usb device is removed
From: Reyad Attiyat @ 2014-07-25 19:06 UTC (permalink / raw)
To: linux-input, Jiri Kosina, Srinivas Pandruvada, linux-kernel; +Cc: Reyad Attiyat
In-Reply-To: <1406265181-4009-1-git-send-email-reyad.attiyat@gmail.com>
The kernel panic happened when the iio sensor hid usb device was
removed. It tries to set the power state by calling hid_hw_request().
This was on kernel 3.16-rc6
https://gist.github.com/soda0289/2ff543d9cfff6f92c360#file-kernel-panic-when-iio-sensor-usb-device-is-removed
On Fri, Jul 25, 2014 at 12:13 AM, Reyad Attiyat <reyad.attiyat@gmail.com> wrote:
> Set disconnected flag in struct usbhid when a usb device
> is removed. Check for disconnected flag before sending urb
> requests. This prevents a kernel panic when a hid driver calls
> hid_hw_request() after removing a usb device.
>
> Signed-off-by: Reyad Attiyat <reyad.attiyat@gmail.com>
> ---
> drivers/hid/usbhid/hid-core.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index 7b88f4c..c8fa957 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
> int head;
> struct usbhid_device *usbhid = hid->driver_data;
>
> - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
> + if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
> + test_bit(HID_DISCONNECTED, &usbhid->iofl))
> return;
>
> if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
> @@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface *intf)
> return;
>
> usbhid = hid->driver_data;
> + spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
> + set_bit(HID_DISCONNECTED, &usbhid->iofl);
> + spin_unlock_irq(&usbhid->lock);
> hid_destroy_device(hid);
> kfree(usbhid);
> }
> --
> 1.9.3
>
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Przemo Firszt @ 2014-07-25 19:26 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
linux-kernel, linux-input
In-Reply-To: <20140725145400.GB12268@mail.corp.redhat.com>
Dnia 2014-07-25, pią o godzinie 10:54 -0400, Benjamin Tissoires pisze:
> [..]
Hi Benjamin,
>
> > If I understand you correctly we cannot have the same entry point in
> > sysfs for OLEDs unless we can tell userspace somehow if the tablet is
> > conected over USB or over bluetooth. The hardware of Intuos4 Wireless
> > over bluetooth allows only 1-bit images. The same hardware over USB
> > allows 4-bit images. Formatting of the images is also completely
>
> Holy crap! I missed that. I did not noticed the 1-bit vs 4-bits
> difference :(
>
> > different and it's not "plain". Check [1] for usb and exisitng
> > hid-wacom.c/wacom_scramble function for bluetooth.
>
> Maybe I overlooked it, but I thought that in case of USB, the scrambling
> is done in user space, and in case of BT, the same scrambling made in the
> kernel. They looks very similar so I thought the user-space scramble for
> USB would have fit. However, the 4-bits/1-bits kills that assumption.
You're correct - USB requires scrambling in the user space, but
scrambling for USB is different than for BT. Example of USB scramble is
here: https://github.com/PrzemoF/i4oled/blob/master/src/i4oled.c#L401
> >
> > If we want to make it consistent single entry on kernel level we
> > probably have to implement image conversion in the kernel. The user land
> > would always use 4-bit, plain formatted images and kernel driver would
> > convert them to 4-bit, wacom usb format or 1-bit wacom bluetooth format
> > depending on how the tablet is connected.
> >
> > The downside of this approach is that the user land wouldn't have 100%
> > control over 1-bit images for bluetooth as kernel would have to create
> > them from 4-bit images.
>
> The USB interface is *very* simple:
> - if incoming data != 1024 -> reject
> - forward everything to the device without in kernel treatment*
>
> How about just changing the expected size to 256 in case of a BT tablet,
> and let the user-space scramble in both cases and forward proper raw
> data?
>
> This way, user space will still have control over 1-bit vs 4-bits, and
> the changes required in the kernel will be small enough.
Sounds good to me. Bit more coding in gnome, but it's a small thing.
> My concern is that I'd like to have this series in 3.17 and I will not
> have access to the hardware until next week :/
> Having all of the user-spaces breakages in the same kernel release will
> I think simplify the user space work.
I agree.
P.S. Could you send me that set of 23 patches using git-send-email that
I should apply on top of linux-next? I got it from lkml, but there is
still something messed (fails on patch 09/23). Of course, if it's not a
problem for you :-)
--
Kind regards,
Przemo Firszt
--
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 00/10] Input - wacom: conversion to HID driver, series 2
From: Benjamin Tissoires @ 2014-07-25 19:32 UTC (permalink / raw)
To: Przemo Firszt
Cc: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
linux-kernel, linux-input
In-Reply-To: <1406316376.12682.18.camel@fedora-lan>
On Jul 25 2014 or thereabouts, Przemo Firszt wrote:
> Dnia 2014-07-25, pią o godzinie 10:54 -0400, Benjamin Tissoires pisze:
> > [..]
> Hi Benjamin,
> >
> > > If I understand you correctly we cannot have the same entry point in
> > > sysfs for OLEDs unless we can tell userspace somehow if the tablet is
> > > conected over USB or over bluetooth. The hardware of Intuos4 Wireless
> > > over bluetooth allows only 1-bit images. The same hardware over USB
> > > allows 4-bit images. Formatting of the images is also completely
> >
> > Holy crap! I missed that. I did not noticed the 1-bit vs 4-bits
> > difference :(
> >
> > > different and it's not "plain". Check [1] for usb and exisitng
> > > hid-wacom.c/wacom_scramble function for bluetooth.
> >
> > Maybe I overlooked it, but I thought that in case of USB, the scrambling
> > is done in user space, and in case of BT, the same scrambling made in the
> > kernel. They looks very similar so I thought the user-space scramble for
> > USB would have fit. However, the 4-bits/1-bits kills that assumption.
>
> You're correct - USB requires scrambling in the user space, but
> scrambling for USB is different than for BT. Example of USB scramble is
> here: https://github.com/PrzemoF/i4oled/blob/master/src/i4oled.c#L401
>
> > >
> > > If we want to make it consistent single entry on kernel level we
> > > probably have to implement image conversion in the kernel. The user land
> > > would always use 4-bit, plain formatted images and kernel driver would
> > > convert them to 4-bit, wacom usb format or 1-bit wacom bluetooth format
> > > depending on how the tablet is connected.
> > >
> > > The downside of this approach is that the user land wouldn't have 100%
> > > control over 1-bit images for bluetooth as kernel would have to create
> > > them from 4-bit images.
> >
> > The USB interface is *very* simple:
> > - if incoming data != 1024 -> reject
> > - forward everything to the device without in kernel treatment*
> >
> > How about just changing the expected size to 256 in case of a BT tablet,
> > and let the user-space scramble in both cases and forward proper raw
> > data?
> >
> > This way, user space will still have control over 1-bit vs 4-bits, and
> > the changes required in the kernel will be small enough.
> Sounds good to me. Bit more coding in gnome, but it's a small thing.
yeah, gnome already scramble for USB, let's have it scramble for BT too
:)
>
> > My concern is that I'd like to have this series in 3.17 and I will not
> > have access to the hardware until next week :/
> > Having all of the user-spaces breakages in the same kernel release will
> > I think simplify the user space work.
> I agree.
OK.
>
> P.S. Could you send me that set of 23 patches using git-send-email that
> I should apply on top of linux-next? I got it from lkml, but there is
> still something messed (fails on patch 09/23). Of course, if it's not a
> problem for you :-)
Sure, I can definitively do that. I also made a small patch to check for
1024 or 256 bits in OLEDs, so if you could give a try, that would be
great.
Cheers,
Benjamin
--
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] Input: wacom_serial4 - prepare for wacom USB moving to HID
From: Dmitry Torokhov @ 2014-07-25 19:42 UTC (permalink / raw)
To: Hans de Goede
Cc: Julian Squires, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <53D2AAB4.1090109@redhat.com>
On Fri, Jul 25, 2014 at 09:06:28PM +0200, Hans de Goede wrote:
> Hi,
>
> On 07/24/2014 10:31 PM, Dmitry Torokhov wrote:
> > wacom_wac.h will be moving to drivers/hid. Since we only need 3 definitions
> > from it let's simply copy them over.
> >
> > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>
> Ack, but you will want to drop the #include of wacom_wac.h yoo.
Right, that was in my v2 ;)
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH 00/15] atmel_mxt_ts - device tree, bootloader, etc
From: Stephen Warren @ 2014-07-25 20:06 UTC (permalink / raw)
To: Nick Dyer, Dmitry Torokhov, Yufeng Shen
Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
Benson Leung, Olof Johansson, Sekhar Nori
In-Reply-To: <53D26572.3030404@itdev.co.uk>
On 07/25/2014 08:10 AM, Nick Dyer wrote:
> On 24/07/14 22:19, Stephen Warren wrote:
...
>> I've uploaded 2 logs to:
>>
>> http://avon.wwwdotorg.org/downloads/mxt-logs/
>> (note there's no directory indexing, so manually add the filenames below to
>> the URL)
>>
>> mxt-save-no-movement.xml
>>
>> This is with the whole series applied. Neither mouse movement nor clicks
>> works. I tried mxt-app --reset and it made no difference to the dump results.
>>
>> mxt-save-move-ok-no-clicking.xml
>>
>> This is with "Input: atmel_mxt_ts - use deep sleep mode when stopped"
>> reverted; mouse movement works, but clicking doesn't.
>
> Great, this has identified the issue with mouse movement (touch).
>
> The config programmed into the NVRAM on your touch controller has the first
> byte of the T9 touchscreen object set to zero. This is the CTRL byte which
> enables/disables the touch object and what it reports. It is relying on
> this to enable the touchscreen on resume:
>
> https://github.com/dtor/input/blob/9d8dc3e529/drivers/input/touchscreen/atmel_mxt_ts.c#L2005-L2006
>
> My "use deep sleep mode when stopped" patch stops the driver writing to the
> T9.CTRL byte, so whatever config you have in NVRAM for that byte will be
> used (ie zero, disabled). Going forward, deep sleep is more generic.
> Indeed, newer chips do not have T9 at all, or they might be using other
> touch objects. The deep sleep mode is a lower power state to be in, and is
> what Atmel recommends.
>
> However, it does mean changing the maxtouch cfg - you can write the 0x83 to
> the first byte of T9 and save it to NVRAM, by doing:
>
> mxt-app [device] -W -T9 83
> mxt-app [device] --backup
If I do that, then both mouse movement and "touch" clicks work:-)
(Dmitry, I guess that means it's fine to go ahead and apply "Input:
atmel_mxt_ts - use deep sleep mode when stopped".)
I wonder why the configuration NVRAM in my device was incorrect though?
I'm CCing a few ChromeOS people to try and find out any relevant history
for the touchpad NVRAM settings on Venice2. Perhaps this is simply
something that wasn't noticed because the driver used to initialize this
configuration bit, so nobody realized the config in NVRAM was wrong.
...
> About the clicking - what does getevent -lp show? It should show the
> BTN_LEFT key. If that is working correctly, then the driver isn't parsing
> the messages correctly, it would be useful if you could add a
> mxt_dump_message() call to mxt_input_button() and capture some dmesg output
> of pressing the button.
I'm not sure what getevent is, but I think I tracked down the issue anyway.
With the NVRAM config fix you mentioned, "touch" clicks work OK.
However, as such as I do a "physical" click (push the touchpad down),
all kinds of click stop working. I think the answer lies in evtest logs:
First "touch" click (with touch pressure/position events removed):
> Event: time 1406318070.891773, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
> Event: time 1406318070.891773, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 1
...
> Event: time 1406318070.941752, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
> Event: time 1406318070.941752, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 0
The second "touch" click generates the same events. Note how all the
events are correctly mirrored between down/up events.
Now, the first "physical" click:
> Event: time 1406318085.303424, type 1 (EV_KEY), code 272 (BTN_LEFT), value 1
...
> Event: time 1406318085.319818, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
> Event: time 1406318085.319818, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 1
...
> Event: time 1406318085.515763, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
> Event: time 1406318085.515763, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 0
Note the extra BTN_LEFT down event, which has no corresponding "up"
event. After this, subsequent "physical" clicks don't generate any more
BTN_LEFT events (down or up) at all, and a USB mouse's BTN_LEFT events
are ignored, I suppose since the system still thinks the touchpad's left
button is being held down.
Is this a driver bug (not generating the correct BTN_LEFT events), or
some other touchpad HW/NVRAM configuration problem?
^ permalink raw reply
* Re: [PATCH v2] Input: add i2c/smbus driver for elan touchpad
From: Dmitry Torokhov @ 2014-07-25 20:06 UTC (permalink / raw)
To: cheng wei Lin
Cc: linux-kernel, linux-input, bleung, agnescheng,
"SRD1 �蝬踐��?都����",
jeff.chuang
In-Reply-To: <20140725182053.GA23356@core.coreip.homeip.net>
On Fri, Jul 25, 2014 at 11:20:53AM -0700, Dmitry Torokhov wrote:
> Hi Duson,
>
> On Sat, Jul 26, 2014 at 02:05:02AM +0800, cheng wei Lin wrote:
> > Hi Dmitry,
> >
> > Sorry for late to reply you and thanks for your command
> >
> > Yes, I also agree, it looks great than my original code.
>
> Thank you for confirming.
>
> > So, should I modify this and upstream v3 patch for you?
>
> No, that is fine, I'll fix it up on my end.
Hmm, I am also looking at elan_get_x_resolution() and in case of SMB
we'll never get negative result since we are doing
"elan_convert_res(val[1] & 0x0F)". Was it intended as such, or do we
need to extend sign here via
(((char)(val[1] & 0x0F)) << 4) >> 4;
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Przemo Firszt @ 2014-07-25 22:13 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
linux-kernel, linux-input
In-Reply-To: <1406225645-32141-1-git-send-email-benjamin.tissoires@redhat.com>
Dnia 2014-07-24, czw o godzinie 14:13 -0400, Benjamin Tissoires pisze:
[..]
Hi Benjamin,
I'm testing the whole series including the OLED patch that's not on the
list yet.
Hardware: 2 x Intuos4 Wireless tested on usb and bluetooth until noted
otherwise.
What works:
1. Tablet in general, pressure, tilt, buttons etc.
2. Battery reporting (including gnome). The double wireless tablet bug
is gone:
$ ls /sys/class/power_supply/
AC BAT0 wacom_ac_2 wacom_ac_3 wacom_battery_2 wacom_battery_3
3. Setting LED selector value
4. Setting LED selector brightness (default and pressed)
5. Rendering images to button displays works on usb ONLY.
$ i4oled -d /sys/bus/hid/drivers/wacom/0003\:056A\:00BC.0009/wacom_led/button0_rawimg -t Linux
On bluetooth writing image goes fine (no error), but there is nothing showing up,
so I suspect the brightness of OLED displays is not set properly.
That's the code before changes:
led = wdata->led_selector | 0x04;
buf = kzalloc(9, GFP_KERNEL);
if (buf) {
buf[0] = WAC_CMD_LED_CONTROL;
buf[1] = led;
buf[2] = value >> 2;
buf[3] = value;
/* use fixed brightness for OLEDs */
buf[4] = 0x08;
hid_hw_raw_request(hdev, buf[0], buf, 9, HID_FEATURE_REPORT,
HID_REQ_SET_REPORT);
kfree(buf);
}
I don't remember for sure, but I think the range of brightness might be different
over usb and over bluetooth.
TL;DR: the only thing that needs to be fixed is image-over-bluetooth, probably caused by not
setting or incorrect setting of OLED brightness.
--
Kind regards,
Przemo Firszt
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Benjamin Tissoires @ 2014-07-25 23:15 UTC (permalink / raw)
To: Przemo Firszt
Cc: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
linux-kernel, linux-input
In-Reply-To: <1406326412.4674.22.camel@fedora-lan>
Hi Przemo,
On Jul 25 2014 or thereabouts, Przemo Firszt wrote:
> Dnia 2014-07-24, czw o godzinie 14:13 -0400, Benjamin Tissoires pisze:
> [..]
> Hi Benjamin,
> I'm testing the whole series including the OLED patch that's not on the
> list yet.
>
> Hardware: 2 x Intuos4 Wireless tested on usb and bluetooth until noted
> otherwise.
>
> What works:
> 1. Tablet in general, pressure, tilt, buttons etc.
> 2. Battery reporting (including gnome). The double wireless tablet bug
> is gone:
>
> $ ls /sys/class/power_supply/
> AC BAT0 wacom_ac_2 wacom_ac_3 wacom_battery_2 wacom_battery_3
>
> 3. Setting LED selector value
> 4. Setting LED selector brightness (default and pressed)
> 5. Rendering images to button displays works on usb ONLY.
>
> $ i4oled -d /sys/bus/hid/drivers/wacom/0003\:056A\:00BC.0009/wacom_led/button0_rawimg -t Linux
>
> On bluetooth writing image goes fine (no error), but there is nothing showing up,
> so I suspect the brightness of OLED displays is not set properly.
>
> That's the code before changes:
>
> led = wdata->led_selector | 0x04;
> buf = kzalloc(9, GFP_KERNEL);
> if (buf) {
> buf[0] = WAC_CMD_LED_CONTROL;
> buf[1] = led;
> buf[2] = value >> 2;
> buf[3] = value;
> /* use fixed brightness for OLEDs */
> buf[4] = 0x08;
> hid_hw_raw_request(hdev, buf[0], buf, 9, HID_FEATURE_REPORT,
> HID_REQ_SET_REPORT);
> kfree(buf);
> }
>
> I don't remember for sure, but I think the range of brightness might be different
> over usb and over bluetooth.
Maybe you can try setting the sysfs file "buttons_luminance" with the
value 8 to check if this will solve the bug.
The bug might also be linked to the slight difference while setting up
the transfer of the image (WAC_CMD_ICON_START) with the value of buf[1]
set to 1 in USB, while it was 0 on bluetooth.
The weird thing is that I remembered having set the OLED (though
scrambled) with these patches applied. I guess the scrambling was due to
the 4-bit vs 1-bit. But I definitively had some results.
Anyway. Przemo, Dmitry, can we consider that this *will* be fixed by
next week, and so we can apply the series for 3.17?
I will have the hardware next week and be able to figure out the
differences between the 2 communication modes.
>
> TL;DR: the only thing that needs to be fixed is image-over-bluetooth, probably caused by not
> setting or incorrect setting of OLED brightness.
Thanks for the extensive testings. I'll send the "OLED patch that's not
on the list yet" as a 11/10 so everybody can have a look.
Cheers,
Benjamin
^ permalink raw reply
* [PATCH 11/10] Input - wacom: Check for bluetooth protocol while setting OLEDs
From: Benjamin Tissoires @ 2014-07-25 23:20 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Ping Cheng, Jason Gerecke,
Przemo Firszt
Cc: linux-kernel, linux-input
In-Reply-To: <1406225645-32141-1-git-send-email-benjamin.tissoires@redhat.com>
Bluetooth Intuos 4 use 1-bit definition while the USB ones use a 4-bits
definition. This changes the size of the raw image we receive, and thus
the kernel will only accept 1-bit images for Bluetooth and 4-bits for
USB.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/wacom_sys.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 3adc6ef..42f139f 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -531,12 +531,14 @@ static int wacom_led_control(struct wacom *wacom)
return retval;
}
-static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *img)
+static int wacom_led_putimage(struct wacom *wacom, int button_id,
+ const unsigned len, const void *img)
{
unsigned char *buf;
int i, retval;
+ const unsigned chunk_len = len / 4; /* 4 chunks are needed to be sent */
- buf = kzalloc(259, GFP_KERNEL);
+ buf = kzalloc(chunk_len + 3 , GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -552,11 +554,11 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im
buf[1] = button_id & 0x07;
for (i = 0; i < 4; i++) {
buf[2] = i;
- memcpy(buf + 3, img + i * 256, 256);
+ memcpy(buf + 3, img + i * chunk_len, chunk_len);
retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT,
WAC_CMD_ICON_XFER,
- buf, 259, WAC_CMD_RETRIES);
+ buf, chunk_len + 3, WAC_CMD_RETRIES);
if (retval < 0)
break;
}
@@ -657,13 +659,14 @@ static ssize_t wacom_button_image_store(struct device *dev, int button_id,
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
struct wacom *wacom = hid_get_drvdata(hdev);
int err;
+ const unsigned len = hdev->bus == BUS_BLUETOOTH ? 256 : 1024;
- if (count != 1024)
+ if (count != len)
return -EINVAL;
mutex_lock(&wacom->lock);
- err = wacom_led_putimage(wacom, button_id, buf);
+ err = wacom_led_putimage(wacom, button_id, len, buf);
mutex_unlock(&wacom->lock);
--
2.0.1
^ permalink raw reply related
* [PATCH] Input: synaptics - properly initialize slots for semi-MT
From: Dmitry Torokhov @ 2014-07-26 0:27 UTC (permalink / raw)
To: linux-input
Cc: Hans de Goede, Benjamin Tissoires, Benson Leung, Henrik Rydberg,
linux-kernel
Semi-MT devices are pointers too, so let's tell that to
input_mt_init_slots(), as well as let it set up the devices as semi-MT,
instead of us doing it manually.
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/synaptics.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index ef9e0b8..fe607e9 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1371,11 +1371,11 @@ static void set_input_params(struct psmouse *psmouse,
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
__set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
} else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
- /* Non-image sensors with AGM use semi-mt */
- __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
- input_mt_init_slots(dev, 2, 0);
set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
ABS_MT_POSITION_Y);
+ /* Non-image sensors with AGM use semi-mt */
+ input_mt_init_slots(dev, 2,
+ INPUT_MT_POINTER | INPUT_MT_SEMI_MT);
}
if (SYN_CAP_PALMDETECT(priv->capabilities))
--
2.0.0.526.g5318336
--
Dmitry
^ permalink raw reply related
* Re: [PATCH v2 06/10] Input - wacom: prepare the driver to include BT devices
From: Dmitry Torokhov @ 2014-07-26 0:39 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <1406225645-32141-7-git-send-email-benjamin.tissoires@redhat.com>
Hi Benjamin,
On Thu, Jul 24, 2014 at 02:14:01PM -0400, Benjamin Tissoires wrote:
> Now that wacom is a hid driver, there is no point in having a separate
> driver for bluetooth devices.
> This patch prepares the common paths of Bluetooth devices in the
> common wacom driver.
> It also adds the sysfs file "speed" used by Bluetooth devices.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
>
> new in v2
>
> drivers/hid/wacom_sys.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++---
> drivers/hid/wacom_wac.h | 2 ++
> 2 files changed, 69 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index d0d06b8..add76ec 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -262,6 +262,12 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> return error < 0 ? error : 0;
> }
>
> +static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
> + struct wacom_features *features)
> +{
> + return 0;
> +}
> +
> /*
> * Switch the tablet into its most-capable mode. Wacom tablets are
> * typically configured to power-up in a mode which sends mouse-like
> @@ -272,6 +278,9 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> static int wacom_query_tablet_data(struct hid_device *hdev,
> struct wacom_features *features)
> {
> + if (hdev->bus == BUS_BLUETOOTH)
> + return wacom_bt_query_tablet_data(hdev, 1, features);
> +
> if (features->device_type == BTN_TOOL_FINGER) {
> if (features->type > TABLETPC) {
> /* MT Tablet PC touch */
> @@ -890,6 +899,38 @@ static void wacom_destroy_battery(struct wacom *wacom)
> }
> }
>
> +static ssize_t wacom_show_speed(struct device *dev,
> + struct device_attribute
> + *attr, char *buf)
> +{
> + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> + struct wacom *wacom = hid_get_drvdata(hdev);
> +
> + return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
> +}
> +
> +static ssize_t wacom_store_speed(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> + struct wacom *wacom = hid_get_drvdata(hdev);
> + int new_speed;
> +
> + if (sscanf(buf, "%1d", &new_speed ) != 1)
Checkpach is unhappy with ')' placement and I agree with it.
> + return -EINVAL;
kstrtou8?
> +
> + if (new_speed == 0 || new_speed == 1) {
> + wacom_bt_query_tablet_data(hdev, new_speed,
> + &wacom->wacom_wac.features);
> + return strnlen(buf, PAGE_SIZE);
This is weird. Normally you want to return count since you should refuse
input with excessive data.
> + } else
> + return -EINVAL;
Need braces on both branches.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Dmitry Torokhov @ 2014-07-26 1:41 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <1406225645-32141-1-git-send-email-benjamin.tissoires@redhat.com>
Hi Benjamin,
On Thu, Jul 24, 2014 at 02:13:55PM -0400, Benjamin Tissoires wrote:
> Hi Dmitry,
>
> this is the second series I told you about for wacom.ko. This series also have
> a good number of removed lines of code. \o/
>
> The first patch is Jason's one that I finally decided to take with me. His
> previous submission still applied correctly even after the moving of the files
> (git is definitively awesome).
>
> The second one is a patch I sent earlier and forgot to include in the v2 of
> the first series. It might have been dropped during my many rebases. So here
> he is.
>
> The rest is for one part enhancing the battery reporting system (to make it
> equal to the one in hid-wacom, and even slightly better). The other part
> is the actual merge of hid-wacom into wacom which gives the same user space API
> for bluetooth and USB devices, fixes the pad-in-a-separate-input-dev, and
> fixes the missing tools not supported in the previous implementation of
> hid-wacom for Intuos 4 BT.
>
I ended up taking 3.16-rc6 and applying your first series and the first
5 patches of this series to it. You should be able to see the result on
kernel.org in wacom branch.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Benjamin Tissoires @ 2014-07-26 3:21 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <20140726014129.GB16900@core.coreip.homeip.net>
On Jul 25 2014 or thereabouts, Dmitry Torokhov wrote:
> Hi Benjamin,
>
> On Thu, Jul 24, 2014 at 02:13:55PM -0400, Benjamin Tissoires wrote:
> > Hi Dmitry,
> >
> > this is the second series I told you about for wacom.ko. This series also have
> > a good number of removed lines of code. \o/
> >
> > The first patch is Jason's one that I finally decided to take with me. His
> > previous submission still applied correctly even after the moving of the files
> > (git is definitively awesome).
> >
> > The second one is a patch I sent earlier and forgot to include in the v2 of
> > the first series. It might have been dropped during my many rebases. So here
> > he is.
> >
> > The rest is for one part enhancing the battery reporting system (to make it
> > equal to the one in hid-wacom, and even slightly better). The other part
> > is the actual merge of hid-wacom into wacom which gives the same user space API
> > for bluetooth and USB devices, fixes the pad-in-a-separate-input-dev, and
> > fixes the missing tools not supported in the previous implementation of
> > hid-wacom for Intuos 4 BT.
> >
>
> I ended up taking 3.16-rc6 and applying your first series and the first
> 5 patches of this series to it. You should be able to see the result on
> kernel.org in wacom branch.
Cool. The resolution of the hid-core.c conflict is in fact better than
what I proposed. It should not conflict with Jiri's pull request IMO. And
when the two branches will hit Linus' we can then un-split hid-rmi and
wacom processes.
I also noticed few differences. Some of them you obviously made, I am
fine with them BTW, and some other I think because your current next
branch already has some wacom patches queued. I guess you will handle
this just fine, as usual, but I'll try to keep an eye on it just in case
git messed up the merge and forgot one branch.
Thanks again Dmitry. And sorry for have pushed you regarding that.
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH v2 06/10] Input - wacom: prepare the driver to include BT devices
From: Benjamin Tissoires @ 2014-07-26 3:25 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <20140726003909.GA16900@core.coreip.homeip.net>
On Jul 25 2014 or thereabouts, Dmitry Torokhov wrote:
> Hi Benjamin,
>
> On Thu, Jul 24, 2014 at 02:14:01PM -0400, Benjamin Tissoires wrote:
> > Now that wacom is a hid driver, there is no point in having a separate
> > driver for bluetooth devices.
> > This patch prepares the common paths of Bluetooth devices in the
> > common wacom driver.
> > It also adds the sysfs file "speed" used by Bluetooth devices.
> >
> > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > ---
> >
> > new in v2
> >
> > drivers/hid/wacom_sys.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++---
> > drivers/hid/wacom_wac.h | 2 ++
> > 2 files changed, 69 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> > index d0d06b8..add76ec 100644
> > --- a/drivers/hid/wacom_sys.c
> > +++ b/drivers/hid/wacom_sys.c
> > @@ -262,6 +262,12 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> > return error < 0 ? error : 0;
> > }
> >
> > +static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
> > + struct wacom_features *features)
> > +{
> > + return 0;
> > +}
> > +
> > /*
> > * Switch the tablet into its most-capable mode. Wacom tablets are
> > * typically configured to power-up in a mode which sends mouse-like
> > @@ -272,6 +278,9 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> > static int wacom_query_tablet_data(struct hid_device *hdev,
> > struct wacom_features *features)
> > {
> > + if (hdev->bus == BUS_BLUETOOTH)
> > + return wacom_bt_query_tablet_data(hdev, 1, features);
> > +
> > if (features->device_type == BTN_TOOL_FINGER) {
> > if (features->type > TABLETPC) {
> > /* MT Tablet PC touch */
> > @@ -890,6 +899,38 @@ static void wacom_destroy_battery(struct wacom *wacom)
> > }
> > }
> >
> > +static ssize_t wacom_show_speed(struct device *dev,
> > + struct device_attribute
> > + *attr, char *buf)
> > +{
> > + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> > + struct wacom *wacom = hid_get_drvdata(hdev);
> > +
> > + return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
> > +}
> > +
> > +static ssize_t wacom_store_speed(struct device *dev,
> > + struct device_attribute *attr,
> > + const char *buf, size_t count)
> > +{
> > + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> > + struct wacom *wacom = hid_get_drvdata(hdev);
> > + int new_speed;
> > +
> > + if (sscanf(buf, "%1d", &new_speed ) != 1)
>
> Checkpach is unhappy with ')' placement and I agree with it.
>
ouch
> > + return -EINVAL;
>
> kstrtou8?
re-ouch
>
> > +
> > + if (new_speed == 0 || new_speed == 1) {
> > + wacom_bt_query_tablet_data(hdev, new_speed,
> > + &wacom->wacom_wac.features);
> > + return strnlen(buf, PAGE_SIZE);
>
> This is weird. Normally you want to return count since you should refuse
> input with excessive data.
indeed
>
> > + } else
> > + return -EINVAL;
>
> Need braces on both branches.
>
Grmblmbl. I should not have blinded copied the code from one driver to
one other. I will send a v3 of the rest of the series on top of your
wacom branch, at some point next week. Other people can still try to
find out other mistakes meanwhile ;)
Thanks for the review.
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH v2 00/10] Input - wacom: conversion to HID driver, series 2
From: Dmitry Torokhov @ 2014-07-26 3:56 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <20140726032127.GB2279@mail.corp.redhat.com>
On Fri, Jul 25, 2014 at 11:21:27PM -0400, Benjamin Tissoires wrote:
> On Jul 25 2014 or thereabouts, Dmitry Torokhov wrote:
> > Hi Benjamin,
> >
> > On Thu, Jul 24, 2014 at 02:13:55PM -0400, Benjamin Tissoires wrote:
> > > Hi Dmitry,
> > >
> > > this is the second series I told you about for wacom.ko. This series also have
> > > a good number of removed lines of code. \o/
> > >
> > > The first patch is Jason's one that I finally decided to take with me. His
> > > previous submission still applied correctly even after the moving of the files
> > > (git is definitively awesome).
> > >
> > > The second one is a patch I sent earlier and forgot to include in the v2 of
> > > the first series. It might have been dropped during my many rebases. So here
> > > he is.
> > >
> > > The rest is for one part enhancing the battery reporting system (to make it
> > > equal to the one in hid-wacom, and even slightly better). The other part
> > > is the actual merge of hid-wacom into wacom which gives the same user space API
> > > for bluetooth and USB devices, fixes the pad-in-a-separate-input-dev, and
> > > fixes the missing tools not supported in the previous implementation of
> > > hid-wacom for Intuos 4 BT.
> > >
> >
> > I ended up taking 3.16-rc6 and applying your first series and the first
> > 5 patches of this series to it. You should be able to see the result on
> > kernel.org in wacom branch.
>
> Cool. The resolution of the hid-core.c conflict is in fact better than
> what I proposed. It should not conflict with Jiri's pull request IMO. And
> when the two branches will hit Linus' we can then un-split hid-rmi and
> wacom processes.
>
> I also noticed few differences. Some of them you obviously made, I am
> fine with them BTW, and some other I think because your current next
> branch already has some wacom patches queued. I guess you will handle
> this just fine, as usual, but I'll try to keep an eye on it just in case
> git messed up the merge and forgot one branch.
>
> Thanks again Dmitry. And sorry for have pushed you regarding that.
No worries, I need to be pushed sometimes ;)
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 06/10] Input - wacom: prepare the driver to include BT devices
From: Dmitry Torokhov @ 2014-07-26 3:58 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, Przemo Firszt,
linux-kernel, linux-input
In-Reply-To: <20140726032517.GC2279@mail.corp.redhat.com>
On Fri, Jul 25, 2014 at 11:25:17PM -0400, Benjamin Tissoires wrote:
> On Jul 25 2014 or thereabouts, Dmitry Torokhov wrote:
> > Hi Benjamin,
> >
> > On Thu, Jul 24, 2014 at 02:14:01PM -0400, Benjamin Tissoires wrote:
> > > Now that wacom is a hid driver, there is no point in having a separate
> > > driver for bluetooth devices.
> > > This patch prepares the common paths of Bluetooth devices in the
> > > common wacom driver.
> > > It also adds the sysfs file "speed" used by Bluetooth devices.
> > >
> > > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > > ---
> > >
> > > new in v2
> > >
> > > drivers/hid/wacom_sys.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++---
> > > drivers/hid/wacom_wac.h | 2 ++
> > > 2 files changed, 69 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> > > index d0d06b8..add76ec 100644
> > > --- a/drivers/hid/wacom_sys.c
> > > +++ b/drivers/hid/wacom_sys.c
> > > @@ -262,6 +262,12 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> > > return error < 0 ? error : 0;
> > > }
> > >
> > > +static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
> > > + struct wacom_features *features)
> > > +{
> > > + return 0;
> > > +}
> > > +
> > > /*
> > > * Switch the tablet into its most-capable mode. Wacom tablets are
> > > * typically configured to power-up in a mode which sends mouse-like
> > > @@ -272,6 +278,9 @@ static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
> > > static int wacom_query_tablet_data(struct hid_device *hdev,
> > > struct wacom_features *features)
> > > {
> > > + if (hdev->bus == BUS_BLUETOOTH)
> > > + return wacom_bt_query_tablet_data(hdev, 1, features);
> > > +
> > > if (features->device_type == BTN_TOOL_FINGER) {
> > > if (features->type > TABLETPC) {
> > > /* MT Tablet PC touch */
> > > @@ -890,6 +899,38 @@ static void wacom_destroy_battery(struct wacom *wacom)
> > > }
> > > }
> > >
> > > +static ssize_t wacom_show_speed(struct device *dev,
> > > + struct device_attribute
> > > + *attr, char *buf)
> > > +{
> > > + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> > > + struct wacom *wacom = hid_get_drvdata(hdev);
> > > +
> > > + return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
> > > +}
> > > +
> > > +static ssize_t wacom_store_speed(struct device *dev,
> > > + struct device_attribute *attr,
> > > + const char *buf, size_t count)
> > > +{
> > > + struct hid_device *hdev = container_of(dev, struct hid_device, dev);
> > > + struct wacom *wacom = hid_get_drvdata(hdev);
> > > + int new_speed;
> > > +
> > > + if (sscanf(buf, "%1d", &new_speed ) != 1)
> >
> > Checkpach is unhappy with ')' placement and I agree with it.
> >
>
> ouch
>
> > > + return -EINVAL;
> >
> > kstrtou8?
>
> re-ouch
>
> >
> > > +
> > > + if (new_speed == 0 || new_speed == 1) {
> > > + wacom_bt_query_tablet_data(hdev, new_speed,
> > > + &wacom->wacom_wac.features);
> > > + return strnlen(buf, PAGE_SIZE);
> >
> > This is weird. Normally you want to return count since you should refuse
> > input with excessive data.
>
> indeed
>
> >
> > > + } else
> > > + return -EINVAL;
> >
> > Need braces on both branches.
> >
>
> Grmblmbl. I should not have blinded copied the code from one driver to
> one other. I will send a v3 of the rest of the series on top of your
> wacom branch, at some point next week. Other people can still try to
> find out other mistakes meanwhile ;)
Great, will be waiting for it and then will merge everything into next for
3.17.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH 14/14] alps: Add support for v7 devices
From: Dmitry Torokhov @ 2014-07-26 5:58 UTC (permalink / raw)
To: Hans de Goede; +Cc: Yunkang Tang, linux-input
In-Reply-To: <1404919459-23561-15-git-send-email-hdegoede@redhat.com>
Hi Hans,
On Wed, Jul 09, 2014 at 05:24:19PM +0200, Hans de Goede wrote:
> From: Yunkang Tang <yunkang.tang@cn.alps.com>
>
> Such as found on the new Toshiba Portégé Z30-A and Z40-A.
>
> Signed-off-by: Yunkang Tang <yunkang.tang@cn.alps.com>
> [hdegoede@redhat.com: Remove softbutton handling, this is done in userspace]
> [hdegoede@redhat.com: Report INPUT_PROP_BUTTONPAD]
> [hdegoede@redhat.com: Do not report fake PRESSURE, reporting BTN_TOUCH is
> enough]
> [hdegoede@redhat.com: Various cleanups / refactoring]
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> drivers/input/mouse/alps.c | 257 ++++++++++++++++++++++++++++++++++++++++++++-
> drivers/input/mouse/alps.h | 18 ++++
> 2 files changed, 272 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
> index ad3a708..8b9b4b0 100644
> --- a/drivers/input/mouse/alps.c
> +++ b/drivers/input/mouse/alps.c
> @@ -100,6 +100,7 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
> #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with
> 6-byte ALPS packet */
> #define ALPS_IS_RUSHMORE 0x100 /* device is a rushmore */
> +#define ALPS_BUTTONPAD 0x200 /* device is a clickpad */
>
> static const struct alps_model_info alps_model_data[] = {
> { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
> @@ -845,6 +846,177 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
> alps_report_semi_mt_data(psmouse, f->fingers);
> }
>
> +static bool alps_is_valid_package_v7(struct psmouse *psmouse)
> +{
> + if ((psmouse->pktcnt == 3) && ((psmouse->packet[2] & 0x40) != 0x40))
> + return false;
> + if ((psmouse->pktcnt == 4) && ((psmouse->packet[3] & 0x48) != 0x48))
> + return false;
> + if ((psmouse->pktcnt == 6) && ((psmouse->packet[5] & 0x40) != 0x0))
> + return false;
> + return true;
Maybe:
switch (psmouse->pktcnt) {
case 3:
return (psmouse->packet[2] & 0x40) == 0x40;
case 4:
return (psmouse->packet[3] & 0x48) == 0x48;
case 6:
return (psmouse->packet[5] & 0x40) == 0x00;
}
return true;
?
> +}
> +
> +static unsigned char alps_get_packet_id_v7(char *byte)
> +{
> + unsigned char packet_id;
> +
> + if (byte[4] & 0x40)
> + packet_id = V7_PACKET_ID_TWO;
> + else if (byte[4] & 0x01)
> + packet_id = V7_PACKET_ID_MULTI;
> + else if ((byte[0] & 0x10) && !(byte[4] & 0x43))
> + packet_id = V7_PACKET_ID_NEW;
> + else if (byte[1] == 0x00 && byte[4] == 0x00)
> + packet_id = V7_PACKET_ID_IDLE;
> + else
> + packet_id = V7_PACKET_ID_UNKNOWN;
> +
> + return packet_id;
> +}
> +
> +static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
> + unsigned char *pkt,
> + unsigned char pkt_id)
> +{
> + mt[0].x = ((pkt[2] & 0x80) << 4);
> + mt[0].x |= ((pkt[2] & 0x3F) << 5);
> + mt[0].x |= ((pkt[3] & 0x30) >> 1);
> + mt[0].x |= (pkt[3] & 0x07);
> + mt[0].y = (pkt[1] << 3) | (pkt[0] & 0x07);
> +
> + mt[1].x = ((pkt[3] & 0x80) << 4);
> + mt[1].x |= ((pkt[4] & 0x80) << 3);
> + mt[1].x |= ((pkt[4] & 0x3F) << 4);
> + mt[1].y = ((pkt[5] & 0x80) << 3);
> + mt[1].y |= ((pkt[5] & 0x3F) << 4);
> +
> + if (pkt_id == V7_PACKET_ID_TWO) {
> + mt[1].x &= ~0x000F;
> + mt[1].y |= 0x000F;
> + } else if (pkt_id == V7_PACKET_ID_MULTI) {
> + mt[1].x &= ~0x003F;
> + mt[1].y &= ~0x0020;
> + mt[1].y |= ((pkt[4] & 0x02) << 4);
> + mt[1].y |= 0x001F;
> + } else if (pkt_id == V7_PACKET_ID_NEW) {
> + mt[1].x &= ~0x003F;
> + mt[1].x |= (pkt[0] & 0x20);
> + mt[1].y |= 0x000F;
> + }
> +
> + mt[0].y = 0x7FF - mt[0].y;
> + mt[1].y = 0x7FF - mt[1].y;
> +}
> +
> +static int alps_get_mt_count(struct input_mt_pos *mt)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++)
> + ;
/* empty */;
just to make sure...
> +
> + return i;
> +}
> +
> +static int alps_decode_packet_v7(struct alps_fields *f,
> + unsigned char *p,
> + struct psmouse *psmouse)
> +{
> + unsigned char pkt_id;
> +
> + pkt_id = alps_get_packet_id_v7(p);
> + if (pkt_id == V7_PACKET_ID_IDLE)
> + return 0;
> + if (pkt_id == V7_PACKET_ID_UNKNOWN)
> + return -1;
> +
> + alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
> +
> + if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) {
> + f->left = (p[0] & 0x80) >> 7;
> + f->right = (p[0] & 0x20) >> 5;
> + f->middle = (p[0] & 0x10) >> 4;
> + }
> +
> + if (pkt_id == V7_PACKET_ID_TWO)
> + f->fingers = alps_get_mt_count(f->mt);
> + else if (pkt_id == V7_PACKET_ID_MULTI)
> + f->fingers = 3 + (p[5] & 0x03);
> +
> + return 0;
> +}
> +
> +static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
> +{
> + struct alps_data *priv = psmouse->private;
> + unsigned char *packet = psmouse->packet;
> + struct input_dev *dev2 = priv->dev2;
> + int x, y, z, left, right, middle;
> +
> + /*
> + * b7 b6 b5 b4 b3 b2 b1 b0
> + * Byte0 0 1 0 0 1 0 0 0
> + * Byte1 1 1 * * 1 M R L
> + * Byte2 X7 1 X5 X4 X3 X2 X1 X0
> + * Byte3 Z6 1 Y6 X6 1 Y2 Y1 Y0
> + * Byte4 Y7 0 Y5 Y4 Y3 1 1 0
> + * Byte5 T&P 0 Z5 Z4 Z3 Z2 Z1 Z0
> + * M / R / L: Middle / Right / Left button
> + */
> +
> + x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2);
> + y = (packet[3] & 0x07) | (packet[4] & 0xb8) |
> + ((packet[3] & 0x20) << 1);
> + z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
> +
> + left = (packet[1] & 0x01);
> + right = (packet[1] & 0x02) >> 1;
> + middle = (packet[1] & 0x04) >> 2;
> +
> + /* Divide 2 since trackpoint's speed is too fast */
> + input_report_rel(dev2, REL_X, (char)x / 2);
> + input_report_rel(dev2, REL_Y, -((char)y / 2));
> +
> + input_report_key(dev2, BTN_LEFT, left);
> + input_report_key(dev2, BTN_RIGHT, right);
> + input_report_key(dev2, BTN_MIDDLE, middle);
> +
> + input_sync(dev2);
> +}
> +
> +static void alps_process_touchpad_packet_v7(struct psmouse *psmouse)
> +{
> + struct alps_data *priv = psmouse->private;
> + struct input_dev *dev = psmouse->dev;
> + struct alps_fields *f = &priv->f;
> +
> + memset(f, 0, sizeof(*f));
> +
> + if (priv->decode_fields(f, psmouse->packet, psmouse))
> + return;
> +
> + alps_report_mt_data(psmouse, alps_get_mt_count(f->mt));
> +
> + input_mt_report_finger_count(dev, f->fingers);
> +
> + input_report_key(dev, BTN_LEFT, f->left);
> + input_report_key(dev, BTN_RIGHT, f->right);
> + input_report_key(dev, BTN_MIDDLE, f->middle);
> +
> + input_sync(dev);
> +}
> +
> +static void alps_process_packet_v7(struct psmouse *psmouse)
> +{
> + unsigned char *packet = psmouse->packet;
> +
> + if ((packet[0] == 0x48) && ((packet[4] & 0x47) == 0x06))
> + alps_process_trackstick_packet_v7(psmouse);
> + else
> + alps_process_touchpad_packet_v7(psmouse);
> +}
> +
> static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
> unsigned char packet[],
> bool report_buttons)
> @@ -1009,6 +1181,14 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
> return PSMOUSE_BAD_DATA;
> }
>
> + if (priv->proto_version == ALPS_PROTO_V7 &&
> + !alps_is_valid_package_v7(psmouse)) {
> + psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
> + psmouse->pktcnt - 1,
> + psmouse->packet[psmouse->pktcnt - 1]);
> + return PSMOUSE_BAD_DATA;
> + }
> +
> if (psmouse->pktcnt == psmouse->pktsize) {
> priv->process_packet(psmouse);
> return PSMOUSE_FULL_PACKET;
> @@ -1121,6 +1301,22 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
> return 0;
> }
>
> +static int alps_check_valid_firmware_id(unsigned char id[])
bool
> +{
> + int valid = 1;
bool; true
> +
> + if (id[0] == 0x73)
> + valid = 1;
true
> + else if (id[0] == 0x88) {
> + if ((id[1] == 0x07) ||
> + (id[1] == 0x08) ||
> + ((id[1] & 0xf0) == 0xB0))
> + valid = 1;
true
> + }
> +
> + return valid;
Hmmm, does not make sense - it is never false...
> +}
> +
> static int alps_enter_command_mode(struct psmouse *psmouse)
> {
> unsigned char param[4];
> @@ -1130,8 +1326,7 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
> return -1;
> }
>
> - if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
> - param[0] != 0x73) {
> + if (!alps_check_valid_firmware_id(param)) {
> psmouse_dbg(psmouse,
> "unknown response while entering command mode\n");
> return -1;
> @@ -1785,6 +1980,32 @@ static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
> return 0;
> }
>
> +static int alps_hw_init_v7(struct psmouse *psmouse)
> +{
> + struct ps2dev *ps2dev = &psmouse->ps2dev;
> + int reg_val, ret = -1;
> +
> + if (alps_enter_command_mode(psmouse) ||
> + alps_command_mode_read_reg(psmouse, 0xc2d9) == -1)
> + goto error;
> +
> + if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
> + goto error;
> +
> + reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
> + if (reg_val == -1)
> + goto error;
> + if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
> + goto error;
> +
> + alps_exit_command_mode(psmouse);
> + return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
> +
> +error:
> + alps_exit_command_mode(psmouse);
> + return ret;
> +}
> +
> static void alps_set_defaults(struct alps_data *priv)
> {
> priv->byte0 = 0x8f;
> @@ -1843,6 +2064,21 @@ static void alps_set_defaults(struct alps_data *priv)
> priv->x_max = 2047;
> priv->y_max = 1535;
> break;
> + case ALPS_PROTO_V7:
> + priv->hw_init = alps_hw_init_v7;
> + priv->process_packet = alps_process_packet_v7;
> + priv->decode_fields = alps_decode_packet_v7;
> + priv->set_abs_params = alps_set_abs_params_mt;
> + priv->nibble_commands = alps_v3_nibble_commands;
> + priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
> + priv->x_max = 0xfff;
> + priv->y_max = 0x7ff;
> + priv->byte0 = 0x48;
> + priv->mask0 = 0x48;
> +
> + if (priv->fw_ver[1] != 0xba)
> + priv->flags |= ALPS_BUTTONPAD;
> + break;
> }
> }
>
> @@ -1914,6 +2150,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
> return -EIO;
> else
> return 0;
> + } else if (ec[0] == 0x88 &&
> + ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) {
> + priv->proto_version = ALPS_PROTO_V7;
> + alps_set_defaults(priv);
> +
> + return 0;
> } else if (ec[0] == 0x88 && ec[1] == 0x08) {
> priv->proto_version = ALPS_PROTO_V3;
> alps_set_defaults(priv);
> @@ -1985,6 +2227,10 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
>
> set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
> set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
> +
> + /* V7 is real multi-touch */
> + if (priv->proto_version == ALPS_PROTO_V7)
> + clear_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
> }
>
> int alps_init(struct psmouse *psmouse)
> @@ -2030,7 +2276,9 @@ int alps_init(struct psmouse *psmouse)
> dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
>
> priv->set_abs_params(priv, dev1);
> - input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
> + /* No pressure on V7 */
> + if (priv->proto_version != ALPS_PROTO_V7)
> + input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
>
> if (priv->flags & ALPS_WHEEL) {
> dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
> @@ -2047,6 +2295,9 @@ int alps_init(struct psmouse *psmouse)
> dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
> dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
> dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
> + } else if (priv->flags & ALPS_BUTTONPAD) {
> + set_bit(INPUT_PROP_BUTTONPAD, dev1->propbit);
> + clear_bit(BTN_RIGHT, dev1->keybit);
> } else {
> dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
> }
> diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
> index e3d0f09..a98ac9b 100644
> --- a/drivers/input/mouse/alps.h
> +++ b/drivers/input/mouse/alps.h
> @@ -20,6 +20,7 @@
> #define ALPS_PROTO_V4 4
> #define ALPS_PROTO_V5 5
> #define ALPS_PROTO_V6 6
> +#define ALPS_PROTO_V7 7 /* t3btl t4s */
>
> #define MAX_TOUCHES 2
>
> @@ -27,6 +28,23 @@
> #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */
> #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */
>
> +/*
> + * enum V7_PACKET_ID - defines the packet type for V7
> + * V7_PACKET_ID_IDLE: There's no finger and no button activity.
> + * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad
> + * or there's button activities.
> + * V7_PACKET_ID_MULTI: There are at least three non-resting fingers.
> + * V7_PACKET_ID_NEW: The finger position in slot is not continues from
> + * previous packet.
> +*/
> +enum V7_PACKET_ID {
> + V7_PACKET_ID_IDLE,
> + V7_PACKET_ID_TWO,
> + V7_PACKET_ID_MULTI,
> + V7_PACKET_ID_NEW,
> + V7_PACKET_ID_UNKNOWN,
> +};
> +
> /**
> * struct alps_model_info - touchpad ID table
> * @signature: E7 response string to match.
> --
> 2.0.0
>
Thanks.
--
Dmitry
--
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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox