* [git pull] Input updates for 3.16-rc6
From: Dmitry Torokhov @ 2014-07-23 5:58 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, linux-input
[-- Attachment #1: Type: text/plain, Size: 1475 bytes --]
Hi Linus,
Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus
to receive a few fixups for the input subsystem.
Changelog:
---------
Bjorn Helgaas (1):
Input: sirfsoc-onkey - fix GPL v2 license string typo
Dmitry Torokhov (1):
Input: fix defuzzing logic
Felipe Balbi (1):
Input: ti_am335x_tsc - warn about incorrect spelling
Hans de Goede (1):
Input: synaptics - add min/max quirk for pnp-id LEN2002 (Edge E531)
Jiri Kosina (1):
Input: i8042 - add Acer Aspire 5710 to nomux blacklist
Peter Hutterer (1):
Input: document INPUT_PROP_TOPBUTTONPAD
Ping Cheng (1):
Input: wacom - cleanup multitouch code when touch_max is 2
Tobias Klauser (1):
Input: st-keyscan - fix 'defined but not used' compiler warnings
Diffstat:
--------
Documentation/input/event-codes.txt | 13 +++++++++++++
drivers/input/input.c | 6 ++++--
drivers/input/keyboard/st-keyscan.c | 2 ++
drivers/input/misc/sirfsoc-onkey.c | 2 +-
drivers/input/mouse/synaptics.c | 5 +++--
drivers/input/serio/i8042-x86ia64io.h | 7 +++++++
drivers/input/tablet/wacom_wac.c | 28 +++++++---------------------
drivers/input/touchscreen/ti_am335x_tsc.c | 5 ++++-
8 files changed, 41 insertions(+), 27 deletions(-)
--
Dmitry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/3] Input: synaptics-rmi4 - add F11 capabilities for touchpads
From: Dmitry Torokhov @ 2014-07-23 6:06 UTC (permalink / raw)
To: Christopher Heiny
Cc: Linux Input, Andrew Duggan, Vincent Huang, Vivian Ly,
Linus Walleij, Benjamin Tissoires, David Herrmann, Jiri Kosina
In-Reply-To: <1396300267-5108-1-git-send-email-cheiny@synaptics.com>
Hi Christopher,
On Mon, Mar 31, 2014 at 02:11:05PM -0700, Christopher Heiny wrote:
> When the device is a touchpad additional capabilities need to
> be set and reported.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> Acked-by: Christopher Heiny <cheiny@synaptics.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Cc: Linux Walleij <linus.walleij@linaro.org>
> Cc: David Herrmann <dh.herrmann@gmail.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
I rebased the branch to 3.14 and applied all 3 patches, thank you.
>
> ---
> drivers/input/rmi4/rmi_f11.c | 23 +++++++++++++++--------
> 1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
> index 8709abe..92eac8a 100644
> --- a/drivers/input/rmi4/rmi_f11.c
> +++ b/drivers/input/rmi4/rmi_f11.c
> @@ -717,7 +717,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
> if (sensor->data.rel_pos)
> rmi_f11_rel_pos_report(sensor, i);
> }
> - input_mt_sync(sensor->input);
> + input_mt_sync_frame(sensor->input);
> input_sync(sensor->input);
> }
>
> @@ -1104,13 +1104,10 @@ static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
> /* We assume touchscreen unless demonstrably a touchpad or specified
> * as a touchpad in the platform data
> */
> - if (sensor->sensor_type == rmi_f11_sensor_touchpad ||
> - (sensor->sens_query.has_info2 &&
> - !sensor->sens_query.is_clear))
> - input_flags = INPUT_PROP_POINTER;
> + if (sensor->sensor_type == rmi_f11_sensor_touchpad)
> + input_flags = INPUT_MT_POINTER;
> else
> - input_flags = INPUT_PROP_DIRECT;
> - set_bit(input_flags, input->propbit);
> + input_flags = INPUT_MT_DIRECT;
>
> if (sensor->axis_align.swap_axes) {
> int temp = device_x_max;
> @@ -1220,11 +1217,20 @@ static int rmi_f11_initialize(struct rmi_function *fn)
> return rc;
> }
>
> + if (sensor->sens_query.has_info2) {
> + if (sensor->sens_query.is_clear)
> + sensor->sensor_type = rmi_f11_sensor_touchscreen;
> + else
> + sensor->sensor_type = rmi_f11_sensor_touchpad;
> + }
> +
> if (pdata->f11_sensor_data) {
> sensor->axis_align =
> pdata->f11_sensor_data->axis_align;
> sensor->type_a = pdata->f11_sensor_data->type_a;
> - sensor->sensor_type =
> +
> + if (sensor->sensor_type == rmi_f11_sensor_default)
> + sensor->sensor_type =
> pdata->f11_sensor_data->sensor_type;
> }
>
> @@ -1490,6 +1496,7 @@ static struct rmi_function_handler rmi_f11_handler = {
> module_rmi_driver(rmi_f11_handler);
>
> MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com");
> +MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com");
> MODULE_DESCRIPTION("RMI F11 module");
> MODULE_LICENSE("GPL");
> MODULE_VERSION(RMI_DRIVER_VERSION);
> --
> 1.8.3.2
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] synaptics: Add min/max quirk for pnp-id LEN2002 (Edge E531)
From: Dmitry Torokhov @ 2014-07-23 6:08 UTC (permalink / raw)
To: Hans de Goede; +Cc: linux-input, stable
In-Reply-To: <1404211212-10382-1-git-send-email-hdegoede@redhat.com>
On Tue, Jul 01, 2014 at 12:40:12PM +0200, Hans de Goede wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1114768
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Applied, thank you.
> ---
> drivers/input/mouse/synaptics.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
> index 75a5154..84c72f6 100644
> --- a/drivers/input/mouse/synaptics.c
> +++ b/drivers/input/mouse/synaptics.c
> @@ -132,7 +132,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
> 1232, 5710, 1156, 4696
> },
> {
> - (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
> + (const char * const []){"LEN0034", "LEN0036", "LEN2002",
> + "LEN2004", NULL},
> 1024, 5112, 2024, 4832
> },
> {
> @@ -168,7 +169,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
> "LEN0049",
> "LEN2000",
> "LEN2001", /* Edge E431 */
> - "LEN2002",
> + "LEN2002", /* Edge E531 */
> "LEN2003",
> "LEN2004", /* L440 */
> "LEN2005",
> --
> 2.0.0
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: s3c2410_ts: Move to clk_prepare_enable/clk_disable_unprepare
From: Dmitry Torokhov @ 2014-07-23 6:09 UTC (permalink / raw)
To: Vasily Khoruzhick
Cc: Ben Dooks, Kukjin Kim, linux-arm-kernel, linux-samsung-soc,
linux-input
In-Reply-To: <2138540.gOK28iFQ6r@vasilykh-desktop-i5>
Hi Vasily,
On Wed, Jul 09, 2014 at 12:13:41PM +0300, Vasily Khoruzhick wrote:
> On 8 July 2014 18:00:49 Dmitry Torokhov wrote:
>
> Hi Dmitry,
>
> > >
> > > - clk_disable(ts.clock);
> > > + clk_disable_unprepare(ts.clock);
> >
> > Do we really need to unprepare on suspend? Why simply disabling is not
> > enough here?
>
> You're right, disabling should be enough here. I'll resend a patch after
> testing on a hardware.
I ended up cutting out suspend/resume parts and applying.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] input synaptics-rmi4: stop scanning PDT after blank page
From: Dmitry Torokhov @ 2014-07-23 6:10 UTC (permalink / raw)
To: Christopher Heiny
Cc: Linux Input, Andrew Duggan, Vincent Huang, Vivian Ly,
Daniel Rosenberg, Linus Walleij, Benjamin Tissoires,
David Herrmann, Jiri Kosina
In-Reply-To: <1394244256-16950-1-git-send-email-cheiny@synaptics.com>
On Fri, Mar 07, 2014 at 06:04:16PM -0800, Christopher Heiny wrote:
> When scanning the Page Descriptor Table, the end of the PDT is marked by a
> page where the first PDT entry is empty. Stop scanning when we find this
> page.
>
> Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Cc: Linux Walleij <linus.walleij@linaro.org>
> Cc: David Herrmann <dh.herrmann@gmail.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
Applied, thank you.
>
> ---
> drivers/input/rmi4/rmi_driver.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index 2172c80..dd3ccf5 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -505,7 +505,8 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
> return retval;
> }
>
> - return data->f01_bootloader_mode ? RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
> + return (data->f01_bootloader_mode || addr == pdt_start) ?
> + RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
> }
>
> static int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
--
Dmitry
^ permalink raw reply
* Re: [PATCH 02/02] input synaptics-rmi4: improved interrupt enable management
From: Dmitry Torokhov @ 2014-07-23 6:10 UTC (permalink / raw)
To: Christopher Heiny
Cc: Linux Input, Andrew Duggan, Vincent Huang, Vivian Ly,
Daniel Rosenberg, Linus Walleij, Benjamin Tissoires,
David Herrmann, Jiri Kosina
In-Reply-To: <1393990760-2587-2-git-send-email-cheiny@synaptics.com>
On Tue, Mar 04, 2014 at 07:39:20PM -0800, Christopher Heiny wrote:
> The previous interrupt save/restore routine was inflexible. Remove
> that and add set_bits() and clear_bits() functions, allowing simpler
> management of individual function interrupt enables.
>
> Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Cc: Linux Walleij <linus.walleij@linaro.org>
> Cc: David Herrmann <dh.herrmann@gmail.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
Applied both, thank you.
>
> ---
>
> drivers/input/rmi4/rmi_bus.h | 12 ++---
> drivers/input/rmi4/rmi_driver.c | 104 ++++++++++++++++------------------------
> drivers/input/rmi4/rmi_driver.h | 3 +-
> 3 files changed, 48 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
> index 1672b05..d4cfc85 100644
> --- a/drivers/input/rmi4/rmi_bus.h
> +++ b/drivers/input/rmi4/rmi_bus.h
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2011-2013 Synaptics Incorporated
> + * Copyright (c) 2011-2014 Synaptics Incorporated
> * Copyright (c) 2011 Unixphere
> *
> * This program is free software; you can redistribute it and/or modify it
> @@ -111,9 +111,8 @@ void rmi_unregister_function_handler(struct rmi_function_handler *);
> * @driver: Device driver model driver
> * @irq_handler: Callback for handling irqs
> * @reset_handler: Called when a reset is detected.
> - * @get_func_irq_mask: Callback for calculating interrupt mask
> - * @store_irq_mask: Callback for storing and replacing interrupt mask
> - * @restore_irq_mask: Callback for restoring previously stored interrupt mask
> + * @clear_irq_bits: Clear the specified bits in the current interrupt mask.
> + * @set_irq_bist: Set the specified bits in the current interrupt mask.
> * @store_productid: Callback for cache product id from function 01
> * @data: Private data pointer
> *
> @@ -123,9 +122,8 @@ struct rmi_driver {
>
> int (*irq_handler)(struct rmi_device *rmi_dev, int irq);
> int (*reset_handler)(struct rmi_device *rmi_dev);
> - int (*store_irq_mask)(struct rmi_device *rmi_dev,
> - unsigned long *new_interupts);
> - int (*restore_irq_mask)(struct rmi_device *rmi_dev);
> + int (*clear_irq_bits)(struct rmi_device *rmi_dev, unsigned long *mask);
> + int (*set_irq_bits)(struct rmi_device *rmi_dev, unsigned long *mask);
> int (*store_productid)(struct rmi_device *rmi_dev);
> int (*set_input_params)(struct rmi_device *rmi_dev,
> struct input_dev *input);
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index 4406a7f..2172c80 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -330,78 +330,56 @@ static int rmi_driver_set_input_params(struct rmi_device *rmi_dev,
> return 0;
> }
>
> -/**
> - * This pair of functions allows functions like function 54 to request to have
> - * other interrupts disabled until the restore function is called. Only one
> - * store happens at a time.
> - */
> -static int rmi_driver_irq_save(struct rmi_device *rmi_dev,
> - unsigned long *new_ints)
> +static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev,
> + unsigned long *mask)
> {
> - int retval = 0;
> + int error = 0;
> struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> struct device *dev = &rmi_dev->dev;
>
> mutex_lock(&data->irq_mutex);
> - if (!data->irq_stored) {
> - /* Save current enabled interrupts */
> - retval = rmi_read_block(rmi_dev,
> - data->f01_container->fd.control_base_addr + 1,
> - data->irq_mask_store, data->num_of_irq_regs);
> - if (retval < 0) {
> - dev_err(dev, "%s: Failed to read enabled interrupts!",
> - __func__);
> - goto error_unlock;
> - }
> - retval = rmi_write_block(rmi_dev,
> - data->f01_container->fd.control_base_addr + 1,
> - new_ints, data->num_of_irq_regs);
> - if (retval < 0) {
> - dev_err(dev, "%s: Failed to change enabled interrupts!",
> - __func__);
> - goto error_unlock;
> - }
> - bitmap_copy(data->current_irq_mask, new_ints, data->irq_count);
> - data->irq_stored = true;
> - } else {
> - retval = -ENOSPC; /* No space to store IRQs.*/
> - dev_err(dev, "Attempted to save IRQs when already stored!");
> + bitmap_or(data->new_irq_mask,
> + data->current_irq_mask, mask, data->irq_count);
> + error = rmi_write_block(rmi_dev,
> + data->f01_container->fd.control_base_addr + 1,
> + data->new_irq_mask, data->num_of_irq_regs);
> + if (error < 0) {
> + dev_err(dev, "%s: Failed to change enabled interrupts!",
> + __func__);
> + goto error_unlock;
> }
> + bitmap_copy(data->current_irq_mask, data->new_irq_mask,
> + data->num_of_irq_regs);
>
> error_unlock:
> mutex_unlock(&data->irq_mutex);
> - return retval;
> + return error;
> }
>
> -static int rmi_driver_irq_restore(struct rmi_device *rmi_dev)
> +static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev,
> + unsigned long *mask)
> {
> - int retval = 0;
> + int error = 0;
> struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> struct device *dev = &rmi_dev->dev;
>
> mutex_lock(&data->irq_mutex);
> -
> - if (data->irq_stored) {
> - retval = rmi_write_block(rmi_dev,
> - data->f01_container->fd.control_base_addr+1,
> - data->irq_mask_store, data->num_of_irq_regs);
> - if (retval < 0) {
> - dev_err(dev, "%s: Failed to write enabled interupts!",
> - __func__);
> - goto error_unlock;
> - }
> - memcpy(data->current_irq_mask, data->irq_mask_store,
> - data->num_of_irq_regs * sizeof(u8));
> - data->irq_stored = false;
> - } else {
> - retval = -EINVAL;
> - dev_err(dev, "%s: Attempted to restore values when not stored!",
> - __func__);
> + bitmap_andnot(data->new_irq_mask,
> + data->current_irq_mask, mask, data->irq_count);
> + error = rmi_write_block(rmi_dev,
> + data->f01_container->fd.control_base_addr + 1,
> + data->new_irq_mask, data->num_of_irq_regs);
> + if (error < 0) {
> + dev_err(dev, "%s: Failed to change enabled interrupts!",
> + __func__);
> + goto error_unlock;
> }
> + bitmap_copy(data->current_irq_mask, data->new_irq_mask,
> + data->num_of_irq_regs);
>
> error_unlock:
> mutex_unlock(&data->irq_mutex);
> - return retval;
> + return error;
> }
>
> static int rmi_driver_irq_handler(struct rmi_device *rmi_dev, int irq)
> @@ -437,21 +415,23 @@ static int rmi_driver_reset_handler(struct rmi_device *rmi_dev)
> return 0;
> }
>
> + error = rmi_read_block(rmi_dev,
> + data->f01_container->fd.control_base_addr + 1,
> + data->current_irq_mask, data->num_of_irq_regs);
> + if (error < 0) {
> + dev_err(&rmi_dev->dev, "%s: Failed to read current IRQ mask.\n",
> + __func__);
> + return error;
> + }
> +
> error = rmi_driver_process_reset_requests(rmi_dev);
> if (error < 0)
> return error;
>
> -
> error = rmi_driver_process_config_requests(rmi_dev);
> if (error < 0)
> return error;
>
> - if (data->irq_stored) {
> - error = rmi_driver_irq_restore(rmi_dev);
> - if (error < 0)
> - return error;
> - }
> -
> return 0;
> }
>
> @@ -846,7 +826,7 @@ static int rmi_driver_probe(struct device *dev)
> data->irq_status = irq_memory + size * 0;
> data->fn_irq_bits = irq_memory + size * 1;
> data->current_irq_mask = irq_memory + size * 2;
> - data->irq_mask_store = irq_memory + size * 3;
> + data->new_irq_mask = irq_memory + size * 3;
>
> irq_count = 0;
> dev_dbg(dev, "Creating functions.");
> @@ -957,8 +937,8 @@ static struct rmi_driver rmi_physical_driver = {
> },
> .irq_handler = rmi_driver_irq_handler,
> .reset_handler = rmi_driver_reset_handler,
> - .store_irq_mask = rmi_driver_irq_save,
> - .restore_irq_mask = rmi_driver_irq_restore,
> + .clear_irq_bits = rmi_driver_clear_irq_bits,
> + .set_irq_bits = rmi_driver_set_irq_bits,
> .set_input_params = rmi_driver_set_input_params,
> };
>
> diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
> index a22a4e6..34f7a7d 100644
> --- a/drivers/input/rmi4/rmi_driver.h
> +++ b/drivers/input/rmi4/rmi_driver.h
> @@ -47,8 +47,7 @@ struct rmi_driver_data {
> unsigned long *irq_status;
> unsigned long *fn_irq_bits;
> unsigned long *current_irq_mask;
> - unsigned long *irq_mask_store;
> - bool irq_stored;
> + unsigned long *new_irq_mask;
> struct mutex irq_mutex;
>
> /* Following are used when polling. */
--
Dmitry
^ permalink raw reply
* [PATCH] Input: synaptics-rmi4 - fix compiler warnings in F11
From: Dmitry Torokhov @ 2014-07-23 6:11 UTC (permalink / raw)
To: linux-input
Cc: Christopher Heiny, Andrew Duggan, Benjamin Tissoires,
linux-kernel
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/rmi4/rmi_f11.c | 135 +++++++++++++++++++++++--------------------
1 file changed, 71 insertions(+), 64 deletions(-)
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index b739d31..7af4f68 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -553,7 +553,7 @@ struct f11_data {
unsigned long *result_bits;
};
-enum finger_state_values {
+enum f11_finger_state {
F11_NO_FINGER = 0x00,
F11_PRESENT = 0x01,
F11_INACCURATE = 0x02,
@@ -563,12 +563,14 @@ enum finger_state_values {
/** F11_INACCURATE state is overloaded to indicate pen present. */
#define F11_PEN F11_INACCURATE
-static int get_tool_type(struct f11_2d_sensor *sensor, u8 finger_state)
+static int rmi_f11_get_tool_type(struct f11_2d_sensor *sensor,
+ enum f11_finger_state finger_state)
{
if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
sensor->sens_query.has_pen &&
finger_state == F11_PEN)
return MT_TOOL_PEN;
+
return MT_TOOL_FINGER;
}
@@ -603,36 +605,32 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor *sensor, u8 n_finger)
static void rmi_f11_abs_pos_report(struct f11_data *f11,
struct f11_2d_sensor *sensor,
- u8 finger_state, u8 n_finger)
+ enum f11_finger_state finger_state,
+ u8 n_finger)
{
struct f11_2d_data *data = &sensor->data;
+ struct input_dev *input = sensor->input;
struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align;
+ u8 *pos_data = &data->abs_pos[n_finger * RMI_F11_ABS_BYTES];
u16 x, y, z;
int w_x, w_y, w_max, w_min, orient;
- int temp;
- u8 abs_base = n_finger * RMI_F11_ABS_BYTES;
+ int tool_type = rmi_f11_get_tool_type(sensor, finger_state);
+
+ if (sensor->type_a) {
+ input_report_abs(input, ABS_MT_TRACKING_ID, n_finger);
+ input_report_abs(input, ABS_MT_TOOL_TYPE, tool_type);
+ } else {
+ input_mt_slot(input, n_finger);
+ input_mt_report_slot_state(input, tool_type,
+ finger_state != F11_NO_FINGER);
+ }
if (finger_state) {
- x = (data->abs_pos[abs_base] << 4) |
- (data->abs_pos[abs_base + 2] & 0x0F);
- y = (data->abs_pos[abs_base + 1] << 4) |
- (data->abs_pos[abs_base + 2] >> 4);
- w_x = data->abs_pos[abs_base + 3] & 0x0F;
- w_y = data->abs_pos[abs_base + 3] >> 4;
- w_max = max(w_x, w_y);
- w_min = min(w_x, w_y);
- z = data->abs_pos[abs_base + 4];
-
- if (axis_align->swap_axes) {
- temp = x;
- x = y;
- y = temp;
- temp = w_x;
- w_x = w_y;
- w_y = temp;
- }
+ x = (pos_data[0] << 4) | (pos_data[2] & 0x0F);
+ y = (pos_data[1] << 4) | (pos_data[2] >> 4);
- orient = w_x > w_y ? 1 : 0;
+ if (axis_align->swap_axes)
+ swap(x, y);
if (axis_align->flip_x)
x = max(sensor->max_x - x, 0);
@@ -641,13 +639,13 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
y = max(sensor->max_y - y, 0);
/*
- * here checking if X offset or y offset are specified is
- * redundant. We just add the offsets or, clip the values
- *
- * note: offsets need to be done before clipping occurs,
- * or we could get funny values that are outside
- * clipping boundaries.
- */
+ * Here checking if X offset or y offset are specified is
+ * redundant. We just add the offsets or clip the values.
+ *
+ * Note: offsets need to be applied before clipping occurs,
+ * or we could get funny values that are outside of
+ * clipping boundaries.
+ */
x += axis_align->offset_x;
y += axis_align->offset_y;
x = max(axis_align->clip_x_low, x);
@@ -657,41 +655,44 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
if (axis_align->clip_y_high)
y = min(axis_align->clip_y_high, y);
- }
+ w_x = pos_data[3] & 0x0f;
+ w_y = pos_data[3] >> 4;
- /* Some UIs ignore W of zero, so we fudge it to 1 for pens. This
- * only appears to be an issue when reporting pens, not plain old
- * fingers. */
- if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
- get_tool_type(sensor, finger_state) == MT_TOOL_PEN) {
- w_max = max(1, w_max);
- w_min = max(1, w_min);
- }
+ if (axis_align->swap_axes)
+ swap(w_x, w_y);
- if (sensor->type_a) {
- input_report_abs(sensor->input, ABS_MT_TRACKING_ID, n_finger);
- input_report_abs(sensor->input, ABS_MT_TOOL_TYPE,
- get_tool_type(sensor, finger_state));
- } else {
- input_mt_slot(sensor->input, n_finger);
- input_mt_report_slot_state(sensor->input,
- get_tool_type(sensor, finger_state), finger_state);
- }
+ orient = w_x > w_y ? 1 : 0;
+
+ w_max = max(w_x, w_y);
+ w_min = min(w_x, w_y);
+
+ /*
+ * Some UIs ignore W of zero, so we fudge it to 1 for pens. This
+ * only appears to be an issue when reporting pens, not plain old
+ * fingers.
+ */
+ if (tool_type == MT_TOOL_PEN) {
+ w_max = max(1, w_max);
+ w_min = max(1, w_min);
+ }
+
+ z = pos_data[4];
+
+ input_report_abs(input, ABS_MT_PRESSURE, z);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR, w_max);
+ input_report_abs(input, ABS_MT_TOUCH_MINOR, w_min);
+ input_report_abs(input, ABS_MT_ORIENTATION, orient);
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
- if (finger_state) {
- input_report_abs(sensor->input, ABS_MT_PRESSURE, z);
- input_report_abs(sensor->input, ABS_MT_TOUCH_MAJOR, w_max);
- input_report_abs(sensor->input, ABS_MT_TOUCH_MINOR, w_min);
- input_report_abs(sensor->input, ABS_MT_ORIENTATION, orient);
- input_report_abs(sensor->input, ABS_MT_POSITION_X, x);
- input_report_abs(sensor->input, ABS_MT_POSITION_Y, y);
dev_dbg(&sensor->fn->dev,
"finger[%d]:%d - x:%d y:%d z:%d w_max:%d w_min:%d\n",
n_finger, finger_state, x, y, z, w_max, w_min);
}
+
/* MT sync between fingers */
if (sensor->type_a)
- input_mt_sync(sensor->input);
+ input_mt_sync(input);
}
static void rmi_f11_finger_handler(struct f11_data *f11,
@@ -710,25 +711,31 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
/* Possible of having 4 fingers per f_statet register */
finger_state = (f_state[i / 4] >> (2 * (i % 4))) &
FINGER_STATE_MASK;
- if (finger_state == F11_RESERVED) {
- pr_err("%s: Invalid finger state[%d]:0x%02x.", __func__,
- i, finger_state);
+ switch (finger_state) {
+ case F11_RESERVED:
+ pr_err("Invalid finger state[%d]: 0x%02x", i, finger_state);
continue;
- } else if ((finger_state == F11_PRESENT) ||
- (finger_state == F11_INACCURATE)) {
+
+ case F11_PRESENT:
+ case F11_INACCURATE:
finger_pressed_count++;
+ break;
+
+ case F11_NO_FINGER:
+ break;
}
abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask,
- num_irq_regs);
+ num_irq_regs);
if (abs_bits)
rmi_f11_abs_pos_report(f11, sensor, finger_state, i);
rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
- num_irq_regs);
+ num_irq_regs);
if (rel_bits)
rmi_f11_rel_pos_report(sensor, i);
}
+
input_mt_sync_frame(sensor->input);
input_sync(sensor->input);
}
--
2.0.0.526.g5318336
--
Dmitry
^ permalink raw reply related
* Re: [PATCH] Input: s3c2410_ts: Move to clk_prepare_enable/clk_disable_unprepare
From: Vasily Khoruzhick @ 2014-07-23 7:59 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Ben Dooks, Kukjin Kim, linux-arm-kernel, linux-samsung-soc,
linux-input
In-Reply-To: <20140723060913.GD25004@core.coreip.homeip.net>
On 22 July 2014 23:09:14 Dmitry Torokhov wrote:
> Hi Vasily,
>
> On Wed, Jul 09, 2014 at 12:13:41PM +0300, Vasily Khoruzhick wrote:
> > On 8 July 2014 18:00:49 Dmitry Torokhov wrote:
> >
> > Hi Dmitry,
> >
> > > > - clk_disable(ts.clock);
> > > > + clk_disable_unprepare(ts.clock);
> > >
> > > Do we really need to unprepare on suspend? Why simply disabling is not
> > > enough here?
> >
> > You're right, disabling should be enough here. I'll resend a patch after
> > testing on a hardware.
>
> I ended up cutting out suspend/resume parts and applying.
Ah, I was about to send v2. I've tested a version with clk_disable/clk_enable
in suspend/resume parts, and it works OK for me.
Thanks!
Regards,
Vasily
>
> Thanks.
^ permalink raw reply
* Re: [PATCH] input: driver for touchscreen on iPaq h3xxx
From: Linus Walleij @ 2014-07-23 8:10 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Linux Input, Dmitry Artamonow, Alessandro GARDICH
In-Reply-To: <20140713025936.GA29513@core.coreip.homeip.net>
On Sun, Jul 13, 2014 at 4:59 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Linus, Dmitry,
>
> On Sat, Jul 12, 2014 at 11:31:21AM +0200, Linus Walleij wrote:
>> From: Dmitry Artamonow <mad_soft@inbox.ru>
>
> So is this Dmitry's or Alessandro's work?
Multiple authors. Alessandro, Dmitry and me. In order of sign-off...
The only viable rule I have for multiple authors is to attribute it
to the author who wrote the bulk of the code, and that comes
from Dmitry.
>> +#include <linux/mfd/ipaq-micro.h>
>
> Has this been merged already?
Yes. v3.16 merge window.
>> +static void micro_ts_receive(void *data, int len, unsigned char *msg)
>> +{
>> + struct touchscreen_data *ts = data;
>> +
>> + if (len == 4) {
>> + input_report_abs(ts->input, ABS_X, (msg[2]<<8)+msg[3]);
>
> be16_to_cpup()?
Yes! Replacing everywhere.
>> + input_report_abs(ts->input, ABS_Y, (msg[0]<<8)+msg[1]);
>> + input_report_abs(ts->input, ABS_PRESSURE, 1);
>
> Please no fake pressure events, update your tslib instead.
>
>> + input_report_key(ts->input, BTN_TOUCH, 0);
>
> This seems completely backwards.
Yeah... I wonder what happened here.
>> + ts->input = input_allocate_device();
>
> Error handling please; also consider using devm_input_allocate_device().
>
>> +
>> + ts->input->evbit[0] = BIT(EV_ABS);
>> + ts->input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
>> + input_set_abs_params(ts->input, ABS_X, 0, 1023, 0, 0);
>> + input_set_abs_params(ts->input, ABS_Y, 0, 1023, 0, 0);
>> + input_set_abs_params(ts->input, ABS_PRESSURE, 0x0, 0x1, 0, 0);
>> +
>
> You are missing setting BTN_TOUCH in capabilities so events you are
> trying to send in micro_ts_receive will not go anywhere.
Yeah. And I switched this to using just input_set_capability().
>> + spin_lock(&ts->micro->lock);
>> + ts->micro->ts = NULL;
>> + ts->micro->ts_data = NULL;
>> + spin_unlock(&ts->micro->lock);
>
> What is the point here?
Unregistering the callbacks so the MFD core device will stop
calling them. Or we will crash the kernel when removing the
driver as next event arrives.
Sending v2 soon.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2] input: driver for touchscreen on iPaq h3xxx
From: Linus Walleij @ 2014-07-23 8:20 UTC (permalink / raw)
To: Dmitry Torokhov, linux-input
Cc: Dmitry Artamonow, Alessandro GARDICH, Linus Walleij
From: Dmitry Artamonow <mad_soft@inbox.ru>
This adds a driver for the touchscreen connected to the
Atmel microcontroller on the iPAQ h3xxx series.
Based on a driver from handhelds.org 2.6.21 kernel, written
by Alessandro GARDICH, with the bulk of the code for the
new input architecture rewritten by Dmitry Atamonow, and
the final polish by Linus Walleij.
Signed-off-by: Alessandro GARDICH <gremlin@gremlin.it>
Signed-off-by: Dmitry Artamonow <mad_soft@inbox.ru>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- More verbose Kconfig selection text including module info.
- Use be16_to_cpup() to deserialize protocol.
- Cut fake pressure event reporting.
- Report button events properly.
- Use devm_input_allocate_device() to allocate input device.
- Use input_set_capability() to set up capabilities.
---
drivers/input/touchscreen/Kconfig | 12 +++
drivers/input/touchscreen/Makefile | 1 +
drivers/input/touchscreen/ipaq-micro-ts.c | 141 ++++++++++++++++++++++++++++++
3 files changed, 154 insertions(+)
create mode 100644 drivers/input/touchscreen/ipaq-micro-ts.c
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index a23a94bb4bcb..6bb9a7dd23b6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -471,6 +471,18 @@ config TOUCHSCREEN_HP7XX
To compile this driver as a module, choose M here: the
module will be called jornada720_ts.
+config TOUCHSCREEN_IPAQ_MICRO
+ tristate "HP iPAQ Atmel Micro ASIC touchscreen"
+ depends on MFD_IPAQ_MICRO
+ help
+ Say Y here to enable support for the touchscreen attached to
+ the Atmel Micro peripheral controller on iPAQ h3100/h3600/h3700
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ipaq-micro-ts.
+
config TOUCHSCREEN_HTCPEN
tristate "HTC Shift X9500 touchscreen"
depends on ISA
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 126479d8c29a..4be94fce41af 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
+obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o
obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c
new file mode 100644
index 000000000000..d044b06b1bfb
--- /dev/null
+++ b/drivers/input/touchscreen/ipaq-micro-ts.c
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ *
+ * h3600 atmel micro companion support, touchscreen subdevice
+ * Author : Alessandro Gardich <gremlin@gremlin.it>
+ * Author : Dmitry Artamonow <mad_soft@inbox.ru>
+ * Author : Linus Walleij <linus.walleij@linaro.org>
+ *
+ */
+
+#include <asm/byteorder.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mfd/ipaq-micro.h>
+
+struct touchscreen_data {
+ struct input_dev *input;
+ struct ipaq_micro *micro;
+};
+
+static void micro_ts_receive(void *data, int len, unsigned char *msg)
+{
+ struct touchscreen_data *ts = data;
+
+ if (len == 4) {
+ input_report_abs(ts->input, ABS_X,
+ be16_to_cpup((__be16 *) &msg[2]));
+ input_report_abs(ts->input, ABS_Y,
+ be16_to_cpup((__be16 *) &msg[0]));
+ input_report_key(ts->input, BTN_TOUCH, 1);
+ }
+ if (len == 0) {
+ input_report_abs(ts->input, ABS_X, 0);
+ input_report_abs(ts->input, ABS_Y, 0);
+ input_report_key(ts->input, BTN_TOUCH, 0);
+ }
+ input_sync(ts->input);
+}
+
+
+static int micro_ts_probe(struct platform_device *pdev)
+{
+ struct touchscreen_data *ts;
+ int ret;
+
+ ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+ ts->micro = dev_get_drvdata(pdev->dev.parent);
+
+ platform_set_drvdata(pdev, ts);
+
+ ts->input = devm_input_allocate_device(&pdev->dev);
+ if (!ts->input) {
+ dev_err(&pdev->dev, "failed to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ input_set_capability(ts->input, EV_KEY, BTN_TOUCH);
+ input_set_capability(ts->input, EV_ABS, ABS_X);
+ input_set_capability(ts->input, EV_ABS, ABS_Y);
+ input_set_abs_params(ts->input, ABS_X, 0, 1023, 0, 0);
+ input_set_abs_params(ts->input, ABS_Y, 0, 1023, 0, 0);
+
+ ts->input->name = "ipaq micro ts";
+
+ ret = input_register_device(ts->input);
+ if (ret) {
+ dev_err(&pdev->dev, "error registering touch input\n");
+ return ret;
+ }
+
+ spin_lock(&ts->micro->lock);
+ ts->micro->ts = micro_ts_receive;
+ ts->micro->ts_data = ts;
+ spin_unlock(&ts->micro->lock);
+
+ dev_info(&pdev->dev, "iPAQ micro touchscreen\n");
+ return 0;
+}
+
+static int micro_ts_remove(struct platform_device *pdev)
+{
+ struct touchscreen_data *ts = platform_get_drvdata(pdev);
+
+ spin_lock(&ts->micro->lock);
+ ts->micro->ts = NULL;
+ ts->micro->ts_data = NULL;
+ spin_unlock(&ts->micro->lock);
+
+ return 0;
+}
+
+static int micro_ts_suspend(struct device *dev)
+{
+ struct touchscreen_data *ts = dev_get_drvdata(dev);
+
+ spin_lock(&ts->micro->lock);
+ ts->micro->ts = NULL;
+ ts->micro->ts_data = NULL;
+ spin_unlock(&ts->micro->lock);
+ return 0;
+}
+
+static int micro_ts_resume(struct device *dev)
+{
+ struct touchscreen_data *ts = dev_get_drvdata(dev);
+
+ spin_lock(&ts->micro->lock);
+ ts->micro->ts = micro_ts_receive;
+ ts->micro->ts_data = ts;
+ spin_unlock(&ts->micro->lock);
+ return 0;
+}
+
+static const struct dev_pm_ops micro_ts_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume)
+};
+
+struct platform_driver micro_ts_device_driver = {
+ .driver = {
+ .name = "ipaq-micro-ts",
+ .pm = µ_ts_dev_pm_ops,
+ },
+ .probe = micro_ts_probe,
+ .remove = micro_ts_remove,
+};
+module_platform_driver(micro_ts_device_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("driver for iPAQ Atmel micro touchscreen");
+MODULE_ALIAS("platform:ipaq-micro-ts");
--
1.9.3
^ permalink raw reply related
* Re: Linux 3.16-rc6
From: Borislav Petkov @ 2014-07-23 9:53 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Linux Kernel Mailing List, linux-usb, linux-input
In-Reply-To: <CA+55aFzJKxzw_as9iGgeM=MdQ6trUkQLDuoEr8nxj88sOqQnQA@mail.gmail.com>
On Sun, Jul 20, 2014 at 09:22:52PM -0700, Linus Torvalds wrote:
> So go get the latest rc and kick the tires, to see that nothing has
> fallen through the cracks, ok?
Well, it looks like we f*cked up something after -rc5 since I'm starting
to see lockdep splats all over the place which I didn't see before. I'm
running rc6 + tip/master.
There was one in r8169 yesterday:
https://lkml.kernel.org/r/20140722081840.GA6462@pd.tnic
and now I'm seeing the following in a kvm guest. I'm adding some more
lists to CC which look like might be related, judging from the stack
traces.
---
...
[ 9.456211] EXT3-fs (sda1): using internal journal
[ 24.623666] 8139cp 0000:00:03.0 eth0: link up, 100Mbps, full-duplex, lpa 0x05E1
[ 28.346202] mtrr: no MTRR for fc000000,100000 found
[ 31.704053]
[ 31.704282] =========================================================
[ 31.704282] [ INFO: possible irq lock inversion dependency detected ]
[ 31.704282] 3.16.0-rc6+ #1 Not tainted
[ 31.704282] ---------------------------------------------------------
[ 31.704282] Xorg/3484 just changed the state of lock:
[ 31.704282] (tasklist_lock){.?.+..}, at: [<ffffffff81184b19>] send_sigio+0x59/0x1b0
[ 31.704282] but this lock took another, HARDIRQ-unsafe lock in the past:
[ 31.704282] (&(&p->alloc_lock)->rlock){+.+...}
and interrupts could create inverse lock ordering between them.
[ 31.704282]
[ 31.704282] other info that might help us debug this:
[ 31.704282] Possible interrupt unsafe locking scenario:
[ 31.704282]
[ 31.704282] CPU0 CPU1
[ 31.704282] ---- ----
[ 31.704282] lock(&(&p->alloc_lock)->rlock);
[ 31.704282] local_irq_disable();
[ 31.704282] lock(tasklist_lock);
[ 31.704282] lock(&(&p->alloc_lock)->rlock);
[ 31.704282] <Interrupt>
[ 31.704282] lock(tasklist_lock);
[ 31.704282]
[ 31.704282] *** DEADLOCK ***
[ 31.704282]
[ 31.704282] 7 locks held by Xorg/3484:
[ 31.704282] #0: (&(&dev->event_lock)->rlock){-.....}, at: [<ffffffff8148c20d>] input_event+0x4d/0x90
[ 31.704282] #1: (rcu_read_lock){......}, at: [<ffffffff8148b365>] input_pass_values.part.3+0x5/0x360
[ 31.704282] #2: (rcu_read_lock){......}, at: [<ffffffff814915a5>] evdev_events+0x5/0x2e0
[ 31.704282] #3: (&(&client->buffer_lock)->rlock){-.....}, at: [<ffffffff81490743>] evdev_pass_values+0x63/0x1d0
[ 31.704282] #4: (rcu_read_lock){......}, at: [<ffffffff81184c7f>] kill_fasync+0xf/0x290
[ 31.704282] #5: (&(&new->fa_lock)->rlock){-.....}, at: [<ffffffff81184d06>] kill_fasync+0x96/0x290
[ 31.704282] #6: (&f->f_owner.lock){.-....}, at: [<ffffffff81184ae4>] send_sigio+0x24/0x1b0
[ 31.704282]
[ 31.704282] the shortest dependencies between 2nd lock and 1st lock:
[ 31.704282] -> (&(&p->alloc_lock)->rlock){+.+...} ops: 35104 {
[ 31.704282] HARDIRQ-ON-W at:
[ 31.704282] [<ffffffff8109a362>] __lock_acquire+0x952/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161f8d1>] _raw_spin_lock+0x41/0x80
[ 31.704282] [<ffffffff811793c9>] __set_task_comm+0x39/0x180
[ 31.704282] [<ffffffff81073c35>] kthreadd+0x45/0x150
[ 31.704282] [<ffffffff81620b6c>] ret_from_fork+0x7c/0xb0
[ 31.704282] SOFTIRQ-ON-W at:
[ 31.704282] [<ffffffff8109a395>] __lock_acquire+0x985/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161f8d1>] _raw_spin_lock+0x41/0x80
[ 31.704282] [<ffffffff811793c9>] __set_task_comm+0x39/0x180
[ 31.704282] [<ffffffff81073c35>] kthreadd+0x45/0x150
[ 31.704282] [<ffffffff81620b6c>] ret_from_fork+0x7c/0xb0
[ 31.704282] INITIAL USE at:
[ 31.704282] [<ffffffff81099e53>] __lock_acquire+0x443/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161f8d1>] _raw_spin_lock+0x41/0x80
[ 31.704282] [<ffffffff811793c9>] __set_task_comm+0x39/0x180
[ 31.704282] [<ffffffff81073c35>] kthreadd+0x45/0x150
[ 31.704282] [<ffffffff81620b6c>] ret_from_fork+0x7c/0xb0
[ 31.704282] }
[ 31.704282] ... key at: [<ffffffff81cc4ae8>] __key.47760+0x0/0x8
[ 31.704282] ... acquired at:
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161f8d1>] _raw_spin_lock+0x41/0x80
[ 31.704282] [<ffffffff81066b45>] do_prlimit+0x205/0x250
[ 31.704282] [<ffffffff81066bba>] SyS_getrlimit+0x2a/0x70
[ 31.704282] [<ffffffff81620c16>] system_call_fastpath+0x1a/0x1f
[ 31.704282]
[ 31.704282] -> (tasklist_lock){.?.+..} ops: 22947 {
[ 31.704282] IN-HARDIRQ-R at:
[ 31.704282] [<ffffffff8109a5a3>] __lock_acquire+0xb93/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161fe14>] _raw_read_lock+0x44/0x80
[ 31.704282] [<ffffffff81184b19>] send_sigio+0x59/0x1b0
[ 31.704282] [<ffffffff81184d34>] kill_fasync+0xc4/0x290
[ 31.704282] [<ffffffff81490776>] evdev_pass_values+0x96/0x1d0
[ 31.704282] [<ffffffff814917bc>] evdev_events+0x21c/0x2e0
[ 31.704282] [<ffffffff81489691>] input_to_handler+0x91/0x100
[ 31.704282] [<ffffffff8148b624>] input_pass_values.part.3+0x2c4/0x360
[ 31.704282] [<ffffffff8148bd1a>] input_handle_event+0xda/0x580
[ 31.704282] [<ffffffff8148c220>] input_event+0x60/0x90
[ 31.704282] [<ffffffff814c546f>] hidinput_report_event+0x3f/0x50
[ 31.704282] [<ffffffff814c3635>] hid_report_raw_event+0x285/0x420
[ 31.704282] [<ffffffff814c38f1>] hid_input_report+0x121/0x1a0
[ 31.704282] [<ffffffff814d1300>] hid_irq_in+0x80/0x1f0
[ 31.704282] [<ffffffff81448c98>] __usb_hcd_giveback_urb+0x68/0x100
[ 31.704282] [<ffffffff81448d7a>] usb_hcd_giveback_urb+0x4a/0x140
[ 31.704282] [<ffffffff8146ba38>] uhci_giveback_urb+0xb8/0x210
[ 31.704282] [<ffffffff8146c4a2>] uhci_scan_schedule.part.32+0x542/0xb60
[ 31.704282] [<ffffffff8146d351>] uhci_irq+0xf1/0x190
[ 31.704282] [<ffffffff81448285>] usb_hcd_irq+0x25/0x40
[ 31.704282] [<ffffffff810af329>] handle_irq_event_percpu+0x39/0x350
[ 31.704282] [<ffffffff810af688>] handle_irq_event+0x48/0x70
[ 31.704282] [<ffffffff810b2a60>] handle_fasteoi_irq+0xa0/0x180
[ 31.704282] [<ffffffff810055ce>] handle_irq+0x1e/0x30
[ 31.704282] [<ffffffff81623618>] do_IRQ+0x68/0x110
[ 31.704282] [<ffffffff8162186f>] ret_from_intr+0x0/0x13
[ 31.704282] HARDIRQ-ON-R at:
[ 31.704282] [<ffffffff81099dac>] __lock_acquire+0x39c/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161fe14>] _raw_read_lock+0x44/0x80
[ 31.704282] [<ffffffff81053109>] do_wait+0xe9/0x370
[ 31.704282] [<ffffffff810537a5>] SyS_wait4+0x75/0xf0
[ 31.704282] [<ffffffff81067f0b>] wait_for_helper+0x4b/0x70
[ 31.704282] [<ffffffff81620b6c>] ret_from_fork+0x7c/0xb0
[ 31.704282] SOFTIRQ-ON-R at:
[ 31.704282] [<ffffffff8109a395>] __lock_acquire+0x985/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff8161fe14>] _raw_read_lock+0x44/0x80
[ 31.704282] [<ffffffff81053109>] do_wait+0xe9/0x370
[ 31.704282] [<ffffffff810537a5>] SyS_wait4+0x75/0xf0
[ 31.704282] [<ffffffff81067f0b>] wait_for_helper+0x4b/0x70
[ 31.704282] [<ffffffff81620b6c>] ret_from_fork+0x7c/0xb0
[ 31.704282] INITIAL USE at:
[ 31.704282] [<ffffffff81099e53>] __lock_acquire+0x443/0x2230
[ 31.704282] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 31.704282] [<ffffffff816202c7>] _raw_write_lock_irq+0x47/0x80
[ 31.704282] [<ffffffff8104dd5a>] copy_process.part.51+0xe5a/0x19d0
[ 31.704282] [<ffffffff8104ea97>] do_fork+0xe7/0x770
[ 31.704282] [<ffffffff8104f146>] kernel_thread+0x26/0x30
[ 31.704282] [<ffffffff81614922>] rest_init+0x22/0x140
[ 31.704282] [<ffffffff81b90e3e>] start_kernel+0x408/0x415
[ 31.704282] [<ffffffff81b90463>] x86_64_start_reservations+0x2a/0x2c
[ 31.704282] [<ffffffff81b9055b>] x86_64_start_kernel+0xf6/0xf9
[ 31.704282] }
[ 31.704282] ... key at: [<ffffffff818ff098>] tasklist_lock+0x18/0x80
[ 31.704282] ... acquired at:
[ 31.704282] [<ffffffff8109636b>] check_usage_forwards+0x15b/0x160
[ 31.704282] [<ffffffff81097188>] mark_lock+0x3d8/0x760
[ 32.044737] [<ffffffff8109a5a3>] __lock_acquire+0xb93/0x2230
[ 32.044737] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 32.044737] [<ffffffff8161fe14>] _raw_read_lock+0x44/0x80
[ 32.044737] [<ffffffff81184b19>] send_sigio+0x59/0x1b0
[ 32.044737] [<ffffffff81184d34>] kill_fasync+0xc4/0x290
[ 32.044737] [<ffffffff81490776>] evdev_pass_values+0x96/0x1d0
[ 32.044737] [<ffffffff814917bc>] evdev_events+0x21c/0x2e0
[ 32.044737] [<ffffffff81489691>] input_to_handler+0x91/0x100
[ 32.044737] [<ffffffff8148b624>] input_pass_values.part.3+0x2c4/0x360
[ 32.044737] [<ffffffff8148bd1a>] input_handle_event+0xda/0x580
[ 32.044737] [<ffffffff8148c220>] input_event+0x60/0x90
[ 32.044737] [<ffffffff814c546f>] hidinput_report_event+0x3f/0x50
[ 32.044737] [<ffffffff814c3635>] hid_report_raw_event+0x285/0x420
[ 32.044737] [<ffffffff814c38f1>] hid_input_report+0x121/0x1a0
[ 32.044737] [<ffffffff814d1300>] hid_irq_in+0x80/0x1f0
[ 32.044737] [<ffffffff81448c98>] __usb_hcd_giveback_urb+0x68/0x100
[ 32.044737] [<ffffffff81448d7a>] usb_hcd_giveback_urb+0x4a/0x140
[ 32.044737] [<ffffffff8146ba38>] uhci_giveback_urb+0xb8/0x210
[ 32.044737] [<ffffffff8146c4a2>] uhci_scan_schedule.part.32+0x542/0xb60
[ 32.044737] [<ffffffff8146d351>] uhci_irq+0xf1/0x190
[ 32.044737] [<ffffffff81448285>] usb_hcd_irq+0x25/0x40
[ 32.044737] [<ffffffff810af329>] handle_irq_event_percpu+0x39/0x350
[ 32.044737] [<ffffffff810af688>] handle_irq_event+0x48/0x70
[ 32.044737] [<ffffffff810b2a60>] handle_fasteoi_irq+0xa0/0x180
[ 32.044737] [<ffffffff810055ce>] handle_irq+0x1e/0x30
[ 32.044737] [<ffffffff81623618>] do_IRQ+0x68/0x110
[ 32.044737] [<ffffffff8162186f>] ret_from_intr+0x0/0x13
[ 32.044737]
[ 32.044737]
[ 32.044737] stack backtrace:
[ 32.044737] CPU: 0 PID: 3484 Comm: Xorg Not tainted 3.16.0-rc6+ #1
[ 32.044737] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
[ 32.044737] ffffffff8280ddc0 ffff88007be03770 ffffffff8161874e ffffffff8280ddc0
[ 32.044737] ffff88007be037b0 ffffffff81617b6f ffffffff8183b4f6 ffff880079da4300
[ 32.044737] ffff880079da3a50 ffffffff8183b4f6 0000000000000000 ffffffff8280ddc0
[ 32.044737] Call Trace:
[ 32.044737] <IRQ> [<ffffffff8161874e>] dump_stack+0x4e/0x7a
[ 32.044737] [<ffffffff81617b6f>] print_irq_inversion_bug.part.31+0x1b8/0x1c4
[ 32.044737] [<ffffffff8109636b>] check_usage_forwards+0x15b/0x160
[ 32.044737] [<ffffffff81097188>] mark_lock+0x3d8/0x760
[ 32.044737] [<ffffffff81096210>] ? print_shortest_lock_dependencies+0x1d0/0x1d0
[ 32.044737] [<ffffffff8109a5a3>] __lock_acquire+0xb93/0x2230
[ 32.044737] [<ffffffff8109c449>] lock_acquire+0xb9/0x200
[ 32.044737] [<ffffffff81184b19>] ? send_sigio+0x59/0x1b0
[ 32.044737] [<ffffffff8161fe14>] _raw_read_lock+0x44/0x80
[ 32.044737] [<ffffffff81184b19>] ? send_sigio+0x59/0x1b0
[ 32.044737] [<ffffffff81184b19>] send_sigio+0x59/0x1b0
[ 32.044737] [<ffffffff81184d34>] kill_fasync+0xc4/0x290
[ 32.044737] [<ffffffff81184c7f>] ? kill_fasync+0xf/0x290
[ 32.044737] [<ffffffff81490776>] evdev_pass_values+0x96/0x1d0
[ 32.044737] [<ffffffff814917bc>] evdev_events+0x21c/0x2e0
[ 32.044737] [<ffffffff814915a5>] ? evdev_events+0x5/0x2e0
[ 32.044737] [<ffffffff81489691>] input_to_handler+0x91/0x100
[ 32.044737] [<ffffffff8148b624>] input_pass_values.part.3+0x2c4/0x360
[ 32.044737] [<ffffffff8148b365>] ? input_pass_values.part.3+0x5/0x360
[ 32.044737] [<ffffffff8148bd1a>] input_handle_event+0xda/0x580
[ 32.044737] [<ffffffff8148c220>] input_event+0x60/0x90
[ 32.044737] [<ffffffff814c546f>] hidinput_report_event+0x3f/0x50
[ 32.044737] [<ffffffff814c3635>] hid_report_raw_event+0x285/0x420
[ 32.044737] [<ffffffff814c38f1>] hid_input_report+0x121/0x1a0
[ 32.044737] [<ffffffff814d1300>] hid_irq_in+0x80/0x1f0
[ 32.044737] [<ffffffff81448c98>] __usb_hcd_giveback_urb+0x68/0x100
[ 32.044737] [<ffffffff81448d7a>] usb_hcd_giveback_urb+0x4a/0x140
[ 32.044737] [<ffffffff8146ba38>] uhci_giveback_urb+0xb8/0x210
[ 32.044737] [<ffffffff8146c4a2>] uhci_scan_schedule.part.32+0x542/0xb60
[ 32.044737] [<ffffffff8146d2d2>] ? uhci_irq+0x72/0x190
[ 32.044737] [<ffffffff8146d351>] uhci_irq+0xf1/0x190
[ 32.044737] [<ffffffff81448285>] usb_hcd_irq+0x25/0x40
[ 32.044737] [<ffffffff810af329>] handle_irq_event_percpu+0x39/0x350
[ 32.044737] [<ffffffff810af688>] handle_irq_event+0x48/0x70
[ 32.044737] [<ffffffff810b2a60>] handle_fasteoi_irq+0xa0/0x180
[ 32.044737] [<ffffffff810055ce>] handle_irq+0x1e/0x30
[ 32.044737] [<ffffffff81623618>] do_IRQ+0x68/0x110
[ 32.044737] [<ffffffff8162186f>] common_interrupt+0x6f/0x6f
[ 32.044737] <EOI> [<ffffffff81621911>] ? retint_swapgs+0xe/0x13
--
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--
^ permalink raw reply
* Re: [PATCH] drivers: Let several drivers depends on HAS_IOMEM for 'devm_ioremap_resource'
From: Chen Gang @ 2014-07-23 11:09 UTC (permalink / raw)
To: Dan Carpenter
Cc: Thierry Reding, linux-iio, Benjamin Herrenschmidt, teg, Lennox Wu,
Marek Vasut, Liqin Chen, Lars-Peter Clausen, Richard Weinberger,
Geert Uytterhoeven, msalter, Guenter Roeck, linux-pwm, devel,
linux-watchdog, arnd, linux-input, Greg Kroah-Hartman,
dmitry.torokhov, linux-kernel@vger.kernel.org, knaack.h,
Martin Schwidefsky, Mischa.Jonker, jic23
In-Reply-To: <53C7951F.6000906@gmail.com>
On 07/17/2014 05:19 PM, Chen Gang wrote:
>
>
> On 07/17/2014 05:16 PM, Dan Carpenter wrote:
>> On Thu, Jul 17, 2014 at 04:59:09PM +0800, Chen Gang wrote:
>>>>> + return (__force void __iomem *)ERR_PTR(-ENXIO);
>>>>
>>>> There's apparently an IOMEM_ERR_PTR() for this nowadays...
>>>>
>>>
>>> IOMEM_ERR_PTR() is defined within "lib/devres.c", not in "./include".
>>> But may we move it from "lib/devres.c" to "./include/linux/err.h"?
>>>
>>> For me, I am not quite sure, it may need additional discussion, but at
>>> least, that will be another patch.
>>
>> Yes. Move it there. That is the right place.
>>
Sorry for replying late about IOMEM_ERR_PTR().
Although no objections within 2 days, for me, when move something to
generic header file, it is not only for future using, but also for
solving current issue, or it has to be suspended for waiting 'trigger'.
So for me, the patch about IOMEM_ERR_PTR() need be suspended, until some
member find an issue which may be related with IOMEM_ERR_PTR(), more or
less.
>
> OK, thanks, if no another objections within 2 days, I shall send another
> related patch for it.
>
Thanks.
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed
^ permalink raw reply
* Re: [PATCH] drivers: Let several drivers depends on HAS_IOMEM for 'devm_ioremap_resource'
From: Dan Carpenter @ 2014-07-23 11:30 UTC (permalink / raw)
To: Chen Gang
Cc: linux-iio, Benjamin Herrenschmidt, teg, Thierry Reding, Lennox Wu,
Marek Vasut, Liqin Chen, Lars-Peter Clausen, Richard Weinberger,
Geert Uytterhoeven, msalter, Guenter Roeck, linux-pwm, devel,
linux-watchdog, arnd, linux-input, Greg Kroah-Hartman,
dmitry.torokhov, linux-kernel@vger.kernel.org, knaack.h,
Martin Schwidefsky, Mischa.Jonker, jic23
In-Reply-To: <53CF97E2.9000906@gmail.com>
On Wed, Jul 23, 2014 at 07:09:22PM +0800, Chen Gang wrote:
>
>
> On 07/17/2014 05:19 PM, Chen Gang wrote:
> >
> >
> > On 07/17/2014 05:16 PM, Dan Carpenter wrote:
> >> On Thu, Jul 17, 2014 at 04:59:09PM +0800, Chen Gang wrote:
> >>>>> + return (__force void __iomem *)ERR_PTR(-ENXIO);
> >>>>
> >>>> There's apparently an IOMEM_ERR_PTR() for this nowadays...
> >>>>
> >>>
> >>> IOMEM_ERR_PTR() is defined within "lib/devres.c", not in "./include".
> >>> But may we move it from "lib/devres.c" to "./include/linux/err.h"?
> >>>
> >>> For me, I am not quite sure, it may need additional discussion, but at
> >>> least, that will be another patch.
> >>
> >> Yes. Move it there. That is the right place.
> >>
>
> Sorry for replying late about IOMEM_ERR_PTR().
>
> Although no objections within 2 days, for me, when move something to
> generic header file, it is not only for future using, but also for
> solving current issue, or it has to be suspended for waiting 'trigger'.
>
> So for me, the patch about IOMEM_ERR_PTR() need be suspended, until some
> member find an issue which may be related with IOMEM_ERR_PTR(), more or
> less.
Matthias Brugger already moved it to include/linux/io.h on Friday.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH] drivers: Let several drivers depends on HAS_IOMEM for 'devm_ioremap_resource'
From: Chen Gang @ 2014-07-23 11:37 UTC (permalink / raw)
To: Dan Carpenter
Cc: linux-iio, Benjamin Herrenschmidt, teg, Thierry Reding, Lennox Wu,
Marek Vasut, Liqin Chen, Lars-Peter Clausen, Richard Weinberger,
Geert Uytterhoeven, msalter, Guenter Roeck, linux-pwm, devel,
linux-watchdog, arnd, linux-input, Greg Kroah-Hartman,
dmitry.torokhov, linux-kernel@vger.kernel.org, knaack.h,
Martin Schwidefsky, Mischa.Jonker, jic23
In-Reply-To: <20140723113023.GT25880@mwanda>
On 07/23/2014 07:30 PM, Dan Carpenter wrote:
> On Wed, Jul 23, 2014 at 07:09:22PM +0800, Chen Gang wrote:
>>
>>
>> On 07/17/2014 05:19 PM, Chen Gang wrote:
>>>
>>>
>>> On 07/17/2014 05:16 PM, Dan Carpenter wrote:
>>>> On Thu, Jul 17, 2014 at 04:59:09PM +0800, Chen Gang wrote:
>>>>>>> + return (__force void __iomem *)ERR_PTR(-ENXIO);
>>>>>>
>>>>>> There's apparently an IOMEM_ERR_PTR() for this nowadays...
>>>>>>
>>>>>
>>>>> IOMEM_ERR_PTR() is defined within "lib/devres.c", not in "./include".
>>>>> But may we move it from "lib/devres.c" to "./include/linux/err.h"?
>>>>>
>>>>> For me, I am not quite sure, it may need additional discussion, but at
>>>>> least, that will be another patch.
>>>>
>>>> Yes. Move it there. That is the right place.
>>>>
>>
>> Sorry for replying late about IOMEM_ERR_PTR().
>>
>> Although no objections within 2 days, for me, when move something to
>> generic header file, it is not only for future using, but also for
>> solving current issue, or it has to be suspended for waiting 'trigger'.
>>
>> So for me, the patch about IOMEM_ERR_PTR() need be suspended, until some
>> member find an issue which may be related with IOMEM_ERR_PTR(), more or
>> less.
>
> Matthias Brugger already moved it to include/linux/io.h on Friday.
>
OK, thank you for your work.
And for me, this 'long discussion' can be finished now (keeping current
status no touch). But if any members have additional suggestions and
ideas, still welcome to reply directly.
Thanks.
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed
^ permalink raw reply
* [PATCHES] hid: Add support for more Huion tablets
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel
Hi everyone,
These patches add support for more Huion tablet models. At least five models
were verified working with the out-of-tree driver [1] which these patches are
based on. This in-tree driver was verified working with Huion H610N.
The Huion tablets seem to all use a single product ID and the iProduct strings
are inconsistent. So there isn't much to identify the models with so far,
although the magic string descriptor containing tablet parameters has some
internal model name which might be used to identify them in the future.
For now, though, the driver leaves the mouse and keyboard interfaces enabled
unconditionally as some models do use them, and it doesn't try to adjust
keyboard report descriptor or interpret keyboard reports to make reported key
combinations more suitable to Linux applications as they might be different
between models.
The driver uses a somewhat non-standard approach: it puts the parameters
extracted from the magic string descriptor into a report descriptor template
and then feeds it to the generic HID layer. This appears simpler than creating
the input device and then parsing the reports in the driver.
However, if the particular approach or implementation is wrong or undesirable
in some way, I'm ready to change it.
Thank you.
Nick
drivers/hid/hid-core.c | 2 +-
drivers/hid/hid-huion.c | 271 ++++++++++++++++++++++++++++++++----------------
drivers/hid/hid-ids.h | 2 +-
3 files changed, 182 insertions(+), 93 deletions(-)
[1] https://github.com/DIGImend/huion-driver
^ permalink raw reply
* [PATCH 1/5] hid: huion: Use "tablet" instead of specific model
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel, Nikolai Kondrashov
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
Use word "tablet" in identifiers and comments instead of referring to specific
Huion tablet model name, as the product ID is used by at least several tablet
models.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
---
drivers/hid/hid-core.c | 2 +-
drivers/hid/hid-huion.c | 25 +++++++++++++------------
drivers/hid/hid-ids.h | 2 +-
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8ed66fd..84ed7d4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1782,7 +1782,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index cbf4da4..25d01cd 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -2,6 +2,7 @@
* HID driver for Huion devices not fully compliant with HID standard
*
* Copyright (c) 2013 Martin Rusko
+ * Copyright (c) 2014 Nikolai Kondrashov
*/
/*
@@ -19,11 +20,11 @@
#include "hid-ids.h"
-/* Original Huion 580 report descriptor size */
-#define HUION_580_RDESC_ORIG_SIZE 177
+/* Original tablet report descriptor size */
+#define HUION_TABLET_RDESC_ORIG_SIZE 177
-/* Fixed Huion 580 report descriptor */
-static __u8 huion_580_rdesc_fixed[] = {
+/* Fixed tablet report descriptor */
+static __u8 huion_tablet_rdesc_fixed[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */
@@ -72,10 +73,10 @@ static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
switch (hdev->product) {
- case USB_DEVICE_ID_HUION_580:
- if (*rsize == HUION_580_RDESC_ORIG_SIZE) {
- rdesc = huion_580_rdesc_fixed;
- *rsize = sizeof(huion_580_rdesc_fixed);
+ case USB_DEVICE_ID_HUION_TABLET:
+ if (*rsize == HUION_TABLET_RDESC_ORIG_SIZE) {
+ rdesc = huion_tablet_rdesc_fixed;
+ *rsize = sizeof(huion_tablet_rdesc_fixed);
}
break;
}
@@ -108,11 +109,11 @@ static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
int ret;
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- /* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet,
+ /* Ignore interfaces 1 (mouse) and 2 (keyboard) for tablet,
* as they are not used
*/
switch (id->product) {
- case USB_DEVICE_ID_HUION_580:
+ case USB_DEVICE_ID_HUION_TABLET:
if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00)
return -ENODEV;
break;
@@ -131,7 +132,7 @@ static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
switch (id->product) {
- case USB_DEVICE_ID_HUION_580:
+ case USB_DEVICE_ID_HUION_TABLET:
ret = huion_tablet_enable(hdev);
if (ret) {
hid_err(hdev, "tablet enabling failed\n");
@@ -158,7 +159,7 @@ static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
}
static const struct hid_device_id huion_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
{ }
};
MODULE_DEVICE_TABLE(hid, huion_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 48b66bb..fe2f163 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -448,7 +448,7 @@
#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
#define USB_VENDOR_ID_HUION 0x256c
-#define USB_DEVICE_ID_HUION_580 0x006e
+#define USB_DEVICE_ID_HUION_TABLET 0x006e
#define USB_VENDOR_ID_IDEACOM 0x1cb6
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
--
2.0.1
^ permalink raw reply related
* [PATCH 2/5] hid: huion: Invert in-range on specific product
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel, Nikolai Kondrashov
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
Limit inverting the in-range bit in raw reports to tablet product ID
only. This will make adding handling of other, non-tablet products,
easier.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
---
drivers/hid/hid-huion.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index 25d01cd..db24472 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -151,9 +151,15 @@ err:
static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *data, int size)
{
- /* If this is a pen input report then invert the in-range bit */
- if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2)
- data[1] ^= 0x40;
+ switch (hdev->product) {
+ case USB_DEVICE_ID_HUION_TABLET:
+ /* If this is a pen input report */
+ if (report->type == HID_INPUT_REPORT &&
+ report->id == 0x07 && size >= 2)
+ /* Invert the in-range bit */
+ data[1] ^= 0x40;
+ break;
+ }
return 0;
}
--
2.0.1
^ permalink raw reply related
* [PATCH 3/5] hid: huion: Don't ignore other interfaces
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel, Nikolai Kondrashov
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
Don't ignore non pen-reporting interfaces as they may be used by some
models reusing the same product ID.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
---
drivers/hid/hid-huion.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index db24472..e5f1e22 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -107,17 +107,6 @@ static int huion_tablet_enable(struct hid_device *hdev)
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
-
- /* Ignore interfaces 1 (mouse) and 2 (keyboard) for tablet,
- * as they are not used
- */
- switch (id->product) {
- case USB_DEVICE_ID_HUION_TABLET:
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00)
- return -ENODEV;
- break;
- }
ret = hid_parse(hdev);
if (ret) {
@@ -151,10 +140,13 @@ err:
static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *data, int size)
{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
switch (hdev->product) {
case USB_DEVICE_ID_HUION_TABLET:
/* If this is a pen input report */
- if (report->type == HID_INPUT_REPORT &&
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0 &&
+ report->type == HID_INPUT_REPORT &&
report->id == 0x07 && size >= 2)
/* Invert the in-range bit */
data[1] ^= 0x40;
--
2.0.1
^ permalink raw reply related
* [PATCH 4/5] hid: huion: Switch to generating report descriptor
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel, Nikolai Kondrashov
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
Switch to generating tablet pen report descriptor from a template and
parameters retrieved from string descriptor 0x64.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
---
drivers/hid/hid-huion.c | 245 +++++++++++++++++++++++++++++++++---------------
1 file changed, 167 insertions(+), 78 deletions(-)
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index e5f1e22..e6f5338 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -16,67 +16,89 @@
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <asm/unaligned.h>
#include "usbhid/usbhid.h"
#include "hid-ids.h"
-/* Original tablet report descriptor size */
-#define HUION_TABLET_RDESC_ORIG_SIZE 177
-
-/* Fixed tablet report descriptor */
-static __u8 huion_tablet_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x07, /* Report ID (7), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
- 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
- 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
+/* Report descriptor template placeholder head */
+#define HUION_PH_HEAD 0xFE, 0xED, 0x1D
+
+/* Report descriptor template placeholder IDs */
+enum huion_ph_id {
+ HUION_PH_ID_X_LM,
+ HUION_PH_ID_X_PM,
+ HUION_PH_ID_Y_LM,
+ HUION_PH_ID_Y_PM,
+ HUION_PH_ID_PRESSURE_LM,
+ HUION_PH_ID_NUM
+};
+
+/* Report descriptor template placeholder */
+#define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
+
+/* Fixed report descriptor template */
+static const __u8 huion_tablet_rdesc_template[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x07, /* Report ID (7), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x09, 0x32, /* Usage (In Range), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x27, HUION_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x47, HUION_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x27, HUION_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x47, HUION_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x27,
+ HUION_PH(PRESSURE_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/* Driver data */
+struct huion_drvdata {
+ __u8 *rdesc;
+ unsigned int rsize;
};
static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
+ struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
switch (hdev->product) {
case USB_DEVICE_ID_HUION_TABLET:
- if (*rsize == HUION_TABLET_RDESC_ORIG_SIZE) {
- rdesc = huion_tablet_rdesc_fixed;
- *rsize = sizeof(huion_tablet_rdesc_fixed);
+ if (drvdata->rdesc != NULL) {
+ rdesc = drvdata->rdesc;
+ *rsize = drvdata->rsize;
}
break;
}
@@ -84,57 +106,124 @@ static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
}
/**
- * Enable fully-functional tablet mode by reading special string
- * descriptor.
+ * Enable fully-functional tablet mode and determine device parameters.
*
* @hdev: HID device
- *
- * The specific string descriptor and data were discovered by sniffing
- * the Windows driver traffic.
*/
static int huion_tablet_enable(struct hid_device *hdev)
{
int rc;
- char buf[22];
+ struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+ struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
+ u16 buf[6];
- rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf));
- if (rc < 0)
- return rc;
+ /*
+ * Read string descriptor containing tablet parameters. The specific
+ * string descriptor and data were discovered by sniffing the Windows
+ * driver traffic.
+ * NOTE: This enables fully-functional tablet mode.
+ */
+ rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (USB_DT_STRING << 8) + 0x64,
+ 0x0409, buf, sizeof(buf),
+ USB_CTRL_GET_TIMEOUT);
+ if (rc == -EPIPE)
+ hid_warn(hdev, "device parameters not found\n");
+ else if (rc < 0)
+ hid_warn(hdev, "failed to get device parameters: %d\n", rc);
+ else if (rc != sizeof(buf))
+ hid_warn(hdev, "invalid device parameters\n");
+ else {
+ s32 params[HUION_PH_ID_NUM];
+ s32 resolution;
+ __u8 *p;
+ s32 v;
+
+ /* Extract device parameters */
+ params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
+ params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
+ params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
+ resolution = le16_to_cpu(buf[5]);
+ if (resolution == 0) {
+ params[HUION_PH_ID_X_PM] = 0;
+ params[HUION_PH_ID_Y_PM] = 0;
+ } else {
+ params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
+ 1000 / resolution;
+ params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
+ 1000 / resolution;
+ }
+
+ /* Allocate fixed report descriptor */
+ drvdata->rdesc = devm_kmalloc(&hdev->dev,
+ sizeof(huion_tablet_rdesc_template),
+ GFP_KERNEL);
+ if (drvdata->rdesc == NULL) {
+ hid_err(hdev, "failed to allocate fixed rdesc\n");
+ return -ENOMEM;
+ }
+ drvdata->rsize = sizeof(huion_tablet_rdesc_template);
+
+ /* Format fixed report descriptor */
+ memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
+ drvdata->rsize);
+ for (p = drvdata->rdesc;
+ p <= drvdata->rdesc + drvdata->rsize - 4;) {
+ if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
+ p[3] < sizeof(params)) {
+ v = params[p[3]];
+ put_unaligned(cpu_to_le32(v), (s32 *)p);
+ p += 4;
+ } else {
+ p++;
+ }
+ }
+ }
return 0;
}
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
+ int rc;
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct huion_drvdata *drvdata;
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
+ /* Allocate and assign driver data */
+ drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (drvdata == NULL) {
+ hid_err(hdev, "failed to allocate driver data\n");
+ return -ENOMEM;
}
+ hid_set_drvdata(hdev, drvdata);
switch (id->product) {
case USB_DEVICE_ID_HUION_TABLET:
- ret = huion_tablet_enable(hdev);
- if (ret) {
- hid_err(hdev, "tablet enabling failed\n");
- goto enabling_err;
+ /* If this is the pen interface */
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+ rc = huion_tablet_enable(hdev);
+ if (rc) {
+ hid_err(hdev, "tablet enabling failed\n");
+ return rc;
+ }
}
break;
}
+ rc = hid_parse(hdev);
+ if (rc) {
+ hid_err(hdev, "parse failed\n");
+ return rc;
+ }
+
+ rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (rc) {
+ hid_err(hdev, "hw start failed\n");
+ return rc;
+ }
+
return 0;
-enabling_err:
- hid_hw_stop(hdev);
-err:
- return ret;
}
static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
--
2.0.1
^ permalink raw reply related
* [PATCH 5/5] hid: huion: Handle tablets with UC-Logic vendor ID
From: Nikolai Kondrashov @ 2014-07-23 12:42 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel, Nikolai Kondrashov
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
Add handling of Huion tablets with UC-Logic vendor ID, but the same
product ID to hid-huion driver. A Huion H580 was seen using it.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
---
drivers/hid/hid-huion.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index e6f5338..1006c2a 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -247,6 +247,7 @@ static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
static const struct hid_device_id huion_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) },
{ }
};
MODULE_DEVICE_TABLE(hid, huion_devices);
--
2.0.1
^ permalink raw reply related
* Re: [PATCHES] hid: Add support for more Huion tablets
From: Nikolai Kondrashov @ 2014-07-23 13:39 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, DIGImend-devel
In-Reply-To: <1406119378-24551-1-git-send-email-spbnick@gmail.com>
On 07/23/2014 03:42 PM, Nikolai Kondrashov wrote:
> The Huion tablets seem to all use a single product ID and the iProduct strings
> are inconsistent. So there isn't much to identify the models with so far,
> although the magic string descriptor containing tablet parameters has some
> internal model name which might be used to identify them in the future.
A minor correction for the record: the internal model is contained in a string
descriptor separate from the one carrying the device parameters.
See https://github.com/DIGImend/huion-tools for details.
Nick
^ permalink raw reply
* Re: [PATCH 1/5] hid: huion: Use "tablet" instead of specific model
From: Benjamin Tissoires @ 2014-07-23 14:30 UTC (permalink / raw)
To: Nikolai Kondrashov; +Cc: Jiri Kosina, linux-input, DIGImend-devel
In-Reply-To: <1406119378-24551-2-git-send-email-spbnick@gmail.com>
On Wed, Jul 23, 2014 at 8:42 AM, Nikolai Kondrashov <spbnick@gmail.com> wrote:
> Use word "tablet" in identifiers and comments instead of referring to specific
> Huion tablet model name, as the product ID is used by at least several tablet
> models.
>
> Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
> ---
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH 2/5] hid: huion: Invert in-range on specific product
From: Benjamin Tissoires @ 2014-07-23 14:34 UTC (permalink / raw)
To: Nikolai Kondrashov; +Cc: Jiri Kosina, linux-input, DIGImend-devel
In-Reply-To: <1406119378-24551-3-git-send-email-spbnick@gmail.com>
On Wed, Jul 23, 2014 at 8:42 AM, Nikolai Kondrashov <spbnick@gmail.com> wrote:
> Limit inverting the in-range bit in raw reports to tablet product ID
> only. This will make adding handling of other, non-tablet products,
> easier.
>
> Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
> ---
I am not particularly a big fan of this one. You are here adding a
test which will be called at each raw_event but currently only tablet
products are bound to hid-huion. Even in the rest of the series, you
add another VID/PID, but it still has the same PID.
So I would say that this will be nice to have when we really have the
problem, not now.
But if you tell me that you already have the need for it, I am fine
with it. It's just that this commit message + the rest of the patch
series makes me feel like this is just a superflous test.
So, in its current state:
NACK
Cheers,
Benjamin
> drivers/hid/hid-huion.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
> index 25d01cd..db24472 100644
> --- a/drivers/hid/hid-huion.c
> +++ b/drivers/hid/hid-huion.c
> @@ -151,9 +151,15 @@ err:
> static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
> u8 *data, int size)
> {
> - /* If this is a pen input report then invert the in-range bit */
> - if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2)
> - data[1] ^= 0x40;
> + switch (hdev->product) {
> + case USB_DEVICE_ID_HUION_TABLET:
> + /* If this is a pen input report */
> + if (report->type == HID_INPUT_REPORT &&
> + report->id == 0x07 && size >= 2)
> + /* Invert the in-range bit */
> + data[1] ^= 0x40;
> + break;
> + }
>
> return 0;
> }
> --
> 2.0.1
>
> --
> 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 2/5] hid: huion: Invert in-range on specific product
From: Nikolai Kondrashov @ 2014-07-23 14:40 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: Jiri Kosina, linux-input, DIGImend-devel
In-Reply-To: <CAN+gG=F3ddT4kgHPMhvMgOFNf0Z29utAPJWsnVWuB98xbZ0gKA@mail.gmail.com>
On 07/23/2014 05:34 PM, Benjamin Tissoires wrote:
> On Wed, Jul 23, 2014 at 8:42 AM, Nikolai Kondrashov <spbnick@gmail.com> wrote:
>> Limit inverting the in-range bit in raw reports to tablet product ID
>> only. This will make adding handling of other, non-tablet products,
>> easier.
>>
>> Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
>> ---
>
> I am not particularly a big fan of this one. You are here adding a
> test which will be called at each raw_event but currently only tablet
> products are bound to hid-huion. Even in the rest of the series, you
> add another VID/PID, but it still has the same PID.
>
> So I would say that this will be nice to have when we really have the
> problem, not now.
>
> But if you tell me that you already have the need for it, I am fine
> with it. It's just that this commit message + the rest of the patch
> series makes me feel like this is just a superflous test.
>
> So, in its current state:
> NACK
I had doubts about this one myself, but left it in just for consistency with
some other drivers. I'll drop it in the next version then.
Thank you.
Nick
^ permalink raw reply
* Re: [PATCH 4/5] hid: huion: Switch to generating report descriptor
From: Benjamin Tissoires @ 2014-07-23 14:42 UTC (permalink / raw)
To: Nikolai Kondrashov; +Cc: Jiri Kosina, linux-input, DIGImend-devel
In-Reply-To: <1406119378-24551-5-git-send-email-spbnick@gmail.com>
On Wed, Jul 23, 2014 at 8:42 AM, Nikolai Kondrashov <spbnick@gmail.com> wrote:
> Switch to generating tablet pen report descriptor from a template and
> parameters retrieved from string descriptor 0x64.
>
> Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
> ---
This is a nice solution.
I still have few remarks/questions inlined:
> drivers/hid/hid-huion.c | 245 +++++++++++++++++++++++++++++++++---------------
> 1 file changed, 167 insertions(+), 78 deletions(-)
>
> diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
> index e5f1e22..e6f5338 100644
> --- a/drivers/hid/hid-huion.c
> +++ b/drivers/hid/hid-huion.c
> @@ -16,67 +16,89 @@
> #include <linux/hid.h>
> #include <linux/module.h>
> #include <linux/usb.h>
> +#include <asm/unaligned.h>
> #include "usbhid/usbhid.h"
>
> #include "hid-ids.h"
>
> -/* Original tablet report descriptor size */
> -#define HUION_TABLET_RDESC_ORIG_SIZE 177
> -
> -/* Fixed tablet report descriptor */
> -static __u8 huion_tablet_rdesc_fixed[] = {
> - 0x05, 0x0D, /* Usage Page (Digitizer), */
> - 0x09, 0x02, /* Usage (Pen), */
> - 0xA1, 0x01, /* Collection (Application), */
> - 0x85, 0x07, /* Report ID (7), */
> - 0x09, 0x20, /* Usage (Stylus), */
> - 0xA0, /* Collection (Physical), */
> - 0x14, /* Logical Minimum (0), */
> - 0x25, 0x01, /* Logical Maximum (1), */
> - 0x75, 0x01, /* Report Size (1), */
> - 0x09, 0x42, /* Usage (Tip Switch), */
> - 0x09, 0x44, /* Usage (Barrel Switch), */
> - 0x09, 0x46, /* Usage (Tablet Pick), */
> - 0x95, 0x03, /* Report Count (3), */
> - 0x81, 0x02, /* Input (Variable), */
> - 0x95, 0x03, /* Report Count (3), */
> - 0x81, 0x03, /* Input (Constant, Variable), */
> - 0x09, 0x32, /* Usage (In Range), */
> - 0x95, 0x01, /* Report Count (1), */
> - 0x81, 0x02, /* Input (Variable), */
> - 0x95, 0x01, /* Report Count (1), */
> - 0x81, 0x03, /* Input (Constant, Variable), */
> - 0x75, 0x10, /* Report Size (16), */
> - 0x95, 0x01, /* Report Count (1), */
> - 0xA4, /* Push, */
> - 0x05, 0x01, /* Usage Page (Desktop), */
> - 0x65, 0x13, /* Unit (Inch), */
> - 0x55, 0xFD, /* Unit Exponent (-3), */
> - 0x34, /* Physical Minimum (0), */
> - 0x09, 0x30, /* Usage (X), */
> - 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
> - 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */
> - 0x81, 0x02, /* Input (Variable), */
> - 0x09, 0x31, /* Usage (Y), */
> - 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
> - 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
> - 0x81, 0x02, /* Input (Variable), */
> - 0xB4, /* Pop, */
> - 0x09, 0x30, /* Usage (Tip Pressure), */
> - 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */
> - 0x81, 0x02, /* Input (Variable), */
> - 0xC0, /* End Collection, */
> - 0xC0 /* End Collection */
> +/* Report descriptor template placeholder head */
> +#define HUION_PH_HEAD 0xFE, 0xED, 0x1D
> +
> +/* Report descriptor template placeholder IDs */
> +enum huion_ph_id {
> + HUION_PH_ID_X_LM,
> + HUION_PH_ID_X_PM,
> + HUION_PH_ID_Y_LM,
> + HUION_PH_ID_Y_PM,
> + HUION_PH_ID_PRESSURE_LM,
> + HUION_PH_ID_NUM
> +};
> +
> +/* Report descriptor template placeholder */
> +#define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
> +
> +/* Fixed report descriptor template */
> +static const __u8 huion_tablet_rdesc_template[] = {
> + 0x05, 0x0D, /* Usage Page (Digitizer), */
> + 0x09, 0x02, /* Usage (Pen), */
> + 0xA1, 0x01, /* Collection (Application), */
> + 0x85, 0x07, /* Report ID (7), */
> + 0x09, 0x20, /* Usage (Stylus), */
> + 0xA0, /* Collection (Physical), */
> + 0x14, /* Logical Minimum (0), */
> + 0x25, 0x01, /* Logical Maximum (1), */
> + 0x75, 0x01, /* Report Size (1), */
> + 0x09, 0x42, /* Usage (Tip Switch), */
> + 0x09, 0x44, /* Usage (Barrel Switch), */
> + 0x09, 0x46, /* Usage (Tablet Pick), */
> + 0x95, 0x03, /* Report Count (3), */
> + 0x81, 0x02, /* Input (Variable), */
> + 0x95, 0x03, /* Report Count (3), */
> + 0x81, 0x03, /* Input (Constant, Variable), */
> + 0x09, 0x32, /* Usage (In Range), */
> + 0x95, 0x01, /* Report Count (1), */
> + 0x81, 0x02, /* Input (Variable), */
> + 0x95, 0x01, /* Report Count (1), */
> + 0x81, 0x03, /* Input (Constant, Variable), */
> + 0x75, 0x10, /* Report Size (16), */
> + 0x95, 0x01, /* Report Count (1), */
> + 0xA4, /* Push, */
> + 0x05, 0x01, /* Usage Page (Desktop), */
> + 0x65, 0x13, /* Unit (Inch), */
> + 0x55, 0xFD, /* Unit Exponent (-3), */
> + 0x34, /* Physical Minimum (0), */
> + 0x09, 0x30, /* Usage (X), */
> + 0x27, HUION_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */
> + 0x47, HUION_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */
> + 0x81, 0x02, /* Input (Variable), */
> + 0x09, 0x31, /* Usage (Y), */
> + 0x27, HUION_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */
> + 0x47, HUION_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */
> + 0x81, 0x02, /* Input (Variable), */
> + 0xB4, /* Pop, */
> + 0x09, 0x30, /* Usage (Tip Pressure), */
> + 0x27,
> + HUION_PH(PRESSURE_LM), /* Logical Maximum (PLACEHOLDER), */
> + 0x81, 0x02, /* Input (Variable), */
> + 0xC0, /* End Collection, */
> + 0xC0 /* End Collection */
> +};
> +
> +/* Driver data */
> +struct huion_drvdata {
> + __u8 *rdesc;
> + unsigned int rsize;
> };
>
> static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> unsigned int *rsize)
> {
> + struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
> switch (hdev->product) {
> case USB_DEVICE_ID_HUION_TABLET:
> - if (*rsize == HUION_TABLET_RDESC_ORIG_SIZE) {
> - rdesc = huion_tablet_rdesc_fixed;
> - *rsize = sizeof(huion_tablet_rdesc_fixed);
> + if (drvdata->rdesc != NULL) {
> + rdesc = drvdata->rdesc;
> + *rsize = drvdata->rsize;
> }
> break;
> }
> @@ -84,57 +106,124 @@ static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> }
>
> /**
> - * Enable fully-functional tablet mode by reading special string
> - * descriptor.
> + * Enable fully-functional tablet mode and determine device parameters.
> *
> * @hdev: HID device
> - *
> - * The specific string descriptor and data were discovered by sniffing
> - * the Windows driver traffic.
> */
> static int huion_tablet_enable(struct hid_device *hdev)
> {
> int rc;
> - char buf[22];
> + struct usb_device *usb_dev = hid_to_usb_dev(hdev);
> + struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
> + u16 buf[6];
>
> - rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf));
> - if (rc < 0)
> - return rc;
> + /*
> + * Read string descriptor containing tablet parameters. The specific
> + * string descriptor and data were discovered by sniffing the Windows
> + * driver traffic.
> + * NOTE: This enables fully-functional tablet mode.
> + */
> + rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
> + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
> + (USB_DT_STRING << 8) + 0x64,
> + 0x0409, buf, sizeof(buf),
> + USB_CTRL_GET_TIMEOUT);
Just out of curiosity, you are replacing usb_string() by
usb_control_msg(). They both seem to do the same, so why bother
changing the call?
> + if (rc == -EPIPE)
> + hid_warn(hdev, "device parameters not found\n");
> + else if (rc < 0)
> + hid_warn(hdev, "failed to get device parameters: %d\n", rc);
> + else if (rc != sizeof(buf))
> + hid_warn(hdev, "invalid device parameters\n");
> + else {
> + s32 params[HUION_PH_ID_NUM];
> + s32 resolution;
> + __u8 *p;
> + s32 v;
> +
> + /* Extract device parameters */
> + params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
> + params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
> + params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
> + resolution = le16_to_cpu(buf[5]);
> + if (resolution == 0) {
> + params[HUION_PH_ID_X_PM] = 0;
> + params[HUION_PH_ID_Y_PM] = 0;
This is not good (not your code I mean). I know OEMs tend to not care
about resolution, but Wayland will for the tablet protocol. The idea
will be to report the coordinate in mm so that we can have a constant
reporting across vendors/products.
Did you ever fall in this case? and if so, isn't there any way of
retrieving the actual resolution or an approximation?
> + } else {
> + params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
> + 1000 / resolution;
> + params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
> + 1000 / resolution;
> + }
> +
> + /* Allocate fixed report descriptor */
> + drvdata->rdesc = devm_kmalloc(&hdev->dev,
> + sizeof(huion_tablet_rdesc_template),
> + GFP_KERNEL);
> + if (drvdata->rdesc == NULL) {
> + hid_err(hdev, "failed to allocate fixed rdesc\n");
> + return -ENOMEM;
> + }
> + drvdata->rsize = sizeof(huion_tablet_rdesc_template);
> +
> + /* Format fixed report descriptor */
> + memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
> + drvdata->rsize);
> + for (p = drvdata->rdesc;
> + p <= drvdata->rdesc + drvdata->rsize - 4;) {
> + if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
> + p[3] < sizeof(params)) {
> + v = params[p[3]];
> + put_unaligned(cpu_to_le32(v), (s32 *)p);
> + p += 4;
> + } else {
> + p++;
> + }
> + }
> + }
>
> return 0;
> }
>
> static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
> {
> - int ret;
> -
> - ret = hid_parse(hdev);
> - if (ret) {
> - hid_err(hdev, "parse failed\n");
> - goto err;
> - }
> + int rc;
> + struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
> + struct huion_drvdata *drvdata;
>
> - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> - if (ret) {
> - hid_err(hdev, "hw start failed\n");
> - goto err;
> + /* Allocate and assign driver data */
> + drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
> + if (drvdata == NULL) {
> + hid_err(hdev, "failed to allocate driver data\n");
> + return -ENOMEM;
> }
> + hid_set_drvdata(hdev, drvdata);
>
> switch (id->product) {
> case USB_DEVICE_ID_HUION_TABLET:
> - ret = huion_tablet_enable(hdev);
> - if (ret) {
> - hid_err(hdev, "tablet enabling failed\n");
> - goto enabling_err;
> + /* If this is the pen interface */
> + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
> + rc = huion_tablet_enable(hdev);
> + if (rc) {
> + hid_err(hdev, "tablet enabling failed\n");
> + return rc;
> + }
> }
> break;
> }
>
> + rc = hid_parse(hdev);
> + if (rc) {
> + hid_err(hdev, "parse failed\n");
> + return rc;
> + }
> +
> + rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> + if (rc) {
> + hid_err(hdev, "hw start failed\n");
> + return rc;
> + }
> +
> return 0;
> -enabling_err:
> - hid_hw_stop(hdev);
> -err:
> - return ret;
> }
>
> static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
> --
> 2.0.1
>
The rest looks fair enough, so even with my questions:
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cheers,
Benjamin
^ 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