* Re: [PATCH] Input: elantech - enable middle button of touchpad on ThinkPad P72
From: Dmitry Torokhov @ 2018-09-18 16:32 UTC (permalink / raw)
To: Aaron Ma; +Cc: linux-input, linux-kernel
In-Reply-To: <20180907070651.6916-1-aaron.ma@canonical.com>
On Fri, Sep 07, 2018 at 03:06:51PM +0800, Aaron Ma wrote:
> Adding 2 new touchpad IDs to support middle button support.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
Applied, thank you.
> ---
> drivers/input/mouse/elantech.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index 44f57cf6675b..2d95e8d93cc7 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -1178,6 +1178,8 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
> static const char * const middle_button_pnp_ids[] = {
> "LEN2131", /* ThinkPad P52 w/ NFC */
> "LEN2132", /* ThinkPad P52 */
> + "LEN2133", /* ThinkPad P72 w/ NFC */
> + "LEN2134", /* ThinkPad P72 */
> NULL
> };
>
> --
> 2.17.1
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: uinput - allow for max == min during input_absinfo validation
From: Martin Kepplinger @ 2018-09-18 11:13 UTC (permalink / raw)
To: Peter Hutterer, dmitry.torokhov, linux-input, linux-kernel
Cc: Benjamin Tissoires
In-Reply-To: <20180918052256.GA23446@jelly>
[-- Attachment #1: Type: text/plain, Size: 256 bytes --]
On 9/18/18 7:22 AM, Peter Hutterer wrote:
> These values are inclusive, so a range of 1 requires min == max.
>
> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
true, nice catch.
Reviewed-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 3616 bytes --]
^ permalink raw reply
* Re: [RFC/PATCH 4/5] gpiolib: add support for fetching descriptors from static properties
From: Mika Westerberg @ 2018-09-18 9:02 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Linus Walleij, Rafael J . Wysocki, linux-input, linux-gpio,
linux-kernel, Andy Shevchenko
In-Reply-To: <20180917181603.125492-5-dmitry.torokhov@gmail.com>
Hi,
On Mon, Sep 17, 2018 at 11:16:02AM -0700, Dmitry Torokhov wrote:
> Now that static device properties understand notion of child nodes, let's
> teach gpiolib to tie such children and machine GPIO descriptor tables.
> We will continue using a single table for entire device, but instead of
> using connection ID as a lookup key in the GPIO descriptor table directly,
> we will perform additional translation: fwnode_get_named_gpiod() when
> dealing with property_set-backed fwnodes will try parsing string property
> with name matching connection ID and use result of the lookup as the key in
> the table:
>
> static const struct property_entry dev_child1_props[] __initconst = {
> ...
> PROPERTY_ENTRY_STRING("gpios", "child-1-gpios"),
> { }
> };
>
> static struct gpiod_lookup_table dev_gpiod_table = {
> .dev_id = "some-device",
> .table = {
> ...
> GPIO_LOOKUP_IDX("B", 1, "child-1-gpios", 1, GPIO_ACTIVE_LOW),
> ...
> },
> };
I wonder if instead of passing and parsing strings (and hoping there are
no typos) we could get the compiler to help us bit more?
Something like below:
static const struct property_entry dev_child1_props[] __initconst = {
...
PROPERTY_ENTRY_STRING("gpios","child-1-gpios"),
{ }
};
static struct gpiod_lookup_table dev_gpiod_table = {
.dev_id = "some-device",
.table = {
...
GPIO_LOOKUP_IDX("B", 1, dev_child1_props, SIZEOF(dev_child1_props),
1, GPIO_ACTIVE_LOW),
...
},
};
^ permalink raw reply
* [PATCH] Input: uinput - allow for max == min during input_absinfo validation
From: Peter Hutterer @ 2018-09-18 5:22 UTC (permalink / raw)
To: dmitry.torokhov, linux-input, linux-kernel; +Cc: Benjamin Tissoires
These values are inclusive, so a range of 1 requires min == max.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
drivers/input/misc/uinput.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 96a887f33698..eb14ddf69346 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -410,7 +410,7 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code,
min = abs->minimum;
max = abs->maximum;
- if ((min != 0 || max != 0) && max <= min) {
+ if ((min != 0 || max != 0) && max < min) {
printk(KERN_DEBUG
"%s: invalid abs[%02x] min:%d max:%d\n",
UINPUT_NAME, code, min, max);
--
2.17.1
^ permalink raw reply related
* Re: [RFC/PATCH 0/5] Support children for legacy device properties
From: Andy Shevchenko @ 2018-09-18 4:23 UTC (permalink / raw)
To: Dmitry Torokhov, Mika Westerberg, Sakari Ailus
Cc: Linus Walleij, Rafael J. Wysocki, linux-input,
open list:GPIO SUBSYSTEM, Linux Kernel Mailing List,
Andy Shevchenko
In-Reply-To: <20180917181603.125492-1-dmitry.torokhov@gmail.com>
On Mon, Sep 17, 2018 at 9:18 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> The generic device properties APIs are very helpful as they allow abstracting
> away details of the platform (whether it is ACPI, device tree, or legacy board
> file), so that individual driver does not need separate code paths to support
> all variants. However there are drivers that currently can not use generic
> device properties API as they need notion of children properties, for example
> gpio_keys driver, that expects every button to be described as a sub-node of
> main device.
>
> This patch series introduces notion of sub-nodes for static properties and ties
> it up with GPIO lookup tables so that they are usable with sub-nodes as well.
I like the idea.
Though, I Cc'ed this to Mika and Sakari who might be interested to see
and, perhaps, comment on it.
>
> Thanks.
>
> --
> Dmitry
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/2] input: atakbd.c - fix Atari CapsLock behaviour
From: Michael Schmitz @ 2018-09-18 2:03 UTC (permalink / raw)
To: Dmitry Torokhov, Andreas Schwab; +Cc: linux-input, debian-68k, linux-m68k
In-Reply-To: <20180917223627.GC203020@dtor-ws>
Thanks Dmitry!
I had asked Andreas' signoff for his keymap fixes only - the rewrite of
the Atari keyboard driver to the current input framework (and hence the
CapsLock toggle bug) was entirely mine, no blame attaches to Andreas there.
Cheers,
Michael
On 18/09/18 10:36, Dmitry Torokhov wrote:
> On Mon, Sep 17, 2018 at 10:29:08PM +0200, Andreas Schwab wrote:
>> On Sep 17 2018, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>>
>>> On Fri, Sep 07, 2018 at 11:40:43AM +1200, Michael Schmitz wrote:
>>>> The CapsLock key on Atari keyboards is not a toggle, it does send the
>>>> normal make and break scancodes.
>>>>
>>>> Drop the CapsLock toggle handling code, which did cause the CapsLock
>>>> key to merely act as a Shift key.
>>>>
>>>> Tested-by: Michael Schmitz <schmitzmic@gmail.com>
>>>> Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
>>> Andreas, I have no idea how Atari keyboards work, can you add your
>>> signed-off-by (or NAK) to this one as well please?
>> The old atakbd driver never had that special handling.
>>
>> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
> Applied, thank you.
>
^ permalink raw reply
* [PATCH 20/20] Input: iforce - use unaligned accessors, where appropriate
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Instead of open-coding conversion from/to little-endian, let's
use proper accessors.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-main.c | 7 ++++---
drivers/input/joystick/iforce/iforce-packets.c | 12 ++++++++----
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 5cb3e80f4e0d..d696b0b653b6 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <asm/unaligned.h>
#include "iforce.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
@@ -286,17 +287,17 @@ int iforce_init_device(struct device *parent, u16 bustype,
*/
if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3)
- input_dev->id.vendor = (buf[2] << 8) | buf[1];
+ input_dev->id.vendor = get_unaligned_le16(buf + 1);
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3)
- input_dev->id.product = (buf[2] << 8) | buf[1];
+ input_dev->id.product = get_unaligned_le16(buf + 1);
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3)
- iforce->device_memory.end = (buf[2] << 8) | buf[1];
+ iforce->device_memory.end = get_unaligned_le16(buf + 1);
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 976ec1c7cf15..76c4475740ab 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <asm/unaligned.h>
#include "iforce.h"
static struct {
@@ -175,8 +176,10 @@ void iforce_process_packet(struct iforce *iforce,
switch (packet_id) {
case 0x01: /* joystick position data */
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+ input_report_abs(dev, ABS_X,
+ (__s16) get_unaligned_le16(data));
+ input_report_abs(dev, ABS_Y,
+ (__s16) get_unaligned_le16(data + 2));
input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
if (len >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
@@ -188,7 +191,8 @@ void iforce_process_packet(struct iforce *iforce,
break;
case 0x03: /* wheel position data */
- input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_WHEEL,
+ (__s16) get_unaligned_le16(data));
input_report_abs(dev, ABS_GAS, 255 - data[2]);
input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
@@ -214,7 +218,7 @@ void iforce_process_packet(struct iforce *iforce,
}
for (j = 3; j < len; j += 2)
- mark_core_as_ready(iforce, data[j] | (data[j + 1] << 8));
+ mark_core_as_ready(iforce, get_unaligned_le16(data + j));
break;
}
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 19/20] Input: iforce - drop couple of temps from transport code
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Transport initialization code now deals mostly with transport-specific
data, so we can drop couple of temporary variables.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-serio.c | 7 ++-----
drivers/input/joystick/iforce/iforce-usb.c | 7 ++-----
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 277522d0f324..e7692a38591e 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -204,16 +204,13 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
{
struct iforce_serio *iforce_serio;
- struct iforce *iforce;
int err;
iforce_serio = kzalloc(sizeof(*iforce_serio), GFP_KERNEL);
if (!iforce_serio)
return -ENOMEM;
- iforce = &iforce_serio->iforce;
-
- iforce->xport_ops = &iforce_serio_xport_ops;
+ iforce_serio->iforce.xport_ops = &iforce_serio_xport_ops;
iforce_serio->serio = serio;
serio_set_drvdata(serio, iforce_serio);
@@ -222,7 +219,7 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
if (err)
goto fail1;
- err = iforce_init_device(&serio->dev, BUS_RS232, iforce);
+ err = iforce_init_device(&serio->dev, BUS_RS232, &iforce_serio->iforce);
if (err)
goto fail2;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index ae2dd5b5a416..a1e670781441 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -208,7 +208,6 @@ static int iforce_usb_probe(struct usb_interface *intf,
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *epirq, *epout;
struct iforce_usb *iforce_usb;
- struct iforce *iforce;
int err = -ENOMEM;
interface = intf->cur_altsetting;
@@ -231,9 +230,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
if (!iforce_usb->out)
goto fail;
- iforce = &iforce_usb->iforce;
-
- iforce->xport_ops = &iforce_usb_xport_ops;
+ iforce_usb->iforce.xport_ops = &iforce_usb_xport_ops;
iforce_usb->usbdev = dev;
iforce_usb->intf = intf;
@@ -248,7 +245,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
iforce_usb->data_out, sizeof(iforce_usb->data_out),
iforce_usb_out, iforce_usb, epout->bInterval);
- err = iforce_init_device(&intf->dev, BUS_USB, iforce);
+ err = iforce_init_device(&intf->dev, BUS_USB, &iforce_usb->iforce);
if (err)
goto fail;
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 18/20] Input: iforce - drop bus type from iforce structure
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
It is not needed anymore as behavior is controlled by the transport
operations set up for given device.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-serio.c | 1 -
drivers/input/joystick/iforce/iforce-usb.c | 1 -
drivers/input/joystick/iforce/iforce.h | 5 -----
3 files changed, 7 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index c73d988cbc92..277522d0f324 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -214,7 +214,6 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
iforce = &iforce_serio->iforce;
iforce->xport_ops = &iforce_serio_xport_ops;
- iforce->bus = IFORCE_232;
iforce_serio->serio = serio;
serio_set_drvdata(serio, iforce_serio);
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index d85258b50be2..ae2dd5b5a416 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -234,7 +234,6 @@ static int iforce_usb_probe(struct usb_interface *intf,
iforce = &iforce_usb->iforce;
iforce->xport_ops = &iforce_usb_xport_ops;
- iforce->bus = IFORCE_USB;
iforce_usb->usbdev = dev;
iforce_usb->intf = intf;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 180de7a3f3a1..3e91cc381488 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -38,10 +38,6 @@
#define IFORCE_MAX_LENGTH 16
-/* iforce::bus */
-#define IFORCE_232 1
-#define IFORCE_USB 2
-
#define IFORCE_EFFECTS_MAX 32
/* Each force feedback effect is made of one core effect, which can be
@@ -105,7 +101,6 @@ struct iforce {
struct input_dev *dev; /* Input device interface */
struct iforce_device *type;
const struct iforce_xport_ops *xport_ops;
- int bus;
spinlock_t xmit_lock;
/* Buffer used for asynchronous sending of bytes to the device */
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 17/20] Input: only credit entropy when events are generated by a device
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Currently we credit entropy (via add_input_randomness()) regardless of
where an event comes form, a device itself, or an input handler, such as
evdev (and thus from userspace). While access to event devices is supposed
to be tightly controlled (one does not want random processes to be able to
observe or inject keystrokes), developers may use evdev to inject events
for testing purposes. Let's make sure that such events to not contribute
to the entropy to keep the pool 'pure' and do not expose developer's
boxes to not so random data.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/input.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 260f00ebe34d..0126b8bb6afa 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -368,12 +368,15 @@ static int input_get_disposition(struct input_dev *dev,
}
static void input_handle_event(struct input_dev *dev,
- unsigned int type, unsigned int code, int value)
+ unsigned int type, unsigned int code, int value,
+ bool can_credit_entropy)
{
int disposition = input_get_disposition(dev, type, code, &value);
- if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
+ if (can_credit_entropy &&
+ disposition != INPUT_IGNORE_EVENT && type != EV_SYN) {
add_input_randomness(type, code, value);
+ }
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value);
@@ -434,7 +437,7 @@ void input_event(struct input_dev *dev,
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
- input_handle_event(dev, type, code, value);
+ input_handle_event(dev, type, code, value, true);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}
@@ -464,7 +467,7 @@ void input_inject_event(struct input_handle *handle,
rcu_read_lock();
grab = rcu_dereference(dev->grab);
if (!grab || grab == handle)
- input_handle_event(dev, type, code, value);
+ input_handle_event(dev, type, code, value, false);
rcu_read_unlock();
spin_unlock_irqrestore(&dev->event_lock, flags);
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 16/20] Input: iforce - use DMA-safe buffores for USB transfers
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
USB transport has to use cache line-aligned buffers for transfers to avoid
DMA issues; serio doe snot have such restrictions. Let's move "data_in"
buffer from main driver structure into transport modules and make sure USB
requirements are respected.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-serio.c | 10 ++++---
drivers/input/joystick/iforce/iforce-usb.c | 28 +++++++++++++-------
drivers/input/joystick/iforce/iforce.h | 2 --
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index be44aed551f7..c73d988cbc92 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -33,6 +33,7 @@ struct iforce_serio {
u8 expect_packet;
u8 cmd_response[IFORCE_MAX_LENGTH];
u8 cmd_response_len;
+ u8 data_in[IFORCE_MAX_LENGTH];
};
static void iforce_serio_xmit(struct iforce *iforce)
@@ -169,7 +170,7 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
}
if (iforce_serio->idx < iforce_serio->len) {
- iforce->data[iforce_serio->idx++] = data;
+ iforce_serio->data_in[iforce_serio->idx++] = data;
iforce_serio->csum += data;
goto out;
}
@@ -178,15 +179,16 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
/* Handle command completion */
if (iforce_serio->expect_packet == iforce_serio->id) {
iforce_serio->expect_packet = 0;
- memcpy(iforce_serio->cmd_response, iforce->data,
- IFORCE_MAX_LENGTH);
+ memcpy(iforce_serio->cmd_response,
+ iforce_serio->data_in, IFORCE_MAX_LENGTH);
iforce_serio->cmd_response_len = iforce_serio->len;
/* Signal that command is done */
wake_up(&iforce->wait);
} else if (likely(iforce->type)) {
iforce_process_packet(iforce, iforce_serio->id,
- iforce->data, iforce_serio->len);
+ iforce_serio->data_in,
+ iforce_serio->len);
}
iforce_serio->pkt = 0;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 68155c4de412..d85258b50be2 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -30,6 +30,9 @@ struct iforce_usb {
struct usb_device *usbdev;
struct usb_interface *intf;
struct urb *irq, *out;
+
+ u8 data_in[IFORCE_MAX_LENGTH] ____cacheline_aligned;
+ u8 data_out[IFORCE_MAX_LENGTH] ____cacheline_aligned;
};
static void __iforce_usb_xmit(struct iforce *iforce)
@@ -171,8 +174,8 @@ static void iforce_usb_irq(struct urb *urb)
goto exit;
}
- iforce_process_packet(iforce, iforce->data[0],
- iforce->data + 1, urb->actual_length - 1);
+ iforce_process_packet(iforce, iforce_usb->data_in[0],
+ iforce_usb->data_in + 1, urb->actual_length - 1);
exit:
status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -216,13 +219,16 @@ static int iforce_usb_probe(struct usb_interface *intf,
epirq = &interface->endpoint[0].desc;
epout = &interface->endpoint[1].desc;
- if (!(iforce_usb = kzalloc(sizeof(*iforce_usb) + 32, GFP_KERNEL)))
+ iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL);
+ if (!iforce_usb)
goto fail;
- if (!(iforce_usb->irq = usb_alloc_urb(0, GFP_KERNEL)))
+ iforce_usb->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!iforce_usb->irq)
goto fail;
- if (!(iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL)))
+ iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL);
+ if (!iforce_usb->out)
goto fail;
iforce = &iforce_usb->iforce;
@@ -233,11 +239,15 @@ static int iforce_usb_probe(struct usb_interface *intf,
iforce_usb->usbdev = dev;
iforce_usb->intf = intf;
- usb_fill_int_urb(iforce_usb->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
- iforce->data, 16, iforce_usb_irq, iforce_usb, epirq->bInterval);
+ usb_fill_int_urb(iforce_usb->irq, dev,
+ usb_rcvintpipe(dev, epirq->bEndpointAddress),
+ iforce_usb->data_in, sizeof(iforce_usb->data_in),
+ iforce_usb_irq, iforce_usb, epirq->bInterval);
- usb_fill_int_urb(iforce_usb->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
- iforce_usb + 1, 32, iforce_usb_out, iforce_usb, epout->bInterval);
+ usb_fill_int_urb(iforce_usb->out, dev,
+ usb_sndintpipe(dev, epout->bEndpointAddress),
+ iforce_usb->data_out, sizeof(iforce_usb->data_out),
+ iforce_usb_out, iforce_usb, epout->bInterval);
err = iforce_init_device(&intf->dev, BUS_USB, iforce);
if (err)
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 68558c594e54..180de7a3f3a1 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -107,8 +107,6 @@ struct iforce {
const struct iforce_xport_ops *xport_ops;
int bus;
- unsigned char data[IFORCE_MAX_LENGTH];
-
spinlock_t xmit_lock;
/* Buffer used for asynchronous sending of bytes to the device */
struct circ_buf xmit;
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 15/20] Input: iforce - allow callers supply data buffer when fetching device IDs
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
We want to move buffer handling into transport layers as the properties of
buffers (DMA-safety, alignment, etc) are different for different
transports. To allow this, let's allow caller to specify their own buffers
for the results of iforce_get_id_packet() and let transport drivers to
figure what buffers they need to use for transfers.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-main.c | 27 ++++++++++---------
drivers/input/joystick/iforce/iforce-serio.c | 28 ++++++++++++++------
drivers/input/joystick/iforce/iforce-usb.c | 11 ++++----
drivers/input/joystick/iforce/iforce.h | 11 ++++----
4 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 9964aa8b3cdc..5cb3e80f4e0d 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -225,7 +225,9 @@ int iforce_init_device(struct device *parent, u16 bustype,
{
struct input_dev *input_dev;
struct ff_device *ff;
- unsigned char c[] = "CEOV";
+ u8 c[] = "CEOV";
+ u8 buf[IFORCE_MAX_LENGTH];
+ size_t len;
int i, error;
int ff_effects = 0;
@@ -269,7 +271,7 @@ int iforce_init_device(struct device *parent, u16 bustype,
*/
for (i = 0; i < 20; i++)
- if (!iforce_get_id_packet(iforce, "O"))
+ if (!iforce_get_id_packet(iforce, 'O', buf, &len))
break;
if (i == 20) { /* 5 seconds */
@@ -283,23 +285,23 @@ int iforce_init_device(struct device *parent, u16 bustype,
* Get device info.
*/
- if (!iforce_get_id_packet(iforce, "M"))
- input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
+ if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3)
+ input_dev->id.vendor = (buf[2] << 8) | buf[1];
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
- if (!iforce_get_id_packet(iforce, "P"))
- input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
+ if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3)
+ input_dev->id.product = (buf[2] << 8) | buf[1];
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
- if (!iforce_get_id_packet(iforce, "B"))
- iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
+ if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3)
+ iforce->device_memory.end = (buf[2] << 8) | buf[1];
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
- if (!iforce_get_id_packet(iforce, "N"))
- ff_effects = iforce->edata[1];
+ if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2)
+ ff_effects = buf[1];
else
dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
@@ -315,8 +317,9 @@ int iforce_init_device(struct device *parent, u16 bustype,
*/
for (i = 0; c[i]; i++)
- if (!iforce_get_id_packet(iforce, c + i))
- iforce_dump_packet(iforce, "info", iforce->ecmd, iforce->edata);
+ if (!iforce_get_id_packet(iforce, c[i], buf, &len))
+ iforce_dump_packet(iforce, "info",
+ (FF_CMD_QUERY & 0xff00) | len, buf);
/*
* Disable spring, enable force feedback.
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 8d7eba9c9f0e..be44aed551f7 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -31,6 +31,8 @@ struct iforce_serio {
int idx, pkt, len, id;
u8 csum;
u8 expect_packet;
+ u8 cmd_response[IFORCE_MAX_LENGTH];
+ u8 cmd_response_len;
};
static void iforce_serio_xmit(struct iforce *iforce)
@@ -81,24 +83,34 @@ static void iforce_serio_xmit(struct iforce *iforce)
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
}
-static int iforce_serio_get_id(struct iforce *iforce, u8 *packet)
+static int iforce_serio_get_id(struct iforce *iforce, u8 id,
+ u8 *response_data, size_t *response_len)
{
struct iforce_serio *iforce_serio = container_of(iforce,
struct iforce_serio,
iforce);
iforce_serio->expect_packet = HI(FF_CMD_QUERY);
- iforce_send_packet(iforce, FF_CMD_QUERY, packet);
+ iforce_serio->cmd_response_len = 0;
+
+ iforce_send_packet(iforce, FF_CMD_QUERY, &id);
wait_event_interruptible_timeout(iforce->wait,
!iforce_serio->expect_packet, HZ);
if (iforce_serio->expect_packet) {
iforce_serio->expect_packet = 0;
- return -EIO;
+ return -ETIMEDOUT;
}
- return -(iforce->edata[0] != packet[0]);
+ if (iforce_serio->cmd_response[0] != id)
+ return -EIO;
+
+ memcpy(response_data, iforce_serio->cmd_response,
+ iforce_serio->cmd_response_len);
+ *response_len = iforce_serio->cmd_response_len;
+
+ return 0;
}
static int iforce_serio_start_io(struct iforce *iforce)
@@ -127,7 +139,7 @@ static void iforce_serio_write_wakeup(struct serio *serio)
}
static irqreturn_t iforce_serio_irq(struct serio *serio,
- unsigned char data, unsigned int flags)
+ unsigned char data, unsigned int flags)
{
struct iforce_serio *iforce_serio = serio_get_drvdata(serio);
struct iforce *iforce = &iforce_serio->iforce;
@@ -166,9 +178,9 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
/* Handle command completion */
if (iforce_serio->expect_packet == iforce_serio->id) {
iforce_serio->expect_packet = 0;
- iforce->ecmd = (iforce_serio->id << 8) |
- iforce_serio->idx;
- memcpy(iforce->edata, iforce->data, IFORCE_MAX_LENGTH);
+ memcpy(iforce_serio->cmd_response, iforce->data,
+ IFORCE_MAX_LENGTH);
+ iforce_serio->cmd_response_len = iforce_serio->len;
/* Signal that command is done */
wake_up(&iforce->wait);
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index b3743fde2a3a..68155c4de412 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -87,7 +87,8 @@ static void iforce_usb_xmit(struct iforce *iforce)
__iforce_usb_xmit(iforce);
}
-static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
+static int iforce_usb_get_id(struct iforce *iforce, u8 id,
+ u8 *response_data, size_t *response_len)
{
struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
iforce);
@@ -100,18 +101,18 @@ static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
status = usb_control_msg(iforce_usb->usbdev,
usb_rcvctrlpipe(iforce_usb->usbdev, 0),
- packet[0],
+ id,
USB_TYPE_VENDOR | USB_DIR_IN |
USB_RECIP_INTERFACE,
0, 0, buf, IFORCE_MAX_LENGTH, HZ);
if (status < 0) {
dev_err(&iforce_usb->intf->dev,
"usb_submit_urb failed: %d\n", status);
- } else if (buf[0] != packet[0]) {
+ } else if (buf[0] != id) {
status = -EIO;
} else {
- iforce->ecmd = 0xff00 | status;
- memcpy(iforce->edata, buf, status);
+ memcpy(response_data, buf, status);
+ *response_len = status;
status = 0;
}
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index ce3c6aead8b6..68558c594e54 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -95,7 +95,8 @@ struct iforce;
struct iforce_xport_ops {
void (*xmit)(struct iforce *iforce);
- int (*get_id)(struct iforce *iforce, u8* id);
+ int (*get_id)(struct iforce *iforce, u8 id,
+ u8 *response_data, size_t *response_len);
int (*start_io)(struct iforce *iforce);
void (*stop_io)(struct iforce *iforce);
};
@@ -107,8 +108,6 @@ struct iforce {
int bus;
unsigned char data[IFORCE_MAX_LENGTH];
- unsigned char edata[IFORCE_MAX_LENGTH];
- u16 ecmd;
spinlock_t xmit_lock;
/* Buffer used for asynchronous sending of bytes to the device */
@@ -135,9 +134,11 @@ struct iforce {
/* Encode a time value */
#define TIME_SCALE(a) (a)
-static inline int iforce_get_id_packet(struct iforce *iforce, u8* id)
+static inline int iforce_get_id_packet(struct iforce *iforce, u8 id,
+ u8 *response_data, size_t *response_len)
{
- return iforce->xport_ops->get_id(iforce, id);
+ return iforce->xport_ops->get_id(iforce, id,
+ response_data, response_len);
}
/* Public functions */
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 14/20] Input: iforce - only call iforce_process_packet() if initialized
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
It is excessive to check if device is fully initialized in
iforce_process_packet(), as for USB-conected devices we do not start
collecting reports until the device is fully initialized.
Let's change serio transport code to not call iforce_process_packet()
until device initialization is done.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-packets.c | 3 ---
drivers/input/joystick/iforce/iforce-serio.c | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index c0a665961c23..976ec1c7cf15 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -172,9 +172,6 @@ void iforce_process_packet(struct iforce *iforce,
struct input_dev *dev = iforce->dev;
int i, j;
- if (!iforce->type)
- return;
-
switch (packet_id) {
case 0x01: /* joystick position data */
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 0dd95d145e85..8d7eba9c9f0e 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -172,7 +172,7 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
/* Signal that command is done */
wake_up(&iforce->wait);
- } else {
+ } else if (likely(iforce->type)) {
iforce_process_packet(iforce, iforce_serio->id,
iforce->data, iforce_serio->len);
}
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 13/20] Input: iforce - signal command completion from transport code
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Signalling command completion from iforce_process_packet() does
not make sense, as not all transport use the same data path for
both commands and motion data form the device, that is why USB
code already has to signal command completion iforce_usb_out().
Let's move signalling completion into individual transport
modules.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-packets.c | 2 --
drivers/input/joystick/iforce/iforce-serio.c | 9 ++++++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 35b7a5206977..c0a665961c23 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -172,8 +172,6 @@ void iforce_process_packet(struct iforce *iforce,
struct input_dev *dev = iforce->dev;
int i, j;
- wake_up(&iforce->wait);
-
if (!iforce->type)
return;
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index f8bf7d2aa59f..0dd95d145e85 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -169,10 +169,13 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
iforce->ecmd = (iforce_serio->id << 8) |
iforce_serio->idx;
memcpy(iforce->edata, iforce->data, IFORCE_MAX_LENGTH);
- }
- iforce_process_packet(iforce, iforce_serio->id,
- iforce->data, iforce_serio->len);
+ /* Signal that command is done */
+ wake_up(&iforce->wait);
+ } else {
+ iforce_process_packet(iforce, iforce_serio->id,
+ iforce->data, iforce_serio->len);
+ }
iforce_serio->pkt = 0;
iforce_serio->id = 0;
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 12/20] Input: iforce - do not combine arguments for iforce_process_packet()
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Current code combines packet type and data length into single argument to
iforce_process_packet() and then has to untangle it. It is much clearer to
simply use separate arguments.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-packets.c | 9 +++++----
drivers/input/joystick/iforce/iforce-serio.c | 8 ++++----
drivers/input/joystick/iforce/iforce-usb.c | 4 ++--
drivers/input/joystick/iforce/iforce.h | 3 ++-
4 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index ffd1dd65deb8..35b7a5206977 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -166,7 +166,8 @@ static void iforce_report_hats_buttons(struct iforce *iforce, u8 *data)
}
}
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
+void iforce_process_packet(struct iforce *iforce,
+ u8 packet_id, u8 *data, size_t len)
{
struct input_dev *dev = iforce->dev;
int i, j;
@@ -176,14 +177,14 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
if (!iforce->type)
return;
- switch (HI(cmd)) {
+ switch (packet_id) {
case 0x01: /* joystick position data */
input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
- if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+ if (len >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
iforce_report_hats_buttons(iforce, data);
@@ -217,7 +218,7 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
- for (j = 3; j < LO(cmd); j += 2)
+ for (j = 3; j < len; j += 2)
mark_core_as_ready(iforce, data[j] | (data[j + 1] << 8));
break;
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 6c6411fbdc32..f8bf7d2aa59f 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -163,16 +163,16 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
}
if (iforce_serio->idx == iforce_serio->len) {
- u16 cmd = (iforce_serio->id << 8) | iforce_serio->idx;
-
/* Handle command completion */
if (iforce_serio->expect_packet == iforce_serio->id) {
iforce_serio->expect_packet = 0;
- iforce->ecmd = cmd;
+ iforce->ecmd = (iforce_serio->id << 8) |
+ iforce_serio->idx;
memcpy(iforce->edata, iforce->data, IFORCE_MAX_LENGTH);
}
- iforce_process_packet(iforce, cmd, iforce->data);
+ iforce_process_packet(iforce, iforce_serio->id,
+ iforce->data, iforce_serio->len);
iforce_serio->pkt = 0;
iforce_serio->id = 0;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index cefaa1c5abc7..b3743fde2a3a 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -170,8 +170,8 @@ static void iforce_usb_irq(struct urb *urb)
goto exit;
}
- iforce_process_packet(iforce,
- (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
+ iforce_process_packet(iforce, iforce->data[0],
+ iforce->data + 1, urb->actual_length - 1);
exit:
status = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 3e3df83b9d77..ce3c6aead8b6 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -147,7 +147,8 @@ int iforce_init_device(struct device *parent, u16 bustype,
/* iforce-packets.c */
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
+void iforce_process_packet(struct iforce *iforce,
+ u8 packet_id, u8 *data, size_t len);
int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
void iforce_dump_packet(struct iforce *iforce, char *msg, u16 cmd, unsigned char *data);
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 11/20] Input: iforce - factor out hat handling when parsing packets
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
This makes code clearer a bit.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
.../input/joystick/iforce/iforce-packets.c | 101 ++++++++++--------
1 file changed, 57 insertions(+), 44 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 7aba2966454a..ffd1dd65deb8 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -130,11 +130,47 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
return -1;
}
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
+static void iforce_report_hats_buttons(struct iforce *iforce, u8 *data)
{
struct input_dev *dev = iforce->dev;
int i;
+ input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
+ input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
+
+ for (i = 0; iforce->type->btn[i] >= 0; i++)
+ input_report_key(dev, iforce->type->btn[i],
+ data[(i >> 3) + 5] & (1 << (i & 7)));
+
+ /* If there are untouched bits left, interpret them as the second hat */
+ if (i <= 8) {
+ u8 btns = data[6];
+
+ if (test_bit(ABS_HAT1X, dev->absbit)) {
+ if (btns & BIT(3))
+ input_report_abs(dev, ABS_HAT1X, -1);
+ else if (btns & BIT(1))
+ input_report_abs(dev, ABS_HAT1X, 1);
+ else
+ input_report_abs(dev, ABS_HAT1X, 0);
+ }
+
+ if (test_bit(ABS_HAT1Y, dev->absbit)) {
+ if (btns & BIT(0))
+ input_report_abs(dev, ABS_HAT1Y, -1);
+ else if (btns & BIT(2))
+ input_report_abs(dev, ABS_HAT1Y, 1);
+ else
+ input_report_abs(dev, ABS_HAT1Y, 0);
+ }
+ }
+}
+
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
+{
+ struct input_dev *dev = iforce->dev;
+ int i, j;
+
wake_up(&iforce->wait);
if (!iforce->type)
@@ -143,48 +179,26 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
switch (HI(cmd)) {
case 0x01: /* joystick position data */
- case 0x03: /* wheel position data */
- if (HI(cmd) == 1) {
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
- input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
- if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
- input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
- } else {
- input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
- input_report_abs(dev, ABS_GAS, 255 - data[2]);
- input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
- }
+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+ input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
- input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
- input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
-
- for (i = 0; iforce->type->btn[i] >= 0; i++)
- input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7)));
-
- /* If there are untouched bits left, interpret them as the second hat */
- if (i <= 8) {
- int btns = data[6];
- if (test_bit(ABS_HAT1X, dev->absbit)) {
- if (btns & 8)
- input_report_abs(dev, ABS_HAT1X, -1);
- else if (btns & 2)
- input_report_abs(dev, ABS_HAT1X, 1);
- else
- input_report_abs(dev, ABS_HAT1X, 0);
- }
- if (test_bit(ABS_HAT1Y, dev->absbit)) {
- if (btns & 1)
- input_report_abs(dev, ABS_HAT1Y, -1);
- else if (btns & 4)
- input_report_abs(dev, ABS_HAT1Y, 1);
- else
- input_report_abs(dev, ABS_HAT1Y, 0);
- }
- }
+ if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+ input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
+
+ iforce_report_hats_buttons(iforce, data);
input_sync(dev);
+ break;
+ case 0x03: /* wheel position data */
+ input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_GAS, 255 - data[2]);
+ input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+
+ iforce_report_hats_buttons(iforce, data);
+
+ input_sync(dev);
break;
case 0x02: /* status report */
@@ -202,11 +216,10 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
/* Report stop event */
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
- if (LO(cmd) > 3) {
- int j;
- for (j = 3; j < LO(cmd); j += 2)
- mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
- }
+
+ for (j = 3; j < LO(cmd); j += 2)
+ mark_core_as_ready(iforce, data[j] | (data[j + 1] << 8));
+
break;
}
}
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 10/20] Input: iforce - update formatting of switch statements
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
According to our coding style case labels in switch statements should
be aligned with the switch keyword.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-ff.c | 18 +--
drivers/input/joystick/iforce/iforce-main.c | 70 +++++------
.../input/joystick/iforce/iforce-packets.c | 112 +++++++++---------
3 files changed, 100 insertions(+), 100 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c
index 3536d5f5ad18..56973dd97fd6 100644
--- a/drivers/input/joystick/iforce/iforce-ff.c
+++ b/drivers/input/joystick/iforce/iforce-ff.c
@@ -384,12 +384,12 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
}
switch (effect->u.periodic.waveform) {
- case FF_SQUARE: wave_code = 0x20; break;
- case FF_TRIANGLE: wave_code = 0x21; break;
- case FF_SINE: wave_code = 0x22; break;
- case FF_SAW_UP: wave_code = 0x23; break;
- case FF_SAW_DOWN: wave_code = 0x24; break;
- default: wave_code = 0x20; break;
+ case FF_SQUARE: wave_code = 0x20; break;
+ case FF_TRIANGLE: wave_code = 0x21; break;
+ case FF_SINE: wave_code = 0x22; break;
+ case FF_SAW_UP: wave_code = 0x23; break;
+ case FF_SAW_DOWN: wave_code = 0x24; break;
+ default: wave_code = 0x20; break;
}
if (!old || need_core(old, effect)) {
@@ -488,9 +488,9 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str
int core_err = 0;
switch (effect->type) {
- case FF_SPRING: type = 0x40; break;
- case FF_DAMPER: type = 0x41; break;
- default: return -1;
+ case FF_SPRING: type = 0x40; break;
+ case FF_DAMPER: type = 0x41; break;
+ default: return -1;
}
if (!old || need_condition_modifier(iforce, old, effect)) {
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 3a0698327c42..9964aa8b3cdc 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -132,22 +132,21 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect,
* Upload the effect
*/
switch (effect->type) {
+ case FF_PERIODIC:
+ ret = iforce_upload_periodic(iforce, effect, old);
+ break;
- case FF_PERIODIC:
- ret = iforce_upload_periodic(iforce, effect, old);
- break;
+ case FF_CONSTANT:
+ ret = iforce_upload_constant(iforce, effect, old);
+ break;
- case FF_CONSTANT:
- ret = iforce_upload_constant(iforce, effect, old);
- break;
+ case FF_SPRING:
+ case FF_DAMPER:
+ ret = iforce_upload_condition(iforce, effect, old);
+ break;
- case FF_SPRING:
- case FF_DAMPER:
- ret = iforce_upload_condition(iforce, effect, old);
- break;
-
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
if (ret == 0) {
@@ -351,34 +350,29 @@ int iforce_init_device(struct device *parent, u16 bustype,
signed short t = iforce->type->abs[i];
switch (t) {
+ case ABS_X:
+ case ABS_Y:
+ case ABS_WHEEL:
+ input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+ set_bit(t, input_dev->ffbit);
+ break;
- case ABS_X:
- case ABS_Y:
- case ABS_WHEEL:
-
- input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
- set_bit(t, input_dev->ffbit);
- break;
-
- case ABS_THROTTLE:
- case ABS_GAS:
- case ABS_BRAKE:
-
- input_set_abs_params(input_dev, t, 0, 255, 0, 0);
- break;
-
- case ABS_RUDDER:
-
- input_set_abs_params(input_dev, t, -128, 127, 0, 0);
- break;
+ case ABS_THROTTLE:
+ case ABS_GAS:
+ case ABS_BRAKE:
+ input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+ break;
- case ABS_HAT0X:
- case ABS_HAT0Y:
- case ABS_HAT1X:
- case ABS_HAT1Y:
+ case ABS_RUDDER:
+ input_set_abs_params(input_dev, t, -128, 127, 0, 0);
+ break;
- input_set_abs_params(input_dev, t, -1, 1, 0, 0);
- break;
+ case ABS_HAT0X:
+ case ABS_HAT0Y:
+ case ABS_HAT1X:
+ case ABS_HAT1Y:
+ input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+ break;
}
}
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 70db273e5045..7aba2966454a 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -142,66 +142,72 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
switch (HI(cmd)) {
- case 0x01: /* joystick position data */
- case 0x03: /* wheel position data */
- if (HI(cmd) == 1) {
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
- input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
- if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
- input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
- } else {
- input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
- input_report_abs(dev, ABS_GAS, 255 - data[2]);
- input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
- }
+ case 0x01: /* joystick position data */
+ case 0x03: /* wheel position data */
+ if (HI(cmd) == 1) {
+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+ input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
+ if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+ input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
+ } else {
+ input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
+ input_report_abs(dev, ABS_GAS, 255 - data[2]);
+ input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+ }
- input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
- input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
-
- for (i = 0; iforce->type->btn[i] >= 0; i++)
- input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7)));
-
- /* If there are untouched bits left, interpret them as the second hat */
- if (i <= 8) {
- int btns = data[6];
- if (test_bit(ABS_HAT1X, dev->absbit)) {
- if (btns & 8) input_report_abs(dev, ABS_HAT1X, -1);
- else if (btns & 2) input_report_abs(dev, ABS_HAT1X, 1);
- else input_report_abs(dev, ABS_HAT1X, 0);
- }
- if (test_bit(ABS_HAT1Y, dev->absbit)) {
- if (btns & 1) input_report_abs(dev, ABS_HAT1Y, -1);
- else if (btns & 4) input_report_abs(dev, ABS_HAT1Y, 1);
- else input_report_abs(dev, ABS_HAT1Y, 0);
- }
+ input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
+ input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
+
+ for (i = 0; iforce->type->btn[i] >= 0; i++)
+ input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7)));
+
+ /* If there are untouched bits left, interpret them as the second hat */
+ if (i <= 8) {
+ int btns = data[6];
+ if (test_bit(ABS_HAT1X, dev->absbit)) {
+ if (btns & 8)
+ input_report_abs(dev, ABS_HAT1X, -1);
+ else if (btns & 2)
+ input_report_abs(dev, ABS_HAT1X, 1);
+ else
+ input_report_abs(dev, ABS_HAT1X, 0);
}
+ if (test_bit(ABS_HAT1Y, dev->absbit)) {
+ if (btns & 1)
+ input_report_abs(dev, ABS_HAT1Y, -1);
+ else if (btns & 4)
+ input_report_abs(dev, ABS_HAT1Y, 1);
+ else
+ input_report_abs(dev, ABS_HAT1Y, 0);
+ }
+ }
- input_sync(dev);
+ input_sync(dev);
- break;
+ break;
- case 0x02: /* status report */
- input_report_key(dev, BTN_DEAD, data[0] & 0x02);
- input_sync(dev);
+ case 0x02: /* status report */
+ input_report_key(dev, BTN_DEAD, data[0] & 0x02);
+ input_sync(dev);
- /* Check if an effect was just started or stopped */
- i = data[1] & 0x7f;
- if (data[1] & 0x80) {
- if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
- /* Report play event */
- input_report_ff_status(dev, i, FF_STATUS_PLAYING);
- }
- } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
- /* Report stop event */
- input_report_ff_status(dev, i, FF_STATUS_STOPPED);
+ /* Check if an effect was just started or stopped */
+ i = data[1] & 0x7f;
+ if (data[1] & 0x80) {
+ if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
+ /* Report play event */
+ input_report_ff_status(dev, i, FF_STATUS_PLAYING);
}
- if (LO(cmd) > 3) {
- int j;
- for (j = 3; j < LO(cmd); j += 2)
- mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
- }
- break;
+ } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
+ /* Report stop event */
+ input_report_ff_status(dev, i, FF_STATUS_STOPPED);
+ }
+ if (LO(cmd) > 3) {
+ int j;
+ for (j = 3; j < LO(cmd); j += 2)
+ mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
+ }
+ break;
}
}
EXPORT_SYMBOL(iforce_process_packet);
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 09/20] Input: iforce - use DMA-safe buffer when getting IDs from USB
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
When working with USB devices we need to use DMA-safe buffers,
and iforce->edata is not one. Let's rework the code to allocate
temporary buffer (iforce_get_id() is called only during initialization
so there is no reason to have permanent buffer) and use it. While at it,
let's utilize usb_control_msg() API which simplifies code.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-usb.c | 68 +++++++---------------
1 file changed, 22 insertions(+), 46 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 9d635f01cf19..cefaa1c5abc7 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -29,8 +29,7 @@ struct iforce_usb {
struct usb_device *usbdev;
struct usb_interface *intf;
- struct urb *irq, *out, *ctrl;
- struct usb_ctrlrequest cr;
+ struct urb *irq, *out;
};
static void __iforce_usb_xmit(struct iforce *iforce)
@@ -92,30 +91,32 @@ static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
{
struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
iforce);
+ u8 *buf;
int status;
- iforce_usb->cr.bRequest = packet[0];
- iforce_usb->ctrl->dev = iforce_usb->usbdev;
-
- status = usb_submit_urb(iforce_usb->ctrl, GFP_KERNEL);
- if (status) {
+ buf = kmalloc(IFORCE_MAX_LENGTH, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ status = usb_control_msg(iforce_usb->usbdev,
+ usb_rcvctrlpipe(iforce_usb->usbdev, 0),
+ packet[0],
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE,
+ 0, 0, buf, IFORCE_MAX_LENGTH, HZ);
+ if (status < 0) {
dev_err(&iforce_usb->intf->dev,
- "usb_submit_urb failed %d\n", status);
- return -EIO;
- }
-
- wait_event_interruptible_timeout(iforce->wait,
- iforce_usb->ctrl->status != -EINPROGRESS, HZ);
-
- if (iforce_usb->ctrl->status) {
- dev_dbg(&iforce_usb->intf->dev,
- "iforce->ctrl->status = %d\n",
- iforce_usb->ctrl->status);
- usb_unlink_urb(iforce_usb->ctrl);
- return -EIO;
+ "usb_submit_urb failed: %d\n", status);
+ } else if (buf[0] != packet[0]) {
+ status = -EIO;
+ } else {
+ iforce->ecmd = 0xff00 | status;
+ memcpy(iforce->edata, buf, status);
+ status = 0;
}
- return -(iforce->edata[0] != packet[0]);
+ kfree(buf);
+ return status;
}
static int iforce_usb_start_io(struct iforce *iforce)
@@ -136,7 +137,6 @@ static void iforce_usb_stop_io(struct iforce *iforce)
usb_kill_urb(iforce_usb->irq);
usb_kill_urb(iforce_usb->out);
- usb_kill_urb(iforce_usb->ctrl);
}
static const struct iforce_xport_ops iforce_usb_xport_ops = {
@@ -197,18 +197,6 @@ static void iforce_usb_out(struct urb *urb)
wake_up(&iforce->wait);
}
-static void iforce_usb_ctrl(struct urb *urb)
-{
- struct iforce_usb *iforce_usb = urb->context;
- struct iforce *iforce = &iforce_usb->iforce;
-
- if (urb->status)
- return;
-
- iforce->ecmd = 0xff00 | urb->actual_length;
- wake_up(&iforce->wait);
-}
-
static int iforce_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -236,9 +224,6 @@ static int iforce_usb_probe(struct usb_interface *intf,
if (!(iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- if (!(iforce_usb->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
- goto fail;
-
iforce = &iforce_usb->iforce;
iforce->xport_ops = &iforce_usb_xport_ops;
@@ -247,19 +232,12 @@ static int iforce_usb_probe(struct usb_interface *intf,
iforce_usb->usbdev = dev;
iforce_usb->intf = intf;
- iforce_usb->cr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
- iforce_usb->cr.wIndex = 0;
- iforce_usb->cr.wLength = cpu_to_le16(16);
-
usb_fill_int_urb(iforce_usb->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
iforce->data, 16, iforce_usb_irq, iforce_usb, epirq->bInterval);
usb_fill_int_urb(iforce_usb->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
iforce_usb + 1, 32, iforce_usb_out, iforce_usb, epout->bInterval);
- usb_fill_control_urb(iforce_usb->ctrl, dev, usb_rcvctrlpipe(dev, 0),
- (void*) &iforce_usb->cr, iforce->edata, 16, iforce_usb_ctrl, iforce_usb);
-
err = iforce_init_device(&intf->dev, BUS_USB, iforce);
if (err)
goto fail;
@@ -271,7 +249,6 @@ static int iforce_usb_probe(struct usb_interface *intf,
if (iforce_usb) {
usb_free_urb(iforce_usb->irq);
usb_free_urb(iforce_usb->out);
- usb_free_urb(iforce_usb->ctrl);
kfree(iforce_usb);
}
@@ -288,7 +265,6 @@ static void iforce_usb_disconnect(struct usb_interface *intf)
usb_free_urb(iforce_usb->irq);
usb_free_urb(iforce_usb->out);
- usb_free_urb(iforce_usb->ctrl);
kfree(iforce_usb);
}
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 08/20] Input: iforce - split into core and transport modules
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Now that we have moved enough transport details into separate source files
we can change them into transport modules so that they are only loaded when
needed.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/Kconfig | 8 ++---
drivers/input/joystick/iforce/Makefile | 7 ++--
drivers/input/joystick/iforce/iforce-main.c | 35 ++-----------------
.../input/joystick/iforce/iforce-packets.c | 2 ++
drivers/input/joystick/iforce/iforce-serio.c | 7 ++++
drivers/input/joystick/iforce/iforce-usb.c | 7 ++++
drivers/input/joystick/iforce/iforce.h | 2 --
7 files changed, 25 insertions(+), 43 deletions(-)
diff --git a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig
index ab4dbcbcbf50..55f6ae1da6b0 100644
--- a/drivers/input/joystick/iforce/Kconfig
+++ b/drivers/input/joystick/iforce/Kconfig
@@ -13,15 +13,15 @@ config JOYSTICK_IFORCE
module will be called iforce.
config JOYSTICK_IFORCE_USB
- bool "I-Force USB joysticks and wheels"
- depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || USB=y) && USB
+ tristate "I-Force USB joysticks and wheels"
+ depends on JOYSTICK_IFORCE && USB
help
Say Y here if you have an I-Force joystick or steering wheel
connected to your USB port.
config JOYSTICK_IFORCE_232
- bool "I-Force Serial joysticks and wheels"
- depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || SERIO=y) && SERIO
+ tristate "I-Force Serial joysticks and wheels"
+ depends on JOYSTICK_IFORCE && SERIO
help
Say Y here if you have an I-Force joystick or steering wheel
connected to your serial (COM) port.
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile
index bc5bda22f15e..414075019a4f 100644
--- a/drivers/input/joystick/iforce/Makefile
+++ b/drivers/input/joystick/iforce/Makefile
@@ -4,8 +4,7 @@
# By Johann Deneux <johann.deneux@gmail.com>
#
-obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
-
+obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
iforce-y := iforce-ff.o iforce-main.o iforce-packets.o
-iforce-$(CONFIG_JOYSTICK_IFORCE_232) += iforce-serio.o
-iforce-$(CONFIG_JOYSTICK_IFORCE_USB) += iforce-usb.o
+obj-$(CONFIG_JOYSTICK_IFORCE_232) += iforce-serio.o
+obj-$(CONFIG_JOYSTICK_IFORCE_USB) += iforce-usb.o
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 894769d03df3..3a0698327c42 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -24,7 +24,7 @@
#include "iforce.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
-MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
+MODULE_DESCRIPTION("Core I-Force joysticks and wheels driver");
MODULE_LICENSE("GPL");
static signed short btn_joystick[] =
@@ -411,35 +411,4 @@ int iforce_init_device(struct device *parent, u16 bustype,
fail: input_free_device(input_dev);
return error;
}
-
-static int __init iforce_init(void)
-{
- int err = 0;
-
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- err = usb_register(&iforce_usb_driver);
- if (err)
- return err;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- err = serio_register_driver(&iforce_serio_drv);
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- if (err)
- usb_deregister(&iforce_usb_driver);
-#endif
-#endif
- return err;
-}
-
-static void __exit iforce_exit(void)
-{
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- usb_deregister(&iforce_usb_driver);
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- serio_unregister_driver(&iforce_serio_drv);
-#endif
-}
-
-module_init(iforce_init);
-module_exit(iforce_exit);
+EXPORT_SYMBOL(iforce_init_device);
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 8a9a152bb595..70db273e5045 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -96,6 +96,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
return 0;
}
+EXPORT_SYMBOL(iforce_send_packet);
/* Start or stop an effect */
int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value)
@@ -203,3 +204,4 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
break;
}
}
+EXPORT_SYMBOL(iforce_process_packet);
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 6ff1bbeeb494..6c6411fbdc32 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/serio.h>
#include "iforce.h"
struct iforce_serio {
@@ -250,3 +251,9 @@ struct serio_driver iforce_serio_drv = {
.connect = iforce_serio_connect,
.disconnect = iforce_serio_disconnect,
};
+
+module_serio_driver(iforce_serio_drv);
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
+MODULE_DESCRIPTION("RS232 I-Force joysticks and wheels driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index d4e7a24922cd..9d635f01cf19 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/usb.h>
#include "iforce.h"
struct iforce_usb {
@@ -316,3 +317,9 @@ struct usb_driver iforce_usb_driver = {
.disconnect = iforce_usb_disconnect,
.id_table = iforce_usb_ids,
};
+
+module_usb_driver(iforce_usb_driver);
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
+MODULE_DESCRIPTION("USB I-Force joysticks and wheels driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index d9712c48ba74..3e3df83b9d77 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -26,8 +26,6 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <linux/usb.h>
-#include <linux/serio.h>
#include <linux/circ_buf.h>
#include <linux/mutex.h>
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 07/20] Input: iforce - move transport data into transport modules
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
This moves transport-specific data from main iforce structure into
transport modules.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-serio.c | 96 ++++++++-----
drivers/input/joystick/iforce/iforce-usb.c | 138 +++++++++++--------
drivers/input/joystick/iforce/iforce.h | 14 +-
3 files changed, 144 insertions(+), 104 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index b5dea273f98e..6ff1bbeeb494 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -23,8 +23,20 @@
#include "iforce.h"
+struct iforce_serio {
+ struct iforce iforce;
+
+ struct serio *serio;
+ int idx, pkt, len, id;
+ u8 csum;
+ u8 expect_packet;
+};
+
static void iforce_serio_xmit(struct iforce *iforce)
{
+ struct iforce_serio *iforce_serio = container_of(iforce,
+ struct iforce_serio,
+ iforce);
unsigned char cs;
int i;
unsigned long flags;
@@ -45,19 +57,20 @@ static void iforce_serio_xmit(struct iforce *iforce)
cs = 0x2b;
- serio_write(iforce->serio, 0x2b);
+ serio_write(iforce_serio->serio, 0x2b);
- serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]);
+ serio_write(iforce_serio->serio, iforce->xmit.buf[iforce->xmit.tail]);
cs ^= iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1);
for (i=iforce->xmit.buf[iforce->xmit.tail]; i >= 0; --i) {
- serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]);
+ serio_write(iforce_serio->serio,
+ iforce->xmit.buf[iforce->xmit.tail]);
cs ^= iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1);
}
- serio_write(iforce->serio, cs);
+ serio_write(iforce_serio->serio, cs);
if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
goto again;
@@ -69,14 +82,18 @@ static void iforce_serio_xmit(struct iforce *iforce)
static int iforce_serio_get_id(struct iforce *iforce, u8 *packet)
{
- iforce->expect_packet = FF_CMD_QUERY;
+ struct iforce_serio *iforce_serio = container_of(iforce,
+ struct iforce_serio,
+ iforce);
+
+ iforce_serio->expect_packet = HI(FF_CMD_QUERY);
iforce_send_packet(iforce, FF_CMD_QUERY, packet);
wait_event_interruptible_timeout(iforce->wait,
- !iforce->expect_packet, HZ);
+ !iforce_serio->expect_packet, HZ);
- if (iforce->expect_packet) {
- iforce->expect_packet = 0;
+ if (iforce_serio->expect_packet) {
+ iforce_serio->expect_packet = 0;
return -EIO;
}
@@ -111,54 +128,56 @@ static void iforce_serio_write_wakeup(struct serio *serio)
static irqreturn_t iforce_serio_irq(struct serio *serio,
unsigned char data, unsigned int flags)
{
- struct iforce *iforce = serio_get_drvdata(serio);
+ struct iforce_serio *iforce_serio = serio_get_drvdata(serio);
+ struct iforce *iforce = &iforce_serio->iforce;
- if (!iforce->pkt) {
+ if (!iforce_serio->pkt) {
if (data == 0x2b)
- iforce->pkt = 1;
+ iforce_serio->pkt = 1;
goto out;
}
- if (!iforce->id) {
+ if (!iforce_serio->id) {
if (data > 3 && data != 0xff)
- iforce->pkt = 0;
+ iforce_serio->pkt = 0;
else
- iforce->id = data;
+ iforce_serio->id = data;
goto out;
}
- if (!iforce->len) {
+ if (!iforce_serio->len) {
if (data > IFORCE_MAX_LENGTH) {
- iforce->pkt = 0;
- iforce->id = 0;
+ iforce_serio->pkt = 0;
+ iforce_serio->id = 0;
} else {
- iforce->len = data;
+ iforce_serio->len = data;
}
goto out;
}
- if (iforce->idx < iforce->len) {
- iforce->csum += iforce->data[iforce->idx++] = data;
+ if (iforce_serio->idx < iforce_serio->len) {
+ iforce->data[iforce_serio->idx++] = data;
+ iforce_serio->csum += data;
goto out;
}
- if (iforce->idx == iforce->len) {
- u16 cmd = (iforce->id << 8) | iforce->idx;
+ if (iforce_serio->idx == iforce_serio->len) {
+ u16 cmd = (iforce_serio->id << 8) | iforce_serio->idx;
/* Handle command completion */
- if (HI(iforce->expect_packet) == HI(cmd)) {
- iforce->expect_packet = 0;
+ if (iforce_serio->expect_packet == iforce_serio->id) {
+ iforce_serio->expect_packet = 0;
iforce->ecmd = cmd;
memcpy(iforce->edata, iforce->data, IFORCE_MAX_LENGTH);
}
iforce_process_packet(iforce, cmd, iforce->data);
- iforce->pkt = 0;
- iforce->id = 0;
- iforce->len = 0;
- iforce->idx = 0;
- iforce->csum = 0;
+ iforce_serio->pkt = 0;
+ iforce_serio->id = 0;
+ iforce_serio->len = 0;
+ iforce_serio->idx = 0;
+ iforce_serio->csum = 0;
}
out:
return IRQ_HANDLED;
@@ -166,18 +185,21 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
{
+ struct iforce_serio *iforce_serio;
struct iforce *iforce;
int err;
- iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL);
- if (!iforce)
+ iforce_serio = kzalloc(sizeof(*iforce_serio), GFP_KERNEL);
+ if (!iforce_serio)
return -ENOMEM;
+ iforce = &iforce_serio->iforce;
+
iforce->xport_ops = &iforce_serio_xport_ops;
iforce->bus = IFORCE_232;
- iforce->serio = serio;
- serio_set_drvdata(serio, iforce);
+ iforce_serio->serio = serio;
+ serio_set_drvdata(serio, iforce_serio);
err = serio_open(serio, drv);
if (err)
@@ -191,18 +213,18 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
fail2: serio_close(serio);
fail1: serio_set_drvdata(serio, NULL);
- kfree(iforce);
+ kfree(iforce_serio);
return err;
}
static void iforce_serio_disconnect(struct serio *serio)
{
- struct iforce *iforce = serio_get_drvdata(serio);
+ struct iforce_serio *iforce_serio = serio_get_drvdata(serio);
- input_unregister_device(iforce->dev);
+ input_unregister_device(iforce_serio->iforce.dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
- kfree(iforce);
+ kfree(iforce_serio);
}
static const struct serio_device_id iforce_serio_ids[] = {
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 824df4273774..d4e7a24922cd 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -23,8 +23,19 @@
#include "iforce.h"
+struct iforce_usb {
+ struct iforce iforce;
+
+ struct usb_device *usbdev;
+ struct usb_interface *intf;
+ struct urb *irq, *out, *ctrl;
+ struct usb_ctrlrequest cr;
+};
+
static void __iforce_usb_xmit(struct iforce *iforce)
{
+ struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
+ iforce);
int n, c;
unsigned long flags;
@@ -36,31 +47,32 @@ static void __iforce_usb_xmit(struct iforce *iforce)
return;
}
- ((char *)iforce->out->transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail];
+ ((char *)iforce_usb->out->transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1);
n = iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1);
- iforce->out->transfer_buffer_length = n + 1;
- iforce->out->dev = iforce->usbdev;
+ iforce_usb->out->transfer_buffer_length = n + 1;
+ iforce_usb->out->dev = iforce_usb->usbdev;
/* Copy rest of data then */
c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE);
if (n < c) c=n;
- memcpy(iforce->out->transfer_buffer + 1,
+ memcpy(iforce_usb->out->transfer_buffer + 1,
&iforce->xmit.buf[iforce->xmit.tail],
c);
if (n != c) {
- memcpy(iforce->out->transfer_buffer + 1 + c,
+ memcpy(iforce_usb->out->transfer_buffer + 1 + c,
&iforce->xmit.buf[0],
n-c);
}
XMIT_INC(iforce->xmit.tail, n);
- if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
+ if ( (n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC)) ) {
clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
- dev_warn(&iforce->intf->dev, "usb_submit_urb failed %d\n", n);
+ dev_warn(&iforce_usb->intf->dev,
+ "usb_submit_urb failed %d\n", n);
}
/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
@@ -77,26 +89,28 @@ static void iforce_usb_xmit(struct iforce *iforce)
static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
{
+ struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
+ iforce);
int status;
- iforce->cr.bRequest = packet[0];
- iforce->ctrl->dev = iforce->usbdev;
+ iforce_usb->cr.bRequest = packet[0];
+ iforce_usb->ctrl->dev = iforce_usb->usbdev;
- status = usb_submit_urb(iforce->ctrl, GFP_KERNEL);
+ status = usb_submit_urb(iforce_usb->ctrl, GFP_KERNEL);
if (status) {
- dev_err(&iforce->intf->dev,
+ dev_err(&iforce_usb->intf->dev,
"usb_submit_urb failed %d\n", status);
return -EIO;
}
wait_event_interruptible_timeout(iforce->wait,
- iforce->ctrl->status != -EINPROGRESS, HZ);
+ iforce_usb->ctrl->status != -EINPROGRESS, HZ);
- if (iforce->ctrl->status) {
- dev_dbg(&iforce->intf->dev,
+ if (iforce_usb->ctrl->status) {
+ dev_dbg(&iforce_usb->intf->dev,
"iforce->ctrl->status = %d\n",
- iforce->ctrl->status);
- usb_unlink_urb(iforce->ctrl);
+ iforce_usb->ctrl->status);
+ usb_unlink_urb(iforce_usb->ctrl);
return -EIO;
}
@@ -105,7 +119,10 @@ static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
static int iforce_usb_start_io(struct iforce *iforce)
{
- if (usb_submit_urb(iforce->irq, GFP_KERNEL))
+ struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
+ iforce);
+
+ if (usb_submit_urb(iforce_usb->irq, GFP_KERNEL))
return -EIO;
return 0;
@@ -113,9 +130,12 @@ static int iforce_usb_start_io(struct iforce *iforce)
static void iforce_usb_stop_io(struct iforce *iforce)
{
- usb_kill_urb(iforce->irq);
- usb_kill_urb(iforce->out);
- usb_kill_urb(iforce->ctrl);
+ struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
+ iforce);
+
+ usb_kill_urb(iforce_usb->irq);
+ usb_kill_urb(iforce_usb->out);
+ usb_kill_urb(iforce_usb->ctrl);
}
static const struct iforce_xport_ops iforce_usb_xport_ops = {
@@ -127,8 +147,9 @@ static const struct iforce_xport_ops iforce_usb_xport_ops = {
static void iforce_usb_irq(struct urb *urb)
{
- struct iforce *iforce = urb->context;
- struct device *dev = &iforce->intf->dev;
+ struct iforce_usb *iforce_usb = urb->context;
+ struct iforce *iforce = &iforce_usb->iforce;
+ struct device *dev = &iforce_usb->intf->dev;
int status;
switch (urb->status) {
@@ -152,7 +173,7 @@ static void iforce_usb_irq(struct urb *urb)
(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
exit:
- status = usb_submit_urb (urb, GFP_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status)
dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
__func__, status);
@@ -160,11 +181,12 @@ static void iforce_usb_irq(struct urb *urb)
static void iforce_usb_out(struct urb *urb)
{
- struct iforce *iforce = urb->context;
+ struct iforce_usb *iforce_usb = urb->context;
+ struct iforce *iforce = &iforce_usb->iforce;
if (urb->status) {
clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
- dev_dbg(&iforce->intf->dev, "urb->status %d, exiting\n",
+ dev_dbg(&iforce_usb->intf->dev, "urb->status %d, exiting\n",
urb->status);
return;
}
@@ -176,8 +198,12 @@ static void iforce_usb_out(struct urb *urb)
static void iforce_usb_ctrl(struct urb *urb)
{
- struct iforce *iforce = urb->context;
- if (urb->status) return;
+ struct iforce_usb *iforce_usb = urb->context;
+ struct iforce *iforce = &iforce_usb->iforce;
+
+ if (urb->status)
+ return;
+
iforce->ecmd = 0xff00 | urb->actual_length;
wake_up(&iforce->wait);
}
@@ -188,6 +214,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *epirq, *epout;
+ struct iforce_usb *iforce_usb;
struct iforce *iforce;
int err = -ENOMEM;
@@ -199,49 +226,52 @@ static int iforce_usb_probe(struct usb_interface *intf,
epirq = &interface->endpoint[0].desc;
epout = &interface->endpoint[1].desc;
- if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
+ if (!(iforce_usb = kzalloc(sizeof(*iforce_usb) + 32, GFP_KERNEL)))
goto fail;
- if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL)))
+ if (!(iforce_usb->irq = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL)))
+ if (!(iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
- if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
+ if (!(iforce_usb->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
+ iforce = &iforce_usb->iforce;
+
iforce->xport_ops = &iforce_usb_xport_ops;
iforce->bus = IFORCE_USB;
- iforce->usbdev = dev;
- iforce->intf = intf;
- iforce->cr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
- iforce->cr.wIndex = 0;
- iforce->cr.wLength = cpu_to_le16(16);
+ iforce_usb->usbdev = dev;
+ iforce_usb->intf = intf;
+
+ iforce_usb->cr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
+ iforce_usb->cr.wIndex = 0;
+ iforce_usb->cr.wLength = cpu_to_le16(16);
- usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
- iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
+ usb_fill_int_urb(iforce_usb->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
+ iforce->data, 16, iforce_usb_irq, iforce_usb, epirq->bInterval);
- usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
- iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval);
+ usb_fill_int_urb(iforce_usb->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
+ iforce_usb + 1, 32, iforce_usb_out, iforce_usb, epout->bInterval);
- usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
- (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
+ usb_fill_control_urb(iforce_usb->ctrl, dev, usb_rcvctrlpipe(dev, 0),
+ (void*) &iforce_usb->cr, iforce->edata, 16, iforce_usb_ctrl, iforce_usb);
err = iforce_init_device(&intf->dev, BUS_USB, iforce);
if (err)
goto fail;
- usb_set_intfdata(intf, iforce);
+ usb_set_intfdata(intf, iforce_usb);
return 0;
fail:
- if (iforce) {
- usb_free_urb(iforce->irq);
- usb_free_urb(iforce->out);
- usb_free_urb(iforce->ctrl);
- kfree(iforce);
+ if (iforce_usb) {
+ usb_free_urb(iforce_usb->irq);
+ usb_free_urb(iforce_usb->out);
+ usb_free_urb(iforce_usb->ctrl);
+ kfree(iforce_usb);
}
return err;
@@ -249,17 +279,17 @@ static int iforce_usb_probe(struct usb_interface *intf,
static void iforce_usb_disconnect(struct usb_interface *intf)
{
- struct iforce *iforce = usb_get_intfdata(intf);
+ struct iforce_usb *iforce_usb = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
- input_unregister_device(iforce->dev);
+ input_unregister_device(iforce_usb->iforce.dev);
- usb_free_urb(iforce->irq);
- usb_free_urb(iforce->out);
- usb_free_urb(iforce->ctrl);
+ usb_free_urb(iforce_usb->irq);
+ usb_free_urb(iforce_usb->out);
+ usb_free_urb(iforce_usb->ctrl);
- kfree(iforce);
+ kfree(iforce_usb);
}
static const struct usb_device_id iforce_usb_ids[] = {
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 3ee9245a415b..d9712c48ba74 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -111,19 +111,7 @@ struct iforce {
unsigned char data[IFORCE_MAX_LENGTH];
unsigned char edata[IFORCE_MAX_LENGTH];
u16 ecmd;
- u16 expect_packet;
-
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- struct serio *serio; /* RS232 transfer */
- int idx, pkt, len, id;
- unsigned char csum;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- struct usb_device *usbdev; /* USB transfer */
- struct usb_interface *intf;
- struct urb *irq, *out, *ctrl;
- struct usb_ctrlrequest cr;
-#endif
+
spinlock_t xmit_lock;
/* Buffer used for asynchronous sending of bytes to the device */
struct circ_buf xmit;
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 06/20] Input: iforce - add bus type and parent arguments to iforce_init_device()
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Note that the parent device for the USB-connected controllers is now
USB interface instead of USB device.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-main.c | 19 ++++---------------
drivers/input/joystick/iforce/iforce-serio.c | 2 +-
drivers/input/joystick/iforce/iforce-usb.c | 2 +-
drivers/input/joystick/iforce/iforce.h | 3 ++-
4 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 4401ca4a4c38..894769d03df3 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -221,7 +221,8 @@ static void iforce_close(struct input_dev *dev)
iforce->xport_ops->stop_io(iforce);
}
-int iforce_init_device(struct iforce *iforce)
+int iforce_init_device(struct device *parent, u16 bustype,
+ struct iforce *iforce)
{
struct input_dev *input_dev;
struct ff_device *ff;
@@ -243,20 +244,8 @@ int iforce_init_device(struct iforce *iforce)
* Input device fields.
*/
- switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- case IFORCE_USB:
- input_dev->id.bustype = BUS_USB;
- input_dev->dev.parent = &iforce->usbdev->dev;
- break;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- case IFORCE_232:
- input_dev->id.bustype = BUS_RS232;
- input_dev->dev.parent = &iforce->serio->dev;
- break;
-#endif
- }
+ input_dev->id.bustype = bustype;
+ input_dev->dev.parent = parent;
input_set_drvdata(input_dev, iforce);
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index afc7521b430d..b5dea273f98e 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -183,7 +183,7 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
if (err)
goto fail1;
- err = iforce_init_device(iforce);
+ err = iforce_init_device(&serio->dev, BUS_RS232, iforce);
if (err)
goto fail2;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 10b583b5fc82..824df4273774 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -229,7 +229,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
- err = iforce_init_device(iforce);
+ err = iforce_init_device(&intf->dev, BUS_USB, iforce);
if (err)
goto fail;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index c020d61eccf2..3ee9245a415b 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -156,7 +156,8 @@ static inline int iforce_get_id_packet(struct iforce *iforce, u8* id)
/* Public functions */
/* iforce-main.c */
-int iforce_init_device(struct iforce *iforce);
+int iforce_init_device(struct device *parent, u16 bustype,
+ struct iforce *iforce);
/* iforce-packets.c */
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 05/20] Input: iforce - introduce start and stop io transport ops
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Add start_io() and stop_io() transport methods so that core
does not have to know the details.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-main.c | 25 ++------------------
drivers/input/joystick/iforce/iforce-serio.c | 13 ++++++++++
drivers/input/joystick/iforce/iforce-usb.c | 17 +++++++++++++
drivers/input/joystick/iforce/iforce.h | 2 ++
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 58d5cfe46526..4401ca4a4c38 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -185,15 +185,7 @@ static int iforce_open(struct input_dev *dev)
{
struct iforce *iforce = input_get_drvdata(dev);
- switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- case IFORCE_USB:
- iforce->irq->dev = iforce->usbdev;
- if (usb_submit_urb(iforce->irq, GFP_KERNEL))
- return -EIO;
- break;
-#endif
- }
+ iforce->xport_ops->start_io(iforce);
if (test_bit(EV_FF, dev->evbit)) {
/* Enable force feedback */
@@ -226,20 +218,7 @@ static void iforce_close(struct input_dev *dev)
!test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags));
}
- switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- case IFORCE_USB:
- usb_kill_urb(iforce->irq);
- usb_kill_urb(iforce->out);
- usb_kill_urb(iforce->ctrl);
- break;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- case IFORCE_232:
- //TODO: Wait for the last packets to be sent
- break;
-#endif
- }
+ iforce->xport_ops->stop_io(iforce);
}
int iforce_init_device(struct iforce *iforce)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index eca2f6eca7f0..afc7521b430d 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -83,9 +83,22 @@ static int iforce_serio_get_id(struct iforce *iforce, u8 *packet)
return -(iforce->edata[0] != packet[0]);
}
+static int iforce_serio_start_io(struct iforce *iforce)
+{
+ /* No special handling required */
+ return 0;
+}
+
+static void iforce_serio_stop_io(struct iforce *iforce)
+{
+ //TODO: Wait for the last packets to be sent
+}
+
static const struct iforce_xport_ops iforce_serio_xport_ops = {
.xmit = iforce_serio_xmit,
.get_id = iforce_serio_get_id,
+ .start_io = iforce_serio_start_io,
+ .stop_io = iforce_serio_stop_io,
};
static void iforce_serio_write_wakeup(struct serio *serio)
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index f7eeaad92602..10b583b5fc82 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -103,9 +103,26 @@ static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
return -(iforce->edata[0] != packet[0]);
}
+static int iforce_usb_start_io(struct iforce *iforce)
+{
+ if (usb_submit_urb(iforce->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void iforce_usb_stop_io(struct iforce *iforce)
+{
+ usb_kill_urb(iforce->irq);
+ usb_kill_urb(iforce->out);
+ usb_kill_urb(iforce->ctrl);
+}
+
static const struct iforce_xport_ops iforce_usb_xport_ops = {
.xmit = iforce_usb_xmit,
.get_id = iforce_usb_get_id,
+ .start_io = iforce_usb_start_io,
+ .stop_io = iforce_usb_stop_io,
};
static void iforce_usb_irq(struct urb *urb)
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index f6636230be31..c020d61eccf2 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -98,6 +98,8 @@ struct iforce;
struct iforce_xport_ops {
void (*xmit)(struct iforce *iforce);
int (*get_id)(struct iforce *iforce, u8* id);
+ int (*start_io)(struct iforce *iforce);
+ void (*stop_io)(struct iforce *iforce);
};
struct iforce {
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 04/20] Input: iforce - move command completion handling to serio code
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
Continue teasing apart protocol-specific bits from core into transport
modules. This time move RS232-specific command completion handling
from core to iforce-serio module.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/joystick/iforce/iforce-packets.c | 7 -------
drivers/input/joystick/iforce/iforce-serio.c | 12 +++++++++++-
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index e677562efc9a..8a9a152bb595 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -134,13 +134,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
struct input_dev *dev = iforce->dev;
int i;
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- if (HI(iforce->expect_packet) == HI(cmd)) {
- iforce->expect_packet = 0;
- iforce->ecmd = cmd;
- memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
- }
-#endif
wake_up(&iforce->wait);
if (!iforce->type)
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index fa45ce425d47..eca2f6eca7f0 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -130,7 +130,17 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
}
if (iforce->idx == iforce->len) {
- iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
+ u16 cmd = (iforce->id << 8) | iforce->idx;
+
+ /* Handle command completion */
+ if (HI(iforce->expect_packet) == HI(cmd)) {
+ iforce->expect_packet = 0;
+ iforce->ecmd = cmd;
+ memcpy(iforce->edata, iforce->data, IFORCE_MAX_LENGTH);
+ }
+
+ iforce_process_packet(iforce, cmd, iforce->data);
+
iforce->pkt = 0;
iforce->id = 0;
iforce->len = 0;
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 03/20] Input: iforce - move get_id to the transport operations
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
To avoid #ifdef-ing out parts of the code and having conditionals in normal
control flow, let's define "get_id" transport method and move
implementation into respective transport modules.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
.../input/joystick/iforce/iforce-packets.c | 64 -------------------
drivers/input/joystick/iforce/iforce-serio.c | 17 +++++
drivers/input/joystick/iforce/iforce-usb.c | 29 +++++++++
drivers/input/joystick/iforce/iforce.h | 6 +-
4 files changed, 51 insertions(+), 65 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index b8ca9bdfdef8..e677562efc9a 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -210,67 +210,3 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
break;
}
}
-
-int iforce_get_id_packet(struct iforce *iforce, char *packet)
-{
- switch (iforce->bus) {
-
- case IFORCE_USB: {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- int status;
-
- iforce->cr.bRequest = packet[0];
- iforce->ctrl->dev = iforce->usbdev;
-
- status = usb_submit_urb(iforce->ctrl, GFP_KERNEL);
- if (status) {
- dev_err(&iforce->intf->dev,
- "usb_submit_urb failed %d\n", status);
- return -1;
- }
-
- wait_event_interruptible_timeout(iforce->wait,
- iforce->ctrl->status != -EINPROGRESS, HZ);
-
- if (iforce->ctrl->status) {
- dev_dbg(&iforce->intf->dev,
- "iforce->ctrl->status = %d\n",
- iforce->ctrl->status);
- usb_unlink_urb(iforce->ctrl);
- return -1;
- }
-#else
- printk(KERN_DEBUG "iforce_get_id_packet: iforce->bus = USB!\n");
-#endif
- }
- break;
-
- case IFORCE_232:
-
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- iforce->expect_packet = FF_CMD_QUERY;
- iforce_send_packet(iforce, FF_CMD_QUERY, packet);
-
- wait_event_interruptible_timeout(iforce->wait,
- !iforce->expect_packet, HZ);
-
- if (iforce->expect_packet) {
- iforce->expect_packet = 0;
- return -1;
- }
-#else
- dev_err(&iforce->dev->dev,
- "iforce_get_id_packet: iforce->bus = SERIO!\n");
-#endif
- break;
-
- default:
- dev_err(&iforce->dev->dev,
- "iforce_get_id_packet: iforce->bus = %d\n",
- iforce->bus);
- break;
- }
-
- return -(iforce->edata[0] != packet[0]);
-}
-
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index c9469209f994..fa45ce425d47 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -67,8 +67,25 @@ static void iforce_serio_xmit(struct iforce *iforce)
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
}
+static int iforce_serio_get_id(struct iforce *iforce, u8 *packet)
+{
+ iforce->expect_packet = FF_CMD_QUERY;
+ iforce_send_packet(iforce, FF_CMD_QUERY, packet);
+
+ wait_event_interruptible_timeout(iforce->wait,
+ !iforce->expect_packet, HZ);
+
+ if (iforce->expect_packet) {
+ iforce->expect_packet = 0;
+ return -EIO;
+ }
+
+ return -(iforce->edata[0] != packet[0]);
+}
+
static const struct iforce_xport_ops iforce_serio_xport_ops = {
.xmit = iforce_serio_xmit,
+ .get_id = iforce_serio_get_id,
};
static void iforce_serio_write_wakeup(struct serio *serio)
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index d4f7f34db9a0..f7eeaad92602 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -75,8 +75,37 @@ static void iforce_usb_xmit(struct iforce *iforce)
__iforce_usb_xmit(iforce);
}
+static int iforce_usb_get_id(struct iforce *iforce, u8 *packet)
+{
+ int status;
+
+ iforce->cr.bRequest = packet[0];
+ iforce->ctrl->dev = iforce->usbdev;
+
+ status = usb_submit_urb(iforce->ctrl, GFP_KERNEL);
+ if (status) {
+ dev_err(&iforce->intf->dev,
+ "usb_submit_urb failed %d\n", status);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(iforce->wait,
+ iforce->ctrl->status != -EINPROGRESS, HZ);
+
+ if (iforce->ctrl->status) {
+ dev_dbg(&iforce->intf->dev,
+ "iforce->ctrl->status = %d\n",
+ iforce->ctrl->status);
+ usb_unlink_urb(iforce->ctrl);
+ return -EIO;
+ }
+
+ return -(iforce->edata[0] != packet[0]);
+}
+
static const struct iforce_xport_ops iforce_usb_xport_ops = {
.xmit = iforce_usb_xmit,
+ .get_id = iforce_usb_get_id,
};
static void iforce_usb_irq(struct urb *urb)
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 2fea3be751ed..f6636230be31 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -97,6 +97,7 @@ struct iforce;
struct iforce_xport_ops {
void (*xmit)(struct iforce *iforce);
+ int (*get_id)(struct iforce *iforce, u8* id);
};
struct iforce {
@@ -146,6 +147,10 @@ struct iforce {
/* Encode a time value */
#define TIME_SCALE(a) (a)
+static inline int iforce_get_id_packet(struct iforce *iforce, u8* id)
+{
+ return iforce->xport_ops->get_id(iforce, id);
+}
/* Public functions */
/* iforce-main.c */
@@ -156,7 +161,6 @@ int iforce_control_playback(struct iforce*, u16 id, unsigned int);
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
void iforce_dump_packet(struct iforce *iforce, char *msg, u16 cmd, unsigned char *data);
-int iforce_get_id_packet(struct iforce *iforce, char *packet);
/* iforce-ff.c */
int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *);
--
2.19.0.397.gdd90340f6a-goog
^ permalink raw reply related
* [PATCH 02/20] Input: iforce - introduce transport ops
From: Dmitry Torokhov @ 2018-09-18 0:47 UTC (permalink / raw)
To: linux-input, Tim Schumacher; +Cc: linux-kernel
In-Reply-To: <20180918004732.9875-1-dmitry.torokhov@gmail.com>
In order to tease apart the driver into core and transport modules, let's
introduce transport operations and make "xmit" the very first one such
operation.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
.../input/joystick/iforce/iforce-packets.c | 20 ++-----------------
drivers/input/joystick/iforce/iforce-serio.c | 9 +++++++--
drivers/input/joystick/iforce/iforce-usb.c | 15 ++++++++++++--
drivers/input/joystick/iforce/iforce.h | 13 ++++++------
4 files changed, 29 insertions(+), 28 deletions(-)
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 91893c751524..b8ca9bdfdef8 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -91,25 +91,9 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
/*
* If necessary, start the transmission
*/
- switch (iforce->bus) {
-
-#ifdef CONFIG_JOYSTICK_IFORCE_232
- case IFORCE_232:
- if (empty)
- iforce_serial_xmit(iforce);
- break;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
- case IFORCE_USB:
+ if (empty)
+ iforce->xport_ops->xmit(iforce);
- if (iforce->usbdev && empty &&
- !test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
-
- iforce_usb_xmit(iforce);
- }
- break;
-#endif
- }
return 0;
}
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index f4ba4a751fe0..c9469209f994 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -23,7 +23,7 @@
#include "iforce.h"
-void iforce_serial_xmit(struct iforce *iforce)
+static void iforce_serio_xmit(struct iforce *iforce)
{
unsigned char cs;
int i;
@@ -67,11 +67,15 @@ void iforce_serial_xmit(struct iforce *iforce)
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
}
+static const struct iforce_xport_ops iforce_serio_xport_ops = {
+ .xmit = iforce_serio_xmit,
+};
+
static void iforce_serio_write_wakeup(struct serio *serio)
{
struct iforce *iforce = serio_get_drvdata(serio);
- iforce_serial_xmit(iforce);
+ iforce_serio_xmit(iforce);
}
static irqreturn_t iforce_serio_irq(struct serio *serio,
@@ -129,6 +133,7 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
if (!iforce)
return -ENOMEM;
+ iforce->xport_ops = &iforce_serio_xport_ops;
iforce->bus = IFORCE_232;
iforce->serio = serio;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 78073259c9a1..d4f7f34db9a0 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -23,7 +23,7 @@
#include "iforce.h"
-void iforce_usb_xmit(struct iforce *iforce)
+static void __iforce_usb_xmit(struct iforce *iforce)
{
int n, c;
unsigned long flags;
@@ -69,6 +69,16 @@ void iforce_usb_xmit(struct iforce *iforce)
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
}
+static void iforce_usb_xmit(struct iforce *iforce)
+{
+ if (!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags))
+ __iforce_usb_xmit(iforce);
+}
+
+static const struct iforce_xport_ops iforce_usb_xport_ops = {
+ .xmit = iforce_usb_xmit,
+};
+
static void iforce_usb_irq(struct urb *urb)
{
struct iforce *iforce = urb->context;
@@ -113,7 +123,7 @@ static void iforce_usb_out(struct urb *urb)
return;
}
- iforce_usb_xmit(iforce);
+ __iforce_usb_xmit(iforce);
wake_up(&iforce->wait);
}
@@ -155,6 +165,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
goto fail;
+ iforce->xport_ops = &iforce_usb_xport_ops;
iforce->bus = IFORCE_USB;
iforce->usbdev = dev;
iforce->intf = intf;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 0e9d01f8bcb6..2fea3be751ed 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -93,9 +93,16 @@ struct iforce_device {
signed short *ff;
};
+struct iforce;
+
+struct iforce_xport_ops {
+ void (*xmit)(struct iforce *iforce);
+};
+
struct iforce {
struct input_dev *dev; /* Input device interface */
struct iforce_device *type;
+ const struct iforce_xport_ops *xport_ops;
int bus;
unsigned char data[IFORCE_MAX_LENGTH];
@@ -141,12 +148,6 @@ struct iforce {
/* Public functions */
-/* iforce-serio.c */
-void iforce_serial_xmit(struct iforce *iforce);
-
-/* iforce-usb.c */
-void iforce_usb_xmit(struct iforce *iforce);
-
/* iforce-main.c */
int iforce_init_device(struct iforce *iforce);
--
2.19.0.397.gdd90340f6a-goog
^ 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