* Re: [Question: Drivers/input/evdev.c] What is the use of write function in evdev_fops?
From: Dmitry Torokhov @ 2014-08-14 20:19 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: linux-input@vger.kernel.org
In-Reply-To: <CADYu30_oB94oORguEu3+Ri4YFu6Vuo1qBvsmFmFbSpZufJ49aQ@mail.gmail.com>
On Fri, Aug 15, 2014 at 12:55:35AM +0530, Aniroop Mathur wrote:
> On Thu, Aug 14, 2014 at 1:12 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> > On August 13, 2014 12:28:46 PM PDT, Aniroop Mathur <aniroop.mathur@gmail.com> wrote:
> >>On Thu, Aug 14, 2014 at 12:50 AM, Dmitry Torokhov
> >><dmitry.torokhov@gmail.com> wrote:
> >>> On August 13, 2014 12:10:16 PM PDT, Aniroop Mathur
> >><aniroop.mathur@gmail.com> wrote:
> >>>>On Thu, Aug 14, 2014 at 12:28 AM, Dmitry Torokhov
> >>>><dmitry.torokhov@gmail.com> wrote:
> >>>>> On Wed, Aug 13, 2014 at 11:41:20PM +0530, Aniroop Mathur wrote:
> >>>>>> Hello Mr. Torokhov :)
> >>>>>>
> >>>>>> On Wed, Aug 13, 2014 at 10:36 PM, Dmitry Torokhov
> >>>>>> <dmitry.torokhov@gmail.com> wrote:
> >>>>>> > Hi Aniroop,
> >>>>>> >
> >>>>>> > On Wed, Aug 13, 2014 at 10:16:34PM +0530, Aniroop Mathur wrote:
> >>>>>> >> Dear Mr. Torokhov and Linux-Input Community,
> >>>>>> >> Greetings of the day !! :)
> >>>>>> >>
> >>>>>> >> I have not seen some good use of write function in input
> >>>>subsystem.
> >>>>>> >> I am trying find the good uses of write function in Input
> >>>>subsystem,
> >>>>>> >> but could not find the solution over internet.
> >>>>>> >> Can you please help in answering my query below:
> >>>>>> >>
> >>>>>> >> As you know, in evdev.c file, fops is defined as below
> >>>>>> >> struct file_operations evdev_fops = {
> >>>>>> >> .read = evdev_read,
> >>>>>> >> .write = evdev_write,
> >>>>>> >> ...
> >>>>>> >> }
> >>>>>> >>
> >>>>>> >> So in what cases, evdev_write function is used ?
> >>>>>> >> One case I can think of is that, it can be used in input device
> >>>>simulator
> >>>>>> >> to write the recorded data back into buffer.
> >>>>>> >
> >>>>>> > You are right, majority of times you are reading from the
> >>buffer.
> >>>>Still,
> >>>>>> > sometimes you want to control hardware state, for example,
> >>toggle
> >>>>keyboard LED.
> >>>>>> > That can be achieved by writing appropriate event to the event
> >>>>device.
> >>>>>> >
> >>>>>>
> >>>>>> Okay. :)
> >>>>>> So it means application upon receiving some key value,
> >>>>>> it can write EV_LED type of event to keyboard input device node
> >>>>>> and if dev->event function is defined in driver, driver can
> >>request
> >>>>>> hardware to toggle led.
> >>>>>> Similarly, it can be done for cases like sound (EV_SND, force
> >>>>>> feedback(EV_FF), etc
> >>>>>> Right ?
> >>>>>
> >>>>> Yes.
> >>>>>
> >>>>>>
> >>>>>> > For simulators I think uinput is suited the best.
> >>>>>> >
> >>>>>>
> >>>>>> As i know, in case of uinput, there is only one device node
> >>>>>> /dev/uinput or /dev/input/uinput.
> >>>>>> and to distinguish the events, we can use event type and code.
> >>>>>>
> >>>>>> But, if we are simulating multiple devices together like
> >>>>>> accelerometer, gyro, mag, light, compass, etc
> >>>>>> then any two devices can have same event type and code.
> >>>>>> Like accel and gyro can both have EV_REL and REL_X/Y/Z.
> >>>>>> In such a case, we won't be able to distinguish between accel and
> >>>>gyro events.
> >>>>>>
> >>>>>> Instead if we use accel and gyro separate device nodes,
> >>>>>> there is no such problem because device nodes itself are
> >>different.
> >>>>:)
> >>>>>> So for such case, I think simulation through proper device node is
> >>>>better.
> >>>>>
> >>>>> Even though there is only one /dev/input/uinput every user (an
> >>entity
> >>>>> opening that device node) will end up creating it's very own and
> >>>>> separate input device, with separate bitmasks, events, etc, etc.
> >>>>>
> >>>>
> >>>>How to use bitmasks to distinguish between two events ?
> >>>>In below code, I can only see type and code as
> >>>>identification variables.
> >>>>Can we use bitmask too here ?
> >>>>
> >>>>fd = open("/dev/uinput", O_RDWR);
> >>>>
> >>>
> >>> You need to open 2 separate file descriptors.
> >>>
> >>
> >>2 separate file descriptors like below ?
> >>int fd1 = open("/dev/uinput", O_RDWR);
> >>int fd2 = open("/dev/uinput", O_RDWR);
> >>
> >>But my reading data will still come in struct input_event as mentioned
> >>above.
> >>It has only time, type, code and value.
> >>So, how we can use bitmask here ?
> >>
> >>struct input_event {
> >>struct timeval time;
> >>__u16 type;
> >>__u16 code;
> >>__s32 value;
> >> };
> >
> > By opening 2 fds you'll end up creating 2 separate input devices with separate evdev nodes, etc, so you will not mix up input events.
> >
> > I think at this time you should just try actually using uinput and that should clear things for you.
> >
>
> Can you please explain what do you mean by separate evdev nodes ?
> Do you mean two separate evdev nodes for uinput ?
> But as we discussed before, there is only one node in case of uinput
> i.e. /dev/uinput.
Uinput allows to creating input devices driven from userspace. You can
create as many separate input devices as you want by opening
/dev/uinput several times since it creates a device per file descriptor.
Each of these input devices will get evdev attached to it and will get
it's own /dev/input/eventX node created.
Really, please try using uinput, it will clear a lot if things for you.
For example, see what http://www.freedesktop.org/wiki/Evemu/ does.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [Question: Drivers/input/evdev.c] What is the use of write function in evdev_fops?
From: Aniroop Mathur @ 2014-08-14 20:31 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org
In-Reply-To: <20140814201903.GB13458@core.coreip.homeip.net>
On Fri, Aug 15, 2014 at 1:49 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Fri, Aug 15, 2014 at 12:55:35AM +0530, Aniroop Mathur wrote:
>> On Thu, Aug 14, 2014 at 1:12 AM, Dmitry Torokhov
>> <dmitry.torokhov@gmail.com> wrote:
>> > On August 13, 2014 12:28:46 PM PDT, Aniroop Mathur <aniroop.mathur@gmail.com> wrote:
>> >>On Thu, Aug 14, 2014 at 12:50 AM, Dmitry Torokhov
>> >><dmitry.torokhov@gmail.com> wrote:
>> >>> On August 13, 2014 12:10:16 PM PDT, Aniroop Mathur
>> >><aniroop.mathur@gmail.com> wrote:
>> >>>>On Thu, Aug 14, 2014 at 12:28 AM, Dmitry Torokhov
>> >>>><dmitry.torokhov@gmail.com> wrote:
>> >>>>> On Wed, Aug 13, 2014 at 11:41:20PM +0530, Aniroop Mathur wrote:
>> >>>>>> Hello Mr. Torokhov :)
>> >>>>>>
>> >>>>>> On Wed, Aug 13, 2014 at 10:36 PM, Dmitry Torokhov
>> >>>>>> <dmitry.torokhov@gmail.com> wrote:
>> >>>>>> > Hi Aniroop,
>> >>>>>> >
>> >>>>>> > On Wed, Aug 13, 2014 at 10:16:34PM +0530, Aniroop Mathur wrote:
>> >>>>>> >> Dear Mr. Torokhov and Linux-Input Community,
>> >>>>>> >> Greetings of the day !! :)
>> >>>>>> >>
>> >>>>>> >> I have not seen some good use of write function in input
>> >>>>subsystem.
>> >>>>>> >> I am trying find the good uses of write function in Input
>> >>>>subsystem,
>> >>>>>> >> but could not find the solution over internet.
>> >>>>>> >> Can you please help in answering my query below:
>> >>>>>> >>
>> >>>>>> >> As you know, in evdev.c file, fops is defined as below
>> >>>>>> >> struct file_operations evdev_fops = {
>> >>>>>> >> .read = evdev_read,
>> >>>>>> >> .write = evdev_write,
>> >>>>>> >> ...
>> >>>>>> >> }
>> >>>>>> >>
>> >>>>>> >> So in what cases, evdev_write function is used ?
>> >>>>>> >> One case I can think of is that, it can be used in input device
>> >>>>simulator
>> >>>>>> >> to write the recorded data back into buffer.
>> >>>>>> >
>> >>>>>> > You are right, majority of times you are reading from the
>> >>buffer.
>> >>>>Still,
>> >>>>>> > sometimes you want to control hardware state, for example,
>> >>toggle
>> >>>>keyboard LED.
>> >>>>>> > That can be achieved by writing appropriate event to the event
>> >>>>device.
>> >>>>>> >
>> >>>>>>
>> >>>>>> Okay. :)
>> >>>>>> So it means application upon receiving some key value,
>> >>>>>> it can write EV_LED type of event to keyboard input device node
>> >>>>>> and if dev->event function is defined in driver, driver can
>> >>request
>> >>>>>> hardware to toggle led.
>> >>>>>> Similarly, it can be done for cases like sound (EV_SND, force
>> >>>>>> feedback(EV_FF), etc
>> >>>>>> Right ?
>> >>>>>
>> >>>>> Yes.
>> >>>>>
>> >>>>>>
>> >>>>>> > For simulators I think uinput is suited the best.
>> >>>>>> >
>> >>>>>>
>> >>>>>> As i know, in case of uinput, there is only one device node
>> >>>>>> /dev/uinput or /dev/input/uinput.
>> >>>>>> and to distinguish the events, we can use event type and code.
>> >>>>>>
>> >>>>>> But, if we are simulating multiple devices together like
>> >>>>>> accelerometer, gyro, mag, light, compass, etc
>> >>>>>> then any two devices can have same event type and code.
>> >>>>>> Like accel and gyro can both have EV_REL and REL_X/Y/Z.
>> >>>>>> In such a case, we won't be able to distinguish between accel and
>> >>>>gyro events.
>> >>>>>>
>> >>>>>> Instead if we use accel and gyro separate device nodes,
>> >>>>>> there is no such problem because device nodes itself are
>> >>different.
>> >>>>:)
>> >>>>>> So for such case, I think simulation through proper device node is
>> >>>>better.
>> >>>>>
>> >>>>> Even though there is only one /dev/input/uinput every user (an
>> >>entity
>> >>>>> opening that device node) will end up creating it's very own and
>> >>>>> separate input device, with separate bitmasks, events, etc, etc.
>> >>>>>
>> >>>>
>> >>>>How to use bitmasks to distinguish between two events ?
>> >>>>In below code, I can only see type and code as
>> >>>>identification variables.
>> >>>>Can we use bitmask too here ?
>> >>>>
>> >>>>fd = open("/dev/uinput", O_RDWR);
>> >>>>
>> >>>
>> >>> You need to open 2 separate file descriptors.
>> >>>
>> >>
>> >>2 separate file descriptors like below ?
>> >>int fd1 = open("/dev/uinput", O_RDWR);
>> >>int fd2 = open("/dev/uinput", O_RDWR);
>> >>
>> >>But my reading data will still come in struct input_event as mentioned
>> >>above.
>> >>It has only time, type, code and value.
>> >>So, how we can use bitmask here ?
>> >>
>> >>struct input_event {
>> >>struct timeval time;
>> >>__u16 type;
>> >>__u16 code;
>> >>__s32 value;
>> >> };
>> >
>> > By opening 2 fds you'll end up creating 2 separate input devices with separate evdev nodes, etc, so you will not mix up input events.
>> >
>> > I think at this time you should just try actually using uinput and that should clear things for you.
>> >
>>
>> Can you please explain what do you mean by separate evdev nodes ?
>> Do you mean two separate evdev nodes for uinput ?
>> But as we discussed before, there is only one node in case of uinput
>> i.e. /dev/uinput.
>
> Uinput allows to creating input devices driven from userspace. You can
> create as many separate input devices as you want by opening
> /dev/uinput several times since it creates a device per file descriptor.
> Each of these input devices will get evdev attached to it and will get
> it's own /dev/input/eventX node created.
>
> Really, please try using uinput, it will clear a lot if things for you.
> For example, see what http://www.freedesktop.org/wiki/Evemu/ does.
>
Thank you Mr. Torokhov for the discussion and answering my queries. :)
I will try to explore more.
Good day !
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* [PATCHv2] HID:hid-logitech: Prevent possibility of infinite loop when using /sys interface
From: Simon Wood @ 2014-08-15 2:43 UTC (permalink / raw)
To: linux-input; +Cc: linux-kernel, Jiri Kosina, Simon Wood
In-Reply-To: <alpine.LNX.2.00.1408121630000.15220@pobox.suse.cz>
If the device data is not accessible for some reason, returning 0 will cause the call to be
continuously called again as none of the string has been 'consumed'.
Signed-off-by: Simon Wood <simon@mungewell.org>
---
drivers/hid/hid-lg4ff.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index cc2bd20..7835717 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
drv_data = hid_get_drvdata(hid);
if (!drv_data) {
hid_err(hid, "Private driver data not found!\n");
- return 0;
+ return -EINVAL;
}
entry = drv_data->device_props;
if (!entry) {
hid_err(hid, "Device properties not found!\n");
- return 0;
+ return -EINVAL;
}
if (range == 0)
--
1.9.1
^ permalink raw reply related
* [git pull] Input updates for 3.17-rc0 (part 2)
From: Dmitry Torokhov @ 2014-08-15 6:12 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, linux-input
[-- Attachment #1: Type: text/plain, Size: 2046 bytes --]
Hi Linus,
Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus
to receive 2nd round of updates for the input subsystem. Mostly small
fixups to the code merged in the first round (atmel_mxt_ts, wacom) but
also a smallish patch to xbox driver to support Xbox One controllers and
a patch to better handle Synaptics profile sensors found in Cr-48
Chromebooks that should not affect any other devices.
Changelog:
---------
Dmitry Torokhov (5):
Input: synaptics - properly initialize slots for semi-MT
Input: cap1106 - allow changing key mapping from userspace
Input: atmel_mxt_ts - simplify mxt_initialize a bit
Input: atmel_mxt_ts - split config update a bit
Input: atmel_mxt_ts - fix a few issues reported by Coverity
Geert Uytterhoeven (1):
Input: wacom - fix compiler warning if !CONFIG_PM
Henrik Rydberg (2):
Input: MT - make slot cleanup callable outside mt_sync_frame()
Input: synaptics - use firmware data for Cr-48
Maks Naumov (1):
Input: edt-ft5x06 - remove superfluous assignment
Mark Brown (1):
Input: joystick - use get_cycles on ARMv8
Nick Dyer (1):
Input: atmel_mxt_ts - mXT224 DMA quirk was fixed in firmware v2.0.AA
Ted Mielczarek (1):
Input: xpad - add support for Xbox One controllers
Diffstat:
--------
drivers/hid/wacom_sys.c | 2 +
drivers/input/input-mt.c | 38 +++-
drivers/input/joystick/analog.c | 2 +-
drivers/input/joystick/xpad.c | 174 +++++++++++++--
drivers/input/keyboard/cap1106.c | 8 +-
drivers/input/mouse/synaptics.c | 72 +++++-
drivers/input/touchscreen/atmel_mxt_ts.c | 366 +++++++++++++++++--------------
drivers/input/touchscreen/edt-ft5x06.c | 1 -
include/linux/input/mt.h | 1 +
9 files changed, 462 insertions(+), 202 deletions(-)
--
Dmitry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH] Input: hyperv-keyboard - implement Type Clipboard Text
From: Dexuan Cui @ 2014-08-15 9:41 UTC (permalink / raw)
To: gregkh, dmitry.torokhov, linux-input, linux-kernel,
driverdev-devel, olaf, apw, jasowang
Cc: kys, haiyangz
In the menu of the Hyper-V's Virtual Machine Connection, there is a feature
called "Clipboard | Type clipboard text", which can be used to copy a string
in the host's clipboard into the guest's current input focus(text console or
a GUI window).
Currently the feature doesn't work for Linux VM because the driver
hyperv-keyboard hasn't been enhanced to support it -- this patch is made
to do it.
For each char in the string, the host sends 2 events (key down/up with the
char's UNICODE value) to the guest.
The patch finds each char's scan codes of key down/up, and injects the
scan codes to the serio keyboard module.
Known issues:
1) Only printable ASCII chars are supported, and unsupported chars are
ignored. It seems unlikely to support generic UNICODE chars because there
is not a generic API to inject a UNICODE char to text mode console, KDE,
gnome, etc.
2) When we use the feature, make sure the CapsLock state of the VM's
(virtual) keyboard is OFF because this patch assumes it -- we'll try to
fix this later, probably by tracking the state of virtual CapsLock, because
it looks the keyboard module doesn't supply an API for us to query the state
of the keyboard.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/input/serio/hyperv-keyboard.c | 213 ++++++++++++++++++++++++++++++++--
1 file changed, 201 insertions(+), 12 deletions(-)
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index e74e5d6..5761869 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -18,6 +18,8 @@
#include <linux/hyperv.h>
#include <linux/serio.h>
#include <linux/slab.h>
+#include <linux/kfifo.h>
+#include <linux/delay.h>
/*
* Current version 1.0
@@ -84,7 +86,15 @@ struct synth_kbd_keystroke {
#define HK_MAXIMUM_MESSAGE_SIZE 256
#define KBD_VSC_SEND_RING_BUFFER_SIZE (10 * PAGE_SIZE)
-#define KBD_VSC_RECV_RING_BUFFER_SIZE (10 * PAGE_SIZE)
+
+/*
+ * For the Type Clipboard Text feature, the host can inject a string of
+ * up to 2047 chars, and each char means 2 events(key down/up) and every
+ * event means a VMBUS packet of 32 Bytes: so the max recv buf's size
+ * should be about 2K * 2 * 32 = 32 pages.
+ * Let's add 8 extra pages for safety.
+ */
+#define KBD_VSC_RECV_RING_BUFFER_SIZE (40 * PAGE_SIZE)
#define XTKBD_EMUL0 0xe0
#define XTKBD_EMUL1 0xe1
@@ -103,8 +113,173 @@ struct hv_kbd_dev {
struct completion wait_event;
spinlock_t lock; /* protects 'started' field */
bool started;
+
+ DECLARE_KFIFO_PTR(fifo, u8);
+ struct work_struct work;
+};
+
+static const u8 ascii_to_scan_code[128] = {
+ ['a'] = 0x1e, ['A'] = 0x1e,
+ ['b'] = 0x30, ['B'] = 0x30,
+ ['c'] = 0x2e, ['C'] = 0x2e,
+ ['d'] = 0x20, ['D'] = 0x20,
+ ['e'] = 0x12, ['E'] = 0x12,
+ ['f'] = 0x21, ['F'] = 0x21,
+ ['g'] = 0x22, ['G'] = 0x22,
+ ['h'] = 0x23, ['H'] = 0x23,
+ ['i'] = 0x17, ['I'] = 0x17,
+ ['j'] = 0x24, ['J'] = 0x24,
+ ['k'] = 0x25, ['K'] = 0x25,
+ ['l'] = 0x26, ['L'] = 0x26,
+ ['m'] = 0x32, ['M'] = 0x32,
+ ['n'] = 0x31, ['N'] = 0x31,
+ ['o'] = 0x18, ['O'] = 0x18,
+ ['p'] = 0x19, ['P'] = 0x19,
+ ['q'] = 0x10, ['Q'] = 0x10,
+ ['r'] = 0x13, ['R'] = 0x13,
+ ['s'] = 0x1f, ['S'] = 0x1f,
+ ['t'] = 0x14, ['T'] = 0x14,
+ ['u'] = 0x16, ['U'] = 0x16,
+ ['v'] = 0x2f, ['V'] = 0x2f,
+ ['w'] = 0x11, ['W'] = 0x11,
+ ['x'] = 0x2d, ['X'] = 0x2d,
+ ['y'] = 0x15, ['Y'] = 0x15,
+ ['z'] = 0x2c, ['Z'] = 0x2c,
+ ['`'] = 0x29, ['~'] = 0x29,
+ ['1'] = 0x02, ['!'] = 0x02,
+ ['2'] = 0x03, ['@'] = 0x03,
+ ['3'] = 0x04, ['#'] = 0x04,
+ ['4'] = 0x05, ['$'] = 0x05,
+ ['5'] = 0x06, ['%'] = 0x06,
+ ['6'] = 0x07, ['^'] = 0x07,
+ ['7'] = 0x08, ['&'] = 0x08,
+ ['8'] = 0x09, ['*'] = 0x09,
+ ['9'] = 0x0a, ['('] = 0x0a,
+ ['0'] = 0x0b, [')'] = 0x0b,
+ ['-'] = 0x0c, ['_'] = 0x0c,
+ ['='] = 0x0d, ['+'] = 0x0d,
+ ['\t'] = 0x0f,
+ ['['] = 0x1a, ['{'] = 0x1a,
+ [']'] = 0x1b, ['}'] = 0x1b,
+ ['\\'] = 0x2b, ['|'] = 0x2b,
+ [';'] = 0x27, [':'] = 0x27,
+ ['\''] = 0x28, ['\"'] = 0x28,
+ ['\r'] = 0x1c,
+ ['\n'] = 0x1c,
+ [','] = 0x33, ['<'] = 0x33,
+ ['.'] = 0x34, ['>'] = 0x34,
+ ['/'] = 0x35, ['?'] = 0x35,
+ [' '] = 0x39,
};
+static const bool ascii_needs_shift[128] = {
+ ['A'] = 1,
+ ['B'] = 1,
+ ['C'] = 1,
+ ['D'] = 1,
+ ['E'] = 1,
+ ['F'] = 1,
+ ['G'] = 1,
+ ['H'] = 1,
+ ['I'] = 1,
+ ['J'] = 1,
+ ['K'] = 1,
+ ['L'] = 1,
+ ['M'] = 1,
+ ['N'] = 1,
+ ['O'] = 1,
+ ['P'] = 1,
+ ['Q'] = 1,
+ ['R'] = 1,
+ ['S'] = 1,
+ ['T'] = 1,
+ ['U'] = 1,
+ ['V'] = 1,
+ ['W'] = 1,
+ ['X'] = 1,
+ ['Y'] = 1,
+ ['Z'] = 1,
+ ['~'] = 1,
+ ['!'] = 1,
+ ['@'] = 1,
+ ['#'] = 1,
+ ['$'] = 1,
+ ['%'] = 1,
+ ['^'] = 1,
+ ['&'] = 1,
+ ['*'] = 1,
+ ['('] = 1,
+ [')'] = 1,
+ ['_'] = 1,
+ ['+'] = 1,
+ ['{'] = 1,
+ ['}'] = 1,
+ ['|'] = 1,
+ [':'] = 1,
+ ['\"'] = 1,
+ ['<'] = 1,
+ ['>'] = 1,
+ ['?'] = 1,
+};
+static void handle_scancode(struct work_struct *work)
+{
+ unsigned long flags;
+ struct hv_kbd_dev *kbd_dev =
+ container_of(work, struct hv_kbd_dev, work);
+
+ u8 scan_code = -1;
+ unsigned int ret;
+
+ /*
+ * Inject the information through the serio interrupt.
+ */
+ do {
+ spin_lock_irqsave(&kbd_dev->lock, flags);
+
+ ret = kfifo_get(&kbd_dev->fifo, &scan_code);
+ if (ret != 0)
+ serio_interrupt(kbd_dev->hv_serio, scan_code, 0);
+
+ spin_unlock_irqrestore(&kbd_dev->lock, flags);
+
+ /*
+ * We can't inject the scan codes too fast, otherwise, some
+ * of the keys can be found lost in a X11 window. Tests show
+ * 10ms is a safe empirical value.
+ */
+ if (ret != 0)
+ msleep(10);
+ } while (ret);
+}
+
+static void handle_unicode(struct hv_kbd_dev *kbd_dev, u32 c, u32 info)
+{
+ u8 scan_code;
+ bool break_code = false;
+
+ /* We don't support generic UNICODE chars. */
+ if (c >= 0x80)
+ return;
+
+ /* We only support printable ASCII chars */
+ scan_code = ascii_to_scan_code[c];
+ if (!scan_code)
+ return;
+
+ if (info & IS_BREAK) {
+ scan_code |= XTKBD_RELEASE;
+ break_code = true;
+ }
+
+ if (ascii_needs_shift[c] && !break_code)
+ kfifo_put(&kbd_dev->fifo, 0x2a); /* L-Shift Down */
+
+ kfifo_put(&kbd_dev->fifo, scan_code);
+
+ if (ascii_needs_shift[c] && break_code)
+ kfifo_put(&kbd_dev->fifo, 0x2a | XTKBD_RELEASE); /* L-Shift Up */
+}
+
static void hv_kbd_on_receive(struct hv_device *hv_dev,
struct synth_kbd_msg *msg, u32 msg_length)
{
@@ -152,22 +327,28 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
ks_msg = (struct synth_kbd_keystroke *)msg;
info = __le32_to_cpu(ks_msg->info);
- /*
- * Inject the information through the serio interrupt.
- */
+ /* Put the scan codes into a fifo and handle it in a work */
spin_lock_irqsave(&kbd_dev->lock, flags);
if (kbd_dev->started) {
if (info & IS_E0)
- serio_interrupt(kbd_dev->hv_serio,
- XTKBD_EMUL0, 0);
+ kfifo_put(&kbd_dev->fifo, XTKBD_EMUL0);
if (info & IS_E1)
- serio_interrupt(kbd_dev->hv_serio,
- XTKBD_EMUL1, 0);
+ kfifo_put(&kbd_dev->fifo, XTKBD_EMUL1);
+
scan_code = __le16_to_cpu(ks_msg->make_code);
- if (info & IS_BREAK)
- scan_code |= XTKBD_RELEASE;
- serio_interrupt(kbd_dev->hv_serio, scan_code, 0);
+ if (!(info & IS_UNICODE)) {
+ if (info & IS_BREAK)
+ scan_code |= XTKBD_RELEASE;
+
+ kfifo_put(&kbd_dev->fifo, scan_code);
+ } else {
+ /* the scan_code is actually a UNICODE char */
+ handle_unicode(kbd_dev, scan_code, info);
+ }
+
+ schedule_work(&kbd_dev->work);
+
}
spin_unlock_irqrestore(&kbd_dev->lock, flags);
@@ -354,6 +535,11 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
goto err_free_mem;
}
+ error = kfifo_alloc(&kbd_dev->fifo, PAGE_SIZE*4, GFP_KERNEL);
+ if (error)
+ goto err_free_mem;
+ INIT_WORK(&kbd_dev->work, handle_scancode);
+
kbd_dev->hv_dev = hv_dev;
kbd_dev->hv_serio = hv_serio;
spin_lock_init(&kbd_dev->lock);
@@ -378,7 +564,7 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
hv_kbd_on_channel_callback,
hv_dev);
if (error)
- goto err_free_mem;
+ goto err_free_fifo;
error = hv_kbd_connect_to_vsp(hv_dev);
if (error)
@@ -392,6 +578,8 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
err_close_vmbus:
vmbus_close(hv_dev->channel);
+err_free_fifo:
+ kfifo_free(&kbd_dev->fifo);
err_free_mem:
kfree(hv_serio);
kfree(kbd_dev);
@@ -405,6 +593,7 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
device_init_wakeup(&hv_dev->device, false);
serio_unregister_port(kbd_dev->hv_serio);
vmbus_close(hv_dev->channel);
+ kfifo_free(&kbd_dev->fifo);
kfree(kbd_dev);
hv_set_drvdata(hv_dev, NULL);
--
1.9.1
^ permalink raw reply related
* Re: [PATCHv2] HID:hid-logitech: Prevent possibility of infinite loop when using /sys interface
From: Jiri Kosina @ 2014-08-15 8:56 UTC (permalink / raw)
To: Simon Wood; +Cc: linux-input, linux-kernel
In-Reply-To: <1408070581-2460-1-git-send-email-simon@mungewell.org>
On Thu, 14 Aug 2014, Simon Wood wrote:
> If the device data is not accessible for some reason, returning 0 will cause the call to be
> continuously called again as none of the string has been 'consumed'.
>
> Signed-off-by: Simon Wood <simon@mungewell.org>
> ---
> drivers/hid/hid-lg4ff.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
> index cc2bd20..7835717 100644
> --- a/drivers/hid/hid-lg4ff.c
> +++ b/drivers/hid/hid-lg4ff.c
> @@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
> drv_data = hid_get_drvdata(hid);
> if (!drv_data) {
> hid_err(hid, "Private driver data not found!\n");
> - return 0;
> + return -EINVAL;
> }
>
> entry = drv_data->device_props;
> if (!entry) {
> hid_err(hid, "Device properties not found!\n");
> - return 0;
> + return -EINVAL;
> }
>
Queued for 3.17, thanks Simon.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 2/2] Input: atmel_mxt_ts - Add keycodes array example
From: Javier Martinez Canillas @ 2014-08-15 12:01 UTC (permalink / raw)
To: Nick Dyer, Dmitry Torokhov
Cc: Stephen Warren, Yufeng Shen, Benson Leung, Doug Anderson,
Olof Johansson, linux-input, devicetree, linux-samsung-soc,
linux-kernel
In-Reply-To: <53E4E41D.4070703@collabora.co.uk>
Hello Nick,
On 08/08/2014 04:52 PM, Javier Martinez Canillas wrote:
On 08/07/2014 02:38 PM, Nick Dyer wrote:
>> >>
>>
>> I'm afraid you have misunderstood the impact of this change to the way that
>> the GPIOs coming in to the touch controller are mapped to key codes. Look
>
> Unfortunately there are no boards in mainline using this "linux,gpio-keymap"
> property so I tried to figure out what the expected values were by reading the
> driver. So is more than possible that I got them wrong.
>
> By passing all these keycodes the touchpad worked as expected for me and the
> driver did the same than the Chrome OS driver that has these keycodes hardcoded
> when is_tp is true.
>
>> at the protocol guide for T19.
>>
>
> I don't have access to proper documentation and I wouldn't expect people to have
> access to non-public docs in order to use a Device Tree binding.
>
> That's why I wanted to document an example, so using this property could be
> easier for others and they shouldn't have to look at the driver in order to
> figure it out (and getting it wrong as you said :) )
>
> So it would be great if you could provide an example on how this is supposed to
> be used.
>
Any comments on this? I would really appreciate if you can expand on how
this DT property is supposed to be used so I can re-spin the atmel support
patch for Peach boards.
Thanks a lot and best regards,
Javier
^ permalink raw reply
* test program to check usb hid devices
From: loody @ 2014-08-15 12:34 UTC (permalink / raw)
To: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
open list:HID CORE LAYER
hi all:
Is there any test program we can use to capture input data send from
usb keyboard/mouse?
I don't need to parsing the binary sent by keyboard/mouse. Just raw
data is fine.
I checked the Kernel sample, hid-example.c, but it seems only get
report and print it out.
appreciate your help in advance,
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: test program to check usb hid devices
From: David Laight @ 2014-08-15 12:54 UTC (permalink / raw)
To: 'loody', linux-usb@vger.kernel.org,
open list:HID CORE LAYER
In-Reply-To: <CANudz+s-2QFtpxDqj2O-tJkhEM0oWoFvjWb=xrt+F_eUmPXaog@mail.gmail.com>
From: loody
> Is there any test program we can use to capture input data send from
> usb keyboard/mouse?
google usbmon
David
^ permalink raw reply
* Transaction XLK-14-TTF/ESP.
From: GVA Abogados. @ 2014-08-15 13:36 UTC (permalink / raw)
Dear Friend,
Please acknowledge and accept my proposal.
My name is Barrister Miguel Martinez Moreno, an Attorney at Law, in
Alicante-Spain.
I am writing to notify you of the unclaimed inheritance deposit of our
late client, who passed on to Great beyond on August 21st, 2010 in a
motor accident in auto pista de Alcala Del Henares, Madrid-Spain.
I got your name and email address through a web search engine in my
quest to get a reliable individual who shall work with me in claiming
this inheritance deposit since all my efforts to get the biological
relative has proved abortive.
Conclusively, I await your urgent response to include the following :(
1).Your full Names & Address. (2).Your Telephone and Fax numbers.
(3).Your business name if any: for more information on how to release
the inheritance deposit, amount, procedure and legality of this claim
send me an email via: gva_abogados@aim.com
Have a very nice day my friend!
Regards,
Miguel Martinez Moreno (Esq)
Attorney At Law.
gvaintencia@aim.com
^ permalink raw reply
* Re: test program to check usb hid devices
From: loody @ 2014-08-15 14:31 UTC (permalink / raw)
To: David Laight; +Cc: linux-usb@vger.kernel.org, open list:HID CORE LAYER
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D17478786@AcuExch.aculab.com>
hi David:
2014-08-15 20:54 GMT+08:00 David Laight <David.Laight@aculab.com>:
> From: loody
>> Is there any test program we can use to capture input data send from
>> usb keyboard/mouse?
>
> google usbmon
Sorry for making you confused.
What I need is not monitor usb bus data.
What I need is some user mode program, and when I execute it, it will
driver usb HID keyboard/mouse to work.
And I can print out the hex value those device send once user press
any key on keyboard or moving mouse around.
It should be like I think
hid_device=hid_open(xxx);
while(1){
data = get input data(hid_device);
printf("0x%x\n",data);
}
Appreciate your kind help,
^ permalink raw reply
* [PATCH] remove explicit devm_kfree
From: Arjun Sreedharan @ 2014-08-15 15:26 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: lejun.zhu, linux-input, linux-kernel
Memory allocated with devm_kzalloc() is freed automatically when device
out of scope.
Signed-off-by: Arjun Sreedharan <arjun024@gmail.com>
---
drivers/input/misc/soc_button_array.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index 5a6334b..123e59f 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -131,7 +131,6 @@ soc_button_device_create(struct pnp_dev *pdev,
err_free_pdev:
platform_device_put(pd);
err_free_mem:
- devm_kfree(&pdev->dev, gpio_keys_pdata);
return ERR_PTR(error);
}
--
1.7.11.7
^ permalink raw reply related
* Re: test program to check usb hid devices
From: Benjamin Tissoires @ 2014-08-15 15:26 UTC (permalink / raw)
To: loody
Cc: David Laight, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
open list:HID CORE LAYER
In-Reply-To: <CANudz+tUuopx=HT0FcKJ8Ak6_K0yz-nRf7=FwtcMDH9WW1MfbA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
If I understood correctly, you just want to dump the hid output.
You can just cat /sys/kernel/debug/hid/*/events if debugfs is mounted.
Or you may want to have a look at these 2 projects:
hid-recorder -> http://bentiss.github.io/hid-replay-docs/
usbhid-dump-> https://github.com/DIGImend/usbhid-dump (part of the
DIGImend project)
Cheers,
Benjamin
On Fri, Aug 15, 2014 at 10:31 AM, loody <miloody-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> hi David:
>
> 2014-08-15 20:54 GMT+08:00 David Laight <David.Laight-JxhZ9S5GRejQT0dZR+AlfA@public.gmane.org>:
>> From: loody
>>> Is there any test program we can use to capture input data send from
>>> usb keyboard/mouse?
>>
>> google usbmon
> Sorry for making you confused.
> What I need is not monitor usb bus data.
> What I need is some user mode program, and when I execute it, it will
> driver usb HID keyboard/mouse to work.
> And I can print out the hex value those device send once user press
> any key on keyboard or moving mouse around.
>
> It should be like I think
> hid_device=hid_open(xxx);
> while(1){
> data = get input data(hid_device);
> printf("0x%x\n",data);
> }
>
> Appreciate your kind help,
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v6] input: drv260x: Add TI drv260x haptics driver
From: Dan Murphy @ 2014-08-15 15:47 UTC (permalink / raw)
To: mark.rutland, linux-input
Cc: linux-kernel, devicetree, dmitry.torokhov, Dan Murphy
Add the TI drv260x haptics/vibrator driver.
This device uses the input force feedback
to produce a wave form to driver an
ERM or LRA actuator device.
The initial driver supports the devices
real time playback mode. But the device
has additional wave patterns in ROM.
This functionality will be added in
future patchsets.
Product data sheet is located here:
http://www.ti.com/product/drv2605
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
v6 - Updated bindings doc to reflect correct pre-programmed library,
updated the vib-overdrive and rated voltage to add -mv, removed _ from
the same, add check to verify LRA libraries are only used in LRA mode,
and finally changed supply -> vbat-supply in binding doc - https://patchwork.kernel.org/patch/4658661/
v5 - Move register defines to c file and rm header file, error check
init in probe, fixed identation, remove empty labels in probe
and just return on fail and removed the remove callback and function.
Did not factor out the suspend into a stop function. - https://patchwork.kernel.org/patch/4649631/
v4 - Convert regulator to devm, added error checking where required,
updated bindings doc, moved dt parsing to separate call and made platform
data the first data point, moved vibrator enable and mode programming from
play entry to worker thread, added user check and input mutex in suspend/resume
calls, moved platform data to individual file and into include platform-data directory,
removed file names from file headers - https://patchwork.kernel.org/patch/4642221/
v3 - Updated binding doc, changed to memless device, updated input alloc to
devm, removed mutex locking, add sanity checks for mode and library - https://patchwork.kernel.org/patch/4635421/
v2 - Fixed binding doc and patch headline - https://patchwork.kernel.org/patch/4619641/
.../devicetree/bindings/input/ti,drv260x.txt | 51 ++
drivers/input/misc/Kconfig | 9 +
drivers/input/misc/Makefile | 1 +
drivers/input/misc/drv260x.c | 704 ++++++++++++++++++++
include/dt-bindings/input/ti-drv260x.h | 36 +
include/linux/platform_data/drv260x-pdata.h | 29 +
6 files changed, 830 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/ti,drv260x.txt
create mode 100644 drivers/input/misc/drv260x.c
create mode 100644 include/dt-bindings/input/ti-drv260x.h
create mode 100644 include/linux/platform_data/drv260x-pdata.h
diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt
new file mode 100644
index 0000000..d54be15
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/ti,drv260x.txt
@@ -0,0 +1,51 @@
+Texas Instruments - drv260x Haptics driver family
+
+The drv260x family serial control bus communicates through I2C protocols
+
+Required properties:
+ - compatible - One of:
+ "ti,drv2604" - DRV2604
+ "ti,drv2605" - DRV2605
+ "ti,drv2605l" - DRV2605L
+ - reg - I2C slave address
+ - vbat-supply- Required supply regulator
+ - mode - Power up mode of the chip (defined in include/dt-bindings/input/ti-drv260x.h)
+ DRV260X_LRA_MODE - Linear Resonance Actuator mode (Piezoelectric)
+ DRV260X_LRA_NO_CAL_MODE - This is a LRA Mode but there is no calibration
+ sequence during init. And the device is configured for real
+ time playback mode (RTP mode).
+ DRV260X_ERM_MODE - Eccentric Rotating Mass mode (Rotary vibrator)
+ - library-sel - These are ROM based waveforms pre-programmed into the IC.
+ This should be set to set the library to use at power up.
+ (defined in include/dt-bindings/input/ti-drv260x.h)
+ DRV260X_LIB_EMPTY - Do not use a pre-programmed library
+ DRV260X_ERM_LIB_A - Pre-programmed Library
+ DRV260X_ERM_LIB_B - Pre-programmed Library
+ DRV260X_ERM_LIB_C - Pre-programmed Library
+ DRV260X_ERM_LIB_D - Pre-programmed Library
+ DRV260X_ERM_LIB_E - Pre-programmed Library
+ DRV260X_ERM_LIB_F - Pre-programmed Library
+ DRV260X_LIB_LRA - Pre-programmed LRA Library
+
+Optional properties:
+ - enable-gpio - gpio pin to enable/disable the device.
+ - vib-rated-mv - The rated voltage of the actuator in millivolts.
+ If this is not set then the value will be defaulted to
+ 3.2 v.
+ - vib-overdrive-mv - The overdrive voltage of the actuator in millivolts.
+ If this is not set then the value will be defaulted to
+ 3.2 v.
+Example:
+
+drv2605l: drv2605l@5a {
+ compatible = "ti,drv2605l";
+ reg = <0x5a>;
+ enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mode = <DRV260X_LRA_MODE>;
+ library-sel = <DRV260X_LIB_LRA>;
+ vib-rated-mv = <3200>;
+ vib-overdriver-mv = <3200>;
+};
+
+For more product information please see the link below:
+http://www.ti.com/product/drv2605
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 2ff4425..99f6762 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -676,4 +676,13 @@ config INPUT_SOC_BUTTON_ARRAY
To compile this driver as a module, choose M here: the
module will be called soc_button_array.
+config INPUT_DRV260X_HAPTICS
+ tristate "TI DRV260X haptics support"
+ depends on INPUT && I2C
+ help
+ Say Y to enable support for the TI DRV260X haptics driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called drv260x-haptics.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 4955ad3..d8ef3c7 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o
+obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
new file mode 100644
index 0000000..2b35e4c
--- /dev/null
+++ b/drivers/input/misc/drv260x.c
@@ -0,0 +1,704 @@
+/*
+ * DRV260X haptics driver family
+ *
+ * Author: Dan Murphy <dmurphy@ti.com>
+ *
+ * Copyright: (C) 2014 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+
+#include <dt-bindings/input/ti-drv260x.h>
+#include <linux/platform_data/drv260x-pdata.h>
+
+#define DRV260X_STATUS 0x0
+#define DRV260X_MODE 0x1
+#define DRV260X_RT_PB_IN 0x2
+#define DRV260X_LIB_SEL 0x3
+#define DRV260X_WV_SEQ_1 0x4
+#define DRV260X_WV_SEQ_2 0x5
+#define DRV260X_WV_SEQ_3 0x6
+#define DRV260X_WV_SEQ_4 0x7
+#define DRV260X_WV_SEQ_5 0x8
+#define DRV260X_WV_SEQ_6 0x9
+#define DRV260X_WV_SEQ_7 0xa
+#define DRV260X_WV_SEQ_8 0xb
+#define DRV260X_GO 0xc
+#define DRV260X_OVERDRIVE_OFF 0xd
+#define DRV260X_SUSTAIN_P_OFF 0xe
+#define DRV260X_SUSTAIN_N_OFF 0xf
+#define DRV260X_BRAKE_OFF 0x10
+#define DRV260X_A_TO_V_CTRL 0x11
+#define DRV260X_A_TO_V_MIN_INPUT 0x12
+#define DRV260X_A_TO_V_MAX_INPUT 0x13
+#define DRV260X_A_TO_V_MIN_OUT 0x14
+#define DRV260X_A_TO_V_MAX_OUT 0x15
+#define DRV260X_RATED_VOLT 0x16
+#define DRV260X_OD_CLAMP_VOLT 0x17
+#define DRV260X_CAL_COMP 0x18
+#define DRV260X_CAL_BACK_EMF 0x19
+#define DRV260X_FEEDBACK_CTRL 0x1a
+#define DRV260X_CTRL1 0x1b
+#define DRV260X_CTRL2 0x1c
+#define DRV260X_CTRL3 0x1d
+#define DRV260X_CTRL4 0x1e
+#define DRV260X_CTRL5 0x1f
+#define DRV260X_LRA_LOOP_PERIOD 0x20
+#define DRV260X_VBAT_MON 0x21
+#define DRV260X_LRA_RES_PERIOD 0x22
+#define DRV260X_MAX_REG 0x23
+
+#define DRV260X_ALLOWED_R_BYTES 25
+#define DRV260X_ALLOWED_W_BYTES 2
+#define DRV260X_MAX_RW_RETRIES 5
+#define DRV260X_I2C_RETRY_DELAY 10
+
+#define DRV260X_GO_BIT 0x01
+
+/* Library Selection */
+#define DRV260X_LIB_SEL_MASK 0x07
+#define DRV260X_LIB_SEL_RAM 0x0
+#define DRV260X_LIB_SEL_OD 0x1
+#define DRV260X_LIB_SEL_40_60 0x2
+#define DRV260X_LIB_SEL_60_80 0x3
+#define DRV260X_LIB_SEL_100_140 0x4
+#define DRV260X_LIB_SEL_140_PLUS 0x5
+
+#define DRV260X_LIB_SEL_HIZ_MASK 0x10
+#define DRV260X_LIB_SEL_HIZ_EN 0x01
+#define DRV260X_LIB_SEL_HIZ_DIS 0
+
+/* Mode register */
+#define DRV260X_STANDBY (1 << 6)
+#define DRV260X_STANDBY_MASK 0x40
+#define DRV260X_INTERNAL_TRIGGER 0x00
+#define DRV260X_EXT_TRIGGER_EDGE 0x01
+#define DRV260X_EXT_TRIGGER_LEVEL 0x02
+#define DRV260X_PWM_ANALOG_IN 0x03
+#define DRV260X_AUDIOHAPTIC 0x04
+#define DRV260X_RT_PLAYBACK 0x05
+#define DRV260X_DIAGNOSTICS 0x06
+#define DRV260X_AUTO_CAL 0x07
+
+/* Audio to Haptics Control */
+#define DRV260X_AUDIO_HAPTICS_PEAK_10MS (0 << 2)
+#define DRV260X_AUDIO_HAPTICS_PEAK_20MS (1 << 2)
+#define DRV260X_AUDIO_HAPTICS_PEAK_30MS (2 << 2)
+#define DRV260X_AUDIO_HAPTICS_PEAK_40MS (3 << 2)
+
+#define DRV260X_AUDIO_HAPTICS_FILTER_100HZ 0x00
+#define DRV260X_AUDIO_HAPTICS_FILTER_125HZ 0x01
+#define DRV260X_AUDIO_HAPTICS_FILTER_150HZ 0x02
+#define DRV260X_AUDIO_HAPTICS_FILTER_200HZ 0x03
+
+/* Min/Max Input/Output Voltages */
+#define DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT 0x19
+#define DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT 0x64
+#define DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT 0x19
+#define DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT 0xFF
+
+/* Feedback register */
+#define DRV260X_FB_REG_ERM_MODE 0x7f
+#define DRV260X_FB_REG_LRA_MODE (1 << 7)
+
+#define DRV260X_BRAKE_FACTOR_MASK 0x1f
+#define DRV260X_BRAKE_FACTOR_2X (1 << 0)
+#define DRV260X_BRAKE_FACTOR_3X (2 << 4)
+#define DRV260X_BRAKE_FACTOR_4X (3 << 4)
+#define DRV260X_BRAKE_FACTOR_6X (4 << 4)
+#define DRV260X_BRAKE_FACTOR_8X (5 << 4)
+#define DRV260X_BRAKE_FACTOR_16 (6 << 4)
+#define DRV260X_BRAKE_FACTOR_DIS (7 << 4)
+
+#define DRV260X_LOOP_GAIN_LOW 0xf3
+#define DRV260X_LOOP_GAIN_MED (1 << 2)
+#define DRV260X_LOOP_GAIN_HIGH (2 << 2)
+#define DRV260X_LOOP_GAIN_VERY_HIGH (3 << 2)
+
+#define DRV260X_BEMF_GAIN_0 0xfc
+#define DRV260X_BEMF_GAIN_1 (1 << 0)
+#define DRV260X_BEMF_GAIN_2 (2 << 0)
+#define DRV260X_BEMF_GAIN_3 (3 << 0)
+
+/* Control 1 register */
+#define DRV260X_AC_CPLE_EN (1 << 5)
+#define DRV260X_STARTUP_BOOST (1 << 7)
+
+/* Control 2 register */
+
+#define DRV260X_IDISS_TIME_45 0
+#define DRV260X_IDISS_TIME_75 (1 << 0)
+#define DRV260X_IDISS_TIME_150 (1 << 1)
+#define DRV260X_IDISS_TIME_225 0x03
+
+#define DRV260X_BLANK_TIME_45 (0 << 2)
+#define DRV260X_BLANK_TIME_75 (1 << 2)
+#define DRV260X_BLANK_TIME_150 (2 << 2)
+#define DRV260X_BLANK_TIME_225 (3 << 2)
+
+#define DRV260X_SAMP_TIME_150 (0 << 4)
+#define DRV260X_SAMP_TIME_200 (1 << 4)
+#define DRV260X_SAMP_TIME_250 (2 << 4)
+#define DRV260X_SAMP_TIME_300 (3 << 4)
+
+#define DRV260X_BRAKE_STABILIZER (1 << 6)
+#define DRV260X_UNIDIR_IN (0 << 7)
+#define DRV260X_BIDIR_IN (1 << 7)
+
+/* Control 3 Register */
+#define DRV260X_LRA_OPEN_LOOP (1 << 0)
+#define DRV260X_ANANLOG_IN (1 << 1)
+#define DRV260X_LRA_DRV_MODE (1 << 2)
+#define DRV260X_RTP_UNSIGNED_DATA (1 << 3)
+#define DRV260X_SUPPLY_COMP_DIS (1 << 4)
+#define DRV260X_ERM_OPEN_LOOP (1 << 5)
+#define DRV260X_NG_THRESH_0 (0 << 6)
+#define DRV260X_NG_THRESH_2 (1 << 6)
+#define DRV260X_NG_THRESH_4 (2 << 6)
+#define DRV260X_NG_THRESH_8 (3 << 6)
+
+/* Control 4 Register */
+#define DRV260X_AUTOCAL_TIME_150MS (0 << 4)
+#define DRV260X_AUTOCAL_TIME_250MS (1 << 4)
+#define DRV260X_AUTOCAL_TIME_500MS (2 << 4)
+#define DRV260X_AUTOCAL_TIME_1000MS (3 << 4)
+
+/**
+ * struct drv260x_data -
+ * @input_dev - Pointer to the input device
+ * @client - Pointer to the I2C client
+ * @regmap - Register map of the device
+ * @work - Work item used to off load the enable/disable of the vibration
+ * @enable_gpio - Pointer to the gpio used for enable/disabling
+ * @regulator - Pointer to the regulator for the IC
+ * @magnitude - Magnitude of the vibration event
+ * @mode - The operating mode of the IC (LRA_NO_CAL, ERM or LRA)
+ * @library - The vibration library to be used
+ * @rated_voltage - The rated_voltage of the actuator
+ * @overdriver_voltage - The over drive voltage of the actuator
+**/
+struct drv260x_data {
+ struct input_dev *input_dev;
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct work_struct work;
+ struct gpio_desc *enable_gpio;
+ struct regulator *regulator;
+ u32 magnitude;
+ u32 mode;
+ u32 library;
+ int rated_voltage;
+ int overdrive_voltage;
+};
+
+static struct reg_default drv260x_reg_defs[] = {
+ { DRV260X_STATUS, 0xe0 },
+ { DRV260X_MODE, 0x40 },
+ { DRV260X_RT_PB_IN, 0x00},
+ { DRV260X_LIB_SEL, 0x00},
+ { DRV260X_WV_SEQ_1, 0x01},
+ { DRV260X_WV_SEQ_2, 0x00},
+ { DRV260X_WV_SEQ_3, 0x00},
+ { DRV260X_WV_SEQ_4, 0x00},
+ { DRV260X_WV_SEQ_5, 0x00},
+ { DRV260X_WV_SEQ_6, 0x00},
+ { DRV260X_WV_SEQ_7, 0x00},
+ { DRV260X_WV_SEQ_8, 0x00},
+ { DRV260X_GO, 0x00},
+ { DRV260X_OVERDRIVE_OFF, 0x00},
+ { DRV260X_SUSTAIN_P_OFF, 0x00},
+ { DRV260X_SUSTAIN_N_OFF, 0x00},
+ { DRV260X_BRAKE_OFF , 0x00},
+ { DRV260X_A_TO_V_CTRL , 0x05},
+ { DRV260X_A_TO_V_MIN_INPUT, 0x19},
+ { DRV260X_A_TO_V_MAX_INPUT, 0xff},
+ { DRV260X_A_TO_V_MIN_OUT, 0x19},
+ { DRV260X_A_TO_V_MAX_OUT, 0xff},
+ { DRV260X_RATED_VOLT, 0x3e},
+ { DRV260X_OD_CLAMP_VOLT, 0x8c},
+ { DRV260X_CAL_COMP, 0x0c},
+ { DRV260X_CAL_BACK_EMF, 0x6c},
+ { DRV260X_FEEDBACK_CTRL, 0x36},
+ { DRV260X_CTRL1, 0x93},
+ { DRV260X_CTRL2, 0xfa},
+ { DRV260X_CTRL3, 0xa0},
+ { DRV260X_CTRL4, 0x20},
+ { DRV260X_CTRL5, 0x80},
+ { DRV260X_LRA_LOOP_PERIOD, 0x33},
+ { DRV260X_VBAT_MON, 0x00},
+ { DRV260X_LRA_RES_PERIOD, 0x00},
+};
+
+#define DRV260X_DEF_RATED_VOLT 0x90
+#define DRV260X_DEF_OD_CLAMP_VOLT 0x90
+/**
+ * Rated and Overdriver Voltages:
+ * Calculated using the formula r = v * 255 / 5.6
+ * where r is what will be written to the register
+ * and v is the rated or overdriver voltage of the actuator
+ **/
+static int drv260x_calculate_voltage(int voltage)
+{
+ return (voltage * 255 / 5600);
+}
+
+static void drv260x_worker(struct work_struct *work)
+{
+ struct drv260x_data *haptics = container_of(work, struct drv260x_data, work);
+ int ret;
+
+ gpiod_set_value(haptics->enable_gpio, 1);
+ /* Data sheet says to wait 250us before trying to communicate */
+ udelay(250);
+
+ ret = regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_RT_PLAYBACK);
+ if (ret != 0) {
+ dev_err(&haptics->client->dev,
+ "Failed to write set mode: %d\n", ret);
+ return;
+ }
+
+ ret = regmap_write(haptics->regmap, DRV260X_RT_PB_IN, haptics->magnitude);
+ if (ret != 0) {
+ dev_err(&haptics->client->dev,
+ "Failed to set magnitude: %d\n", ret);
+ }
+}
+
+static int drv260x_haptics_play(struct input_dev *input, void *data,
+ struct ff_effect *effect)
+{
+ struct drv260x_data *haptics = input_get_drvdata(input);
+
+ haptics->mode = DRV260X_LRA_NO_CAL_MODE;
+ haptics->magnitude = 0;
+
+ if (effect->u.rumble.strong_magnitude ||
+ effect->u.rumble.weak_magnitude) {
+ if (effect->u.rumble.strong_magnitude > 0)
+ haptics->magnitude = effect->u.rumble.strong_magnitude;
+ else if (effect->u.rumble.weak_magnitude > 0)
+ haptics->magnitude = effect->u.rumble.weak_magnitude;
+ }
+
+ schedule_work(&haptics->work);
+
+ return 0;
+}
+
+static void drv260x_close(struct input_dev *input)
+{
+ struct drv260x_data *haptics = input_get_drvdata(input);
+ int ret;
+
+ cancel_work_sync(&haptics->work);
+
+ ret = regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_STANDBY);
+ if (ret != 0) {
+ dev_err(&haptics->client->dev,
+ "Failed to write standby mode: %d\n", ret);
+ }
+
+ gpiod_set_value(haptics->enable_gpio, 0);
+}
+
+static const struct reg_default drv260x_lra_cal_regs[] = {
+ { DRV260X_MODE, DRV260X_AUTO_CAL },
+ { DRV260X_CTRL3, DRV260X_NG_THRESH_2},
+ { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH },
+};
+
+static const struct reg_default drv260x_lra_init_regs[] = {
+ { DRV260X_MODE, DRV260X_RT_PLAYBACK},
+ { DRV260X_A_TO_V_CTRL, DRV260X_AUDIO_HAPTICS_PEAK_20MS | DRV260X_AUDIO_HAPTICS_FILTER_125HZ},
+ { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
+ { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
+ { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT },
+ { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT },
+ { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | DRV260X_BRAKE_FACTOR_2X | DRV260X_LOOP_GAIN_MED | DRV260X_BEMF_GAIN_3 },
+ { DRV260X_CTRL1, DRV260X_STARTUP_BOOST },
+ { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 },
+ { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANANLOG_IN },
+ { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
+};
+
+static const struct reg_default drv260x_erm_cal_regs[] = {
+ { DRV260X_MODE, DRV260X_AUTO_CAL },
+ { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT },
+ { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT },
+ { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT },
+ { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT },
+ { DRV260X_FEEDBACK_CTRL, DRV260X_BRAKE_FACTOR_3X | DRV260X_LOOP_GAIN_MED | DRV260X_BEMF_GAIN_2 },
+ { DRV260X_CTRL1, DRV260X_STARTUP_BOOST },
+ { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 | DRV260X_BLANK_TIME_75 | DRV260X_SAMP_TIME_250 | DRV260X_IDISS_TIME_75 },
+ { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ERM_OPEN_LOOP },
+ { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS },
+};
+
+static int drv260x_init(struct drv260x_data *haptics)
+{
+ int ret;
+ unsigned int cal_buf;
+
+ ret = regmap_write(haptics->regmap,
+ DRV260X_RATED_VOLT, haptics->rated_voltage);
+ if (ret != 0)
+ goto write_failure;
+
+ ret = regmap_write(haptics->regmap,
+ DRV260X_OD_CLAMP_VOLT, haptics->overdrive_voltage);
+ if (ret != 0)
+ goto write_failure;
+
+ switch(haptics->mode) {
+ case DRV260X_LRA_MODE:
+ ret = regmap_register_patch(haptics->regmap,
+ drv260x_lra_cal_regs,
+ ARRAY_SIZE(drv260x_lra_cal_regs));
+ if (ret != 0)
+ goto write_failure;
+ break;
+ case DRV260X_ERM_MODE:
+ ret = regmap_register_patch(haptics->regmap,
+ drv260x_erm_cal_regs,
+ ARRAY_SIZE(drv260x_erm_cal_regs));
+ if (ret != 0)
+ goto write_failure;
+
+ ret = regmap_update_bits(haptics->regmap, DRV260X_LIB_SEL,
+ DRV260X_LIB_SEL_MASK,
+ haptics->library);
+ if (ret != 0)
+ goto write_failure;
+ break;
+ default:
+ ret = regmap_register_patch(haptics->regmap,
+ drv260x_lra_init_regs,
+ ARRAY_SIZE(drv260x_lra_init_regs));
+ if (ret != 0)
+ goto write_failure;
+
+ ret = regmap_update_bits(haptics->regmap, DRV260X_LIB_SEL,
+ DRV260X_LIB_SEL_MASK,
+ haptics->library);
+ if (ret != 0)
+ goto write_failure;
+
+ goto skip_go_bit;
+ break;
+ }
+
+ if (ret != 0) {
+ dev_err(&haptics->client->dev,
+ "Failed to write init registers: %d\n",
+ ret);
+ goto write_failure;
+ }
+
+ ret = regmap_write(haptics->regmap, DRV260X_GO, DRV260X_GO_BIT);
+ if (ret != 0)
+ goto write_failure;
+
+ do {
+ ret = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf);
+ if (ret != 0)
+ goto write_failure;
+ } while (cal_buf == DRV260X_GO_BIT || ret != 0);
+
+ return ret;
+
+write_failure:
+ dev_err(&haptics->client->dev,
+ "Failed to write init registers: %d\n",
+ ret);
+skip_go_bit:
+ return ret;
+}
+
+static const struct regmap_config drv260x_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = DRV260X_MAX_REG,
+ .reg_defaults = drv260x_reg_defs,
+ .num_reg_defaults = ARRAY_SIZE(drv260x_reg_defs),
+ .cache_type = REGCACHE_NONE,
+};
+
+#ifdef CONFIG_OF
+static int drv260x_parse_dt(struct device_node *dev_node,
+ struct drv260x_data *haptics,
+ struct device *dev)
+{
+ int ret;
+ int voltage;
+
+ ret = of_property_read_u32(dev_node, "mode", &haptics->mode);
+ if (ret < 0) {
+ dev_err(dev, "%s: No entry for mode\n", __func__);
+
+ return ret;
+ }
+ ret = of_property_read_u32(dev_node, "library-sel",
+ &haptics->library);
+ if (ret < 0) {
+ dev_err(dev, "%s: No entry for library selection\n",
+ __func__);
+
+ return ret;
+ }
+ ret = of_property_read_u32(dev_node, "vib-rated-mv",
+ &voltage);
+ if (!ret)
+ haptics->rated_voltage = drv260x_calculate_voltage(voltage);
+
+
+ ret = of_property_read_u32(dev_node, "vib-overdrive-mv",
+ &voltage);
+ if (!ret)
+ haptics->overdrive_voltage = drv260x_calculate_voltage(voltage);
+
+ return ret;
+
+}
+#else
+static inline int drv260x_parse_dt(struct device *dev)
+{
+ dev_err(dev, "no platform data defined\n");
+
+ return -EINVAL;
+}
+#endif
+static int drv260x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct drv260x_data *haptics;
+ struct device_node *np = client->dev.of_node;
+ struct drv260x_platform_data *pdata = dev_get_platdata(&client->dev);
+ int ret;
+
+ haptics = devm_kzalloc(&client->dev, sizeof(*haptics), GFP_KERNEL);
+ if (!haptics)
+ return -ENOMEM;
+
+ haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT;
+ haptics->rated_voltage = DRV260X_DEF_RATED_VOLT;
+
+ if (pdata) {
+ haptics->mode = pdata->mode;
+ haptics->library = pdata->library_selection;
+ if (pdata->vib_overdrive_voltage)
+ haptics->overdrive_voltage = drv260x_calculate_voltage(pdata->vib_overdrive_voltage);
+ if (pdata->vib_rated_voltage)
+ haptics->rated_voltage = drv260x_calculate_voltage(pdata->vib_rated_voltage);
+ } else if (np) {
+ ret = drv260x_parse_dt(np, haptics, &client->dev);
+ if (ret)
+ return ret;
+ } else {
+ dev_err(&client->dev, "Platform data not set\n");
+ return -ENODEV;
+ }
+
+
+ if (haptics->mode < DRV260X_LRA_MODE ||
+ haptics->mode > DRV260X_ERM_MODE) {
+ dev_err(&client->dev,
+ "Vibrator mode is invalid: %i\n",
+ haptics->mode);
+ return -EINVAL;
+ }
+
+ if (haptics->library < DRV260X_LIB_EMPTY ||
+ haptics->library > DRV260X_ERM_LIB_F) {
+ dev_err(&client->dev,
+ "Library value is invalid: %i\n", haptics->library);
+ return -EINVAL;
+ }
+
+ if (haptics->mode == DRV260X_LRA_MODE &&
+ (haptics->library != DRV260X_LIB_EMPTY ||
+ haptics->library != DRV260X_LIB_LRA)) {
+ dev_err(&client->dev,
+ "LRA Mode with ERM Library mismatch\n");
+ return -EINVAL;
+ }
+
+ haptics->regulator = devm_regulator_get(&client->dev, "vbat");
+ if (IS_ERR(haptics->regulator)) {
+ ret = PTR_ERR(haptics->regulator);
+ dev_err(&client->dev,
+ "unable to get regulator, error: %d\n", ret);
+ return ret;
+ }
+
+ haptics->enable_gpio = devm_gpiod_get(&client->dev, "enable");
+ if (IS_ERR(haptics->enable_gpio)) {
+ ret = PTR_ERR(haptics->enable_gpio);
+ if (ret != -ENOENT && ret != -ENOSYS)
+ return ret;
+ haptics->enable_gpio = NULL;
+ } else {
+ gpiod_direction_output(haptics->enable_gpio, 1);
+ }
+
+ haptics->input_dev = devm_input_allocate_device(&client->dev);
+ if (haptics->input_dev == NULL) {
+ dev_err(&client->dev, "Failed to allocate input device\n");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ haptics->input_dev->name = "drv260x:haptics";
+ haptics->input_dev->dev.parent = client->dev.parent;
+ haptics->input_dev->close = drv260x_close;
+ input_set_drvdata(haptics->input_dev, haptics);
+ input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);
+
+ ret = input_ff_create_memless(haptics->input_dev, NULL,
+ drv260x_haptics_play);
+ if (ret < 0) {
+ dev_err(&client->dev, "input_ff_create() failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ INIT_WORK(&haptics->work, drv260x_worker);
+
+ haptics->client = client;
+ i2c_set_clientdata(client, haptics);
+
+ haptics->regmap = devm_regmap_init_i2c(client, &drv260x_regmap_config);
+ if (IS_ERR(haptics->regmap)) {
+ ret = PTR_ERR(haptics->regmap);
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = drv260x_init(haptics);
+ if (ret < 0) {
+ dev_err(&client->dev, "Device init failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = input_register_device(haptics->input_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "couldn't register input device: %d\n",
+ ret);
+ return ret;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int drv260x_suspend(struct device *dev)
+{
+ struct drv260x_data *haptics = dev_get_drvdata(dev);
+ int ret = 0;
+
+ mutex_lock(&haptics->input_dev->mutex);
+
+ if (haptics->input_dev->users) {
+ ret = regmap_update_bits(haptics->regmap,
+ DRV260X_MODE,
+ DRV260X_STANDBY_MASK,
+ DRV260X_STANDBY);
+ if (ret) {
+ dev_err(dev, "Failed to set standby mode\n");
+ goto out;
+ }
+
+ gpiod_set_value(haptics->enable_gpio, 0);
+
+ ret = regulator_disable(haptics->regulator);
+ if (ret)
+ dev_err(dev, "Failed to disable regulator\n");
+ }
+out:
+ mutex_unlock(&haptics->input_dev->mutex);
+ return ret;
+}
+
+static int drv260x_resume(struct device *dev)
+{
+ struct drv260x_data *haptics = dev_get_drvdata(dev);
+ int ret = 0;
+
+ mutex_lock(&haptics->input_dev->mutex);
+
+ if (haptics->input_dev->users) {
+ ret = regulator_enable(haptics->regulator);
+ if (ret) {
+ dev_err(dev, "Failed to enable regulator\n");
+ goto out;
+ }
+ ret = regmap_update_bits(haptics->regmap,
+ DRV260X_MODE,
+ DRV260X_STANDBY_MASK, 0);
+ if (ret) {
+ dev_err(dev, "Failed to unset standby mode\n");
+ goto out;
+ }
+
+ gpiod_set_value(haptics->enable_gpio, 1);
+ }
+
+out:
+ mutex_unlock(&haptics->input_dev->mutex);
+ return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume);
+
+static const struct i2c_device_id drv260x_id[] = {
+ { "drv2605l", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, drv260x_id);
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id drv260x_of_match[] = {
+ { .compatible = "ti,drv2604", },
+ { .compatible = "ti,drv2604l", },
+ { .compatible = "ti,drv2605", },
+ { .compatible = "ti,drv2605l", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, drv260x_of_match);
+#endif
+
+static struct i2c_driver drv260x_driver = {
+ .probe = drv260x_probe,
+ .driver = {
+ .name = "drv260x-haptics",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(drv260x_of_match),
+ .pm = &drv260x_pm_ops,
+ },
+ .id_table = drv260x_id,
+};
+module_i2c_driver(drv260x_driver);
+
+MODULE_ALIAS("platform:drv260x-haptics");
+MODULE_DESCRIPTION("TI DRV260x haptics driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
diff --git a/include/dt-bindings/input/ti-drv260x.h b/include/dt-bindings/input/ti-drv260x.h
new file mode 100644
index 0000000..b2e5126
--- /dev/null
+++ b/include/dt-bindings/input/ti-drv260x.h
@@ -0,0 +1,36 @@
+/*
+ * DRV260X haptics driver family
+ *
+ * Author: Dan Murphy <dmurphy@ti.com>
+ *
+ * Copyright: (C) 2014 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_TI_DRV260X_H
+#define _DT_BINDINGS_TI_DRV260X_H
+
+/* Calibration Types */
+#define DRV260X_LRA_MODE 0x00
+#define DRV260X_LRA_NO_CAL_MODE 0x01
+#define DRV260X_ERM_MODE 0x02
+
+/* Library Selection */
+#define DRV260X_LIB_EMPTY 0x00
+#define DRV260X_ERM_LIB_A 0x01
+#define DRV260X_ERM_LIB_B 0x02
+#define DRV260X_ERM_LIB_C 0x03
+#define DRV260X_ERM_LIB_D 0x04
+#define DRV260X_ERM_LIB_E 0x05
+#define DRV260X_LIB_LRA 0x06
+#define DRV260X_ERM_LIB_F 0x07
+
+#endif
diff --git a/include/linux/platform_data/drv260x-pdata.h b/include/linux/platform_data/drv260x-pdata.h
new file mode 100644
index 0000000..4091a9b
--- /dev/null
+++ b/include/linux/platform_data/drv260x-pdata.h
@@ -0,0 +1,29 @@
+/*
+ * Platform data for DRV260X haptics driver family
+ *
+ * Author: Dan Murphy <dmurphy@ti.com>
+ *
+ * Copyright: (C) 2014 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _LINUX_DRV260X_PDATA_H
+#define _LINUX_DRV260X_PDATA_H
+
+struct drv260x_platform_data {
+ int enable_gpio;
+ u32 library_selection;
+ u32 mode;
+ u32 vib_rated_voltage;
+ u32 vib_overdrive_voltage;
+};
+
+#endif
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 2/2] Input: atmel_mxt_ts - Add keycodes array example
From: Nick Dyer @ 2014-08-15 16:08 UTC (permalink / raw)
To: Javier Martinez Canillas, Dmitry Torokhov
Cc: Stephen Warren, Yufeng Shen, Benson Leung, Doug Anderson,
Olof Johansson, linux-input, devicetree, linux-samsung-soc,
linux-kernel
In-Reply-To: <53EDF6B4.7080804@collabora.co.uk>
On 15/08/14 13:01, Javier Martinez Canillas wrote:
>> By passing all these keycodes the touchpad worked as expected for me and the
>> driver did the same than the Chrome OS driver that has these keycodes hardcoded
>> when is_tp is true.
>>
>>> at the protocol guide for T19.
>>
>> I don't have access to proper documentation and I wouldn't expect people to have
>> access to non-public docs in order to use a Device Tree binding.
>>
>> That's why I wanted to document an example, so using this property could be
>> easier for others and they shouldn't have to look at the driver in order to
>> figure it out (and getting it wrong as you said :) )
>>
>> So it would be great if you could provide an example on how this is supposed to
>> be used.
>
> Any comments on this? I would really appreciate if you can expand on how
> this DT property is supposed to be used so I can re-spin the atmel support
> patch for Peach boards.
The below patch improves the documentation for the gpio-property. Stephen
Warren has a good example here:
https://github.com/swarren/linux-tegra/commit/09789801
trackpad@4b {
compatible = "atmel,maxtouch";
reg = <0x4b>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_LOW>;
linux,gpio-keymap = <0 0 0 BTN_LEFT>;
};
This maps BTN_LEFT to the 4th bit of the T19 message. I haven't looked up
what GPIO number that corresponds to on the mXT224SL that he has, it varies
with the particular maXTouch device you have.
Hope this helps.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
Documentation/devicetree/bindings/input/atmel,maxtouch.txt | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index baef432..1852906 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -11,10 +11,17 @@ Required properties:
Optional properties for main touchpad device:
-- linux,gpio-keymap: An array of up to 4 entries indicating the Linux
- keycode generated by each GPIO. Linux keycodes are defined in
+- linux,gpio-keymap: When enabled, the SPT_GPIOPWN_T19 object sends messages
+ on GPIO bit changes. An array of up to 8 entries can be provided
+ indicating the Linux keycode mapped to each bit of the status byte,
+ starting at the LSB. Linux keycodes are defined in
<dt-bindings/input/input.h>.
+ Note: the numbering of the GPIOs and the bit they start at varies between
+ maXTouch devices. You must either refer to the documentation, or
+ experiment to determine which bit corresponds to which input. Use
+ KEY_RESERVED for unused padding values.
+
Example:
touch@4b {
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 2/2] Input: atmel_mxt_ts - Add keycodes array example
From: Stephen Warren @ 2014-08-15 16:13 UTC (permalink / raw)
To: Nick Dyer, Javier Martinez Canillas, Dmitry Torokhov
Cc: Stephen Warren, Yufeng Shen, Benson Leung, Doug Anderson,
Olof Johansson, linux-input, devicetree, linux-samsung-soc,
linux-kernel
In-Reply-To: <53EE307E.8060507@itdev.co.uk>
On 08/15/2014 10:08 AM, Nick Dyer wrote:
> On 15/08/14 13:01, Javier Martinez Canillas wrote:
>>> By passing all these keycodes the touchpad worked as expected for me and the
>>> driver did the same than the Chrome OS driver that has these keycodes hardcoded
>>> when is_tp is true.
>>>
>>>> at the protocol guide for T19.
>>>
>>> I don't have access to proper documentation and I wouldn't expect people to have
>>> access to non-public docs in order to use a Device Tree binding.
>>>
>>> That's why I wanted to document an example, so using this property could be
>>> easier for others and they shouldn't have to look at the driver in order to
>>> figure it out (and getting it wrong as you said :) )
>>>
>>> So it would be great if you could provide an example on how this is supposed to
>>> be used.
>>
>> Any comments on this? I would really appreciate if you can expand on how
>> this DT property is supposed to be used so I can re-spin the atmel support
>> patch for Peach boards.
>
> The below patch improves the documentation for the gpio-property.
That patch makes sense, and is a nice description,
Acked-by: Stephen Warren <swarren@nvidia.com>
> diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> Example:
>
> touch@4b {
>
Perhaps it makes sense to add a linux,gpio-keymap property into the
example too though; IIRC there was an earlier patch to the docs that did
this?
^ permalink raw reply
* Re: [PATCH] remove explicit devm_kfree
From: Dmitry Torokhov @ 2014-08-15 16:51 UTC (permalink / raw)
To: Arjun Sreedharan; +Cc: lejun.zhu, linux-input, linux-kernel
In-Reply-To: <1408116365-3013-1-git-send-email-arjun024@gmail.com>
On Fri, Aug 15, 2014 at 08:56:05PM +0530, Arjun Sreedharan wrote:
> Memory allocated with devm_kzalloc() is freed automatically when device
> out of scope.
But in this case the device does not necessarily goes "out of scope" and we
still want to release memory.
Thanks.
>
> Signed-off-by: Arjun Sreedharan <arjun024@gmail.com>
> ---
> drivers/input/misc/soc_button_array.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
> index 5a6334b..123e59f 100644
> --- a/drivers/input/misc/soc_button_array.c
> +++ b/drivers/input/misc/soc_button_array.c
> @@ -131,7 +131,6 @@ soc_button_device_create(struct pnp_dev *pdev,
> err_free_pdev:
> platform_device_put(pd);
> err_free_mem:
> - devm_kfree(&pdev->dev, gpio_keys_pdata);
> return ERR_PTR(error);
> }
>
> --
> 1.7.11.7
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: hyperv-keyboard - implement Type Clipboard Text
From: Dmitry Torokhov @ 2014-08-15 16:57 UTC (permalink / raw)
To: Dexuan Cui
Cc: olaf, gregkh, jasowang, driverdev-devel, linux-kernel,
linux-input, apw, haiyangz
In-Reply-To: <1408095719-19117-1-git-send-email-decui@microsoft.com>
Hi Dexuan,
On Fri, Aug 15, 2014 at 02:41:59AM -0700, Dexuan Cui wrote:
> In the menu of the Hyper-V's Virtual Machine Connection, there is a feature
> called "Clipboard | Type clipboard text", which can be used to copy a string
> in the host's clipboard into the guest's current input focus(text console or
> a GUI window).
>
> Currently the feature doesn't work for Linux VM because the driver
> hyperv-keyboard hasn't been enhanced to support it -- this patch is made
> to do it.
>
> For each char in the string, the host sends 2 events (key down/up with the
> char's UNICODE value) to the guest.
> The patch finds each char's scan codes of key down/up, and injects the
> scan codes to the serio keyboard module.
>
> Known issues:
> 1) Only printable ASCII chars are supported, and unsupported chars are
> ignored. It seems unlikely to support generic UNICODE chars because there
> is not a generic API to inject a UNICODE char to text mode console, KDE,
> gnome, etc.
>
> 2) When we use the feature, make sure the CapsLock state of the VM's
> (virtual) keyboard is OFF because this patch assumes it -- we'll try to
> fix this later, probably by tracking the state of virtual CapsLock, because
> it looks the keyboard module doesn't supply an API for us to query the state
> of the keyboard.
>
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
No way. If you want to do this this way, do it in hypervisor code and keep
feeding AT scan codes to hyperv-keyboard, although I am pretty sure users of
French, Czech and other keyboard layouts with numbers in upper register and
symbols in lower will have a few choice words for you.
If you want real cut-and-paste support in various DEs I'd recommend working
with VMware on open-vm-tools package to see what can be shared/reused there.
Consider this NACked with prejudice.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: atmel_mxt_ts - remove unneeded check
From: Dmitry Torokhov @ 2014-08-17 14:28 UTC (permalink / raw)
To: linux-input; +Cc: Nick Dyer, Stephen Warren, linux-kernel
This fixes the following issue reported by Coverity:
** CID 1231785: Unsigned compared against 0 (NO_EFFECT)
/drivers/input/touchscreen/atmel_mxt_ts.c: 1157 in mxt_prepare_cfg_mem()
The variable 'byte_offset' is declared as unsigned int and therefore can never
be less than 0.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index db178ed..8780c9a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1154,7 +1154,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
byte_offset = reg + i - cfg_start_ofs;
- if (byte_offset >= 0 && byte_offset < config_mem_size) {
+ if (byte_offset < config_mem_size) {
*(config_mem + byte_offset) = val;
} else {
dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",
--
2.1.0.rc2.206.gedb03e5
--
Dmitry
^ permalink raw reply related
* Re: [RESEND PATCH] Support Xbox One controllers in xpad driver.
From: Dmitry Torokhov @ 2014-08-17 16:20 UTC (permalink / raw)
To: Ted Mielczarek
Cc: linux-input, paul.gortmaker, hor27, petr, magissia, linux-kernel
In-Reply-To: <1407509169-6849-1-git-send-email-ted@mielczarek.org>
On Fri, Aug 08, 2014 at 10:46:09AM -0400, Ted Mielczarek wrote:
> Xbox One controllers require an initialization message to start sending data,
> so xpad_init_output becomes a required function. The Xbox One controller does
> not have LEDs like the Xbox 360 controller, so that functionality is not
> implemented. The format of messages controlling rumble is currently
> undocumented, so rumble support is not yet implemented.
>
> The only thing I'm not certain about in this patch is the check against bInterfaceNumber in xpad_probe. The Xbox One controller advertises three interfaces with the same interface class, subclass and protocol, and I couldn't see any way to match just the first one using usb_device_id.
>
> Signed-off-by: Ted Mielczarek <ted@mielczarek.org>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* [PATCH] HID: usbhid: quirk for NEC Corp. PA302W monitor
From: pancho horrillo @ 2014-08-17 22:35 UTC (permalink / raw)
To: linux-input
This device has an odd HID entry and causes a 10 second delay in boot.
Add this device to the quirks list with HID_QUIRK_NO_INIT_REPORTS.
[EDIT OUT THE FOLLOWING AS NEEDED IF EXPLANATION IS TOO MUCH, THIS LINE INCL.]
dmesg shows the 10 second delay, which hinders normal operation
(e.g., using the keyboard):
[ +10.098394] hid-generic 0003:0409:042F.005A: timeout initializing reports
Passing this arg to the kernel fixes the issue:
usbhid.quirks=0x0409:0x042f:0x20000000
This patch expresses precisely the above quirk.
See https://bugzilla.redhat.com/attachment.cgi?id=710695 for a similar case.
For reference, here is the output of 'lsusb -v -d 0409:042f':
Bus 002 Device 003: ID 0409:042f NEC Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0409 NEC Corp.
idProduct 0x042f
bcdDevice 0.01
iManufacturer 1 NEC
iProduct 2 PA302W
iSerial 3 3X100603TW
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 41
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 39
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Device Status: 0x0001
Self Powered
Signed-off-by: pancho horrillo <pancho@pancho.name>
---
drivers/hid/hid-ids.h | 3 +++
drivers/hid/usbhid/hid-quirks.c | 1 +
2 files changed, 4 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 25cd674..d636c37 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -665,6 +665,9 @@
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
+#define USB_VENDOR_ID_NEC_CORP 0x0409
+#define USB_DEVICE_ID_NEC_CORP_PA302W 0x042f
+
#define USB_VENDOR_ID_NEXIO 0x1870
#define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d
#define USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750 0x0110
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 15225f3..34c1bc9 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -41,6 +41,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_NEC_CORP, USB_DEVICE_ID_NEC_CORP_PA302W, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
--
2.0.4
--
pancho horrillo
To be conscious that
you are ignorant is a great step
to knowledge.
Benjamin Disraeli
^ permalink raw reply related
* Re: [Question: Drivers/input/evdev.c] What is the use of write function in evdev_fops?
From: Peter Hutterer @ 2014-08-18 1:57 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: Dmitry Torokhov, linux-input@vger.kernel.org
In-Reply-To: <CADYu308JT8owRimn4i9mW4eKa3T--yjCdbGns1O9R_WWx_uF-w@mail.gmail.com>
On Fri, Aug 15, 2014 at 02:01:48AM +0530, Aniroop Mathur wrote:
[...]
> >> >>
> >> >>2 separate file descriptors like below ?
> >> >>int fd1 = open("/dev/uinput", O_RDWR);
> >> >>int fd2 = open("/dev/uinput", O_RDWR);
> >> >>
> >> >>But my reading data will still come in struct input_event as mentioned
> >> >>above.
> >> >>It has only time, type, code and value.
> >> >>So, how we can use bitmask here ?
> >> >>
> >> >>struct input_event {
> >> >>struct timeval time;
> >> >>__u16 type;
> >> >>__u16 code;
> >> >>__s32 value;
> >> >> };
> >> >
> >> > By opening 2 fds you'll end up creating 2 separate input devices with separate evdev nodes, etc, so you will not mix up input events.
> >> >
> >> > I think at this time you should just try actually using uinput and that should clear things for you.
> >> >
> >>
> >> Can you please explain what do you mean by separate evdev nodes ?
> >> Do you mean two separate evdev nodes for uinput ?
> >> But as we discussed before, there is only one node in case of uinput
> >> i.e. /dev/uinput.
> >
> > Uinput allows to creating input devices driven from userspace. You can
> > create as many separate input devices as you want by opening
> > /dev/uinput several times since it creates a device per file descriptor.
> > Each of these input devices will get evdev attached to it and will get
> > it's own /dev/input/eventX node created.
> >
> > Really, please try using uinput, it will clear a lot if things for you.
> > For example, see what http://www.freedesktop.org/wiki/Evemu/ does.
> >
>
>
> Thank you Mr. Torokhov for the discussion and answering my queries. :)
> I will try to explore more.
I recommend you look at libevdev if you're planning to use uinput. evemu
uses that now too and it makes a whole bunch of stuff easier and less likely
to go wrong.
http://freedesktop.org/wiki/Software/libevdev/
specifically:
http://www.freedesktop.org/software/libevdev/doc/1.2/group__uinput.html
Cheers,
Peter
^ permalink raw reply
* RE: [PATCH] Input: hyperv-keyboard - implement Type Clipboard Text
From: Dexuan Cui @ 2014-08-18 3:54 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: gregkh@linuxfoundation.org, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org,
driverdev-devel@linuxdriverproject.org, olaf@aepfle.de,
apw@canonical.com, jasowang@redhat.com, KY Srinivasan,
Haiyang Zhang
In-Reply-To: <20140815165733.GB25225@core.coreip.homeip.net>
> -----Original Message-----
> From: Dmitry Torokhov
> Sent: Saturday, August 16, 2014 0:58 AM
> To: Dexuan Cui
> > For each char in the string, the host sends 2 events (key down/up with the
> > char's UNICODE value) to the guest.
> > The patch finds each char's scan codes of key down/up, and injects the
> > scan codes to the serio keyboard module.
> >
> > Known issues:
> > 1) Only printable ASCII chars are supported, and unsupported chars are
> > ignored. It seems unlikely to support generic UNICODE chars because there
> > is not a generic API to inject a UNICODE char to text mode console, KDE,
> > gnome, etc.
> >
> > 2) When we use the feature, make sure the CapsLock state of the VM's
> > (virtual) keyboard is OFF because this patch assumes it -- we'll try to
> > fix this later, probably by tracking the state of virtual CapsLock, because
> > it looks the keyboard module doesn't supply an API for us to query the
> state
> > of the keyboard.
> >
> No way. If you want to do this this way, do it in hypervisor code and keep
> feeding AT scan codes to hyperv-keyboard, although I am pretty sure users
Hi Dmitry,
Yeah, I had the same wish, but later I found this seems unlikely because IMO
the feature was firstly invented for Windows VM + generic UNICODE chars,
and we know there is no "scan code" for generic UNICODE chars... :-(
> of
> French, Czech and other keyboard layouts with numbers in upper register
> and
> symbols in lower will have a few choice words for you.
Sorry, I can't understand what these are.
Can you please give more details or a link to further info?
> If you want real cut-and-paste support in various DEs I'd recommend
> working
> with VMware on open-vm-tools package to see what can be shared/reused
> there.
> Consider this NACked with prejudice.
> Dmitry
Thanks for the suggestion!
Let me study open-vm-tools and report back.
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH 2/2] Input: atmel_mxt_ts - Add keycodes array example
From: Javier Martinez Canillas @ 2014-08-18 13:20 UTC (permalink / raw)
To: Nick Dyer, Dmitry Torokhov
Cc: Stephen Warren, Yufeng Shen, Benson Leung, Doug Anderson,
Olof Johansson, linux-input, devicetree, linux-samsung-soc,
linux-kernel
In-Reply-To: <53EE307E.8060507@itdev.co.uk>
Hello Nick,
On 08/15/2014 06:08 PM, Nick Dyer wrote:
>>
>> Any comments on this? I would really appreciate if you can expand on how
>> this DT property is supposed to be used so I can re-spin the atmel support
>> patch for Peach boards.
>
> The below patch improves the documentation for the gpio-property. Stephen
> Warren has a good example here:
> https://github.com/swarren/linux-tegra/commit/09789801
>
> trackpad@4b {
> compatible = "atmel,maxtouch";
> reg = <0x4b>;
> interrupt-parent = <&gpio>;
> interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_LOW>;
> linux,gpio-keymap = <0 0 0 BTN_LEFT>;
> };
>
> This maps BTN_LEFT to the 4th bit of the T19 message. I haven't looked up
> what GPIO number that corresponds to on the mXT224SL that he has, it varies
> with the particular maXTouch device you have.
>
> Hope this helps.
>
Thanks a lot for the patch and the pointer to Stephen's DTS. I'll do some
experimentation then to figure out the right values since I don't have
proper documentation. Fortunately the Chrome OS 3.8 downstream driver
works on -next so I can use evdev to compare if both drivers behave the same.
> Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Best regards,
Javier
^ permalink raw reply
* [PATCH] evdev: Replace rcu_assign_pointer() with RCU_INIT_POINTER()
From: Andreea-Cristina Bernat @ 2014-08-18 14:44 UTC (permalink / raw)
To: dmitry.torokhov, rydberg, linux-input, linux-kernel; +Cc: paulmck
The use of "rcu_assign_pointer()" is NULLing out the pointer.
According to RCU_INIT_POINTER()'s block comment:
"1. This use of RCU_INIT_POINTER() is NULLing out the pointer"
it is better to use it instead of rcu_assign_pointer() because it has a
smaller overhead.
The following Coccinelle semantic patch was used:
@@
@@
- rcu_assign_pointer
+ RCU_INIT_POINTER
(..., NULL)
Signed-off-by: Andreea-Cristina Bernat <bernat.ada@gmail.com>
---
drivers/input/evdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index fd325ec..33e53a7 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -291,7 +291,7 @@ static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client)
if (grab != client)
return -EINVAL;
- rcu_assign_pointer(evdev->grab, NULL);
+ RCU_INIT_POINTER(evdev->grab, NULL);
synchronize_rcu();
input_release_device(&evdev->handle);
--
1.9.1
^ 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