* Re: [PATCH 1/5] add missing blob structure field for tag id
From: Hans Verkuil @ 2018-02-06 21:22 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <1517950905-5015-2-git-send-email-floe@butterbrot.org>
On 02/06/2018 10:01 PM, Florian Echtler wrote:
> The SUR40 can recognize specific printed patterns directly in hardware;
> this information (i.e. the pattern id) is present but currently unused
> in the blob structure.
>
> Signed-off-by: Florian Echtler <floe@butterbrot.org>
> ---
> drivers/input/touchscreen/sur40.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index f16f835..8375b06 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -81,7 +81,10 @@ struct sur40_blob {
>
> __le32 area; /* size in pixels/pressure (?) */
>
> - u8 padding[32];
> + u8 padding[24];
> +
> + __le32 tag_id; /* valid when type == 0x04 (SUR40_TAG) */
> + __le32 unknown;
>
> } __packed;
>
>
Usually new fields are added before the padding, not after.
Unless there is a good reason for this I'd change this.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH 4/5] register control handlers using V4L2 control framework
From: Hans Verkuil @ 2018-02-06 21:26 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <1517950905-5015-5-git-send-email-floe@butterbrot.org>
On 02/06/2018 10:01 PM, Florian Echtler wrote:
> This patch registers four standard control handlers using the corresponding
> V4L2 framework.
>
> Signed-off-by: Florian Echtler <floe@butterbrot.org>
> ---
> drivers/input/touchscreen/sur40.c | 51 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index 7f6461d..66ef7e6 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -38,6 +38,7 @@
> #include <media/v4l2-device.h>
> #include <media/v4l2-dev.h>
> #include <media/v4l2-ioctl.h>
> +#include <media/v4l2-ctrls.h>
> #include <media/videobuf2-v4l2.h>
> #include <media/videobuf2-dma-sg.h>
>
> @@ -198,6 +199,7 @@ struct sur40_state {
> struct video_device vdev;
> struct mutex lock;
> struct v4l2_pix_format pix_fmt;
> + struct v4l2_ctrl_handler ctrls;
This is normally called 'hdl' or 'ctrl_handler'.
>
> struct vb2_queue queue;
> struct list_head buf_list;
> @@ -207,6 +209,7 @@ struct sur40_state {
> struct sur40_data *bulk_in_buffer;
> size_t bulk_in_size;
> u8 bulk_in_epaddr;
> + u8 vsvideo;
>
> char phys[64];
> };
> @@ -220,6 +223,11 @@ struct sur40_buffer {
> static const struct video_device sur40_video_device;
> static const struct vb2_queue sur40_queue;
> static void sur40_process_video(struct sur40_state *sur40);
> +static int sur40_s_ctrl(struct v4l2_ctrl *ctrl);
> +
> +static const struct v4l2_ctrl_ops sur40_ctrl_ops = {
> + .s_ctrl = sur40_s_ctrl,
> +};
>
> /*
> * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
> @@ -722,6 +730,23 @@ static int sur40_probe(struct usb_interface *interface,
> sur40->vdev.queue = &sur40->queue;
> video_set_drvdata(&sur40->vdev, sur40);
>
> + /* initialize the control handler for 4 controls */
> + v4l2_ctrl_handler_init(&sur40->ctrls, 4);
> + sur40->v4l2.ctrl_handler = &sur40->ctrls;
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_BRIGHTNESS,
> + SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX, 1, SUR40_BRIGHTNESS_DEF);
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_CONTRAST,
> + SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX, 1, SUR40_CONTRAST_DEF);
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_GAIN,
> + SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, SUR40_GAIN_DEF);
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops,
> + V4L2_CID_BACKLIGHT_COMPENSATION, SUR40_BACKLIGHT_MIN,
> + SUR40_BACKLIGHT_MAX, 1, SUR40_BACKLIGHT_DEF);
You need to check if the creation succeeded:
if (ctrls->error) {
v4l2_ctrl_handler_free(ctrls);
// exit
}
> +
> error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
> if (error) {
> dev_err(&interface->dev,
> @@ -754,6 +779,7 @@ static void sur40_disconnect(struct usb_interface *interface)
> {
> struct sur40_state *sur40 = usb_get_intfdata(interface);
>
> + v4l2_ctrl_handler_free(&sur40->ctrls);
> video_unregister_device(&sur40->vdev);
> v4l2_device_unregister(&sur40->v4l2);
>
> @@ -947,6 +973,31 @@ static int sur40_vidioc_g_fmt(struct file *file, void *priv,
> return 0;
> }
>
> +static int sur40_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct sur40_state *sur40 = container_of(ctrl->handler,
> + struct sur40_state, ctrls);
> + u8 value = sur40->vsvideo;
> +
> + switch (ctrl->id) {
> + case V4L2_CID_BRIGHTNESS:
> + sur40_set_irlevel(sur40, ctrl->val);
> + break;
> + case V4L2_CID_CONTRAST:
> + value = (value & 0x0F) | (ctrl->val << 4);
> + sur40_set_vsvideo(sur40, value);
> + break;
> + case V4L2_CID_GAIN:
> + value = (value & 0xF0) | (ctrl->val);
> + sur40_set_vsvideo(sur40, value);
> + break;
> + case V4L2_CID_BACKLIGHT_COMPENSATION:
> + sur40_set_preprocessor(sur40, ctrl->val);
> + break;
> + }
> + return 0;
> +}
> +
> static int sur40_ioctl_parm(struct file *file, void *priv,
> struct v4l2_streamparm *p)
> {
>
Looks good otherwise.
Hans
^ permalink raw reply
* Re: [PATCH 5/5] add module parameters for default values
From: Hans Verkuil @ 2018-02-06 21:31 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <1517950905-5015-6-git-send-email-floe@butterbrot.org>
On 02/06/2018 10:01 PM, Florian Echtler wrote:
> To allow setting custom parameters for the sensor directly at startup, the
> three primary controls are exposed as module parameters in this patch.
>
> Signed-off-by: Florian Echtler <floe@butterbrot.org>
> ---
> drivers/input/touchscreen/sur40.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index 66ef7e6..d1fcb95 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -167,6 +167,17 @@ struct sur40_image_header {
> #define SUR40_BACKLIGHT_MIN 0x00
> #define SUR40_BACKLIGHT_DEF 0x01
>
> +/* module parameters */
> +static uint brightness = SUR40_BRIGHTNESS_DEF;
> +module_param(brightness, uint, 0644);
> +MODULE_PARM_DESC(brightness, "set default brightness");
> +static uint contrast = SUR40_CONTRAST_DEF;
> +module_param(contrast, uint, 0644);
> +MODULE_PARM_DESC(contrast, "set default contrast");
> +static uint gain = SUR40_GAIN_DEF;
> +module_param(gain, uint, 0644);
> +MODULE_PARM_DESC(contrast, "set default gain");
contrast -> gain
Isn't 'initial gain' better than 'default gain'?
If I load this module with gain=X, will the gain control also
start off at X? I didn't see any code for that.
It might be useful to add the allowed range in the description.
E.g.: "set initial gain, range=0-255". Perhaps mention even the
default value, but I'm not sure if that's really needed.
Regards,
Hans
> +
> static const struct v4l2_pix_format sur40_pix_format[] = {
> {
> .pixelformat = V4L2_TCH_FMT_TU08,
> @@ -374,6 +385,11 @@ static void sur40_open(struct input_polled_dev *polldev)
>
> dev_dbg(sur40->dev, "open\n");
> sur40_init(sur40);
> +
> + /* set default values */
> + sur40_set_irlevel(sur40, brightness & 0xFF);
> + sur40_set_vsvideo(sur40, ((contrast & 0x0F) << 4) | (gain & 0x0F));
> + sur40_set_preprocessor(sur40, SUR40_BACKLIGHT_DEF);
> }
>
> /* Disable device, polling has stopped. */
>
^ permalink raw reply
* Re: [PATCH 1/5] add missing blob structure field for tag id
From: Florian Echtler @ 2018-02-07 8:24 UTC (permalink / raw)
To: Hans Verkuil, linux-media; +Cc: linux-input, modin
In-Reply-To: <3219b5c2-2497-25a5-a22f-2f0f874692fe@xs4all.nl>
[-- Attachment #1.1: Type: text/plain, Size: 799 bytes --]
On 06.02.2018 22:22, Hans Verkuil wrote:
> On 02/06/2018 10:01 PM, Florian Echtler wrote:
>> The SUR40 can recognize specific printed patterns directly in hardware;
>> this information (i.e. the pattern id) is present but currently unused
>> in the blob structure.
>>
>>
>> __le32 area; /* size in pixels/pressure (?) */
>>
>> - u8 padding[32];
>> + u8 padding[24];
>> +
>> + __le32 tag_id; /* valid when type == 0x04 (SUR40_TAG) */
>> + __le32 unknown;
>>
>> } __packed;
>>
> Usually new fields are added before the padding, not after.
>
> Unless there is a good reason for this I'd change this.
This is how the hardware sends it, so there's little choice in how to arrange
the fields...
Best regards, Florian
--
SENT FROM MY DEC VT50 TERMINAL
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [PATCH 5/5] add module parameters for default values
From: Florian Echtler @ 2018-02-07 8:33 UTC (permalink / raw)
To: Hans Verkuil, linux-media; +Cc: linux-input, modin
In-Reply-To: <c64ae317-d393-1784-1184-4a24a2907112@xs4all.nl>
[-- Attachment #1.1: Type: text/plain, Size: 1681 bytes --]
On 06.02.2018 22:31, Hans Verkuil wrote:
> On 02/06/2018 10:01 PM, Florian Echtler wrote:
>> To allow setting custom parameters for the sensor directly at startup, the
>> three primary controls are exposed as module parameters in this patch.
>>
>> +/* module parameters */
>> +static uint brightness = SUR40_BRIGHTNESS_DEF;
>> +module_param(brightness, uint, 0644);
>> +MODULE_PARM_DESC(brightness, "set default brightness");
>> +static uint contrast = SUR40_CONTRAST_DEF;
>> +module_param(contrast, uint, 0644);
>> +MODULE_PARM_DESC(contrast, "set default contrast");
>> +static uint gain = SUR40_GAIN_DEF;
>> +module_param(gain, uint, 0644);
>> +MODULE_PARM_DESC(contrast, "set default gain");
>
> contrast -> gain
Ah, typo. Thanks, will fix that.
> Isn't 'initial gain' better than 'default gain'?
Probably correct, yes.
> If I load this module with gain=X, will the gain control also
> start off at X? I didn't see any code for that.
This reminds me: how can I get/set the control from inside the driver?
Should I use something like the following:
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&sur40->ctrls, V4L2_CID_BRIGHTNESS);
int val = v4l2_ctrl_g_ctrl(ctrl);
// modify val...
v4l2_ctrl_s_ctrl(ctrl, val);
> It might be useful to add the allowed range in the description.
> E.g.: "set initial gain, range=0-255". Perhaps mention even the
> default value, but I'm not sure if that's really needed.
Good point, though - right now the code directly sets the registers without any
clamping, I guess it would be better to call the control framework as mentioned
above?
Best regards, Florian
--
SENT FROM MY DEC VT50 TERMINAL
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [PATCH 5/5] add module parameters for default values
From: Hans Verkuil @ 2018-02-07 9:02 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <039aaa61-4150-ebde-5f9e-a0ffc8888cfb@butterbrot.org>
On 02/07/18 09:33, Florian Echtler wrote:
> On 06.02.2018 22:31, Hans Verkuil wrote:
>> On 02/06/2018 10:01 PM, Florian Echtler wrote:
>>> To allow setting custom parameters for the sensor directly at startup, the
>>> three primary controls are exposed as module parameters in this patch.
>>>
>>> +/* module parameters */
>>> +static uint brightness = SUR40_BRIGHTNESS_DEF;
>>> +module_param(brightness, uint, 0644);
>>> +MODULE_PARM_DESC(brightness, "set default brightness");
>>> +static uint contrast = SUR40_CONTRAST_DEF;
>>> +module_param(contrast, uint, 0644);
>>> +MODULE_PARM_DESC(contrast, "set default contrast");
>>> +static uint gain = SUR40_GAIN_DEF;
>>> +module_param(gain, uint, 0644);
>>> +MODULE_PARM_DESC(contrast, "set default gain");
>>
>> contrast -> gain
>
> Ah, typo. Thanks, will fix that.
>
>> Isn't 'initial gain' better than 'default gain'?
>
> Probably correct, yes.
>
>> If I load this module with gain=X, will the gain control also
>> start off at X? I didn't see any code for that.
>
> This reminds me: how can I get/set the control from inside the driver?
> Should I use something like the following:
>
> struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&sur40->ctrls, V4L2_CID_BRIGHTNESS);
> int val = v4l2_ctrl_g_ctrl(ctrl);
> // modify val...
> v4l2_ctrl_s_ctrl(ctrl, val);
Yes, that's correct. Usually drivers store the ctrl in their state struct
when they create the control. That way you don't have to find it.
>
>> It might be useful to add the allowed range in the description.
>> E.g.: "set initial gain, range=0-255". Perhaps mention even the
>> default value, but I'm not sure if that's really needed.
>
> Good point, though - right now the code directly sets the registers without any
> clamping, I guess it would be better to call the control framework as mentioned
> above?
Easiest is just to use this value for the default when you create the
control. Just clamp it first.
E.g.:
static uint gain = SUR40_GAIN_DEF;
module_param(gain, uint, 0644);
...
gain = clamp(gain, SUR40_GAIN_MIN, SUR40_GAIN_MAX);
v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_GAIN,
SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, gain);
You need to clamp gain first, otherwise v4l2_ctrl_new_std would fail
if the given default value is out of range.
Regards,
Hans
^ permalink raw reply
* Lenovo T460p touchpad and kernel 4.15.0
From: Peter Suetterlin @ 2018-02-07 12:31 UTC (permalink / raw)
To: linux-input
Hi,
After switching to kernel 4.15.0 (openSUSE Tumbleweed 20180203) the touchpad of
my Lenovo T460p stops working after a resume/suspend cycle.
Comparing to old logfiles I found a notice
"Your touchpad (PNP: LEN2018 PNP0f13) says it can support a different bus. If
i2c-hid and hid-rmi are not used, you might want to try setting
psmouse.synaptics_intertouch to 1 and report this to linux-input@vger.kernel.org."
That's why I'm writing here now.
The old logfile (from kernel 4.14.15) had this notice from psmouse:
kernel: psmouse serio1: synaptics: queried max coordinates: x [..5676], y [..4758]
kernel: psmouse serio1: synaptics: queried min coordinates: x [1266..], y [1096..]
kernel: psmouse serio1: synaptics: Your touchpad (PNP:
LEN2018 PNP0f13) says it can support a different bus. If i2c-hid and hid-rmi are
not used, you might want to try setting psmouse.synaptics_intertouch to 1 and
report this to linux-input@vger.kernel.org.
kernel: psmouse serio1: synaptics: Touchpad model: 1, fw: 8.2, id: 0x1e2b1, caps: 0xf006a3/0x943300/0x12e800/0x10000, board id: 3053,fw id: 2010421
kernel: psmouse serio1: synaptics: serio: Synaptics pass-through port at isa0060/serio1/input0
rmi was not used in this version
Booting 4.15.0 shows the same, just without the notice, but further down also
kernel: input: Synaptics TM3053-006 as /devices/rmi4-00/input/input23
During resume I then get the following:
kernel: rmi4_smbus 8-002c: failed to get SMBus version number!
kernel: rmi4_physical rmi4-00: rmi_driver_reset_handler: Failed to read current IRQ mask.
kernel: rmi4_f01 rmi4-00.fn01: Failed to restore normal operation: -16.
kernel: rmi4_f01 rmi4-00.fn01: Resume failed with code -16.
kernel: rmi4_physical rmi4-00: Failed to suspend functions: -16
kernel: rmi4_smbus 8-002c: Failed to resume device: -16
kernel: rmi4_f03 rmi4-00.fn03: rmi_f03_pt_write: Failed to write to F03 TX register (-16).
which likely(?) is the reason for the non-working touchpad.
(The trackpoint is affected, too, BTW, but I don't use it)
If you need more info let me know (please via direct mail, I'm not on the list)
Regards,
Pit
--
Dr. Peter "Pit" Suetterlin http://www.astro.su.se/~pit
Institute for Solar Physics
Tel.: +34 922 405 590 (Spain) P.Suetterlin@royac.iac.es
+46 8 5537 8558 (Sweden) Peter.Suetterlin@astro.su.se
^ permalink raw reply
* [PATCH v3] add video controls for SUR40 driver
From: Florian Echtler @ 2018-02-07 13:00 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin
As discussed previously, here's the third iteration of my patch to add
control functions for the SUR40 driver, with (hopefully) correct handling
of default values/module parameters, using the V4L2 control framework.
Best regards, Florian
^ permalink raw reply
* [PATCH 2/4] add default settings and module parameters for video controls
From: Florian Echtler @ 2018-02-07 13:00 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518008438-26603-1-git-send-email-floe@butterbrot.org>
This patch adds parameter definitions and module parameters for the four
userspace controls that the SUR40 can currently provide.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 8375b06..8a5b031 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -149,6 +149,34 @@ struct sur40_image_header {
#define SUR40_TOUCH 0x02
#define SUR40_TAG 0x04
+/* video controls */
+#define SUR40_BRIGHTNESS_MAX 0xFF
+#define SUR40_BRIGHTNESS_MIN 0x00
+#define SUR40_BRIGHTNESS_DEF 0xFF
+
+#define SUR40_CONTRAST_MAX 0x0F
+#define SUR40_CONTRAST_MIN 0x00
+#define SUR40_CONTRAST_DEF 0x0A
+
+#define SUR40_GAIN_MAX 0x09
+#define SUR40_GAIN_MIN 0x00
+#define SUR40_GAIN_DEF 0x08
+
+#define SUR40_BACKLIGHT_MAX 0x01
+#define SUR40_BACKLIGHT_MIN 0x00
+#define SUR40_BACKLIGHT_DEF 0x01
+
+/* module parameters */
+static uint brightness = SUR40_BRIGHTNESS_DEF;
+module_param(brightness, uint, 0644);
+MODULE_PARM_DESC(brightness, "set initial brightness");
+static uint contrast = SUR40_CONTRAST_DEF;
+module_param(contrast, uint, 0644);
+MODULE_PARM_DESC(contrast, "set initial contrast");
+static uint gain = SUR40_GAIN_DEF;
+module_param(gain, uint, 0644);
+MODULE_PARM_DESC(gain, "set initial gain");
+
static const struct v4l2_pix_format sur40_pix_format[] = {
{
.pixelformat = V4L2_TCH_FMT_TU08,
--
2.7.4
^ permalink raw reply related
* [PATCH 3/4] add panel register access functions
From: Florian Echtler @ 2018-02-07 13:00 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518008438-26603-1-git-send-email-floe@butterbrot.org>
These functions provide write access to the internal LCD panel registers
which also control the sensor. They can be used to disable the
preprocessor, set the illumination brightness, and adjust gain/contrast
(which are stored together in one register internally called "vsvideo").
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 75 +++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 8a5b031..d6fa25e 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -251,6 +251,81 @@ static int sur40_command(struct sur40_state *dev,
0x00, index, buffer, size, 1000);
}
+/* poke a byte in the panel register space */
+static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value)
+{
+ int result;
+ u8 index = 0x96; // 0xae for permanent write
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x32, index, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x72, offset, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0xb2, value, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+error:
+ return result;
+}
+
+static int sur40_set_preprocessor(struct sur40_state *dev, u8 value)
+{
+ u8 setting_07[2] = { 0x01, 0x00 };
+ u8 setting_17[2] = { 0x85, 0x80 };
+ int result;
+
+ if (value > 1)
+ return -ERANGE;
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x07, setting_07[value], NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x17, setting_17[value], NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+error:
+ return result;
+}
+
+static void sur40_set_vsvideo(struct sur40_state *handle, u8 value)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ sur40_poke(handle, 0x1c+i, value);
+ handle->vsvideo = value;
+}
+
+static void sur40_set_irlevel(struct sur40_state *handle, u8 value)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ sur40_poke(handle, 0x08+(2*i), value);
+}
+
/* Initialization routine, called from sur40_open */
static int sur40_init(struct sur40_state *dev)
{
--
2.7.4
^ permalink raw reply related
* [PATCH 1/4] add missing blob structure field for tag id
From: Florian Echtler @ 2018-02-07 13:00 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518008438-26603-1-git-send-email-floe@butterbrot.org>
The SUR40 can recognize specific printed patterns directly in hardware;
this information (i.e. the pattern id) is present but currently unused
in the blob structure.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index f16f835..8375b06 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -81,7 +81,10 @@ struct sur40_blob {
__le32 area; /* size in pixels/pressure (?) */
- u8 padding[32];
+ u8 padding[24];
+
+ __le32 tag_id; /* valid when type == 0x04 (SUR40_TAG) */
+ __le32 unknown;
} __packed;
--
2.7.4
^ permalink raw reply related
* [PATCH 4/4] add video control handlers using V4L2 control framework
From: Florian Echtler @ 2018-02-07 13:00 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518008438-26603-1-git-send-email-floe@butterbrot.org>
This patch registers four standard control handlers using the corresponding
V4L2 framework.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 64 +++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index d6fa25e..b92325b 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -38,6 +38,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>
@@ -209,6 +210,7 @@ struct sur40_state {
struct video_device vdev;
struct mutex lock;
struct v4l2_pix_format pix_fmt;
+ struct v4l2_ctrl_handler ctrls;
struct vb2_queue queue;
struct list_head buf_list;
@@ -218,6 +220,7 @@ struct sur40_state {
struct sur40_data *bulk_in_buffer;
size_t bulk_in_size;
u8 bulk_in_epaddr;
+ u8 vsvideo;
char phys[64];
};
@@ -231,6 +234,11 @@ struct sur40_buffer {
static const struct video_device sur40_video_device;
static const struct vb2_queue sur40_queue;
static void sur40_process_video(struct sur40_state *sur40);
+static int sur40_s_ctrl(struct v4l2_ctrl *ctrl);
+
+static const struct v4l2_ctrl_ops sur40_ctrl_ops = {
+ .s_ctrl = sur40_s_ctrl,
+};
/*
* Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
@@ -737,6 +745,36 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = &sur40->queue;
video_set_drvdata(&sur40->vdev, sur40);
+ /* initialize the control handler for 4 controls */
+ v4l2_ctrl_handler_init(&sur40->ctrls, 4);
+ sur40->v4l2.ctrl_handler = &sur40->ctrls;
+ sur40->vsvideo = (SUR40_CONTRAST_DEF << 4) | SUR40_GAIN_DEF;
+
+ v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_BRIGHTNESS,
+ SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX, 1, clamp(brightness,
+ (uint)SUR40_BRIGHTNESS_MIN, (uint)SUR40_BRIGHTNESS_MAX));
+
+ v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_CONTRAST,
+ SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX, 1, clamp(contrast,
+ (uint)SUR40_CONTRAST_MIN, (uint)SUR40_CONTRAST_MAX));
+
+ v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_GAIN,
+ SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, clamp(gain,
+ (uint)SUR40_GAIN_MIN, (uint)SUR40_GAIN_MAX));
+
+ v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops,
+ V4L2_CID_BACKLIGHT_COMPENSATION, SUR40_BACKLIGHT_MIN,
+ SUR40_BACKLIGHT_MAX, 1, SUR40_BACKLIGHT_DEF);
+
+ v4l2_ctrl_handler_setup(&sur40->ctrls);
+
+ if (sur40->ctrls.error) {
+ dev_err(&interface->dev,
+ "Unable to register video controls.");
+ v4l2_ctrl_handler_free(&sur40->ctrls);
+ goto err_unreg_v4l2;
+ }
+
error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(&interface->dev,
@@ -769,6 +807,7 @@ static void sur40_disconnect(struct usb_interface *interface)
{
struct sur40_state *sur40 = usb_get_intfdata(interface);
+ v4l2_ctrl_handler_free(&sur40->ctrls);
video_unregister_device(&sur40->vdev);
v4l2_device_unregister(&sur40->v4l2);
@@ -962,6 +1001,31 @@ static int sur40_vidioc_g_fmt(struct file *file, void *priv,
return 0;
}
+static int sur40_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct sur40_state *sur40 = container_of(ctrl->handler,
+ struct sur40_state, ctrls);
+ u8 value = sur40->vsvideo;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ sur40_set_irlevel(sur40, ctrl->val);
+ break;
+ case V4L2_CID_CONTRAST:
+ value = (value & 0x0F) | (ctrl->val << 4);
+ sur40_set_vsvideo(sur40, value);
+ break;
+ case V4L2_CID_GAIN:
+ value = (value & 0xF0) | (ctrl->val);
+ sur40_set_vsvideo(sur40, value);
+ break;
+ case V4L2_CID_BACKLIGHT_COMPENSATION:
+ sur40_set_preprocessor(sur40, ctrl->val);
+ break;
+ }
+ return 0;
+}
+
static int sur40_ioctl_parm(struct file *file, void *priv,
struct v4l2_streamparm *p)
{
--
2.7.4
^ permalink raw reply related
* Re: [PATCH 2/4] add default settings and module parameters for video controls
From: Hans Verkuil @ 2018-02-07 13:20 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <1518008438-26603-3-git-send-email-floe@butterbrot.org>
On 02/07/18 14:00, Florian Echtler wrote:
> This patch adds parameter definitions and module parameters for the four
> userspace controls that the SUR40 can currently provide.
>
> Signed-off-by: Florian Echtler <floe@butterbrot.org>
> ---
> drivers/input/touchscreen/sur40.c | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
>
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index 8375b06..8a5b031 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -149,6 +149,34 @@ struct sur40_image_header {
> #define SUR40_TOUCH 0x02
> #define SUR40_TAG 0x04
>
> +/* video controls */
> +#define SUR40_BRIGHTNESS_MAX 0xFF
> +#define SUR40_BRIGHTNESS_MIN 0x00
> +#define SUR40_BRIGHTNESS_DEF 0xFF
> +
> +#define SUR40_CONTRAST_MAX 0x0F
> +#define SUR40_CONTRAST_MIN 0x00
> +#define SUR40_CONTRAST_DEF 0x0A
It's kernel style to use lowercase hex values.
> +
> +#define SUR40_GAIN_MAX 0x09
> +#define SUR40_GAIN_MIN 0x00
> +#define SUR40_GAIN_DEF 0x08
> +
> +#define SUR40_BACKLIGHT_MAX 0x01
> +#define SUR40_BACKLIGHT_MIN 0x00
> +#define SUR40_BACKLIGHT_DEF 0x01
> +
> +/* module parameters */
> +static uint brightness = SUR40_BRIGHTNESS_DEF;
> +module_param(brightness, uint, 0644);
> +MODULE_PARM_DESC(brightness, "set initial brightness");
No range in the param description? I think you can do some macro magic so you
can use the MIN/MAX defines in the string.
Regards,
Hans
> +static uint contrast = SUR40_CONTRAST_DEF;
> +module_param(contrast, uint, 0644);
> +MODULE_PARM_DESC(contrast, "set initial contrast");
> +static uint gain = SUR40_GAIN_DEF;
> +module_param(gain, uint, 0644);
> +MODULE_PARM_DESC(gain, "set initial gain");
> +
> static const struct v4l2_pix_format sur40_pix_format[] = {
> {
> .pixelformat = V4L2_TCH_FMT_TU08,
>
^ permalink raw reply
* Re: [PATCH 4/4] add video control handlers using V4L2 control framework
From: Hans Verkuil @ 2018-02-07 13:22 UTC (permalink / raw)
To: Florian Echtler, linux-media; +Cc: linux-input, modin
In-Reply-To: <1518008438-26603-5-git-send-email-floe@butterbrot.org>
On 02/07/18 14:00, Florian Echtler wrote:
> This patch registers four standard control handlers using the corresponding
> V4L2 framework.
>
> Signed-off-by: Florian Echtler <floe@butterbrot.org>
> ---
> drivers/input/touchscreen/sur40.c | 64 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 64 insertions(+)
>
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index d6fa25e..b92325b 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -38,6 +38,7 @@
> #include <media/v4l2-device.h>
> #include <media/v4l2-dev.h>
> #include <media/v4l2-ioctl.h>
> +#include <media/v4l2-ctrls.h>
> #include <media/videobuf2-v4l2.h>
> #include <media/videobuf2-dma-sg.h>
>
> @@ -209,6 +210,7 @@ struct sur40_state {
> struct video_device vdev;
> struct mutex lock;
> struct v4l2_pix_format pix_fmt;
> + struct v4l2_ctrl_handler ctrls;
Please rename this to either hdl or ctrl_handler. 'ctrls' is confusing.
>
> struct vb2_queue queue;
> struct list_head buf_list;
> @@ -218,6 +220,7 @@ struct sur40_state {
> struct sur40_data *bulk_in_buffer;
> size_t bulk_in_size;
> u8 bulk_in_epaddr;
> + u8 vsvideo;
>
> char phys[64];
> };
> @@ -231,6 +234,11 @@ struct sur40_buffer {
> static const struct video_device sur40_video_device;
> static const struct vb2_queue sur40_queue;
> static void sur40_process_video(struct sur40_state *sur40);
> +static int sur40_s_ctrl(struct v4l2_ctrl *ctrl);
> +
> +static const struct v4l2_ctrl_ops sur40_ctrl_ops = {
> + .s_ctrl = sur40_s_ctrl,
> +};
>
> /*
> * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
> @@ -737,6 +745,36 @@ static int sur40_probe(struct usb_interface *interface,
> sur40->vdev.queue = &sur40->queue;
> video_set_drvdata(&sur40->vdev, sur40);
>
> + /* initialize the control handler for 4 controls */
> + v4l2_ctrl_handler_init(&sur40->ctrls, 4);
> + sur40->v4l2.ctrl_handler = &sur40->ctrls;
> + sur40->vsvideo = (SUR40_CONTRAST_DEF << 4) | SUR40_GAIN_DEF;
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_BRIGHTNESS,
> + SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX, 1, clamp(brightness,
> + (uint)SUR40_BRIGHTNESS_MIN, (uint)SUR40_BRIGHTNESS_MAX));
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_CONTRAST,
> + SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX, 1, clamp(contrast,
> + (uint)SUR40_CONTRAST_MIN, (uint)SUR40_CONTRAST_MAX));
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops, V4L2_CID_GAIN,
> + SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, clamp(gain,
> + (uint)SUR40_GAIN_MIN, (uint)SUR40_GAIN_MAX));
> +
> + v4l2_ctrl_new_std(&sur40->ctrls, &sur40_ctrl_ops,
> + V4L2_CID_BACKLIGHT_COMPENSATION, SUR40_BACKLIGHT_MIN,
> + SUR40_BACKLIGHT_MAX, 1, SUR40_BACKLIGHT_DEF);
> +
> + v4l2_ctrl_handler_setup(&sur40->ctrls);
> +
> + if (sur40->ctrls.error) {
> + dev_err(&interface->dev,
> + "Unable to register video controls.");
> + v4l2_ctrl_handler_free(&sur40->ctrls);
> + goto err_unreg_v4l2;
> + }
> +
> error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
> if (error) {
> dev_err(&interface->dev,
> @@ -769,6 +807,7 @@ static void sur40_disconnect(struct usb_interface *interface)
> {
> struct sur40_state *sur40 = usb_get_intfdata(interface);
>
> + v4l2_ctrl_handler_free(&sur40->ctrls);
> video_unregister_device(&sur40->vdev);
> v4l2_device_unregister(&sur40->v4l2);
>
> @@ -962,6 +1001,31 @@ static int sur40_vidioc_g_fmt(struct file *file, void *priv,
> return 0;
> }
>
> +static int sur40_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct sur40_state *sur40 = container_of(ctrl->handler,
> + struct sur40_state, ctrls);
> + u8 value = sur40->vsvideo;
> +
> + switch (ctrl->id) {
> + case V4L2_CID_BRIGHTNESS:
> + sur40_set_irlevel(sur40, ctrl->val);
> + break;
> + case V4L2_CID_CONTRAST:
> + value = (value & 0x0F) | (ctrl->val << 4);
> + sur40_set_vsvideo(sur40, value);
> + break;
> + case V4L2_CID_GAIN:
> + value = (value & 0xF0) | (ctrl->val);
> + sur40_set_vsvideo(sur40, value);
> + break;
> + case V4L2_CID_BACKLIGHT_COMPENSATION:
> + sur40_set_preprocessor(sur40, ctrl->val);
> + break;
> + }
> + return 0;
> +}
> +
> static int sur40_ioctl_parm(struct file *file, void *priv,
> struct v4l2_streamparm *p)
> {
>
Looks good otherwise.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH] Input: synaptics - Lenovo Carbon X1 Gen5 (2017) devices should use RMI
From: Damjan Georgievski @ 2018-02-07 14:43 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
In-Reply-To: <CAEk1YH7=aWJDGbdNj7jeRsOAn01eTCnm9Sc=KVTQ4KFEZ2PsSA@mail.gmail.com>
On 5 February 2018 at 12:56, Damjan Georgievski <gdamjan@gmail.com> wrote:
>>> >>> Second issues is, trackpoint is reported as "ImPS/2 Generic Wheel
>>> >>> Mouse". Middle button scrolling is not enabled by default.
>>> >>
>>> >> I think this will be fixed by:
>>> >>
>>> >> https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/patch/?id=ec667683c532c93fb41e100e5d61a518971060e2
>>> >>
>>> >
>>> > Interesting, with this patch, the trackpoint appeared sooner, but
>>> > still late (at the 44 second mark):
>>>
>>> but that seems sporadic. on second boot, it didn't show up until I
>>> reloaded the psmouse module
>>>
>>> any ideas how to debug this issue further? possibly before the change
>>> goes upstream.
>>
>> Damjan,
>>
>> Since my other patches seem to have fixed the trackpoint detection
>> issue, mind giving your "tested-by" to this patch so I can get it in?
>
> let me just run some more tests and I'll get back to you soon.
>
> I'm getting some weird clicks on the trackpad, I want to compare with
> vanilla kernel.
>
> Dimitry, what's best for testing, 4.15.1 + your patches or should I use 4.16rc1?
The only difference I've noticed is these event that seems to be
repeated/stuck (BTN_LEFT 19.60)?:
$ sudo libinput debug-events --device /dev/input/event16
-event16 DEVICE_ADDED Synaptics TM3289-002 seat0
default group1 cap:pg size 102x56mm tap(dl off) left scroll-nat
scroll-2fg-edge click-buttonareas-clickfinger dwt-on
…
event16 POINTER_BUTTON +19.56s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +19.58s BTN_LEFT (272) released, seat count: 0
event16 POINTER_BUTTON +19.60s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +19.66s BTN_LEFT (272) released, seat count: 0
event16 POINTER_BUTTON +20.47s BTN_MIDDLE (274) pressed, seat count: 1
event16 POINTER_BUTTON +19.60s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +20.54s BTN_MIDDLE (274) released, seat count: 0
event16 POINTER_BUTTON +20.57s BTN_MIDDLE (274) pressed, seat count: 1
event16 POINTER_BUTTON +19.60s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +20.57s BTN_MIDDLE (274) released, seat count: 0
event16 POINTER_BUTTON +21.34s BTN_MIDDLE (274) pressed, seat count: 1
event16 POINTER_BUTTON +19.60s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +21.43s BTN_MIDDLE (274) released, seat count: 0
event16 POINTER_BUTTON +21.94s BTN_MIDDLE (274) pressed, seat count: 1
event16 POINTER_BUTTON +19.60s BTN_LEFT (272) pressed, seat count: 1
event16 POINTER_BUTTON +22.02s BTN_MIDDLE (274) released, seat count: 0
--
damjan
^ permalink raw reply
* [PATCH 0/3] hid: logitech-dj: code style improvements
From: Christoph Böhmwalder @ 2018-02-07 17:07 UTC (permalink / raw)
To: jikos, benjamin.tissoires
Cc: linux-input, linux-kernel, Christoph Böhmwalder
Fix several rather trivial code style issues in the Logitech DJ HID
driver. Most of these were reported by checkpatch, others are just
attempts to make the code adhere more to the kernel coding guidelines.
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
Christoph Böhmwalder (3):
hid: logitech-dj: fix various style issues
hid: logitech-dj: fix checkpatch issues
hid: logitech-dj: delete unnecessary error messages
drivers/hid/hid-logitech-dj.c | 318 +++++++++++++++++++++---------------------
1 file changed, 161 insertions(+), 157 deletions(-)
--
2.13.6
^ permalink raw reply
* [PATCH 2/3] hid: logitech-dj: fix checkpatch issues
From: Christoph Böhmwalder @ 2018-02-07 17:07 UTC (permalink / raw)
To: jikos, benjamin.tissoires
Cc: linux-input, linux-kernel, Christoph Böhmwalder
In-Reply-To: <20180207170800.15015-1-christoph@boehmwalder.at>
Fix some code style issues, mostly related to making sure quoted strings
aren't split over multiple lines.
Other fixes:
* Drop != NULL from some null pointer checks
* Use sizeof(*ptr) instead of sizeof(ptr_type)
* Combine some if statements to reduce indentation
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
---
drivers/hid/hid-logitech-dj.c | 71 ++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 35 deletions(-)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 530d10b5a404..59c54cb4bc64 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -347,13 +347,14 @@ static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
djrcv_dev->paired_dj_devices[dj_report->device_index] = NULL;
spin_unlock_irqrestore(&djrcv_dev->lock, flags);
- if (dj_dev != NULL) {
+ if (dj_dev) {
hid_destroy_device(dj_dev->hdev);
kfree(dj_dev);
- } else {
- dev_err(&djrcv_dev->hdev->dev, "%s: can't destroy a NULL device\n",
- __func__);
+ return;
}
+
+ dev_err(&djrcv_dev->hdev->dev, "%s: can't destroy a NULL device\n",
+ __func__);
}
static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
@@ -411,7 +412,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
snprintf(tmpstr, sizeof(tmpstr), ":%d", dj_report->device_index);
strlcat(dj_hiddev->phys, tmpstr, sizeof(dj_hiddev->phys));
- dj_dev = kzalloc(sizeof(struct dj_device), GFP_KERNEL);
+ dj_dev = kzalloc(sizeof(*dj_dev), GFP_KERNEL);
if (!dj_dev) {
dev_err(&djrcv_hdev->dev, "%s: failed allocating dj_device\n",
@@ -419,8 +420,9 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
goto dj_device_allocate_fail;
}
- dj_dev->reports_supported = get_unaligned_le32(
- dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE);
+ dj_dev->reports_supported =
+ get_unaligned_le32(dj_report->report_params
+ + DEVICE_PAIRED_RF_REPORT_TYPE);
dj_dev->hdev = dj_hiddev;
dj_dev->dj_receiver_dev = djrcv_dev;
dj_dev->device_index = dj_report->device_index;
@@ -461,17 +463,17 @@ static void delayedwork_callback(struct work_struct *work)
sizeof(struct dj_report));
if (count != sizeof(struct dj_report)) {
- dev_err(&djrcv_dev->hdev->dev, "%s: workitem triggered without "
- "notifications available\n", __func__);
+ dev_err(&djrcv_dev->hdev->dev,
+ "%s: workitem triggered without notifications available"
+ "\n", __func__);
spin_unlock_irqrestore(&djrcv_dev->lock, flags);
return;
}
- if (!kfifo_is_empty(&djrcv_dev->notif_fifo)) {
- if (schedule_work(&djrcv_dev->work) == 0) {
- dbg_hid("%s: did not schedule the work item, was "
- "already queued\n", __func__);
- }
+ if (!kfifo_is_empty(&djrcv_dev->notif_fifo) &&
+ schedule_work(&djrcv_dev->work) == 0) {
+ dbg_hid("%s: did not schedule the work item, was already queued"
+ "\n", __func__);
}
spin_unlock_irqrestore(&djrcv_dev->lock, flags);
@@ -504,8 +506,8 @@ static void delayedwork_callback(struct work_struct *work)
break;
}
dev_err(&djrcv_dev->hdev->dev,
- "%s:logi_dj_recv_query_paired_devices"
- " error:%d\n", __func__, retval);
+ "%s: logi_dj_recv_query_paired_devices error: "
+ "%d\n", __func__, retval);
}
dbg_hid("%s: unexpected report type\n", __func__);
}
@@ -519,8 +521,8 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
if (schedule_work(&djrcv_dev->work) == 0) {
- dbg_hid("%s: did not schedule the work item, was already "
- "queued\n", __func__);
+ dbg_hid("%s: did not schedule the work item, was already queued"
+ "\n", __func__);
}
}
@@ -543,8 +545,7 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
HID_INPUT_REPORT,
reportbuffer,
hid_reportid_size_map[i], 1)) {
- dbg_hid("hid_input_report error sending null "
- "report\n");
+ dbg_hid("hid_input_report error sending null report\n");
}
}
}
@@ -559,8 +560,8 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||
- (hid_reportid_size_map[dj_report->report_type] == 0)) {
- dbg_hid("invalid report type:%x\n", dj_report->report_type);
+ hid_reportid_size_map[dj_report->report_type] == 0) {
+ dbg_hid("invalid report type: %x\n", dj_report->report_type);
return;
}
@@ -613,7 +614,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
if (djrcv_dev->querying_devices)
return 0;
- dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
+ dj_report = kzalloc(sizeof(*dj_report), GFP_KERNEL);
if (!dj_report)
return -ENOMEM;
dj_report->report_id = REPORT_ID_DJ_SHORT;
@@ -625,14 +626,14 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
}
static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
- unsigned timeout)
+ unsigned int timeout)
{
struct hid_device *hdev = djrcv_dev->hdev;
struct dj_report *dj_report;
u8 *buf;
int retval;
- dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
+ dj_report = kzalloc(sizeof(*dj_report), GFP_KERNEL);
if (!dj_report)
return -ENOMEM;
dj_report->report_id = REPORT_ID_DJ_SHORT;
@@ -704,8 +705,8 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
u8 *out_buf;
int ret;
- if ((buf[0] == REPORT_ID_HIDPP_SHORT) ||
- (buf[0] == REPORT_ID_HIDPP_LONG)) {
+ if (buf[0] == REPORT_ID_HIDPP_SHORT ||
+ buf[0] == REPORT_ID_HIDPP_LONG) {
if (count < 2)
return -EINVAL;
@@ -857,8 +858,8 @@ static int logi_dj_dj_event(struct hid_device *hdev,
* and return 1 so hid-core does not anything else with it.
*/
- if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
- (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
+ if (dj_report->device_index < DJ_DEVICE_INDEX_MIN ||
+ dj_report->device_index > DJ_DEVICE_INDEX_MAX) {
/*
* Device index is wrong, bail out.
* This driver can safely ignore the receiver notifications,
@@ -931,8 +932,8 @@ static int logi_dj_hidpp_event(struct hid_device *hdev,
* via the receiver.
*/
- if ((device_index < DJ_DEVICE_INDEX_MIN) ||
- (device_index > DJ_DEVICE_INDEX_MAX)) {
+ if (device_index < DJ_DEVICE_INDEX_MIN ||
+ device_index > DJ_DEVICE_INDEX_MAX) {
/*
* Device index is wrong, bail out.
* This driver can safely ignore the receiver notifications,
@@ -1013,7 +1014,7 @@ static int logi_dj_probe(struct hid_device *hdev,
/* Treat interface 2 */
- djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL);
+ djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL);
if (!djrcv_dev) {
dev_err(&hdev->dev,
"%s:failed allocating dj_receiver_dev\n", __func__);
@@ -1083,8 +1084,8 @@ static int logi_dj_probe(struct hid_device *hdev,
retval = logi_dj_recv_query_paired_devices(djrcv_dev);
if (retval < 0) {
- dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices "
- "error:%d\n", __func__, retval);
+ dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices error:"
+ "%d\n", __func__, retval);
goto logi_dj_recv_query_paired_devices_failed;
}
@@ -1144,7 +1145,7 @@ static void logi_dj_remove(struct hid_device *hdev)
*/
for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
dj_dev = djrcv_dev->paired_dj_devices[i];
- if (dj_dev != NULL) {
+ if (dj_dev) {
hid_destroy_device(dj_dev->hdev);
kfree(dj_dev);
djrcv_dev->paired_dj_devices[i] = NULL;
--
2.13.6
^ permalink raw reply related
* [PATCH 3/3] hid: logitech-dj: delete unnecessary error messages
From: Christoph Böhmwalder @ 2018-02-07 17:08 UTC (permalink / raw)
To: jikos, benjamin.tissoires
Cc: linux-input, linux-kernel, Christoph Böhmwalder
In-Reply-To: <20180207170800.15015-1-christoph@boehmwalder.at>
Remove some "out of memory" messages that are considered useless.
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
---
drivers/hid/hid-logitech-dj.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 59c54cb4bc64..ba5239840cda 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -414,11 +414,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
dj_dev = kzalloc(sizeof(*dj_dev), GFP_KERNEL);
- if (!dj_dev) {
- dev_err(&djrcv_hdev->dev, "%s: failed allocating dj_device\n",
- __func__);
+ if (!dj_dev)
goto dj_device_allocate_fail;
- }
dj_dev->reports_supported =
get_unaligned_le32(dj_report->report_params
@@ -1015,11 +1012,9 @@ static int logi_dj_probe(struct hid_device *hdev,
/* Treat interface 2 */
djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL);
- if (!djrcv_dev) {
- dev_err(&hdev->dev,
- "%s:failed allocating dj_receiver_dev\n", __func__);
+ if (!djrcv_dev)
return -ENOMEM;
- }
+
djrcv_dev->hdev = hdev;
INIT_WORK(&djrcv_dev->work, delayedwork_callback);
spin_lock_init(&djrcv_dev->lock);
--
2.13.6
^ permalink raw reply related
* [PATCH 1/3] hid: logitech-dj: fix various style issues
From: Christoph Böhmwalder @ 2018-02-07 17:07 UTC (permalink / raw)
To: jikos, benjamin.tissoires
Cc: linux-input, linux-kernel, Christoph Böhmwalder
In-Reply-To: <20180207170800.15015-1-christoph@boehmwalder.at>
Fix some problems regarding comment/whitespace style. Mostly reported
by checkpatch.pl
Individual changes:
* Remove paragraph about writing to the FSF in GPL header
* Fix several spelling and grammar mistakes in comments
* Fix various misalignments
* Remove some unnecessary blank lines
* Adapt comment style to fit the kernel coding standard
Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
---
drivers/hid/hid-logitech-dj.c | 240 ++++++++++++++++++++++--------------------
1 file changed, 124 insertions(+), 116 deletions(-)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 826fa1e1c8d9..530d10b5a404 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -14,14 +14,8 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
*/
-
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
@@ -53,13 +47,13 @@
#define REPORT_TYPE_RFREPORT_FIRST 0x01
#define REPORT_TYPE_RFREPORT_LAST 0x1F
-/* Command Switch to DJ mode */
+/* Command to switch to DJ mode */
#define REPORT_TYPE_CMD_SWITCH 0x80
#define CMD_SWITCH_PARAM_DEVBITFIELD 0x00
#define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01
#define TIMEOUT_NO_KEEPALIVE 0x00
-/* Command to Get the list of Paired devices */
+/* Command to get the list of paired devices */
#define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81
/* Device Paired Notification */
@@ -74,7 +68,6 @@
/* Device Un-Paired Notification */
#define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40
-
/* Connection Status Notification */
#define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42
#define CONNECTION_STATUS_PARAM_STATUS 0x00
@@ -85,7 +78,7 @@
#define NOTIF_ERROR_PARAM_ETYPE 0x00
#define ETYPE_KEEPALIVE_TIMEOUT 0x01
-/* supported DJ HID && RF report types */
+/* Supported DJ HID & RF report types */
#define REPORT_TYPE_KEYBOARD 0x01
#define REPORT_TYPE_MOUSE 0x02
#define REPORT_TYPE_CONSUMER_CONTROL 0x03
@@ -127,38 +120,38 @@ struct dj_device {
/* Keyboard descriptor (1) */
static const char kbd_descriptor[] = {
- 0x05, 0x01, /* USAGE_PAGE (generic Desktop) */
- 0x09, 0x06, /* USAGE (Keyboard) */
- 0xA1, 0x01, /* COLLECTION (Application) */
- 0x85, 0x01, /* REPORT_ID (1) */
- 0x95, 0x08, /* REPORT_COUNT (8) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
- 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */
- 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x95, 0x06, /* REPORT_COUNT (6) */
- 0x75, 0x08, /* REPORT_SIZE (8) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x26, 0xFF, 0x00, /* LOGICAL_MAXIMUM (255) */
- 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
- 0x19, 0x00, /* USAGE_MINIMUM (no event) */
- 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */
- 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
- 0x85, 0x0e, /* REPORT_ID (14) */
- 0x05, 0x08, /* USAGE PAGE (LED page) */
- 0x95, 0x05, /* REPORT COUNT (5) */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x19, 0x01, /* USAGE MINIMUM (1) */
- 0x29, 0x05, /* USAGE MAXIMUM (5) */
+ 0x05, 0x01, /* USAGE_PAGE (generic Desktop) */
+ 0x09, 0x06, /* USAGE (Keyboard) */
+ 0xA1, 0x01, /* COLLECTION (Application) */
+ 0x85, 0x01, /* REPORT_ID (1) */
+ 0x95, 0x08, /* REPORT_COUNT (8) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */
+ 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0x95, 0x06, /* REPORT_COUNT (6) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x26, 0xFF, 0x00, /* LOGICAL_MAXIMUM (255) */
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
+ 0x19, 0x00, /* USAGE_MINIMUM (no event) */
+ 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
+ 0x85, 0x0e, /* REPORT_ID (14) */
+ 0x05, 0x08, /* USAGE PAGE (LED page) */
+ 0x95, 0x05, /* REPORT COUNT (5) */
+ 0x75, 0x01, /* REPORT SIZE (1) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x19, 0x01, /* USAGE MINIMUM (1) */
+ 0x29, 0x05, /* USAGE MAXIMUM (5) */
0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x75, 0x03, /* REPORT SIZE (3) */
- 0x91, 0x01, /* OUTPUT (Constant) */
+ 0x95, 0x01, /* REPORT COUNT (1) */
+ 0x75, 0x03, /* REPORT SIZE (3) */
+ 0x91, 0x01, /* OUTPUT (Constant) */
0xC0
};
@@ -314,16 +307,17 @@ static const char hidpp_descriptor[] = {
sizeof(media_descriptor) + \
sizeof(hidpp_descriptor))
-/* Number of possible hid report types that can be created by this driver.
+/*
+ * Number of possible hid report types that can be created by this driver.
*
* Right now, RF report types have the same report types (or report id's)
- * than the hid report created from those RF reports. In the future
- * this doesnt have to be true.
+ * as the hid report created from those RF reports. In the future
+ * this doesn't have to be true.
*
* For instance, RF report type 0x01 which has a size of 8 bytes, corresponds
- * to hid report id 0x01, this is standard keyboard. Same thing applies to mice
- * reports and consumer control, etc. If a new RF report is created, it doesn't
- * has to have the same report id as its corresponding hid report, so an
+ * to hid report id 0x01, this is a standard keyboard. Same thing applies to
+ * mice reports and consumer control, etc. If a new RF report is created, it
+ * doesn't have to have the same report id as its corresponding hid report, so a
* translation may have to take place for future report types.
*/
#define NUMBER_OF_HID_REPORTS 32
@@ -335,7 +329,6 @@ static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {
[8] = 2, /* Media Center */
};
-
#define LOGITECH_DJ_INTERFACE_NUMBER 0x02
static struct hid_ll_driver logi_dj_ll_driver;
@@ -343,7 +336,7 @@ static struct hid_ll_driver logi_dj_ll_driver;
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
- struct dj_report *dj_report)
+ struct dj_report *dj_report)
{
/* Called in delayed work context */
struct dj_device *dj_dev;
@@ -373,7 +366,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
struct hid_device *dj_hiddev;
struct dj_device *dj_dev;
- /* Device index goes from 1 to 6, we need 3 bytes to store the
+ /*
+ * Device index goes from 1 to 6, we need 3 bytes to store the
* semicolon, the index, and a null terminator
*/
unsigned char tmpstr[3];
@@ -408,8 +402,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
<< 8) |
dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB];
snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),
- "Logitech Unifying Device. Wireless PID:%04x",
- dj_hiddev->product);
+ "Logitech Unifying Device. Wireless PID:%04x",
+ dj_hiddev->product);
dj_hiddev->group = HID_GROUP_LOGITECH_DJ_DEVICE;
@@ -464,7 +458,7 @@ static void delayedwork_callback(struct work_struct *work)
spin_lock_irqsave(&djrcv_dev->lock, flags);
count = kfifo_out(&djrcv_dev->notif_fifo, &dj_report,
- sizeof(struct dj_report));
+ sizeof(struct dj_report));
if (count != sizeof(struct dj_report)) {
dev_err(&djrcv_dev->hdev->dev, "%s: workitem triggered without "
@@ -490,33 +484,37 @@ static void delayedwork_callback(struct work_struct *work)
logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
break;
default:
- /* A normal report (i. e. not belonging to a pair/unpair notification)
- * arriving here, means that the report arrived but we did not have a
- * paired dj_device associated to the report's device_index, this
- * means that the original "device paired" notification corresponding
- * to this dj_device never arrived to this driver. The reason is that
- * hid-core discards all packets coming from a device while probe() is
- * executing. */
- if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
- /* ok, we don't know the device, just re-ask the
- * receiver for the list of connected devices. */
- retval = logi_dj_recv_query_paired_devices(djrcv_dev);
- if (!retval) {
- /* everything went fine, so just leave */
- break;
- }
- dev_err(&djrcv_dev->hdev->dev,
- "%s:logi_dj_recv_query_paired_devices "
- "error:%d\n", __func__, retval);
+ /*
+ * A normal report (i.e. not belonging to a pair/unpair
+ * notification) arriving here, means that the report arrived
+ * but we did not have a paired dj_device associated to the
+ * report's device_index, this means that the original "device
+ * paired" notification corresponding to this dj_device never
+ * arrived to this driver. The reason is that hid-core discards
+ * all packets coming from a device while probe() is executing.
+ */
+ if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
+ /*
+ * ok, we don't know the device, just re-ask the
+ * receiver for the list of connected devices.
+ */
+ retval = logi_dj_recv_query_paired_devices(djrcv_dev);
+ if (!retval) {
+ /* everything went fine, so just leave */
+ break;
+ }
+ dev_err(&djrcv_dev->hdev->dev,
+ "%s:logi_dj_recv_query_paired_devices"
+ " error:%d\n", __func__, retval);
}
dbg_hid("%s: unexpected report type\n", __func__);
}
}
static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
- struct dj_report *dj_report)
+ struct dj_report *dj_report)
{
- /* We are called from atomic context (tasklet && djrcv->lock held) */
+ /* We are called from an atomic context (tasklet && djrcv->lock held) */
kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
@@ -529,7 +527,7 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
struct dj_report *dj_report)
{
- /* We are called from atomic context (tasklet && djrcv->lock held) */
+ /* We are called from an atomic context (tasklet && djrcv->lock held) */
unsigned int i;
u8 reportbuffer[MAX_REPORT_SIZE];
struct dj_device *djdev;
@@ -555,7 +553,7 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
struct dj_report *dj_report)
{
- /* We are called from atomic context (tasklet && djrcv->lock held) */
+ /* We are called from an atomic context (tasklet && djrcv->lock held) */
struct dj_device *dj_device;
dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
@@ -567,8 +565,8 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
}
if (hid_input_report(dj_device->hdev,
- HID_INPUT_REPORT, &dj_report->report_type,
- hid_reportid_size_map[dj_report->report_type], 1)) {
+ HID_INPUT_REPORT, &dj_report->report_type,
+ hid_reportid_size_map[dj_report->report_type], 1)) {
dbg_hid("hid_input_report error\n");
}
}
@@ -576,7 +574,7 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
static void logi_dj_recv_forward_hidpp(struct dj_device *dj_dev, u8 *data,
int size)
{
- /* We are called from atomic context (tasklet && djrcv->lock held) */
+ /* We are called from an atomic context (tasklet && djrcv->lock held) */
if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1))
dbg_hid("hid_input_report error\n");
}
@@ -626,7 +624,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
return retval;
}
-
static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
unsigned timeout)
{
@@ -647,8 +644,8 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
/*
* Ugly sleep to work around a USB 3.0 bug when the receiver is still
- * processing the "switch-to-dj" command while we send an other command.
- * 50 msec should gives enough time to the receiver to be ready.
+ * processing the "switch-to-dj" command while we send another command.
+ * 50 msec should give the receiver enough time to be ready.
*/
msleep(50);
@@ -672,19 +669,17 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
buf[6] = 0x00;
hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
- HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
- HID_REQ_SET_REPORT);
+ HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
+ HID_REQ_SET_REPORT);
kfree(dj_report);
return retval;
}
-
static int logi_dj_ll_open(struct hid_device *hid)
{
dbg_hid("%s:%s\n", __func__, hid->phys);
return 0;
-
}
static void logi_dj_ll_close(struct hid_device *hid)
@@ -714,8 +709,10 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
if (count < 2)
return -EINVAL;
- /* special case where we should not overwrite
- * the device_index */
+ /*
+ * special case where we should not overwrite
+ * the device_index
+ */
if (count == 7 && !memcmp(buf, unifying_pairing_query,
sizeof(unifying_pairing_query)))
buf[4] = (buf[4] & 0xf0) | (djdev->device_index - 1);
@@ -740,13 +737,14 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
memcpy(out_buf + 2, buf, count);
ret = hid_hw_raw_request(djrcv_dev->hdev, out_buf[0], out_buf,
- DJREPORT_SHORT_LENGTH, report_type, reqtype);
+ DJREPORT_SHORT_LENGTH, report_type, reqtype);
kfree(out_buf);
return ret;
}
-static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
+static void rdcat(char *rdesc, unsigned int *rsize, const char *data,
+ unsigned int size)
{
memcpy(rdesc + *rsize, data, size);
*rsize += size;
@@ -783,13 +781,15 @@ static int logi_dj_ll_parse(struct hid_device *hid)
if (djdev->reports_supported & MULTIMEDIA) {
dbg_hid("%s: sending a multimedia report descriptor: %x\n",
__func__, djdev->reports_supported);
- rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
+ rdcat(rdesc, &rsize, consumer_descriptor,
+ sizeof(consumer_descriptor));
}
if (djdev->reports_supported & POWER_KEYS) {
dbg_hid("%s: sending a power keys report descriptor: %x\n",
__func__, djdev->reports_supported);
- rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
+ rdcat(rdesc, &rsize, syscontrol_descriptor,
+ sizeof(syscontrol_descriptor));
}
if (djdev->reports_supported & MEDIA_CENTER) {
@@ -822,7 +822,6 @@ static void logi_dj_ll_stop(struct hid_device *hid)
dbg_hid("%s\n", __func__);
}
-
static struct hid_ll_driver logi_dj_ll_driver = {
.parse = logi_dj_ll_parse,
.start = logi_dj_ll_start,
@@ -833,17 +832,17 @@ static struct hid_ll_driver logi_dj_ll_driver = {
};
static int logi_dj_dj_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data,
- int size)
+ struct hid_report *report, u8 *data,
+ int size)
{
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
- struct dj_report *dj_report = (struct dj_report *) data;
+ struct dj_report *dj_report = (struct dj_report *)data;
unsigned long flags;
/*
* Here we receive all data coming from iface 2, there are 3 cases:
*
- * 1) Data is intended for this driver i. e. data contains arrival,
+ * 1) Data is intended for this driver i.e. data contains arrival,
* departure, etc notifications, in which case we queue them for delayed
* processing by the work queue. We return 1 to hid-core as no further
* processing is required from it.
@@ -854,15 +853,15 @@ static int logi_dj_dj_event(struct hid_device *hdev,
* layer. Return 1 to hid-core as no further processing is required.
*
* 3) Data is an actual input event from a paired DJ device in which
- * case we forward it to the correct hid device (via hid_input_report()
- * ) and return 1 so hid-core does not anything else with it.
+ * case we forward it to the correct hid device (via hid_input_report())
+ * and return 1 so hid-core does not anything else with it.
*/
if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
(dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
/*
* Device index is wrong, bail out.
- * This driver can ignore safely the receiver notifications,
+ * This driver can safely ignore the receiver notifications,
* so ignore those reports too.
*/
if (dj_report->device_index != DJ_RECEIVER_INDEX)
@@ -903,17 +902,19 @@ static int logi_dj_dj_event(struct hid_device *hdev,
}
static int logi_dj_hidpp_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data,
- int size)
+ struct hid_report *report, u8 *data,
+ int size)
{
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
- struct dj_report *dj_report = (struct dj_report *) data;
+ struct dj_report *dj_report = (struct dj_report *)data;
unsigned long flags;
u8 device_index = dj_report->device_index;
if (device_index == HIDPP_RECEIVER_INDEX) {
- /* special case were the device wants to know its unifying
- * name */
+ /*
+ * special case were the device wants to know its unifying
+ * name
+ */
if (size == HIDPP_REPORT_LONG_LENGTH &&
!memcmp(data, unifying_pairing_answer,
sizeof(unifying_pairing_answer)))
@@ -934,11 +935,11 @@ static int logi_dj_hidpp_event(struct hid_device *hdev,
(device_index > DJ_DEVICE_INDEX_MAX)) {
/*
* Device index is wrong, bail out.
- * This driver can ignore safely the receiver notifications,
+ * This driver can safely ignore the receiver notifications,
* so ignore those reports too.
*/
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
- __func__, dj_report->device_index);
+ __func__, dj_report->device_index);
return false;
}
@@ -999,8 +1000,10 @@ static int logi_dj_probe(struct hid_device *hdev,
dbg_hid("%s called for ifnum %d\n", __func__,
intf->cur_altsetting->desc.bInterfaceNumber);
- /* Ignore interfaces 0 and 1, they will not carry any data, dont create
- * any hid_device for them */
+ /*
+ * Ignore interfaces 0 and 1, they will not carry any data, dont create
+ * any hid_device for them
+ */
if (intf->cur_altsetting->desc.bInterfaceNumber !=
LOGITECH_DJ_INTERFACE_NUMBER) {
dbg_hid("%s: ignoring ifnum %d\n", __func__,
@@ -1029,10 +1032,12 @@ static int logi_dj_probe(struct hid_device *hdev,
}
hid_set_drvdata(hdev, djrcv_dev);
- /* Call to usbhid to fetch the HID descriptors of interface 2 and
+ /*
+ * Call to usbhid to fetch the HID descriptors of interface 2 and
* subsequently call to the hid/hid-core to parse the fetched
* descriptors, this will in turn create the hidraw and hiddev nodes
- * for interface 2 of the receiver */
+ * for interface 2 of the receiver
+ */
retval = hid_parse(hdev);
if (retval) {
dev_err(&hdev->dev,
@@ -1046,8 +1051,10 @@ static int logi_dj_probe(struct hid_device *hdev,
goto hid_parse_fail;
}
- /* Starts the usb device and connects to upper interfaces hiddev and
- * hidraw */
+ /*
+ * Starts the usb device and connects to upper interfaces hiddev and
+ * hidraw
+ */
retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (retval) {
dev_err(&hdev->dev,
@@ -1071,7 +1078,7 @@ static int logi_dj_probe(struct hid_device *hdev,
goto llopen_failed;
}
- /* Allow incoming packets to arrive: */
+ /* Allow incoming packets to arrive */
hid_device_io_start(hdev);
retval = logi_dj_recv_query_paired_devices(djrcv_dev);
@@ -1096,7 +1103,6 @@ static int logi_dj_probe(struct hid_device *hdev,
kfree(djrcv_dev);
hid_set_drvdata(hdev, NULL);
return retval;
-
}
#ifdef CONFIG_PM
@@ -1129,11 +1135,13 @@ static void logi_dj_remove(struct hid_device *hdev)
hid_hw_close(hdev);
hid_hw_stop(hdev);
- /* I suppose that at this point the only context that can access
+ /*
+ * I suppose that at this point the only context that can access
* the djrecv_data is this thread as the work item is guaranteed to
* have finished and no more raw_event callbacks should arrive after
* the remove callback was triggered so no locks are put around the
- * code below */
+ * code below
+ */
for (i = 0; i < (DJ_MAX_PAIRED_DEVICES + DJ_DEVICE_INDEX_MIN); i++) {
dj_dev = djrcv_dev->paired_dj_devices[i];
if (dj_dev != NULL) {
--
2.13.6
^ permalink raw reply related
* Re: [PATCH 3/3] hid: logitech-dj: delete unnecessary error messages
From: Marcus Folkesson @ 2018-02-08 7:56 UTC (permalink / raw)
To: Christoph Böhmwalder
Cc: jikos, benjamin.tissoires, linux-input, linux-kernel
In-Reply-To: <20180207170800.15015-4-christoph@boehmwalder.at>
[-- Attachment #1: Type: text/plain, Size: 1529 bytes --]
Hello Christoph,
On Wed, Feb 07, 2018 at 06:08:00PM +0100, Christoph Böhmwalder wrote:
> Remove some "out of memory" messages that are considered useless.
>
> Signed-off-by: Christoph Böhmwalder <christoph@boehmwalder.at>
> ---
> drivers/hid/hid-logitech-dj.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
> index 59c54cb4bc64..ba5239840cda 100644
> --- a/drivers/hid/hid-logitech-dj.c
> +++ b/drivers/hid/hid-logitech-dj.c
> @@ -414,11 +414,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
>
> dj_dev = kzalloc(sizeof(*dj_dev), GFP_KERNEL);
>
> - if (!dj_dev) {
> - dev_err(&djrcv_hdev->dev, "%s: failed allocating dj_device\n",
> - __func__);
> + if (!dj_dev)
> goto dj_device_allocate_fail;
> - }
>
> dj_dev->reports_supported =
> get_unaligned_le32(dj_report->report_params
> @@ -1015,11 +1012,9 @@ static int logi_dj_probe(struct hid_device *hdev,
> /* Treat interface 2 */
>
> djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL);
> - if (!djrcv_dev) {
> - dev_err(&hdev->dev,
> - "%s:failed allocating dj_receiver_dev\n", __func__);
> + if (!djrcv_dev)
> return -ENOMEM;
> - }
> +
> djrcv_dev->hdev = hdev;
> INIT_WORK(&djrcv_dev->work, delayedwork_callback);
> spin_lock_init(&djrcv_dev->lock);
> --
> 2.13.6
>
Thank you, but Markus Elfring already has a submitted a patch for this one.
/Marcus
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH 3/4] add panel register access functions
From: Florian Echtler @ 2018-02-08 8:43 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518079386-4647-1-git-send-email-floe@butterbrot.org>
These functions provide write access to the internal LCD panel registers
which also control the sensor. They can be used to disable the
preprocessor, set the illumination brightness, and adjust gain/contrast
(which are stored together in one register internally called "vsvideo").
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 75 +++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 8a5b031..d6fa25e 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -251,6 +251,81 @@ static int sur40_command(struct sur40_state *dev,
0x00, index, buffer, size, 1000);
}
+/* poke a byte in the panel register space */
+static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value)
+{
+ int result;
+ u8 index = 0x96; // 0xae for permanent write
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x32, index, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x72, offset, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0xb2, value, NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+error:
+ return result;
+}
+
+static int sur40_set_preprocessor(struct sur40_state *dev, u8 value)
+{
+ u8 setting_07[2] = { 0x01, 0x00 };
+ u8 setting_17[2] = { 0x85, 0x80 };
+ int result;
+
+ if (value > 1)
+ return -ERANGE;
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x07, setting_07[value], NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+ result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
+ SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x17, setting_17[value], NULL, 0, 1000);
+ if (result < 0)
+ goto error;
+ msleep(5);
+
+error:
+ return result;
+}
+
+static void sur40_set_vsvideo(struct sur40_state *handle, u8 value)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ sur40_poke(handle, 0x1c+i, value);
+ handle->vsvideo = value;
+}
+
+static void sur40_set_irlevel(struct sur40_state *handle, u8 value)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ sur40_poke(handle, 0x08+(2*i), value);
+}
+
/* Initialization routine, called from sur40_open */
static int sur40_init(struct sur40_state *dev)
{
--
2.7.4
^ permalink raw reply related
* [PATCH 4/4] add video control handlers using V4L2 control framework
From: Florian Echtler @ 2018-02-08 8:43 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518079386-4647-1-git-send-email-floe@butterbrot.org>
This patch registers four standard control handlers using the corresponding
V4L2 framework.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 64 +++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index d6fa25e..b92325b 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -38,6 +38,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-sg.h>
@@ -209,6 +210,7 @@ struct sur40_state {
struct video_device vdev;
struct mutex lock;
struct v4l2_pix_format pix_fmt;
+ struct v4l2_ctrl_handler hdl;
struct vb2_queue queue;
struct list_head buf_list;
@@ -218,6 +220,7 @@ struct sur40_state {
struct sur40_data *bulk_in_buffer;
size_t bulk_in_size;
u8 bulk_in_epaddr;
+ u8 vsvideo;
char phys[64];
};
@@ -231,6 +234,11 @@ struct sur40_buffer {
static const struct video_device sur40_video_device;
static const struct vb2_queue sur40_queue;
static void sur40_process_video(struct sur40_state *sur40);
+static int sur40_s_ctrl(struct v4l2_ctrl *ctrl);
+
+static const struct v4l2_ctrl_ops sur40_ctrl_ops = {
+ .s_ctrl = sur40_s_ctrl,
+};
/*
* Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
@@ -737,6 +745,36 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = &sur40->queue;
video_set_drvdata(&sur40->vdev, sur40);
+ /* initialize the control handler for 4 controls */
+ v4l2_ctrl_handler_init(&sur40->hdl, 4);
+ sur40->v4l2.ctrl_handler = &sur40->hdl;
+ sur40->vsvideo = (SUR40_CONTRAST_DEF << 4) | SUR40_GAIN_DEF;
+
+ v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_BRIGHTNESS,
+ SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX, 1, clamp(brightness,
+ (uint)SUR40_BRIGHTNESS_MIN, (uint)SUR40_BRIGHTNESS_MAX));
+
+ v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_CONTRAST,
+ SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX, 1, clamp(contrast,
+ (uint)SUR40_CONTRAST_MIN, (uint)SUR40_CONTRAST_MAX));
+
+ v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_GAIN,
+ SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, clamp(gain,
+ (uint)SUR40_GAIN_MIN, (uint)SUR40_GAIN_MAX));
+
+ v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops,
+ V4L2_CID_BACKLIGHT_COMPENSATION, SUR40_BACKLIGHT_MIN,
+ SUR40_BACKLIGHT_MAX, 1, SUR40_BACKLIGHT_DEF);
+
+ v4l2_ctrl_handler_setup(&sur40->hdl);
+
+ if (sur40->hdl.error) {
+ dev_err(&interface->dev,
+ "Unable to register video controls.");
+ v4l2_ctrl_handler_free(&sur40->hdl);
+ goto err_unreg_v4l2;
+ }
+
error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(&interface->dev,
@@ -769,6 +807,7 @@ static void sur40_disconnect(struct usb_interface *interface)
{
struct sur40_state *sur40 = usb_get_intfdata(interface);
+ v4l2_ctrl_handler_free(&sur40->hdl);
video_unregister_device(&sur40->vdev);
v4l2_device_unregister(&sur40->v4l2);
@@ -962,6 +1001,31 @@ static int sur40_vidioc_g_fmt(struct file *file, void *priv,
return 0;
}
+static int sur40_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct sur40_state *sur40 = container_of(ctrl->handler,
+ struct sur40_state, hdl);
+ u8 value = sur40->vsvideo;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ sur40_set_irlevel(sur40, ctrl->val);
+ break;
+ case V4L2_CID_CONTRAST:
+ value = (value & 0x0F) | (ctrl->val << 4);
+ sur40_set_vsvideo(sur40, value);
+ break;
+ case V4L2_CID_GAIN:
+ value = (value & 0xF0) | (ctrl->val);
+ sur40_set_vsvideo(sur40, value);
+ break;
+ case V4L2_CID_BACKLIGHT_COMPENSATION:
+ sur40_set_preprocessor(sur40, ctrl->val);
+ break;
+ }
+ return 0;
+}
+
static int sur40_ioctl_parm(struct file *file, void *priv,
struct v4l2_streamparm *p)
{
--
2.7.4
^ permalink raw reply related
* [PATCH v4] add video controls for SUR40 driver
From: Florian Echtler @ 2018-02-08 8:43 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin
Iteration 4, now with min/max values for module parameters.
Best regards, Florian
^ permalink raw reply
* [PATCH 2/4] add default settings and module parameters for video controls
From: Florian Echtler @ 2018-02-08 8:43 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518079386-4647-1-git-send-email-floe@butterbrot.org>
This patch adds parameter definitions and module parameters for the four
userspace controls that the SUR40 can currently provide.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 8375b06..8a5b031 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -149,6 +149,40 @@ struct sur40_image_header {
#define SUR40_TOUCH 0x02
#define SUR40_TAG 0x04
+/* video controls */
+#define SUR40_BRIGHTNESS_MAX 0xff
+#define SUR40_BRIGHTNESS_MIN 0x00
+#define SUR40_BRIGHTNESS_DEF 0xff
+
+#define SUR40_CONTRAST_MAX 0x0f
+#define SUR40_CONTRAST_MIN 0x00
+#define SUR40_CONTRAST_DEF 0x0a
+
+#define SUR40_GAIN_MAX 0x09
+#define SUR40_GAIN_MIN 0x00
+#define SUR40_GAIN_DEF 0x08
+
+#define SUR40_BACKLIGHT_MAX 0x01
+#define SUR40_BACKLIGHT_MIN 0x00
+#define SUR40_BACKLIGHT_DEF 0x01
+
+#define sur40_str(s) #s
+#define SUR40_PARAM_RANGE(lo, hi) " (range " sur40_str(lo) "-" sur40_str(hi) ")"
+
+/* module parameters */
+static uint brightness = SUR40_BRIGHTNESS_DEF;
+module_param(brightness, uint, 0644);
+MODULE_PARM_DESC(brightness, "set initial brightness"
+ SUR40_PARAM_RANGE(SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX));
+static uint contrast = SUR40_CONTRAST_DEF;
+module_param(contrast, uint, 0644);
+MODULE_PARM_DESC(contrast, "set initial contrast"
+ SUR40_PARAM_RANGE(SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX));
+static uint gain = SUR40_GAIN_DEF;
+module_param(gain, uint, 0644);
+MODULE_PARM_DESC(gain, "set initial gain"
+ SUR40_PARAM_RANGE(SUR40_GAIN_MIN, SUR40_GAIN_MAX));
+
static const struct v4l2_pix_format sur40_pix_format[] = {
{
.pixelformat = V4L2_TCH_FMT_TU08,
--
2.7.4
^ permalink raw reply related
* [PATCH 1/4] add missing blob structure field for tag id
From: Florian Echtler @ 2018-02-08 8:43 UTC (permalink / raw)
To: hverkuil, linux-media; +Cc: linux-input, modin, Florian Echtler
In-Reply-To: <1518079386-4647-1-git-send-email-floe@butterbrot.org>
The SUR40 can recognize specific printed patterns directly in hardware;
this information (i.e. the pattern id) is present but currently unused
in the blob structure.
Signed-off-by: Florian Echtler <floe@butterbrot.org>
---
drivers/input/touchscreen/sur40.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index f16f835..8375b06 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -81,7 +81,10 @@ struct sur40_blob {
__le32 area; /* size in pixels/pressure (?) */
- u8 padding[32];
+ u8 padding[24];
+
+ __le32 tag_id; /* valid when type == 0x04 (SUR40_TAG) */
+ __le32 unknown;
} __packed;
--
2.7.4
^ permalink raw reply related
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