* Re: [PATCH 0/4] HID: implement new transport-driver callbacks
From: David Herrmann @ 2014-01-29 8:37 UTC (permalink / raw)
To: Jiri Kosina; +Cc: Frank Praznik, open list:HID CORE LAYER, Benjamin Tissoires
In-Reply-To: <alpine.LNX.2.00.1401282153141.22492@pobox.suse.cz>
Hi
On Tue, Jan 28, 2014 at 9:53 PM, Jiri Kosina <jkosina@suse.cz> wrote:
> On Wed, 22 Jan 2014, David Herrmann wrote:
>
>> > These patches are originally the work of David Herrmann who suggested that I
>> > update and submit them as their functionality is required for some pending
>> > patches to the hid-sony driver.
>> >
>> > These patches implement the SET/GET_REPORT and raw intr OUTPUT requests for all
>> > transport drivers. It adds two callbacks to the hid_ll_driver struct:
>> >
>> > int (*raw_request)(struct hid_device *hdev, unsigned char reportnum,
>> > __u8 *buf, size_t len, unsigned char rtype, int reqtype);
>> >
>> > int (*output_report)(struct hid_device *hdev, __u8 *buf, size_t len);
>> >
>> > along with the necessary support fuctions in the USBHID, and HIDP drivers.
>> >
>> > UHID is not converted yet.
>>
>> Thanks for picking it up. As background, people should read my HID
>> summary which originally was part of this series:
>> http://cgit.freedesktop.org/~dvdhrm/linux/tree/Documentation/hid/hid-transport.txt?h=hid&id=86c08bb28302bb31dcd3b9aaf22b222f890397e0
>>
>> Our current hid_output_raw_report() callbacks are implemented
>> differently in the USBHID, HIDP, I2CHID and UHID backends (I even
>> think they're all mutually different). We cannot easily change these
>> as drivers actually depend on the backends to do it differently.
>> Therefore, I proposed the raw_request() and output_report() functions.
>> raw_request() is basically the same as request() but takes a raw
>> buffer instead of an hid_report. output_report() is what HIDP
>> currently does with hid_output_raw_report() and sends the report as
>> asynchronous intr report.
>>
>> The plan should be to use request(), raw_request() and output_report()
>> exclusively and carefully port drivers to use them. Once we're done,
>> we can remove hid_output_raw_report() (and any other legacy). This
>> should guarantee, that drivers can choose between ctrl-SET_REPORT and
>> intr-OUTPUT_REPORT messages without depending on the underlying
>> backend to choose the right one.
>
> I haven't finished reviewing the patchset yet, but anyway -- David, can I
> consider your e-mail as a potential Acked-by:?
Yes, definitely. It's basically my 1-year old patch split into 3.
Thanks
David
^ permalink raw reply
* Re: [PATCH] HID: i2c-hid: add runtime PM support
From: Mika Westerberg @ 2014-01-29 9:13 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: linux-input, Jiri Kosina, Benjamin Tissoires,
linux-kernel@vger.kernel.org
In-Reply-To: <CAN+gG=GPHyWdM+G=dzswfqVT4Jm8kEbnQs58jq2M_7_-FVB0=w@mail.gmail.com>
On Tue, Jan 28, 2014 at 09:19:33AM -0500, Benjamin Tissoires wrote:
> On Tue, Jan 28, 2014 at 4:12 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Mon, Jan 27, 2014 at 10:36:25PM -0500, Benjamin Tissoires wrote:
> >> On Tue, Jan 14, 2014 at 5:13 AM, Mika Westerberg
> >> <mika.westerberg@linux.intel.com> wrote:
> >> > This patch adds runtime PM support for the HID over I2C driver. When the
> >> > i2c-hid device is first opened we power it on and on the last close we
> >> > power it off.
> >> >
> >> > The implementation is not the most power efficient because it needs some
> >> > interaction from the userspace (e.g close the device node whenever we are
> >> > no more interested in getting events), nevertheless it allows us to save
> >> > some power and works with devices that are not wake capable.
> >> >
> >>
> >> Hi Mika,
> >>
> >> I am a little bit puzzled here. The commit message just says that you
> >> changed the implementation of the power saving with the exact same
> >> behavior... At least that's what I understand.
> >> Currently, the devices should be put on sleep if nobody is reading,
> >> and back alive if a reader arrives.
> >> I think there is a gain with the patch, but my knowledge of the pm
> >> subsystem is far too limited to see it :(
> >
> > Yes, there should be gain. If there is power domain involved like, ACPI in
> > our case, runtime suspending the device on close will let ACPI to move the
> > device to D3cold (e.g full off) which saves more power.
>
> Oh, right. So, if you could just put this last sentence in the commit
> message, that would be great.
Sure.
>
> >
> >> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> >> > ---
> >> > drivers/hid/i2c-hid/i2c-hid.c | 81 ++++++++++++++++++++++++++++---------------
> >> > 1 file changed, 54 insertions(+), 27 deletions(-)
> >> >
> >> > diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
> >> > index d1f81f52481a..ff767d03d60e 100644
> >> > --- a/drivers/hid/i2c-hid/i2c-hid.c
> >> > +++ b/drivers/hid/i2c-hid/i2c-hid.c
> >> > @@ -25,6 +25,7 @@
> >> > #include <linux/delay.h>
> >> > #include <linux/slab.h>
> >> > #include <linux/pm.h>
> >> > +#include <linux/pm_runtime.h>
> >> > #include <linux/device.h>
> >> > #include <linux/wait.h>
> >> > #include <linux/err.h>
> >> > @@ -454,10 +455,18 @@ static void i2c_hid_init_reports(struct hid_device *hid)
> >> > return;
> >> > }
> >> >
> >> > + /*
> >> > + * The device must be powered on while we fetch initial reports
> >> > + * from it.
> >> > + */
> >> > + pm_runtime_get_sync(&client->dev);
> >> > +
> >> > list_for_each_entry(report,
> >> > &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
> >> > i2c_hid_init_report(report, inbuf, ihid->bufsize);
> >> >
> >> > + pm_runtime_put(&client->dev);
> >> > +
> >> > kfree(inbuf);
> >> > }
> >> >
> >> > @@ -703,8 +712,8 @@ static int i2c_hid_open(struct hid_device *hid)
> >> >
> >> > mutex_lock(&i2c_hid_open_mut);
> >> > if (!hid->open++) {
> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
> >> > - if (ret) {
> >> > + ret = pm_runtime_get_sync(&client->dev);
> >>
> >> dummy question (kind of late here...). Is there a counter of how many
> >> get/put has been called in pm_runtime which could allow us to get rid
> >> of the hid->open count?
> >
> > There is a counter but I'm not sure if drivers are supposed to use that. I
> > would prefer not to use that.
>
> ok
>
> >
> >>
> >> > + if (ret < 0) {
> >> > hid->open--;
> >> > goto done;
> >> > }
> >> > @@ -712,7 +721,7 @@ static int i2c_hid_open(struct hid_device *hid)
> >> > }
> >> > done:
> >> > mutex_unlock(&i2c_hid_open_mut);
> >> > - return ret;
> >> > + return ret < 0 ? ret : 0;
> >> > }
> >> >
> >> > static void i2c_hid_close(struct hid_device *hid)
> >> > @@ -729,37 +738,17 @@ static void i2c_hid_close(struct hid_device *hid)
> >> > clear_bit(I2C_HID_STARTED, &ihid->flags);
> >> >
> >> > /* Save some power */
> >> > - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
> >> > + pm_runtime_put(&client->dev);
> >> > }
> >> > mutex_unlock(&i2c_hid_open_mut);
> >> > }
> >> >
> >> > -static int i2c_hid_power(struct hid_device *hid, int lvl)
> >> > -{
> >> > - struct i2c_client *client = hid->driver_data;
> >> > - struct i2c_hid *ihid = i2c_get_clientdata(client);
> >> > - int ret = 0;
> >> > -
> >> > - i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl);
> >> > -
> >> > - switch (lvl) {
> >> > - case PM_HINT_FULLON:
> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
> >> > - break;
> >> > - case PM_HINT_NORMAL:
> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
> >> > - break;
> >> > - }
> >> > - return ret;
> >> > -}
> >> > -
> >> > static struct hid_ll_driver i2c_hid_ll_driver = {
> >> > .parse = i2c_hid_parse,
> >> > .start = i2c_hid_start,
> >> > .stop = i2c_hid_stop,
> >> > .open = i2c_hid_open,
> >> > .close = i2c_hid_close,
> >> > - .power = i2c_hid_power,
> >>
> >> If I understand correctly, here you are trying to fix hidraw (with
> >> i2c_hid tramsport) which used to set_power on/off twice with the first
> >> reader, right?
> >
> > Right.
> >
> >> I don't think we have other i2c_hid users of hid_hw_power, but I am a
> >> little bit worried of simply removing the callback.
> >
> > OK.
> >
> >> What if we just change i2c_hid_set_power in i2c_hid_power by the
> >> corresponding pm_runtime calls?
> >
> > Sure, I'll change that in the next version.
> >
> >>
> >> > .request = i2c_hid_request,
> >> > };
> >> >
> >> > @@ -973,13 +962,17 @@ static int i2c_hid_probe(struct i2c_client *client,
> >> > if (ret < 0)
> >> > goto err;
> >> >
> >> > + pm_runtime_get_noresume(&client->dev);
> >> > + pm_runtime_set_active(&client->dev);
> >> > + pm_runtime_enable(&client->dev);
> >> > +
> >> > ret = i2c_hid_fetch_hid_descriptor(ihid);
> >> > if (ret < 0)
> >> > - goto err;
> >> > + goto err_pm;
> >> >
> >> > ret = i2c_hid_init_irq(client);
> >> > if (ret < 0)
> >> > - goto err;
> >> > + goto err_pm;
> >> >
> >> > hid = hid_allocate_device();
> >> > if (IS_ERR(hid)) {
> >> > @@ -1010,6 +1003,7 @@ static int i2c_hid_probe(struct i2c_client *client,
> >> > goto err_mem_free;
> >> > }
> >> >
> >> > + pm_runtime_put(&client->dev);
> >> > return 0;
> >> >
> >> > err_mem_free:
> >> > @@ -1018,6 +1012,10 @@ err_mem_free:
> >> > err_irq:
> >> > free_irq(client->irq, ihid);
> >> >
> >> > +err_pm:
> >> > + pm_runtime_put_noidle(&client->dev);
> >> > + pm_runtime_disable(&client->dev);
> >> > +
> >> > err:
> >> > i2c_hid_free_buffers(ihid);
> >> > kfree(ihid);
> >> > @@ -1029,6 +1027,11 @@ static int i2c_hid_remove(struct i2c_client *client)
> >> > struct i2c_hid *ihid = i2c_get_clientdata(client);
> >> > struct hid_device *hid;
> >> >
> >> > + pm_runtime_get_sync(&client->dev);
> >> > + pm_runtime_disable(&client->dev);
> >> > + pm_runtime_set_suspended(&client->dev);
> >> > + pm_runtime_put_noidle(&client->dev);
> >> > +
> >> > hid = ihid->hid;
> >> > hid_destroy_device(hid);
> >> >
> >> > @@ -1074,7 +1077,31 @@ static int i2c_hid_resume(struct device *dev)
> >> > }
> >> > #endif
> >> >
> >> > -static SIMPLE_DEV_PM_OPS(i2c_hid_pm, i2c_hid_suspend, i2c_hid_resume);
> >> > +#ifdef CONFIG_PM_RUNTIME
> >> > +static int i2c_hid_runtime_suspend(struct device *dev)
> >> > +{
> >> > + struct i2c_client *client = to_i2c_client(dev);
> >> > +
> >> > + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
> >> > + disable_irq(client->irq);
> >> > + return 0;
> >> > +}
> >> > +
> >> > +static int i2c_hid_runtime_resume(struct device *dev)
> >> > +{
> >> > + struct i2c_client *client = to_i2c_client(dev);
> >> > +
> >> > + enable_irq(client->irq);
> >> > + i2c_hid_set_power(client, I2C_HID_PWR_ON);
> >> > + return 0;
> >> > +}
> >>
> >> These two functions looks very similar to i2c_hid_suspend and
> >> i2c_hid_resume, without the reset and the irq_wake :(
> >> So, my question here is can we use some common code for them?
> >> It may not be possible regarding CONFIG_PM_RUNTIME and
> >> CONFIG_PM_SLEEP, but it still looks ugly to me.
> >
> > It looks ugly, I agree and we can probably reuse some code in the
> > callbacks. I'll look into that.
>
> well, anyway, if this involve something even more ugly, we can for
> sure stick with this version :)
It turned out that it is going to be ugly, no matter what :-( I'll keep the
current version for now.
>
> >
> >> I tested this today, and it works, so you should be right, but I'd
> >> like to have your opinion on this.
> >
> > Thanks for testing and comments.
> >
> > I'll prepare a new version with the suggested changes if you are OK with my
> > explanations ;-)
>
> Sure I am. Thanks for handling the whole ACPI part of this module. I
> was really pleased the other day to see that the touchscreen of a Bay
> trail tablet is now working out of the box :) I still have many other
> problems with this tablet, but still, having the input working is
> always good with a tablet...
If that's the Asus T100 tablet, we are going to fix rest of the problems
soon :-)
^ permalink raw reply
* [PATCH v2] HID: i2c-hid: add runtime PM support
From: Mika Westerberg @ 2014-01-29 9:24 UTC (permalink / raw)
To: linux-input
Cc: Jiri Kosina, Benjamin Tissoires, Mika Westerberg, linux-kernel
This patch adds runtime PM support for the HID over I2C driver. When the
i2c-hid device is first opened we power it on and on the last close we
power it off. This is actually what the driver is already doing but in
addition it allows subsystems, like ACPI power domain to power off the
device during runtime PM suspend, which should save even more power.
The implementation is not the most power efficient because it needs some
interaction from the userspace (e.g close the device node whenever we are
no more interested in getting events), nevertheless it allows us to save
some power and works with devices that are not wake capable.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
v2:
- Update changelog to mention that ACPI power domain for example can
power off the device on suspend.
- Make i2c_hid_power to just call RPM get/put
drivers/hid/i2c-hid/i2c-hid.c | 68 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 11 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index d1f81f52481a..923ff818a1bf 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/err.h>
@@ -454,10 +455,18 @@ static void i2c_hid_init_reports(struct hid_device *hid)
return;
}
+ /*
+ * The device must be powered on while we fetch initial reports
+ * from it.
+ */
+ pm_runtime_get_sync(&client->dev);
+
list_for_each_entry(report,
&hid->report_enum[HID_FEATURE_REPORT].report_list, list)
i2c_hid_init_report(report, inbuf, ihid->bufsize);
+ pm_runtime_put(&client->dev);
+
kfree(inbuf);
}
@@ -703,8 +712,8 @@ static int i2c_hid_open(struct hid_device *hid)
mutex_lock(&i2c_hid_open_mut);
if (!hid->open++) {
- ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
- if (ret) {
+ ret = pm_runtime_get_sync(&client->dev);
+ if (ret < 0) {
hid->open--;
goto done;
}
@@ -712,7 +721,7 @@ static int i2c_hid_open(struct hid_device *hid)
}
done:
mutex_unlock(&i2c_hid_open_mut);
- return ret;
+ return ret < 0 ? ret : 0;
}
static void i2c_hid_close(struct hid_device *hid)
@@ -729,7 +738,7 @@ static void i2c_hid_close(struct hid_device *hid)
clear_bit(I2C_HID_STARTED, &ihid->flags);
/* Save some power */
- i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+ pm_runtime_put(&client->dev);
}
mutex_unlock(&i2c_hid_open_mut);
}
@@ -738,19 +747,18 @@ static int i2c_hid_power(struct hid_device *hid, int lvl)
{
struct i2c_client *client = hid->driver_data;
struct i2c_hid *ihid = i2c_get_clientdata(client);
- int ret = 0;
i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl);
switch (lvl) {
case PM_HINT_FULLON:
- ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+ pm_runtime_get_sync(&client->dev);
break;
case PM_HINT_NORMAL:
- ret = i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+ pm_runtime_put(&client->dev);
break;
}
- return ret;
+ return 0;
}
static struct hid_ll_driver i2c_hid_ll_driver = {
@@ -973,13 +981,17 @@ static int i2c_hid_probe(struct i2c_client *client,
if (ret < 0)
goto err;
+ pm_runtime_get_noresume(&client->dev);
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_enable(&client->dev);
+
ret = i2c_hid_fetch_hid_descriptor(ihid);
if (ret < 0)
- goto err;
+ goto err_pm;
ret = i2c_hid_init_irq(client);
if (ret < 0)
- goto err;
+ goto err_pm;
hid = hid_allocate_device();
if (IS_ERR(hid)) {
@@ -1010,6 +1022,7 @@ static int i2c_hid_probe(struct i2c_client *client,
goto err_mem_free;
}
+ pm_runtime_put(&client->dev);
return 0;
err_mem_free:
@@ -1018,6 +1031,10 @@ err_mem_free:
err_irq:
free_irq(client->irq, ihid);
+err_pm:
+ pm_runtime_put_noidle(&client->dev);
+ pm_runtime_disable(&client->dev);
+
err:
i2c_hid_free_buffers(ihid);
kfree(ihid);
@@ -1029,6 +1046,11 @@ static int i2c_hid_remove(struct i2c_client *client)
struct i2c_hid *ihid = i2c_get_clientdata(client);
struct hid_device *hid;
+ pm_runtime_get_sync(&client->dev);
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
hid = ihid->hid;
hid_destroy_device(hid);
@@ -1074,7 +1096,31 @@ static int i2c_hid_resume(struct device *dev)
}
#endif
-static SIMPLE_DEV_PM_OPS(i2c_hid_pm, i2c_hid_suspend, i2c_hid_resume);
+#ifdef CONFIG_PM_RUNTIME
+static int i2c_hid_runtime_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+ disable_irq(client->irq);
+ return 0;
+}
+
+static int i2c_hid_runtime_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ enable_irq(client->irq);
+ i2c_hid_set_power(client, I2C_HID_PWR_ON);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops i2c_hid_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume)
+ SET_RUNTIME_PM_OPS(i2c_hid_runtime_suspend, i2c_hid_runtime_resume,
+ NULL)
+};
static const struct i2c_device_id i2c_hid_id_table[] = {
{ "hid", 0 },
--
1.8.5.2
^ permalink raw reply related
* Re: Can I limit the scope of an input device to specific processes ?
From: Dr. Zimmermann @ 2014-01-29 9:44 UTC (permalink / raw)
To: David Herrmann; +Cc: linux-input
In-Reply-To: <CANq1E4TUjuB9yfu5U0NJx97ysmNOo+7aeFSFYQgxi+eTu_PYQA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6676 bytes --]
Am 28.01.2014 13:49, schrieb David Herrmann:
> Hi
>
Hi David,
> On Tue, Jan 28, 2014 at 1:27 PM, Dr. Zimmermann
> <R.Zimmermann@uke.uni-hamburg.de> wrote:
>> Am 28.01.2014 12:15, schrieb David Herrmann:
>>
>>> Hi
>>>
>>> On Tue, Jan 28, 2014 at 11:20 AM, Dr. Zimmermann
>>> <R.Zimmermann@uke.uni-hamburg.de> wrote:
>>>>
>>>> Hi,
>>>>
>>>> we've got a special type of keyboard which should only be available in
>>>> one
>>>> specific process and not publicly, as usually keyboards are.
>>>>
>>>> Is it possible to limit the scope of a specific keyboard?
>>>>
>>>> Or is there a more suited forum where to ask?
>>
>>
>> Hi David,
>>
>>>
>>> There is no such interface in the kernel. However, with careful
>>> access-management, you can get what you want by just allowing your
>>> single process access to the device. But I guess you are working with
>>> an X11 system, so a description of what you actually want to achieve
>>> would help a lot.
>>
>>
>> Thnx for Your quick reply.
>>
>> (Yes, we are using X. No, the problem is not specific to X: It'll also occur
>> when You switch between system consoles.)
>
> Just don't use the system-console for that. It's not intended for that
> purpose and no-one will enhance it to do device-separation (why would
> you.. it's mainly meant as system-administrator fallback). But see
> below..
We've never intended to use it for our purposes, still the effect that
we've got is the same than under X.
>
>> For research purposes we are measuring human brain activity under the
>> influence of external stimuli (visual/auditory/somatosensory). The subject
>> has to reply to tasks using 'button boxes' which are implemented as
>> keyboards. Usually, type and time of the buttonpress are of importance (and
>> will probably change further procedere). Keyboard responses usually go to
>> that window (or system console) which has the current focus or is active and
>> *this* is something, we do not want.
>>
>> Sometimes we show visual stimuli on one screen(#1) and operate the system
>> from another screen(#2). Sometimes we even have no visual stimuli at all,
>> but like to read subject responses and control the stimuli from within a
>> control window. In all cases it would be helpful if the response-boxes would
>> not automatically send their output to the active window resp. application.
>>
>> Helpful would be, if the output of the response-box-keyboards
>> * could be restricted to a specific process
>> * is not sent automatically, but only to a program which 'opened' the device
>> * is not sent automatically, but has to be read from a device.
>> (Could this be done preserving the exact timepoint of each buttonpress?)
>
> First of all, nothing is "sent automatically". Processes have to read
> the events from the kernel, so point #3 doesn't make much sense to me.
Think of me as quite unaware in these matters. I'm seeing this 'signal'
(keyboard events) distributed by default to every application which gets
active/the focus.
> But regarding your issue: You should simply configure you xserver to
> not use the devices in question. Add an X11 config to
> /etc/X11/xorg.conf.d/50-ignore-custom-devices.conf which contains
> something like:
>
> Section "InputClass"
> Identifier "Custom Input Blacklist"
> MatchProduct "<Product-Name-of-Your-Device>"
> MatchDevicePath "/dev/input/event*"
> Option "Ignore" "on"
> EndSection
>
> You can read the product-name of your device via: `cat
> /sys/class/input/input<num>/name`
> where "input<num>" is your device in question.
>
> This will cause the Xserver to stop using your input devices and no
> window will get any events from them. Now you can program your custom
> applications to open the correct devices manually and reading events
> from them. However, this requires modifications to these applications.
> But if you just want your xserver to route specific events to specific
> processes, your applications must be XInput2-aware/capable.
>
> Instructing the kernel to route specific events to specific processes
> is the wrong approach here (except regarding the linux-console, which
> is special but *really* shouldn't be used for such stuff). The kernel
> does not care for policy but only provides hardware-abstraction. It's
> up to your applications to use the correct X11 APIs to only read
> events from specific XInput2-devices. So the correct people to ask
> about this are actually the developers of your applications and the
> X11 people. The kernel, by default, restricts input-device access to
> root, so basically *no* user gets input access. The X-Server now
> applies some default policies on these devices to route events to X11
> applications. By default, hot-plugging is enabled in new X-Servers and
> all devices are markes as Master devices. This means, their events are
> broad-casted to all X11 windows. If you don't want that, you can mark
> devices as "Floating", which means, the device will not broadcast
> events, but use the XInput API to report input events. Only
> applications which use XInput can now request events from the device.
>
> You can mark devices as floating via:
> Section "InputClass"
> Identifier "Custom Input Blacklist"
> MatchProduct "<Product-Name-of-Your-Device>"
> MatchDevicePath "/dev/input/event*"
> Option "Floating" "on"
> EndSection
>
> Also see "man xorg.conf" and search for "Floating".
Thanks for this explanation. It helped a lot and I now see, which 'path'
to go on...
>
> I hope that helps! I it's still unclear, let me know.
> As a side-note, please always put the mailing-lists on CC. I'm not
> doing that myself now, as I don't know whether you excluded them on
> purpose. But if you start a discussion on the mailing-list, you should
> keep it there so other people can comment, too. Most mail-clients
> provide the "reply to all" feature to do that automatically.
My mailer didn't do it correctly. But short time after the mail to You,
the same mail was sent to the list manually...
>
> Thanks
> David
Thanks again & Regards,
Roger
> .
>
--
Besuchen Sie uns auf: www.uke.de
_____________________________________________________________________
Universitätsklinikum Hamburg-Eppendorf; Körperschaft des öffentlichen Rechts; Gerichtsstand: Hamburg
Vorstandsmitglieder: Prof. Dr. Christian Gerloff (Vertreter des Vorsitzenden), Prof. Dr. Dr. Uwe Koch-Gromus, Joachim Prölß, Rainer Schoppik
_____________________________________________________________________
SAVE PAPER - THINK BEFORE PRINTING
[-- Attachment #2: R_Zimmermann.vcf --]
[-- Type: text/x-vcard, Size: 427 bytes --]
begin:vcard
fn:Dr. Roger Zimmermann
n:Zimmermann;Dr. Roger
org;quoted-printable;quoted-printable:Zentrum f=C3=BCr exp. Medizin;Institut f=C3=BCr Neuro- und Pathophysiologie
adr;quoted-printable:;;Martinistra=C3=9Fe 52;Hamburg;;20246;Germany
email;internet:R.Zimmermann@UKE.Uni-Hamburg.de
tel;work:..49 (0)40 42803 5351
tel;fax:..49 (0)40 42803 7255
x-mozilla-html:FALSE
url:http://www.uke.uni-hamburg.de
version:2.1
end:vcard
^ permalink raw reply
* [Novatech N1402 NNB-978] Touchpad does not work at all
From: Geoff Kelsall @ 2014-01-29 9:53 UTC (permalink / raw)
To: linux-input
[Novatech N1402 NNB-978] Touchpad does not work at all
WORKAROUND: Kernel parameter: i8042.noloop
Linux version 3.13.0-031300-generic (apw@gomeisa) (gcc version 4.6.3
(Ubuntu/Linaro 4.6.3-1ubuntu5) ) #201401192235 SMP Mon Jan 20 03:46:44
UTC 2014
Description: Ubuntu 12.04.2 LTS
Release: 12.04
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ sh ver_linux
If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.
Linux geoff-laptop 3.13.0-031300-generic #201401192235 SMP Mon Jan 20
03:46:44 UTC 2014 i686 i686 i386 GNU/Linux
Gnu C 4.6
Gnu make 3.81
binutils 2.22
util-linux 2.20.1
mount support
module-init-tools 3.16
e2fsprogs 1.42
pcmciautils 018
PPP 2.4.5
Linux C Library 2.15
Dynamic linker (ldd) 2.15
Procps 3.2.8
Net-tools 1.60
Kbd 1.15.2
Sh-utils 8.13
wireless-tools 30
Modules Loaded ctr ccm uvcvideo videobuf2_core videodev
videobuf2_vmalloc videobuf2_memops promethean joydev
snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel psmouse
snd_hda_codec serio_raw snd_hwdep arc4 snd_pcm rt2800pci snd_seq_midi
rt2800mmio snd_rawmidi rt2800lib snd_seq_midi_event crc_ccitt i915
rt2x00mmio rt2x00pci rt2x00lib snd_seq mac80211 snd_timer
snd_seq_device drm_kms_helper drm cfg80211 rfcomm snd bnep mac_hid
lpc_ich i2c_algo_bit mei_me bluetooth parport_pc eeprom_93cx6 ppdev
video mei soundcore snd_page_alloc binfmt_misc lp parport ahci libahci
r8169 mii
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300$ sh ver_linux
sh: 0: Can't open ver_linux
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300$ cd scripts/
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ sh ver_linux
If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.
Linux geoff-laptop 3.13.0-031300-generic #201401192235 SMP Mon Jan 20
03:46:44 UTC 2014 i686 i686 i386 GNU/Linux
Gnu C 4.6
Gnu make 3.81
binutils 2.22
util-linux 2.20.1
mount support
module-init-tools 3.16
e2fsprogs 1.42
pcmciautils 018
PPP 2.4.5
Linux C Library 2.15
Dynamic linker (ldd) 2.15
Procps 3.2.8
Net-tools 1.60
Kbd 1.15.2
Sh-utils 8.13
wireless-tools 30
Modules Loaded ctr ccm uvcvideo videobuf2_core videodev
videobuf2_vmalloc videobuf2_memops promethean joydev
snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel psmouse
snd_hda_codec serio_raw snd_hwdep arc4 snd_pcm rt2800pci snd_seq_midi
rt2800mmio snd_rawmidi rt2800lib snd_seq_midi_event crc_ccitt i915
rt2x00mmio rt2x00pci rt2x00lib snd_seq mac80211 snd_timer
snd_seq_device drm_kms_helper drm cfg80211 rfcomm snd bnep mac_hid
lpc_ich i2c_algo_bit mei_me bluetooth parport_pc eeprom_93cx6 ppdev
video mei soundcore snd_page_alloc binfmt_misc lp parport ahci libahci
r8169 mii
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ cat
/proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
stepping : 9
microcode : 0x10
cpu MHz : 2193.664
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fdiv_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx
rdtscp lm constant_tsc arch_perfmon pebs bts xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2
ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt
tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb
xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase
smep erms
bogomips : 3392.08
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
stepping : 9
microcode : 0x10
cpu MHz : 2512.414
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 2
initial apicid : 2
fdiv_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx
rdtscp lm constant_tsc arch_perfmon pebs bts xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2
ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt
tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb
xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase
smep erms
bogomips : 3392.08
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 2
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
stepping : 9
microcode : 0x10
cpu MHz : 1779.820
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 1
initial apicid : 1
fdiv_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx
rdtscp lm constant_tsc arch_perfmon pebs bts xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2
ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt
tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb
xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase
smep erms
bogomips : 3392.08
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
stepping : 9
microcode : 0x10
cpu MHz : 1553.175
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 3
initial apicid : 3
fdiv_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx
rdtscp lm constant_tsc arch_perfmon pebs bts xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2
ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt
tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb
xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase
smep erms
bogomips : 3392.08
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ cat
/proc/modules
ctr 13025 1 - Live 0x00000000
ccm 17596 1 - Live 0x00000000
uvcvideo 72275 0 - Live 0x00000000
videobuf2_core 39510 1 uvcvideo, Live 0x00000000
videodev 108952 2 uvcvideo,videobuf2_core, Live 0x00000000
videobuf2_vmalloc 13048 1 uvcvideo, Live 0x00000000
videobuf2_memops 13170 1 videobuf2_vmalloc, Live 0x00000000
promethean 47575 0 - Live 0x00000000 (OF)
joydev 17299 0 - Live 0x00000000
snd_hda_codec_hdmi 45847 1 - Live 0x00000000
snd_hda_codec_realtek 51482 1 - Live 0x00000000
snd_hda_intel 43398 3 - Live 0x00000000
psmouse 97012 0 - Live 0x00000000
snd_hda_codec 169779 3
snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intel, Live
0x00000000
serio_raw 13230 0 - Live 0x00000000
snd_hwdep 13276 1 snd_hda_codec, Live 0x00000000
arc4 12509 2 - Live 0x00000000
snd_pcm 90501 3 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec, Live 0x00000000
rt2800pci 13410 0 - Live 0x00000000
snd_seq_midi 13132 0 - Live 0x00000000
rt2800mmio 20399 1 rt2800pci, Live 0x00000000
snd_rawmidi 25198 1 snd_seq_midi, Live 0x00000000
rt2800lib 89156 2 rt2800pci,rt2800mmio, Live 0x00000000
snd_seq_midi_event 14475 1 snd_seq_midi, Live 0x00000000
crc_ccitt 12627 1 rt2800lib, Live 0x00000000
i915 732633 3 - Live 0x00000000
rt2x00mmio 13445 2 rt2800pci,rt2800mmio, Live 0x00000000
rt2x00pci 13111 1 rt2800pci, Live 0x00000000
rt2x00lib 49529 5 rt2800pci,rt2800mmio,rt2800lib,rt2x00mmio,rt2x00pci,
Live 0x00000000
snd_seq 55716 2 snd_seq_midi,snd_seq_midi_event, Live 0x00000000
mac80211 560429 3 rt2800lib,rt2x00pci,rt2x00lib, Live 0x00000000
snd_timer 28971 2 snd_pcm,snd_seq, Live 0x00000000
snd_seq_device 14137 3 snd_seq_midi,snd_rawmidi,snd_seq, Live 0x00000000
drm_kms_helper 47293 1 i915, Live 0x00000000
drm 249196 4 i915,drm_kms_helper, Live 0x00000000
cfg80211 430030 2 rt2x00lib,mac80211, Live 0x00000000
rfcomm 59026 0 - Live 0x00000000
snd 61351 17 snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_seq_midi,snd_rawmidi,snd_seq,snd_timer,snd_seq_device,
Live 0x00000000
bnep 19107 2 - Live 0x00000000
mac_hid 13077 0 - Live 0x00000000
lpc_ich 16987 0 - Live 0x00000000
i2c_algo_bit 13316 1 i915, Live 0x00000000
mei_me 14058 0 - Live 0x00000000
bluetooth 356681 10 rfcomm,bnep, Live 0x00000000
parport_pc 32114 0 - Live 0x00000000
eeprom_93cx6 13168 1 rt2800pci, Live 0x00000000
ppdev 17423 0 - Live 0x00000000
video 19283 1 i915, Live 0x00000000
mei 71172 1 mei_me, Live 0x00000000
soundcore 12600 1 snd, Live 0x00000000
snd_page_alloc 18398 2 snd_hda_intel,snd_pcm, Live 0x00000000
binfmt_misc 13172 1 - Live 0x00000000
lp 13359 0 - Live 0x00000000
parport 40945 3 parport_pc,ppdev,lp, Live 0x00000000
ahci 25703 2 - Live 0x00000000
libahci 30969 1 ahci, Live 0x00000000
r8169 62856 0 - Live 0x00000000
mii 13693 1 r8169, Live 0x00000000
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ cat
/proc/ioports
0000-0cf7 : PCI Bus 0000:00
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0062-0062 : EC data
0064-0064 : keyboard
0066-0066 : EC cmd
0070-0077 : rtc0
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0200-020f : pnp 00:04
0400-0403 : ACPI PM1a_EVT_BLK
0404-0405 : ACPI PM1a_CNT_BLK
0408-040b : ACPI PM_TMR
0410-0415 : ACPI CPU throttle
0420-042f : ACPI GPE0_BLK
0430-0433 : iTCO_wdt
0450-0450 : ACPI PM2_CNT_BLK
0454-0457 : pnp 00:06
0458-047f : pnp 00:04
0460-047f : iTCO_wdt
04d0-04d1 : pnp 00:08
0500-057f : pnp 00:04
0680-069f : pnp 00:04
0680-068f : pnp 00:07
0a00-0a0f : pnp 00:04
0a10-0a1f : pnp 00:07
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
164e-164f : pnp 00:04
e000-efff : PCI Bus 0000:02
e000-e0ff : 0000:02:00.0
e000-e0ff : r8169
f000-f03f : 0000:00:02.0
f040-f05f : 0000:00:1f.3
f060-f07f : 0000:00:1f.2
f060-f07f : ahci
f080-f083 : 0000:00:1f.2
f080-f083 : ahci
f090-f097 : 0000:00:1f.2
f090-f097 : ahci
f0a0-f0a3 : 0000:00:1f.2
f0a0-f0a3 : ahci
f0b0-f0b7 : 0000:00:1f.2
f0b0-f0b7 : ahci
ffff-ffff : pnp 00:04
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ cat /proc/iomem
00000000-00000fff : reserved
00001000-0009d7ff : System RAM
0009d800-0009ffff : reserved
000a0000-000bffff : PCI Bus 0000:00
000a0000-000bffff : Video RAM area
000c0000-000cefff : Video ROM
000d0000-000d3fff : PCI Bus 0000:00
000d4000-000d7fff : PCI Bus 0000:00
000d8000-000dbfff : PCI Bus 0000:00
000dc000-000dffff : PCI Bus 0000:00
000e0000-000fffff : reserved
000e0000-000e3fff : PCI Bus 0000:00
000e4000-000e7fff : PCI Bus 0000:00
000f0000-000fffff : System ROM
00100000-1fffffff : System RAM
01000000-016790b2 : Kernel code
016790b3-019e56bf : Kernel data
01ac8000-01badfff : Kernel bss
20000000-201fffff : reserved
20000000-201fffff : pnp 00:0d
20200000-40003fff : System RAM
40004000-40004fff : reserved
40004000-40004fff : pnp 00:0d
40005000-d9aeffff : System RAM
d9af0000-da22efff : reserved
da22f000-da22ffff : ACPI Tables
da230000-da344fff : ACPI Non-volatile Storage
da345000-da6fdfff : reserved
da6fe000-da6fefff : System RAM
da6ff000-da741fff : ACPI Non-volatile Storage
da742000-dae02fff : System RAM
dae03000-daff1fff : reserved
daff2000-daffffff : System RAM
db000000-db7fffff : RAM buffer
db800000-df9fffff : reserved
dba00000-df9fffff : Graphics Stolen Memory
dfa00000-feafffff : PCI Bus 0000:00
dfa00000-dfa00fff : pnp 00:0c
e0000000-efffffff : 0000:00:02.0
e0000000-e0407fff : BOOTFB
f0000000-f00fffff : PCI Bus 0000:02
f0000000-f0003fff : 0000:02:00.0
f0000000-f0003fff : r8169
f0004000-f0004fff : 0000:02:00.0
f0004000-f0004fff : r8169
f7800000-f7bfffff : 0000:00:02.0
f7c00000-f7dfffff : PCI Bus 0000:01
f7c00000-f7cfffff : 0000:01:00.1
f7d00000-f7d0ffff : 0000:01:00.1
f7d10000-f7d1ffff : 0000:01:00.1
f7d20000-f7d2ffff : 0000:01:00.1
f7d30000-f7d3ffff : 0000:01:00.0
f7d30000-f7d3ffff : 0000:01:00.0
f7d40000-f7d4ffff : 0000:01:00.0
f7d40000-f7d4ffff : 0000:01:00.0
f7e00000-f7e0ffff : 0000:00:14.0
f7e00000-f7e0ffff : xhci_hcd
f7e10000-f7e13fff : 0000:00:1b.0
f7e10000-f7e13fff : ICH HD audio
f7e15000-f7e150ff : 0000:00:1f.3
f7e16000-f7e167ff : 0000:00:1f.2
f7e16000-f7e167ff : ahci
f7e17000-f7e173ff : 0000:00:1d.0
f7e17000-f7e173ff : ehci_hcd
f7e18000-f7e183ff : 0000:00:1a.0
f7e18000-f7e183ff : ehci_hcd
f7e1b000-f7e1b00f : 0000:00:16.0
f7e1b000-f7e1b00f : mei_me
f8000000-fbffffff : PCI MMCONFIG 0000 [bus 00-3f]
f8000000-fbffffff : reserved
f8000000-fbffffff : pnp 00:0c
fec00000-fec00fff : reserved
fec00000-fec003ff : IOAPIC 0
fed00000-fed03fff : reserved
fed00000-fed003ff : HPET 0
fed10000-fed17fff : pnp 00:0c
fed18000-fed18fff : pnp 00:0c
fed19000-fed19fff : pnp 00:0c
fed1c000-fed1ffff : reserved
fed1c000-fed1ffff : pnp 00:0c
fed1f410-fed1f414 : iTCO_wdt
fed20000-fed3ffff : pnp 00:0c
fed40000-fed44fff : pnp 00:00
fed45000-fed8ffff : pnp 00:0c
fed90000-fed93fff : pnp 00:0c
fed90000-fed90fff : dmar0
fed91000-fed91fff : dmar1
fee00000-fee00fff : Local APIC
fee00000-fee00fff : reserved
ff000000-ffffffff : reserved
ff000000-ffffffff : pnp 00:0c
100000000-11f5fffff : System RAM
11f600000-11fffffff : RAM buffer
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ sudo lspci -vvv
[sudo] password for geoff:
00:00.0 Host bridge: Intel Corporation Ivy Bridge DRAM Controller (rev 09)
Subsystem: Device 1b50:5717
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort+ >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
00:02.0 VGA compatible controller: Intel Corporation Ivy Bridge
Graphics Controller (rev 09) (prog-if 00 [VGA controller])
Subsystem: Device 1b50:571c
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 44
Region 0: Memory at f7800000 (64-bit, non-prefetchable) [size=4M]
Region 2: Memory at e0000000 (64-bit, prefetchable) [size=256M]
Region 4: I/O ports at f000 [size=64]
Expansion ROM at <unassigned> [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0a00c Data: 41c1
Capabilities: [d0] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA
PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a4] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: i915
Kernel modules: i915
00:14.0 USB controller: Intel Corporation Panther Point USB xHCI Host
Controller (rev 04) (prog-if 30 [XHCI])
Subsystem: Device 1b50:5706
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 40
Region 0: Memory at f7e00000 (64-bit, non-prefetchable) [size=64K]
Capabilities: [70] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0-,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [80] MSI: Enable+ Count=1/8 Maskable- 64bit+
Address: 00000000fee0f00c Data: 4171
Kernel driver in use: xhci_hcd
00:16.0 Communication controller: Intel Corporation Panther Point MEI
Controller #1 (rev 04)
Subsystem: Device 1b50:5701
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 43
Region 0: Memory at f7e1b000 (64-bit, non-prefetchable) [size=16]
Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [8c] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0f00c Data: 41b1
Kernel driver in use: mei_me
Kernel modules: mei-me
00:1a.0 USB controller: Intel Corporation Panther Point USB Enhanced
Host Controller #2 (rev 04) (prog-if 20 [EHCI])
Subsystem: Device 1b50:5707
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 16
Region 0: Memory at f7e18000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci
00:1b.0 Audio device: Intel Corporation Panther Point High Definition
Audio Controller (rev 04)
Subsystem: Device 1b50:5608
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 45
Region 0: Memory at f7e10000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0100c Data: 41e1
Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset+
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown,
Latency L0 <64ns, L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk-
DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=1 ArbSelect=Fixed TC/VC=22
Status: NegoPending- InProgress-
Capabilities: [130 v1] Root Complex Link
Desc: PortNumber=0f ComponentID=00 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=00 AssocRCRB-
LinkType=MemMapped LinkValid+
Addr: 00000000fed1c000
Kernel driver in use: snd_hda_intel
Kernel modules: snd-hda-intel
00:1c.0 PCI bridge: Intel Corporation Panther Point PCI Express Root
Port 1 (rev c4) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: f7c00000-f7dfffff
Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort+ <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #1, Speed 5GT/s, Width x1, ASPM L0s L1,
Latency L0 <512ns, L1 <16us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
DLActive+ BWMgmt+ ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt-
HPIrq- LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-,
Selectable De-emphasis: -6dB
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB
Capabilities: [80] MSI: Enable- Count=1/1 Maskable- 64bit-
Address: 00000000 Data: 0000
Capabilities: [90] Subsystem: Device 1b50:5708
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport
Kernel modules: shpchp
00:1c.2 PCI bridge: Intel Corporation Panther Point PCI Express Root
Port 3 (rev c4) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
I/O behind bridge: 0000e000-0000efff
Memory behind bridge: fff00000-000fffff
Prefetchable memory behind bridge: 00000000f0000000-00000000f00fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #3, Speed 5GT/s, Width x1, ASPM L0s L1,
Latency L0 <512ns, L1 <16us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
DLActive+ BWMgmt+ ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
Slot #2, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt-
HPIrq- LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-,
Selectable De-emphasis: -6dB
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB
Capabilities: [80] MSI: Enable- Count=1/1 Maskable- 64bit-
Address: 00000000 Data: 0000
Capabilities: [90] Subsystem: Device 1b50:570a
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport
Kernel modules: shpchp
00:1d.0 USB controller: Intel Corporation Panther Point USB Enhanced
Host Controller #1 (rev 04) (prog-if 20 [EHCI])
Subsystem: Device 1b50:5710
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 23
Region 0: Memory at f7e17000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci
00:1f.0 ISA bridge: Intel Corporation Panther Point LPC Controller (rev 04)
Subsystem: Device 1b50:5712
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich
Kernel modules: lpc_ich
00:1f.2 SATA controller: Intel Corporation Panther Point 6 port SATA
Controller [AHCI mode] (rev 04) (prog-if 01 [AHCI 1.0])
Subsystem: Device 1b50:5713
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin B routed to IRQ 42
Region 0: I/O ports at f0b0 [size=8]
Region 1: I/O ports at f0a0 [size=4]
Region 2: I/O ports at f090 [size=8]
Region 3: I/O ports at f080 [size=4]
Region 4: I/O ports at f060 [size=32]
Region 5: Memory at f7e16000 (32-bit, non-prefetchable) [size=2K]
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0100c Data: 41a1
Capabilities: [70] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0-,D1-,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a8] SATA HBA v1.0 BAR4 Offset=00000004
Capabilities: [b0] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ahci
Kernel modules: ahci
00:1f.3 SMBus: Intel Corporation Panther Point SMBus Controller (rev 04)
Subsystem: Device 1b50:5714
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin C routed to IRQ 3
Region 0: Memory at f7e15000 (64-bit, non-prefetchable) [size=256]
Region 4: I/O ports at f040 [size=32]
Kernel modules: i2c-i801
01:00.0 Network controller: Ralink corp. Device 3290
Subsystem: AzureWave Device 2b87
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 16
Region 0: Memory at f7d40000 (32-bit, non-prefetchable) [size=64K]
Region 1: Memory at f7d30000 (32-bit, non-prefetchable) [size=64K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable- Count=1/32 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [70] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s
<128ns, L1 <2us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1,
Latency L0 <512ns, L1 <64us
ClockPM+ Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Not Supported, TimeoutDis+
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance-
SpeedDis-, Selectable De-emphasis: -6dB
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -6dB
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [140 v1] Device Serial Number 00-00-73-50-df-c9-db-94
Kernel driver in use: rt2800pci
Kernel modules: rt2800pci
01:00.1 Bluetooth: Ralink corp. Device 3298
Subsystem: AzureWave Device 2787
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 11
Region 0: Memory at f7d20000 (32-bit, non-prefetchable) [size=64K]
Region 1: Memory at f7d10000 (32-bit, non-prefetchable) [size=64K]
Region 2: Memory at f7c00000 (32-bit, non-prefetchable) [size=1M]
Expansion ROM at f7d00000 [disabled] [size=64K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA
PME(D0+,D1+,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable- Count=1/32 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [70] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s
<128ns, L1 <2us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1,
Latency L0 <512ns, L1 <64us
ClockPM+ Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Not Supported, TimeoutDis+
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance-
SpeedDis-, Selectable De-emphasis: -6dB
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -6dB
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [140 v1] Device Serial Number 00-00-74-50-df-c9-db-94
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.
RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06)
Subsystem: Device 1b50:4606
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort-
<TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 41
Region 0: I/O ports at e000 [size=256]
Region 2: Memory at f0004000 (64-bit, prefetchable) [size=4K]
Region 4: Memory at f0000000 (64-bit, prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA
PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0f00c Data: 4181
Capabilities: [70] Express (v2) Endpoint, MSI 01
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s
<512ns, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1,
Latency L0 unlimited, L1 <64us
ClockPM+ Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance-
SpeedDis-, Selectable De-emphasis: -6dB
Transmit Margin: Normal Operating Range,
EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -6dB
Capabilities: [b0] MSI-X: Enable- Count=4 Masked-
Vector table: BAR=4 offset=00000000
PBA: BAR=4 offset=00000800
Capabilities: [d0] Vital Product Data
No end tag found
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [140 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
Capabilities: [160 v1] Device Serial Number 05-00-00-00-68-4c-e0-00
Kernel driver in use: r8169
Kernel modules: r8169
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ cat
/proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
Vendor: ATA Model: M4-CT128M4SSD1 Rev: 000F
Type: Direct-Access ANSI SCSI revision: 05
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$ ls /proc
1 1084 1578 1799 1842 1974 2107 2237 2448 280 37 58
777 asound filesystems locks slabinfo
zoneinfo
10 1093 1595 18 1847 1980 2111 2267 2454 283 4 61 8
buddyinfo fs mdstat softirqs
1007 1097 16 1801 1851 1984 2113 23 2489 29 40 62
800 bus interrupts meminfo stat
1013 1098 1617 1809 1853 1985 2115 2303 25 3 41 643
81 cgroups iomem misc swaps
1022 11 1623 1812 1856 1991 2116 2314 26 30 42 668
82 cmdline ioports modules sys
1024 1136 163 1815 1861 1992 2154 2318 2600 31 426 672
84 consoles irq mounts sysrq-trigger
1028 12 1695 1821 1865 2 2157 2323 2607 311 43 691 9
cpuinfo kallsyms mtrr sysvipc
1037 1250 17 1822 1883 20 2165 2359 27 312 434 692
902 crypto kcore net timer_list
1042 1260 1731 1823 1912 2012 2167 2368 275 32 44 7
911 devices key-users pagetypeinfo timer_stats
1043 1279 1742 1824 1923 2031 2170 2382 276 33 45 708
920 diskstats kmsg partitions tty
1044 13 1777 1827 1924 2067 2176 2387 277 34 46 716
934 dma kpagecount sched_debug uptime
1064 1393 1780 1837 1930 2071 22 2388 278 35 5 717
958 driver kpageflags schedstat version
1065 15 1781 1839 1950 2092 2211 2446 279 36 512 723
979 execdomains latency_stats scsi vmallocinfo
1066 1535 1790 1840 1952 21 2223 2447 28 368 550 739
acpi fb loadavg self vmstat
geoff@geoff-laptop:/usr/src/linux-headers-3.13.0-031300/scripts$
WORKAROUND: Kernel parameter: i8042.noloop
Launchpad bug 1244643
Regards
Geoff Kelsall
^ permalink raw reply
* Re: Can I limit the scope of an input device to specific processes ?
From: Fabien André @ 2014-01-29 12:35 UTC (permalink / raw)
To: R.Zimmermann; +Cc: David Herrmann, linux-input
In-Reply-To: <52E8CD67.4010705@UKE.Uni-Hamburg.de>
Hi,
On Wed, Jan 29, 2014 at 10:44 AM, Dr. Zimmermann
<R.Zimmermann@uke.uni-hamburg.de> wrote:
> Am 28.01.2014 13:49, schrieb David Herrmann:
>>
>> Hi
>>
> Hi David,
>
>> On Tue, Jan 28, 2014 at 1:27 PM, Dr. Zimmermann
>> <R.Zimmermann@uke.uni-hamburg.de> wrote:
>>
>> You can mark devices as floating via:
>> Section "InputClass"
>> Identifier "Custom Input Blacklist"
>> MatchProduct "<Product-Name-of-Your-Device>"
>> MatchDevicePath "/dev/input/event*"
>> Option "Floating" "on"
>> EndSection
>>
>> Also see "man xorg.conf" and search for "Floating".
An alternative to X config file is the xinput command line tool
$> xinput list
to get the name and id of your device
$>xinput float NAME_OR_ID
to "detach" the device from the virtual core keyboard
(the name will be stable while id can change after unplug or restart,
thus name is a better candidate for scripting)
Regards,
Fabien
^ permalink raw reply
* Re: [PATCH 2/2] iio: hid-sensor-hub: Remove hard coded indexes
From: Jiri Kosina @ 2014-01-29 13:13 UTC (permalink / raw)
To: Srinivas Pandruvada; +Cc: jic23, linux-iio, linux-input
In-Reply-To: <1390531822-7640-2-git-send-email-srinivas.pandruvada@linux.intel.com>
On Thu, 23 Jan 2014, Srinivas Pandruvada wrote:
> Remove the hard coded indexes, instead search for usage id and
> use the index to set the power and report state.
> This will fix issue, where the report descriptor doesn't contain
> the full list of possible selector for power and report state.
>
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Jonathan, I'd probably take this together with the patch for HID API
change. Could you please provide your Ack/Signoff, and I'll take it
through my tree, if you agree?
Thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 0/4] HID: implement new transport-driver callbacks
From: Jiri Kosina @ 2014-01-29 13:25 UTC (permalink / raw)
To: Frank Praznik; +Cc: linux-input, dh.herrmann
In-Reply-To: <1390416584-3667-1-git-send-email-frank.praznik@oh.rr.com>
On Wed, 22 Jan 2014, Frank Praznik wrote:
> These patches are originally the work of David Herrmann who suggested that I
> update and submit them as their functionality is required for some pending
> patches to the hid-sony driver.
>
> These patches implement the SET/GET_REPORT and raw intr OUTPUT requests for all
> transport drivers. It adds two callbacks to the hid_ll_driver struct:
>
> int (*raw_request)(struct hid_device *hdev, unsigned char reportnum,
> __u8 *buf, size_t len, unsigned char rtype, int reqtype);
>
> int (*output_report)(struct hid_device *hdev, __u8 *buf, size_t len);
>
> along with the necessary support fuctions in the USBHID, and HIDP drivers.
>
> UHID is not converted yet.
I have finished reviewing the patchset and don't have any objections. I am
queuing them for 3.15.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: Sony Vaio Duo 11: getting middle mouse button to work
From: Benjamin Tissoires @ 2014-01-29 14:53 UTC (permalink / raw)
To: Stephan Mueller
Cc: Mattia Dongili, platform-driver-x86, Jiri Kosina, linux-input
In-Reply-To: <2093581.PZC0zrVCWg@myon.chronox.de>
On Fri, Jan 24, 2014 at 11:51 PM, Stephan Mueller <smueller@chronox.de> wrote:
> Am Samstag, 25. Januar 2014, 12:17:13 schrieb Mattia Dongili:
>
> Hi Mattia,
>
>>
>> I'd try with the input subsystem and the synaptics_usb driver first but
>> it's just a wild guess. Your kernel log should give you more hints about
>> which driver is bound to the device and the sysfs tree under
>> /sys/class/input/event*/device/* has all the capabilities and
>> identifiers.
>
> The following did not help:
>
> modprobe synaptics_usb
> cd /sys/bus/usb/drivers/usbhid
> echo -n "1-1.3:1.0" > unbind
> #now the mouse is without driver, does not move, and
> #/sys/class/input/event2/device/device is without driver
> cd /sys/bus/usb/drivers/synaptics_usb
> echo -n "1-1.3:1.0" > bind
> #error: no such device, mouse does not work, nothing in dmesg
> cd /sys/bus/usb/drivers/usbhid
> echo -n "1-1.3:1.0" > bind
> #mouse works again without middle button
>
Hi Stephan,
in this case, you definitively want to talk to HID (and input) folks.
Adding Jiri, the HID maintainer in the discussion.
Your mouse does not seem to be handled properly by the hid subsystem
and needs quirks, or fix.
Can you send us some hid-recorder[1] traces of your device? We should
then be able to check what's wrong and hopefully fix the problem.
Cheers,
Benjamin
[1] http://bentiss.github.io/hid-replay-docs/
^ permalink raw reply
* Re: [PATCH] HID: i2c-hid: add runtime PM support
From: Benjamin Tissoires @ 2014-01-29 14:57 UTC (permalink / raw)
To: Mika Westerberg
Cc: linux-input, Jiri Kosina, Benjamin Tissoires,
linux-kernel@vger.kernel.org
In-Reply-To: <20140129091313.GK18029@intel.com>
On Wed, Jan 29, 2014 at 4:13 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Tue, Jan 28, 2014 at 09:19:33AM -0500, Benjamin Tissoires wrote:
>> On Tue, Jan 28, 2014 at 4:12 AM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>> > On Mon, Jan 27, 2014 at 10:36:25PM -0500, Benjamin Tissoires wrote:
>> >> On Tue, Jan 14, 2014 at 5:13 AM, Mika Westerberg
>> >> <mika.westerberg@linux.intel.com> wrote:
>> >> > This patch adds runtime PM support for the HID over I2C driver. When the
>> >> > i2c-hid device is first opened we power it on and on the last close we
>> >> > power it off.
>> >> >
>> >> > The implementation is not the most power efficient because it needs some
>> >> > interaction from the userspace (e.g close the device node whenever we are
>> >> > no more interested in getting events), nevertheless it allows us to save
>> >> > some power and works with devices that are not wake capable.
>> >> >
>> >>
>> >> Hi Mika,
>> >>
>> >> I am a little bit puzzled here. The commit message just says that you
>> >> changed the implementation of the power saving with the exact same
>> >> behavior... At least that's what I understand.
>> >> Currently, the devices should be put on sleep if nobody is reading,
>> >> and back alive if a reader arrives.
>> >> I think there is a gain with the patch, but my knowledge of the pm
>> >> subsystem is far too limited to see it :(
>> >
>> > Yes, there should be gain. If there is power domain involved like, ACPI in
>> > our case, runtime suspending the device on close will let ACPI to move the
>> > device to D3cold (e.g full off) which saves more power.
>>
>> Oh, right. So, if you could just put this last sentence in the commit
>> message, that would be great.
>
> Sure.
>
>>
>> >
>> >> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>> >> > ---
>> >> > drivers/hid/i2c-hid/i2c-hid.c | 81 ++++++++++++++++++++++++++++---------------
>> >> > 1 file changed, 54 insertions(+), 27 deletions(-)
>> >> >
>> >> > diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
>> >> > index d1f81f52481a..ff767d03d60e 100644
>> >> > --- a/drivers/hid/i2c-hid/i2c-hid.c
>> >> > +++ b/drivers/hid/i2c-hid/i2c-hid.c
>> >> > @@ -25,6 +25,7 @@
>> >> > #include <linux/delay.h>
>> >> > #include <linux/slab.h>
>> >> > #include <linux/pm.h>
>> >> > +#include <linux/pm_runtime.h>
>> >> > #include <linux/device.h>
>> >> > #include <linux/wait.h>
>> >> > #include <linux/err.h>
>> >> > @@ -454,10 +455,18 @@ static void i2c_hid_init_reports(struct hid_device *hid)
>> >> > return;
>> >> > }
>> >> >
>> >> > + /*
>> >> > + * The device must be powered on while we fetch initial reports
>> >> > + * from it.
>> >> > + */
>> >> > + pm_runtime_get_sync(&client->dev);
>> >> > +
>> >> > list_for_each_entry(report,
>> >> > &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
>> >> > i2c_hid_init_report(report, inbuf, ihid->bufsize);
>> >> >
>> >> > + pm_runtime_put(&client->dev);
>> >> > +
>> >> > kfree(inbuf);
>> >> > }
>> >> >
>> >> > @@ -703,8 +712,8 @@ static int i2c_hid_open(struct hid_device *hid)
>> >> >
>> >> > mutex_lock(&i2c_hid_open_mut);
>> >> > if (!hid->open++) {
>> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
>> >> > - if (ret) {
>> >> > + ret = pm_runtime_get_sync(&client->dev);
>> >>
>> >> dummy question (kind of late here...). Is there a counter of how many
>> >> get/put has been called in pm_runtime which could allow us to get rid
>> >> of the hid->open count?
>> >
>> > There is a counter but I'm not sure if drivers are supposed to use that. I
>> > would prefer not to use that.
>>
>> ok
>>
>> >
>> >>
>> >> > + if (ret < 0) {
>> >> > hid->open--;
>> >> > goto done;
>> >> > }
>> >> > @@ -712,7 +721,7 @@ static int i2c_hid_open(struct hid_device *hid)
>> >> > }
>> >> > done:
>> >> > mutex_unlock(&i2c_hid_open_mut);
>> >> > - return ret;
>> >> > + return ret < 0 ? ret : 0;
>> >> > }
>> >> >
>> >> > static void i2c_hid_close(struct hid_device *hid)
>> >> > @@ -729,37 +738,17 @@ static void i2c_hid_close(struct hid_device *hid)
>> >> > clear_bit(I2C_HID_STARTED, &ihid->flags);
>> >> >
>> >> > /* Save some power */
>> >> > - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
>> >> > + pm_runtime_put(&client->dev);
>> >> > }
>> >> > mutex_unlock(&i2c_hid_open_mut);
>> >> > }
>> >> >
>> >> > -static int i2c_hid_power(struct hid_device *hid, int lvl)
>> >> > -{
>> >> > - struct i2c_client *client = hid->driver_data;
>> >> > - struct i2c_hid *ihid = i2c_get_clientdata(client);
>> >> > - int ret = 0;
>> >> > -
>> >> > - i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl);
>> >> > -
>> >> > - switch (lvl) {
>> >> > - case PM_HINT_FULLON:
>> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
>> >> > - break;
>> >> > - case PM_HINT_NORMAL:
>> >> > - ret = i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
>> >> > - break;
>> >> > - }
>> >> > - return ret;
>> >> > -}
>> >> > -
>> >> > static struct hid_ll_driver i2c_hid_ll_driver = {
>> >> > .parse = i2c_hid_parse,
>> >> > .start = i2c_hid_start,
>> >> > .stop = i2c_hid_stop,
>> >> > .open = i2c_hid_open,
>> >> > .close = i2c_hid_close,
>> >> > - .power = i2c_hid_power,
>> >>
>> >> If I understand correctly, here you are trying to fix hidraw (with
>> >> i2c_hid tramsport) which used to set_power on/off twice with the first
>> >> reader, right?
>> >
>> > Right.
>> >
>> >> I don't think we have other i2c_hid users of hid_hw_power, but I am a
>> >> little bit worried of simply removing the callback.
>> >
>> > OK.
>> >
>> >> What if we just change i2c_hid_set_power in i2c_hid_power by the
>> >> corresponding pm_runtime calls?
>> >
>> > Sure, I'll change that in the next version.
>> >
>> >>
>> >> > .request = i2c_hid_request,
>> >> > };
>> >> >
>> >> > @@ -973,13 +962,17 @@ static int i2c_hid_probe(struct i2c_client *client,
>> >> > if (ret < 0)
>> >> > goto err;
>> >> >
>> >> > + pm_runtime_get_noresume(&client->dev);
>> >> > + pm_runtime_set_active(&client->dev);
>> >> > + pm_runtime_enable(&client->dev);
>> >> > +
>> >> > ret = i2c_hid_fetch_hid_descriptor(ihid);
>> >> > if (ret < 0)
>> >> > - goto err;
>> >> > + goto err_pm;
>> >> >
>> >> > ret = i2c_hid_init_irq(client);
>> >> > if (ret < 0)
>> >> > - goto err;
>> >> > + goto err_pm;
>> >> >
>> >> > hid = hid_allocate_device();
>> >> > if (IS_ERR(hid)) {
>> >> > @@ -1010,6 +1003,7 @@ static int i2c_hid_probe(struct i2c_client *client,
>> >> > goto err_mem_free;
>> >> > }
>> >> >
>> >> > + pm_runtime_put(&client->dev);
>> >> > return 0;
>> >> >
>> >> > err_mem_free:
>> >> > @@ -1018,6 +1012,10 @@ err_mem_free:
>> >> > err_irq:
>> >> > free_irq(client->irq, ihid);
>> >> >
>> >> > +err_pm:
>> >> > + pm_runtime_put_noidle(&client->dev);
>> >> > + pm_runtime_disable(&client->dev);
>> >> > +
>> >> > err:
>> >> > i2c_hid_free_buffers(ihid);
>> >> > kfree(ihid);
>> >> > @@ -1029,6 +1027,11 @@ static int i2c_hid_remove(struct i2c_client *client)
>> >> > struct i2c_hid *ihid = i2c_get_clientdata(client);
>> >> > struct hid_device *hid;
>> >> >
>> >> > + pm_runtime_get_sync(&client->dev);
>> >> > + pm_runtime_disable(&client->dev);
>> >> > + pm_runtime_set_suspended(&client->dev);
>> >> > + pm_runtime_put_noidle(&client->dev);
>> >> > +
>> >> > hid = ihid->hid;
>> >> > hid_destroy_device(hid);
>> >> >
>> >> > @@ -1074,7 +1077,31 @@ static int i2c_hid_resume(struct device *dev)
>> >> > }
>> >> > #endif
>> >> >
>> >> > -static SIMPLE_DEV_PM_OPS(i2c_hid_pm, i2c_hid_suspend, i2c_hid_resume);
>> >> > +#ifdef CONFIG_PM_RUNTIME
>> >> > +static int i2c_hid_runtime_suspend(struct device *dev)
>> >> > +{
>> >> > + struct i2c_client *client = to_i2c_client(dev);
>> >> > +
>> >> > + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
>> >> > + disable_irq(client->irq);
>> >> > + return 0;
>> >> > +}
>> >> > +
>> >> > +static int i2c_hid_runtime_resume(struct device *dev)
>> >> > +{
>> >> > + struct i2c_client *client = to_i2c_client(dev);
>> >> > +
>> >> > + enable_irq(client->irq);
>> >> > + i2c_hid_set_power(client, I2C_HID_PWR_ON);
>> >> > + return 0;
>> >> > +}
>> >>
>> >> These two functions looks very similar to i2c_hid_suspend and
>> >> i2c_hid_resume, without the reset and the irq_wake :(
>> >> So, my question here is can we use some common code for them?
>> >> It may not be possible regarding CONFIG_PM_RUNTIME and
>> >> CONFIG_PM_SLEEP, but it still looks ugly to me.
>> >
>> > It looks ugly, I agree and we can probably reuse some code in the
>> > callbacks. I'll look into that.
>>
>> well, anyway, if this involve something even more ugly, we can for
>> sure stick with this version :)
>
> It turned out that it is going to be ugly, no matter what :-( I'll keep the
> current version for now.
>
>>
>> >
>> >> I tested this today, and it works, so you should be right, but I'd
>> >> like to have your opinion on this.
>> >
>> > Thanks for testing and comments.
>> >
>> > I'll prepare a new version with the suggested changes if you are OK with my
>> > explanations ;-)
>>
>> Sure I am. Thanks for handling the whole ACPI part of this module. I
>> was really pleased the other day to see that the touchscreen of a Bay
>> trail tablet is now working out of the box :) I still have many other
>> problems with this tablet, but still, having the input working is
>> always good with a tablet...
>
> If that's the Asus T100 tablet, we are going to fix rest of the problems
> soon :-)
That's great. I hope this will also fix my Lenovo Miix 2 (the T100 is
too expensive compared to the Dell Venue pro 8 and the Lenovo one) :)
I think most of my problems are ACPI related (WIFI card not powered
up, SD-ext reader not working, suspend/resume not there, etc...), so I
expect great of you :)
I'll give a last shot to the v2, before giving the reviewed by.
Cheers,
Benjamin
^ permalink raw reply
* Re: Sony Vaio Duo 11: getting middle mouse button to work
From: Stephan Mueller @ 2014-01-29 14:59 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Mattia Dongili, platform-driver-x86, Jiri Kosina, linux-input
In-Reply-To: <CAN+gG=Ev=ebkx8Usa=BgXMYVMQekG-s2gwa5N2TQSw7hisMT_w@mail.gmail.com>
Am Mittwoch, 29. Januar 2014, 09:53:03 schrieb Benjamin Tissoires:
Hi Benjamin,
>On Fri, Jan 24, 2014 at 11:51 PM, Stephan Mueller <smueller@chronox.de>
wrote:
>> Am Samstag, 25. Januar 2014, 12:17:13 schrieb Mattia Dongili:
>>
>> Hi Mattia,
>>
>>> I'd try with the input subsystem and the synaptics_usb driver first
>>> but it's just a wild guess. Your kernel log should give you more
>>> hints about which driver is bound to the device and the sysfs tree
>>> under
>>> /sys/class/input/event*/device/* has all the capabilities and
>>> identifiers.
>>
>> The following did not help:
>>
>> modprobe synaptics_usb
>> cd /sys/bus/usb/drivers/usbhid
>> echo -n "1-1.3:1.0" > unbind
>> #now the mouse is without driver, does not move, and
>> #/sys/class/input/event2/device/device is without driver
>> cd /sys/bus/usb/drivers/synaptics_usb
>> echo -n "1-1.3:1.0" > bind
>> #error: no such device, mouse does not work, nothing in dmesg
>> cd /sys/bus/usb/drivers/usbhid
>> echo -n "1-1.3:1.0" > bind
>> #mouse works again without middle button
>
>Hi Stephan,
>
>in this case, you definitively want to talk to HID (and input) folks.
>Adding Jiri, the HID maintainer in the discussion.
>
>Your mouse does not seem to be handled properly by the hid subsystem
>and needs quirks, or fix.
>
>Can you send us some hid-recorder[1] traces of your device? We should
>then be able to check what's wrong and hopefully fix the problem.
Thanks a lot for the helping hand. I will try your suggestion tonight
and report back.
But please allow me to point out that I have doubts that HID or input is
at fault, because when sniffing on the USB bus with usbmon, I do *not*
see any information transported when pressing the middle button.
Therefore, I would suspect it is rather the base USB driver that somehow
needs a quirk to access the mouse properly.
Thanks a lot
Stephan
^ permalink raw reply
* Re: Sony Vaio Duo 11: getting middle mouse button to work
From: Benjamin Tissoires @ 2014-01-29 15:07 UTC (permalink / raw)
To: Stephan Mueller
Cc: Mattia Dongili, platform-driver-x86, Jiri Kosina, linux-input
In-Reply-To: <3981247.bRK36pG72j@tauon>
On Wed, Jan 29, 2014 at 9:59 AM, Stephan Mueller <smueller@chronox.de> wrote:
> Am Mittwoch, 29. Januar 2014, 09:53:03 schrieb Benjamin Tissoires:
>
> Hi Benjamin,
>
>>On Fri, Jan 24, 2014 at 11:51 PM, Stephan Mueller <smueller@chronox.de>
> wrote:
>>> Am Samstag, 25. Januar 2014, 12:17:13 schrieb Mattia Dongili:
>>>
>>> Hi Mattia,
>>>
>>>> I'd try with the input subsystem and the synaptics_usb driver first
>>>> but it's just a wild guess. Your kernel log should give you more
>>>> hints about which driver is bound to the device and the sysfs tree
>>>> under
>>>> /sys/class/input/event*/device/* has all the capabilities and
>>>> identifiers.
>>>
>>> The following did not help:
>>>
>>> modprobe synaptics_usb
>>> cd /sys/bus/usb/drivers/usbhid
>>> echo -n "1-1.3:1.0" > unbind
>>> #now the mouse is without driver, does not move, and
>>> #/sys/class/input/event2/device/device is without driver
>>> cd /sys/bus/usb/drivers/synaptics_usb
>>> echo -n "1-1.3:1.0" > bind
>>> #error: no such device, mouse does not work, nothing in dmesg
>>> cd /sys/bus/usb/drivers/usbhid
>>> echo -n "1-1.3:1.0" > bind
>>> #mouse works again without middle button
>>
>>Hi Stephan,
>>
>>in this case, you definitively want to talk to HID (and input) folks.
>>Adding Jiri, the HID maintainer in the discussion.
>>
>>Your mouse does not seem to be handled properly by the hid subsystem
>>and needs quirks, or fix.
>>
>>Can you send us some hid-recorder[1] traces of your device? We should
>>then be able to check what's wrong and hopefully fix the problem.
>
> Thanks a lot for the helping hand. I will try your suggestion tonight
> and report back.
>
> But please allow me to point out that I have doubts that HID or input is
> at fault, because when sniffing on the USB bus with usbmon, I do *not*
> see any information transported when pressing the middle button.
> Therefore, I would suspect it is rather the base USB driver that somehow
> needs a quirk to access the mouse properly.
>
Oh, then in this case it may be that your device needs to be put in a
special mode, and the report descriptors will show us some hints on
how to do it (maybe).
I strongly doubt that USB is in fault here. I can not see any reasons
why the USB or underlying driver would select which packets are
transmitted.
What you can also do is setup a windows virtual machine, assign the
usb device to it, and sniff through usbmon or wireshark what packets
are emitted from/to the mouse. Then, we will duplicate this behavior
in the hid driver, and you would be good to go. Still, having the
reports descriptors (which are provided by hid-recorder, or in
/sys/kernel/debug/hid/DEVICE/rdesc, or in lsusb -vv when the usbhid
driver is not bound) would help us to understand the mouse firmware.
Cheers,
Benjamin
^ permalink raw reply
* [PATCH] HID: Add HID transport driver documentation
From: Frank Praznik @ 2014-01-29 15:28 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik
Add David Herrmann's documentation for the new low-level HID transport driver
functions.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Sorry, I forgot to include this in the original patch set.
Documentation/hid/hid-transport.txt | 324 ++++++++++++++++++++++++++++++++++++
1 file changed, 324 insertions(+)
create mode 100644 Documentation/hid/hid-transport.txt
diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.txt
new file mode 100644
index 0000000..14b1c18
--- /dev/null
+++ b/Documentation/hid/hid-transport.txt
@@ -0,0 +1,324 @@
+ HID I/O Transport Drivers
+ ===========================
+
+The HID subsystem is independent of the underlying transport driver. Initially,
+only USB was supported, but other specifications adopted the HID design and
+provided new transport drivers. The kernel includes at least support for USB,
+Bluetooth, I2C and user-space I/O drivers.
+
+1) HID Bus
+==========
+
+The HID subsystem is designed as a bus. Any I/O subsystem may provide HID
+devices and register them with the HID bus. HID core then loads generic device
+drivers on top of it. The transport drivers are responsible of raw data
+transport and device setup/management. HID core is responsible of
+report-parsing, report interpretation and the user-space API. Device specifics
+and quirks are handled by all layers depending on the quirk.
+
+ +-----------+ +-----------+ +-----------+ +-----------+
+ | Device #1 | | Device #i | | Device #j | | Device #k |
+ +-----------+ +-----------+ +-----------+ +-----------+
+ \\ // \\ //
+ +------------+ +------------+
+ | I/O Driver | | I/O Driver |
+ +------------+ +------------+
+ || ||
+ +------------------+ +------------------+
+ | Transport Driver | | Transport Driver |
+ +------------------+ +------------------+
+ \___ ___/
+ \ /
+ +----------------+
+ | HID Core |
+ +----------------+
+ / | | \
+ / | | \
+ ____________/ | | \_________________
+ / | | \
+ / | | \
+ +----------------+ +-----------+ +------------------+ +------------------+
+ | Generic Driver | | MT Driver | | Custom Driver #1 | | Custom Driver #2 |
+ +----------------+ +-----------+ +------------------+ +------------------+
+
+Example Drivers:
+ I/O: USB, I2C, Bluetooth-l2cap
+ Transport: USB-HID, I2C-HID, BT-HIDP
+
+Everything below "HID Core" is simplified in this graph as it is only of
+interest to HID device drivers. Transport drivers do not need to know the
+specifics.
+
+1.1) Device Setup
+-----------------
+
+I/O drivers normally provide hotplug detection or device enumeration APIs to the
+transport drivers. Transport drivers use this to find any suitable HID device.
+They allocate HID device objects and register them with HID core. Transport
+drivers are not required to register themselves with HID core. HID core is never
+aware of which transport drivers are available and is not interested in it. It
+is only interested in devices.
+
+Transport drivers attach a constant "struct hid_ll_driver" object with each
+device. Once a device is registered with HID core, the callbacks provided via
+this struct are used by HID core to communicate with the device.
+
+Transport drivers are responsible of detecting device failures and unplugging.
+HID core will operate a device as long as it is registered regardless of any
+device failures. Once transport drivers detect unplug or failure events, they
+must unregister the device from HID core and HID core will stop using the
+provided callbacks.
+
+1.2) Transport Driver Requirements
+----------------------------------
+
+The terms "asynchronous" and "synchronous" in this document describe the
+transmission behavior regarding acknowledgements. An asynchronous channel must
+not perform any synchronous operations like waiting for acknowledgements or
+verifications. Generally, HID calls operating on asynchronous channels must be
+running in atomic-context just fine.
+On the other hand, synchronous channels can be implemented by the transport
+driver in whatever way they like. They might just be the same as asynchronous
+channels, but they can also provide acknowledgement reports, automatic
+retransmission on failure, etc. in a blocking manner. If such functionality is
+required on asynchronous channels, a transport-driver must implement that via
+its own worker threads.
+
+HID core requires transport drivers to follow a given design. A Transport
+driver must provide two bi-directional I/O channels to each HID device. These
+channels must not necessarily be bi-directional in the hardware itself. A
+transport driver might just provide 4 uni-directional channels. Or it might
+multiplex all four on a single physical channel. However, in this document we
+will describe them as two bi-directional channels as they have several
+properties in common.
+
+ - Interrupt Channel (intr): The intr channel is used for asynchronous data
+ reports. No management commands or data acknowledgements are sent on this
+ channel. Any unrequested incoming or outgoing data report must be sent on
+ this channel and is never acknowledged by the remote side. Devices usually
+ send their input events on this channel. Outgoing events are normally
+ not send via intr, except if high throughput is required.
+ - Control Channel (ctrl): The ctrl channel is used for synchronous requests and
+ device management. Unrequested data input events must not be sent on this
+ channel and are normally ignored. Instead, devices only send management
+ events or answers to host requests on this channel.
+ The control-channel is used for direct blocking queries to the device
+ independent of any events on the intr-channel.
+ Outgoing reports are usually sent on the ctrl channel via synchronous
+ SET_REPORT requests.
+
+Communication between devices and HID core is mostly done via HID reports. A
+report can be of one of three types:
+
+ - INPUT Report: Input reports provide data from device to host. This
+ data may include button events, axis events, battery status or more. This
+ data is generated by the device and sent to the host with or without
+ requiring explicit requests. Devices can choose to send data continuously or
+ only on change.
+ - OUTPUT Report: Output reports change device states. They are sent from host
+ to device and may include LED requests, rumble requests or more. Output
+ reports are never sent from device to host, but a host can retrieve their
+ current state.
+ Hosts may choose to send output reports either continuously or only on
+ change.
+ - FEATURE Report: Feature reports are used for specific static device features
+ and never reported spontaneously. A host can read and/or write them to access
+ data like battery-state or device-settings.
+ Feature reports are never sent without requests. A host must explicitly set
+ or retrieve a feature report. This also means, feature reports are never sent
+ on the intr channel as this channel is asynchronous.
+
+INPUT and OUTPUT reports can be sent as pure data reports on the intr channel.
+For INPUT reports this is the usual operational mode. But for OUTPUT reports,
+this is rarely done as OUTPUT reports are normally quite scarce. But devices are
+free to make excessive use of asynchronous OUTPUT reports (for instance, custom
+HID audio speakers make great use of it).
+
+Plain reports must not be sent on the ctrl channel, though. Instead, the ctrl
+channel provides synchronous GET/SET_REPORT requests. Plain reports are only
+allowed on the intr channel and are the only means of data there.
+
+ - GET_REPORT: A GET_REPORT request has a report ID as payload and is sent
+ from host to device. The device must answer with a data report for the
+ requested report ID on the ctrl channel as a synchronous acknowledgement.
+ Only one GET_REPORT request can be pending for each device. This restriction
+ is enforced by HID core as several transport drivers don't allow multiple
+ simultaneous GET_REPORT requests.
+ Note that data reports which are sent as answer to a GET_REPORT request are
+ not handled as generic device events. That is, if a device does not operate
+ in continuous data reporting mode, an answer to GET_REPORT does not replace
+ the raw data report on the intr channel on state change.
+ GET_REPORT is only used by custom HID device drivers to query device state.
+ Normally, HID core caches any device state so this request is not necessary
+ on devices that follow the HID specs except during device initialization to
+ retrieve the current state.
+ GET_REPORT requests can be sent for any of the 3 report types and shall
+ return the current report state of the device. However, OUTPUT reports as
+ payload may be blocked by the underlying transport driver if the
+ specification does not allow them.
+ - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is
+ sent from host to device and a device must update it's current report state
+ according to the given data. Any of the 3 report types can be used. However,
+ INPUT reports as payload might be blocked by the underlying transport driver
+ if the specification does not allow them.
+ A device must answer with a synchronous acknowledgement. However, HID core
+ does not require transport drivers to forward this acknowledgement to HID
+ core.
+ Same as for GET_REPORT, only one SET_REPORT can be pending at a time. This
+ restriction is enforced by HID core as some transport drivers do not support
+ multiple synchronous SET_REPORT requests.
+
+Other ctrl-channel requests are supported by USB-HID but are not available
+(or deprecated) in most other transport level specifications:
+
+ - GET/SET_IDLE: Only used by USB-HID and I2C-HID.
+ - GET/SET_PROTOCOL: Not used by HID core.
+ - RESET: Used by I2C-HID, not hooked up in HID core.
+ - SET_POWER: Used by I2C-HID, not hooked up in HID core.
+
+2) HID API
+==========
+
+2.1) Initialization
+-------------------
+
+Transport drivers normally use the following procedure to register a new device
+with HID core:
+
+ struct hid_device *hid;
+ int ret;
+
+ hid = hid_allocate_device();
+ if (IS_ERR(hid)) {
+ ret = PTR_ERR(hid);
+ goto err_<...>;
+ }
+
+ strlcpy(hid->name, <device-name-src>, 127);
+ strlcpy(hid->phys, <device-phys-src>, 63);
+ strlcpy(hid->uniq, <device-uniq-src>, 63);
+
+ hid->ll_driver = &custom_ll_driver;
+ hid->bus = <device-bus>;
+ hid->vendor = <device-vendor>;
+ hid->product = <device-product>;
+ hid->version = <device-version>;
+ hid->country = <device-country>;
+ hid->dev.parent = <pointer-to-parent-device>;
+ hid->driver_data = <transport-driver-data-field>;
+
+ ret = hid_add_device(hid);
+ if (ret)
+ goto err_<...>;
+
+Once hid_add_device() is entered, HID core might use the callbacks provided in
+"custom_ll_driver". Note that fields like "country" can be ignored by underlying
+transport-drivers if not supported.
+
+To unregister a device, use:
+
+ hid_destroy_device(hid);
+
+Once hid_destroy_device() returns, HID core will no longer make use of any
+driver callbacks.
+
+2.2) hid_ll_driver operations
+-----------------------------
+
+The available HID callbacks are:
+ - int (*start) (struct hid_device *hdev)
+ Called from HID device drivers once they want to use the device. Transport
+ drivers can choose to setup their device in this callback. However, normally
+ devices are already set up before transport drivers register them to HID core
+ so this is mostly only used by USB-HID.
+
+ - void (*stop) (struct hid_device *hdev)
+ Called from HID device drivers once they are done with a device. Transport
+ drivers can free any buffers and deinitialize the device. But note that
+ ->start() might be called again if another HID device driver is loaded on the
+ device.
+ Transport drivers are free to ignore it and deinitialize devices after they
+ destroyed them via hid_destroy_device().
+
+ - int (*open) (struct hid_device *hdev)
+ Called from HID device drivers once they are interested in data reports.
+ Usually, while user-space didn't open any input API/etc., device drivers are
+ not interested in device data and transport drivers can put devices asleep.
+ However, once ->open() is called, transport drivers must be ready for I/O.
+ ->open() calls are nested for each client that opens the HID device.
+
+ - void (*close) (struct hid_device *hdev)
+ Called from HID device drivers after ->open() was called but they are no
+ longer interested in device reports. (Usually if user-space closed any input
+ devices of the driver).
+ Transport drivers can put devices asleep and terminate any I/O of all
+ ->open() calls have been followed by a ->close() call. However, ->start() may
+ be called again if the device driver is interested in input reports again.
+
+ - int (*parse) (struct hid_device *hdev)
+ Called once during device setup after ->start() has been called. Transport
+ drivers must read the HID report-descriptor from the device and tell HID core
+ about it via hid_parse_report().
+
+ - int (*power) (struct hid_device *hdev, int level)
+ Called by HID core to give PM hints to transport drivers. Usually this is
+ analogical to the ->open() and ->close() hints and redundant.
+
+ - void (*request) (struct hid_device *hdev, struct hid_report *report,
+ int reqtype)
+ Send an HID request on the ctrl channel. "report" contains the report that
+ should be sent and "reqtype" the request type. Request-type can be
+ HID_REQ_SET_REPORT or HID_REQ_GET_REPORT.
+ This callback is optional. If not provided, HID core will assemble a raw
+ report following the HID specs and send it via the ->raw_request() callback.
+ The transport driver is free to implement this asynchronously.
+
+ - int (*wait) (struct hid_device *hdev)
+ Used by HID core before calling ->request() again. A transport driver can use
+ it to wait for any pending requests to complete if only one request is
+ allowed at a time.
+
+ - int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
+ __u8 *buf, size_t count, unsigned char rtype,
+ int reqtype)
+ Same as ->request() but provides the report as raw buffer. This request shall
+ be synchronous. A transport driver must not use ->wait() to complete such
+ requests.
+
+ - int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
+ Send raw output report via intr channel. Used by some HID device drivers
+ which require high throughput for outgoing requests on the intr channel. This
+ must not cause SET_REPORT calls! This must be implemented as asynchronous
+ output report on the intr channel!
+
+ - int (*hidinput_input_event) (struct input_dev *idev, unsigned int type,
+ unsigned int code, int value)
+ Obsolete callback used by logitech converters. It is called when userspace
+ writes input events to the input device (eg., EV_LED). A driver can use this
+ callback to convert it into an output report and send it to the device. If
+ this callback is not provided, HID core will use ->request() or
+ ->raw_request() respectively.
+
+ - int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
+ Perform SET/GET_IDLE request. Only used by USB-HID, do not implement!
+
+2.3) Data Path
+--------------
+
+Transport drivers are responsible of reading data from I/O devices. They must
+handle any I/O-related state-tracking themselves. HID core does not implement
+protocol handshakes or other management commands which can be required by the
+given HID transport specification.
+
+Every raw data packet read from a device must be fed into HID core via
+hid_input_report(). You must specify the channel-type (intr or ctrl) and report
+type (input/output/feature). Under normal conditions, only input reports are
+provided via this API.
+
+Responses to GET_REPORT requests via ->request() must also be provided via this
+API. Responses to ->raw_request() are synchronous and must be intercepted by the
+transport driver and not passed to hid_input_report().
+Acknowledgements to SET_REPORT requests are not of interest to HID core.
+
+----------------------------------------------------
+Written 2013, David Herrmann <dh.herrmann@gmail.com>
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] HID: Add HID transport driver documentation
From: David Herrmann @ 2014-01-29 15:35 UTC (permalink / raw)
To: Frank Praznik, Benjamin Tissoires; +Cc: open list:HID CORE LAYER, Jiri Kosina
In-Reply-To: <1391009323-3122-1-git-send-email-frank.praznik@oh.rr.com>
Hi
On Wed, Jan 29, 2014 at 4:28 PM, Frank Praznik <frank.praznik@oh.rr.com> wrote:
> Add David Herrmann's documentation for the new low-level HID transport driver
> functions.
>
> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
If you copy code, you really should keep the signed-off-by chain. A
signed-off-by in kernel context means that you either wrote the code
or have permission to copy it. See here:
http://developercertificate.org/ (which is a public copy of the
kernel's signed-off-by practice).
If you copy code unchanged, it's common practice to even keep the
"Author" field via "git commit --author", but that's optional.
Anyhow, patch is good, thanks for picking it up!
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Putting Benjamin on CC as he reviewed the patch last time and might
have some more comments (or his final reviewed-by).
Thanks!
David
> ---
>
> Sorry, I forgot to include this in the original patch set.
>
> Documentation/hid/hid-transport.txt | 324 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 324 insertions(+)
> create mode 100644 Documentation/hid/hid-transport.txt
>
> diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.txt
> new file mode 100644
> index 0000000..14b1c18
> --- /dev/null
> +++ b/Documentation/hid/hid-transport.txt
> @@ -0,0 +1,324 @@
> + HID I/O Transport Drivers
> + ===========================
> +
> +The HID subsystem is independent of the underlying transport driver. Initially,
> +only USB was supported, but other specifications adopted the HID design and
> +provided new transport drivers. The kernel includes at least support for USB,
> +Bluetooth, I2C and user-space I/O drivers.
> +
> +1) HID Bus
> +==========
> +
> +The HID subsystem is designed as a bus. Any I/O subsystem may provide HID
> +devices and register them with the HID bus. HID core then loads generic device
> +drivers on top of it. The transport drivers are responsible of raw data
> +transport and device setup/management. HID core is responsible of
> +report-parsing, report interpretation and the user-space API. Device specifics
> +and quirks are handled by all layers depending on the quirk.
> +
> + +-----------+ +-----------+ +-----------+ +-----------+
> + | Device #1 | | Device #i | | Device #j | | Device #k |
> + +-----------+ +-----------+ +-----------+ +-----------+
> + \\ // \\ //
> + +------------+ +------------+
> + | I/O Driver | | I/O Driver |
> + +------------+ +------------+
> + || ||
> + +------------------+ +------------------+
> + | Transport Driver | | Transport Driver |
> + +------------------+ +------------------+
> + \___ ___/
> + \ /
> + +----------------+
> + | HID Core |
> + +----------------+
> + / | | \
> + / | | \
> + ____________/ | | \_________________
> + / | | \
> + / | | \
> + +----------------+ +-----------+ +------------------+ +------------------+
> + | Generic Driver | | MT Driver | | Custom Driver #1 | | Custom Driver #2 |
> + +----------------+ +-----------+ +------------------+ +------------------+
> +
> +Example Drivers:
> + I/O: USB, I2C, Bluetooth-l2cap
> + Transport: USB-HID, I2C-HID, BT-HIDP
> +
> +Everything below "HID Core" is simplified in this graph as it is only of
> +interest to HID device drivers. Transport drivers do not need to know the
> +specifics.
> +
> +1.1) Device Setup
> +-----------------
> +
> +I/O drivers normally provide hotplug detection or device enumeration APIs to the
> +transport drivers. Transport drivers use this to find any suitable HID device.
> +They allocate HID device objects and register them with HID core. Transport
> +drivers are not required to register themselves with HID core. HID core is never
> +aware of which transport drivers are available and is not interested in it. It
> +is only interested in devices.
> +
> +Transport drivers attach a constant "struct hid_ll_driver" object with each
> +device. Once a device is registered with HID core, the callbacks provided via
> +this struct are used by HID core to communicate with the device.
> +
> +Transport drivers are responsible of detecting device failures and unplugging.
> +HID core will operate a device as long as it is registered regardless of any
> +device failures. Once transport drivers detect unplug or failure events, they
> +must unregister the device from HID core and HID core will stop using the
> +provided callbacks.
> +
> +1.2) Transport Driver Requirements
> +----------------------------------
> +
> +The terms "asynchronous" and "synchronous" in this document describe the
> +transmission behavior regarding acknowledgements. An asynchronous channel must
> +not perform any synchronous operations like waiting for acknowledgements or
> +verifications. Generally, HID calls operating on asynchronous channels must be
> +running in atomic-context just fine.
> +On the other hand, synchronous channels can be implemented by the transport
> +driver in whatever way they like. They might just be the same as asynchronous
> +channels, but they can also provide acknowledgement reports, automatic
> +retransmission on failure, etc. in a blocking manner. If such functionality is
> +required on asynchronous channels, a transport-driver must implement that via
> +its own worker threads.
> +
> +HID core requires transport drivers to follow a given design. A Transport
> +driver must provide two bi-directional I/O channels to each HID device. These
> +channels must not necessarily be bi-directional in the hardware itself. A
> +transport driver might just provide 4 uni-directional channels. Or it might
> +multiplex all four on a single physical channel. However, in this document we
> +will describe them as two bi-directional channels as they have several
> +properties in common.
> +
> + - Interrupt Channel (intr): The intr channel is used for asynchronous data
> + reports. No management commands or data acknowledgements are sent on this
> + channel. Any unrequested incoming or outgoing data report must be sent on
> + this channel and is never acknowledged by the remote side. Devices usually
> + send their input events on this channel. Outgoing events are normally
> + not send via intr, except if high throughput is required.
> + - Control Channel (ctrl): The ctrl channel is used for synchronous requests and
> + device management. Unrequested data input events must not be sent on this
> + channel and are normally ignored. Instead, devices only send management
> + events or answers to host requests on this channel.
> + The control-channel is used for direct blocking queries to the device
> + independent of any events on the intr-channel.
> + Outgoing reports are usually sent on the ctrl channel via synchronous
> + SET_REPORT requests.
> +
> +Communication between devices and HID core is mostly done via HID reports. A
> +report can be of one of three types:
> +
> + - INPUT Report: Input reports provide data from device to host. This
> + data may include button events, axis events, battery status or more. This
> + data is generated by the device and sent to the host with or without
> + requiring explicit requests. Devices can choose to send data continuously or
> + only on change.
> + - OUTPUT Report: Output reports change device states. They are sent from host
> + to device and may include LED requests, rumble requests or more. Output
> + reports are never sent from device to host, but a host can retrieve their
> + current state.
> + Hosts may choose to send output reports either continuously or only on
> + change.
> + - FEATURE Report: Feature reports are used for specific static device features
> + and never reported spontaneously. A host can read and/or write them to access
> + data like battery-state or device-settings.
> + Feature reports are never sent without requests. A host must explicitly set
> + or retrieve a feature report. This also means, feature reports are never sent
> + on the intr channel as this channel is asynchronous.
> +
> +INPUT and OUTPUT reports can be sent as pure data reports on the intr channel.
> +For INPUT reports this is the usual operational mode. But for OUTPUT reports,
> +this is rarely done as OUTPUT reports are normally quite scarce. But devices are
> +free to make excessive use of asynchronous OUTPUT reports (for instance, custom
> +HID audio speakers make great use of it).
> +
> +Plain reports must not be sent on the ctrl channel, though. Instead, the ctrl
> +channel provides synchronous GET/SET_REPORT requests. Plain reports are only
> +allowed on the intr channel and are the only means of data there.
> +
> + - GET_REPORT: A GET_REPORT request has a report ID as payload and is sent
> + from host to device. The device must answer with a data report for the
> + requested report ID on the ctrl channel as a synchronous acknowledgement.
> + Only one GET_REPORT request can be pending for each device. This restriction
> + is enforced by HID core as several transport drivers don't allow multiple
> + simultaneous GET_REPORT requests.
> + Note that data reports which are sent as answer to a GET_REPORT request are
> + not handled as generic device events. That is, if a device does not operate
> + in continuous data reporting mode, an answer to GET_REPORT does not replace
> + the raw data report on the intr channel on state change.
> + GET_REPORT is only used by custom HID device drivers to query device state.
> + Normally, HID core caches any device state so this request is not necessary
> + on devices that follow the HID specs except during device initialization to
> + retrieve the current state.
> + GET_REPORT requests can be sent for any of the 3 report types and shall
> + return the current report state of the device. However, OUTPUT reports as
> + payload may be blocked by the underlying transport driver if the
> + specification does not allow them.
> + - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is
> + sent from host to device and a device must update it's current report state
> + according to the given data. Any of the 3 report types can be used. However,
> + INPUT reports as payload might be blocked by the underlying transport driver
> + if the specification does not allow them.
> + A device must answer with a synchronous acknowledgement. However, HID core
> + does not require transport drivers to forward this acknowledgement to HID
> + core.
> + Same as for GET_REPORT, only one SET_REPORT can be pending at a time. This
> + restriction is enforced by HID core as some transport drivers do not support
> + multiple synchronous SET_REPORT requests.
> +
> +Other ctrl-channel requests are supported by USB-HID but are not available
> +(or deprecated) in most other transport level specifications:
> +
> + - GET/SET_IDLE: Only used by USB-HID and I2C-HID.
> + - GET/SET_PROTOCOL: Not used by HID core.
> + - RESET: Used by I2C-HID, not hooked up in HID core.
> + - SET_POWER: Used by I2C-HID, not hooked up in HID core.
> +
> +2) HID API
> +==========
> +
> +2.1) Initialization
> +-------------------
> +
> +Transport drivers normally use the following procedure to register a new device
> +with HID core:
> +
> + struct hid_device *hid;
> + int ret;
> +
> + hid = hid_allocate_device();
> + if (IS_ERR(hid)) {
> + ret = PTR_ERR(hid);
> + goto err_<...>;
> + }
> +
> + strlcpy(hid->name, <device-name-src>, 127);
> + strlcpy(hid->phys, <device-phys-src>, 63);
> + strlcpy(hid->uniq, <device-uniq-src>, 63);
> +
> + hid->ll_driver = &custom_ll_driver;
> + hid->bus = <device-bus>;
> + hid->vendor = <device-vendor>;
> + hid->product = <device-product>;
> + hid->version = <device-version>;
> + hid->country = <device-country>;
> + hid->dev.parent = <pointer-to-parent-device>;
> + hid->driver_data = <transport-driver-data-field>;
> +
> + ret = hid_add_device(hid);
> + if (ret)
> + goto err_<...>;
> +
> +Once hid_add_device() is entered, HID core might use the callbacks provided in
> +"custom_ll_driver". Note that fields like "country" can be ignored by underlying
> +transport-drivers if not supported.
> +
> +To unregister a device, use:
> +
> + hid_destroy_device(hid);
> +
> +Once hid_destroy_device() returns, HID core will no longer make use of any
> +driver callbacks.
> +
> +2.2) hid_ll_driver operations
> +-----------------------------
> +
> +The available HID callbacks are:
> + - int (*start) (struct hid_device *hdev)
> + Called from HID device drivers once they want to use the device. Transport
> + drivers can choose to setup their device in this callback. However, normally
> + devices are already set up before transport drivers register them to HID core
> + so this is mostly only used by USB-HID.
> +
> + - void (*stop) (struct hid_device *hdev)
> + Called from HID device drivers once they are done with a device. Transport
> + drivers can free any buffers and deinitialize the device. But note that
> + ->start() might be called again if another HID device driver is loaded on the
> + device.
> + Transport drivers are free to ignore it and deinitialize devices after they
> + destroyed them via hid_destroy_device().
> +
> + - int (*open) (struct hid_device *hdev)
> + Called from HID device drivers once they are interested in data reports.
> + Usually, while user-space didn't open any input API/etc., device drivers are
> + not interested in device data and transport drivers can put devices asleep.
> + However, once ->open() is called, transport drivers must be ready for I/O.
> + ->open() calls are nested for each client that opens the HID device.
> +
> + - void (*close) (struct hid_device *hdev)
> + Called from HID device drivers after ->open() was called but they are no
> + longer interested in device reports. (Usually if user-space closed any input
> + devices of the driver).
> + Transport drivers can put devices asleep and terminate any I/O of all
> + ->open() calls have been followed by a ->close() call. However, ->start() may
> + be called again if the device driver is interested in input reports again.
> +
> + - int (*parse) (struct hid_device *hdev)
> + Called once during device setup after ->start() has been called. Transport
> + drivers must read the HID report-descriptor from the device and tell HID core
> + about it via hid_parse_report().
> +
> + - int (*power) (struct hid_device *hdev, int level)
> + Called by HID core to give PM hints to transport drivers. Usually this is
> + analogical to the ->open() and ->close() hints and redundant.
> +
> + - void (*request) (struct hid_device *hdev, struct hid_report *report,
> + int reqtype)
> + Send an HID request on the ctrl channel. "report" contains the report that
> + should be sent and "reqtype" the request type. Request-type can be
> + HID_REQ_SET_REPORT or HID_REQ_GET_REPORT.
> + This callback is optional. If not provided, HID core will assemble a raw
> + report following the HID specs and send it via the ->raw_request() callback.
> + The transport driver is free to implement this asynchronously.
> +
> + - int (*wait) (struct hid_device *hdev)
> + Used by HID core before calling ->request() again. A transport driver can use
> + it to wait for any pending requests to complete if only one request is
> + allowed at a time.
> +
> + - int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
> + __u8 *buf, size_t count, unsigned char rtype,
> + int reqtype)
> + Same as ->request() but provides the report as raw buffer. This request shall
> + be synchronous. A transport driver must not use ->wait() to complete such
> + requests.
> +
> + - int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
> + Send raw output report via intr channel. Used by some HID device drivers
> + which require high throughput for outgoing requests on the intr channel. This
> + must not cause SET_REPORT calls! This must be implemented as asynchronous
> + output report on the intr channel!
> +
> + - int (*hidinput_input_event) (struct input_dev *idev, unsigned int type,
> + unsigned int code, int value)
> + Obsolete callback used by logitech converters. It is called when userspace
> + writes input events to the input device (eg., EV_LED). A driver can use this
> + callback to convert it into an output report and send it to the device. If
> + this callback is not provided, HID core will use ->request() or
> + ->raw_request() respectively.
> +
> + - int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
> + Perform SET/GET_IDLE request. Only used by USB-HID, do not implement!
> +
> +2.3) Data Path
> +--------------
> +
> +Transport drivers are responsible of reading data from I/O devices. They must
> +handle any I/O-related state-tracking themselves. HID core does not implement
> +protocol handshakes or other management commands which can be required by the
> +given HID transport specification.
> +
> +Every raw data packet read from a device must be fed into HID core via
> +hid_input_report(). You must specify the channel-type (intr or ctrl) and report
> +type (input/output/feature). Under normal conditions, only input reports are
> +provided via this API.
> +
> +Responses to GET_REPORT requests via ->request() must also be provided via this
> +API. Responses to ->raw_request() are synchronous and must be intercepted by the
> +transport driver and not passed to hid_input_report().
> +Acknowledgements to SET_REPORT requests are not of interest to HID core.
> +
> +----------------------------------------------------
> +Written 2013, David Herrmann <dh.herrmann@gmail.com>
> --
> 1.8.3.2
>
^ permalink raw reply
* [PATCH 0/4] input: Add support for special keys on ms office kb
From: Hans de Goede @ 2014-01-29 16:57 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input
Hi All,
A member of my local hackerspace has donated a Microsoft Office keyboard to
me. This keyboard has lots of special keys, some of which don't work
and a scrollwheel which does not work. This patch-set adds support for the
scrollwheel and the non working special-keys.
Regards,
Hans
^ permalink raw reply
* [PATCH 1/4] input: Add some missing HUT mappings
From: Hans de Goede @ 2014-01-29 16:57 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, Hans de Goede
In-Reply-To: <1391014664-2642-1-git-send-email-hdegoede@redhat.com>
Add mapping for "AL Next Task/Application", "AL Previous Task/Application"
and "AL File Browser" buttons, as found on the Microsoft Office keyboard.
Note that there already is a mapping for "AL Local Machine Browser" to
KEY_FILE. Unless we ever encounter a device with both that should not be
a problem.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/hid/hid-input.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d97f232..ef17163 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -789,10 +789,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x199: map_key_clear(KEY_CHAT); break;
case 0x19c: map_key_clear(KEY_LOGOFF); break;
case 0x19e: map_key_clear(KEY_COFFEE); break;
+ case 0x1a3: map_key_clear(KEY_NEXT); break;
+ case 0x1a4: map_key_clear(KEY_PREVIOUS); break;
case 0x1a6: map_key_clear(KEY_HELP); break;
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
case 0x1ae: map_key_clear(KEY_KEYBOARD); break;
+ case 0x1b4: map_key_clear(KEY_FILE); break;
case 0x1b6: map_key_clear(KEY_IMAGES); break;
case 0x1b7: map_key_clear(KEY_AUDIO); break;
case 0x1b8: map_key_clear(KEY_VIDEO); break;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 2/4] input: hid-microsoft: Do the check for the ms usage page per device
From: Hans de Goede @ 2014-01-29 16:57 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, Hans de Goede
In-Reply-To: <1391014664-2642-1-git-send-email-hdegoede@redhat.com>
For some devices we may also want to do custom mappings for other pages.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/hid/hid-microsoft.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 551795b..a161afd 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -62,6 +62,9 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
{
struct input_dev *input = hi->input;
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+ return 0;
+
switch (usage->hid & HID_USAGE) {
case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
@@ -82,6 +85,9 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
unsigned long **bit, int *max)
{
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+ return 0;
+
set_bit(EV_REP, hi->input->evbit);
switch (usage->hid & HID_USAGE) {
case 0xfd08: ms_map_key_clear(KEY_FORWARD); break;
@@ -101,9 +107,6 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
- return 0;
-
if (quirks & MS_ERGONOMY) {
int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
if (ret)
--
1.8.4.2
^ permalink raw reply related
* [PATCH 3/4] input: hid-microsoft: Add support for scrollwheel and special keypad keys
From: Hans de Goede @ 2014-01-29 16:57 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, Hans de Goede
In-Reply-To: <1391014664-2642-1-git-send-email-hdegoede@redhat.com>
The Microsoft Office keyboard has a scrollwheel as well as some special keys
above the keypad which are handled through the custom MS usage page, this
commit adds support for these.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-microsoft.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 253fe23..fe5fa34 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1778,6 +1778,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index f9304cb..c4f5147 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -603,6 +603,7 @@
#define USB_VENDOR_ID_MICROSOFT 0x045e
#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
+#define USB_DEVICE_ID_MS_OFFICE_KB 0x0048
#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
#define USB_DEVICE_ID_MS_NE4K 0x00db
#define USB_DEVICE_ID_MS_NE4K_JP 0x00dc
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index a161afd..992252b 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -68,6 +68,26 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
switch (usage->hid & HID_USAGE) {
case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
+ case 0xff00:
+ /* Special keypad keys */
+ ms_map_key_clear(KEY_KPEQUAL);
+ set_bit(KEY_KPLEFTPAREN, input->keybit);
+ set_bit(KEY_KPRIGHTPAREN, input->keybit);
+ break;
+ case 0xff01:
+ /* Scroll wheel */
+ hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
+ break;
+ case 0xff02:
+ /*
+ * This byte contains a copy of the modifier keys byte of a
+ * standard hid keyboard report, as send by interface 0
+ * (this usage is found on interface 1).
+ *
+ * This byte only gets send when another key in the same report
+ * changes state, and as such is useless, ignore it.
+ */
+ return -1;
case 0xff05:
set_bit(EV_REP, input->evbit);
ms_map_key_clear(KEY_F13);
@@ -136,14 +156,39 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+ struct input_dev *input;
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
!usage->type)
return 0;
+ input = field->hidinput->input;
+
/* Handling MS keyboards special buttons */
+ if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
+ /* Special keypad keys */
+ input_report_key(input, KEY_KPEQUAL, value & 0x01);
+ input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
+ input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
+ return 1;
+ }
+
+ if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
+ /* Scroll wheel */
+ int step = ((value & 0x60) >> 5) + 1;
+
+ switch (value & 0x1f) {
+ case 0x01:
+ input_report_rel(input, REL_WHEEL, step);
+ break;
+ case 0x1f:
+ input_report_rel(input, REL_WHEEL, -step);
+ break;
+ }
+ return 1;
+ }
+
if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
- struct input_dev *input = field->hidinput->input;
static unsigned int last_key = 0;
unsigned int key = 0;
switch (value) {
@@ -196,6 +241,8 @@ err_free:
static const struct hid_device_id ms_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
.driver_data = MS_HIDINPUT },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
+ .driver_data = MS_ERGONOMY },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
.driver_data = MS_ERGONOMY },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),
--
1.8.4.2
^ permalink raw reply related
* [PATCH 4/4] input: hid-microsoft: Add support for 2 reserved usage ids used on ms office kb
From: Hans de Goede @ 2014-01-29 16:57 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, Hans de Goede
In-Reply-To: <1391014664-2642-1-git-send-email-hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/hid/hid-microsoft.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 992252b..10dd20f 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -62,6 +62,22 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
{
struct input_dev *input = hi->input;
+ if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
+ switch (usage->hid & HID_USAGE) {
+ /*
+ * Microsoft uses these 2 reserved usage ids for 2 keys on
+ * the MS office kb labelled "Office Home" and "Task Pane".
+ */
+ case 0x29d:
+ ms_map_key_clear(KEY_PROG1);
+ return 1;
+ case 0x29e:
+ ms_map_key_clear(KEY_PROG2);
+ return 1;
+ }
+ return 0;
+ }
+
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
return 0;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 0/7] HID: sony: Add full support for the Dualshock 4 on Bluetooth
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
Since the low-level transport driver changes are queued up, I can submit the
patches which enable full Bluetooth functionality for the Dualshock 4.
Note that BlueZ 5.14 or newer is required to successfully pair a Dualshock 4
controller via Bluetooth.
This uses the new low-level transport driver functions as the Dualshock 4 wants
output reports sent on the control channel instead of the interrupt channel when
connected via Bluetooth. If someone wants to test this, they will have to merge
the for-3.15/ll-driver-new-callbacks branch into the for-3.15/sony branch.
The HID descriptor had to be rewritten as once an output report is sent to the
controller it starts sending back data in report 17 instead of 1, which is
unmapped in the default descriptor.
The format of the data in the input and output reports is the same on Bluetooth
as on USB, but it starts at different offsets.
When no USB cable is connected and the battery is discharging, the battery level
is reported from 0 to 9 instead of from 0 to 11.
A single controller can show up as two devices in the event that a user connects
it via USB while it is already connected via Bluetooth. To remedy this a global
list of connected controllers and their MAC addresses is maintained and newly
connected controllers are checked against this list. If it is already connected
via some other means, the probe function returns with a code of EEXIST.
^ permalink raw reply
* [PATCH 1/7] HID: sony: Change dualshock4_state_worker to use the low-level transport driver function
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1391016797-12842-1-git-send-email-frank.praznik@oh.rr.com>
Use the new low-level transport driver functions to send the output reports to
the controller.
Remove sony_set_output_report since it is no longer used.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 56 +++++++++++++-------------------------------------
1 file changed, 14 insertions(+), 42 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2bd3f13..a3cefdec 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -502,7 +502,6 @@ struct sony_sc {
spinlock_t lock;
struct hid_device *hdev;
struct led_classdev *leds[MAX_LEDS];
- struct hid_report *output_report;
unsigned long quirks;
struct work_struct state_worker;
struct power_supply battery;
@@ -1053,21 +1052,26 @@ static void dualshock4_state_worker(struct work_struct *work)
{
struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
struct hid_device *hdev = sc->hdev;
- struct hid_report *report = sc->output_report;
- __s32 *value = report->field[0]->value;
+ int offset;
+
+ __u8 buf[32] = { 0 };
- value[0] = 0x03;
+ buf[0] = 0x05;
+ buf[1] = 0x03;
+ offset = 4;
#ifdef CONFIG_SONY_FF
- value[3] = sc->right;
- value[4] = sc->left;
+ buf[offset++] = sc->right;
+ buf[offset++] = sc->left;
+#else
+ offset += 2;
#endif
- value[5] = sc->led_state[0];
- value[6] = sc->led_state[1];
- value[7] = sc->led_state[2];
+ buf[offset++] = sc->led_state[0];
+ buf[offset++] = sc->led_state[1];
+ buf[offset++] = sc->led_state[2];
- hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+ hdev->ll_driver->output_report(hdev, buf, sizeof(buf));
}
#ifdef CONFIG_SONY_FF
@@ -1200,33 +1204,6 @@ static void sony_battery_remove(struct sony_sc *sc)
sc->battery.name = NULL;
}
-static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size)
-{
- struct list_head *head, *list;
- struct hid_report *report;
- struct hid_device *hdev = sc->hdev;
-
- list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
-
- list_for_each(head, list) {
- report = list_entry(head, struct hid_report, list);
-
- if (report->id == req_id) {
- if (report->size < req_size) {
- hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n",
- req_id, report->size, req_size);
- return -EINVAL;
- }
- sc->output_report = report;
- return 0;
- }
- }
-
- hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id);
-
- return -EINVAL;
-}
-
static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
int w, int h)
{
@@ -1291,11 +1268,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
ret = sixaxis_set_operational_bt(hdev);
else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
- /* Report 5 (31 bytes) is used to send data to the controller via USB */
- ret = sony_set_output_report(sc, 0x05, 248);
- if (ret < 0)
- goto err_stop;
-
/* The Dualshock 4 touchpad supports 2 touches and has a
* resolution of 1920x940.
*/
--
1.8.5.3
^ permalink raw reply related
* [PATCH 2/7] HID: sony: Add Bluetooth HID descriptor for Dualshock 4
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1391016797-12842-1-git-send-email-frank.praznik@oh.rr.com>
Add the modified Bluetooth HID descriptor for the Dualshock 4.
By default, the Dualshock 4 sends controller data via report 1. Once an output
report is received the controller changes to sending data in report 17, which is
unmapped in the default descriptor. The mappings had to be moved to report 17 to
let the HID driver properly process the incoming reports.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 214 insertions(+)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index a3cefdec..8e82073f 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -336,6 +336,216 @@ static u8 dualshock4_usb_rdesc[] = {
0xC0 /* End Collection */
};
+/* The default behavior of the Dualshock 4 is to send reports using report
+ * type 1 when running over Bluetooth. However, as soon as it receives a
+ * report of type 17 to set the LEDs or rumble it starts returning it's state
+ * in report 17 instead of 1. Since report 17 is undefined in the default HID
+ * descriptor the button and axis definitions must be moved to report 17 or
+ * the HID layer won't process the received input once a report is sent.
+ */
+static u8 dualshock4_bt_rdesc[] = {
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x05, /* Usage (Gamepad), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x01, /* Report ID (1), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x0A, /* Report Count (9), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */
+ 0x85, 0x02, /* Report ID (2), */
+ 0x09, 0x24, /* Usage (24h), */
+ 0x95, 0x24, /* Report Count (36), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xA3, /* Report ID (163), */
+ 0x09, 0x25, /* Usage (25h), */
+ 0x95, 0x30, /* Report Count (48), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x05, /* Report ID (5), */
+ 0x09, 0x26, /* Usage (26h), */
+ 0x95, 0x28, /* Report Count (40), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x06, /* Report ID (6), */
+ 0x09, 0x27, /* Usage (27h), */
+ 0x95, 0x34, /* Report Count (52), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x07, /* Report ID (7), */
+ 0x09, 0x28, /* Usage (28h), */
+ 0x95, 0x30, /* Report Count (48), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x08, /* Report ID (8), */
+ 0x09, 0x29, /* Usage (29h), */
+ 0x95, 0x2F, /* Report Count (47), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */
+ 0x85, 0x03, /* Report ID (3), */
+ 0x09, 0x21, /* Usage (21h), */
+ 0x95, 0x26, /* Report Count (38), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x04, /* Report ID (4), */
+ 0x09, 0x22, /* Usage (22h), */
+ 0x95, 0x2E, /* Report Count (46), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xF0, /* Report ID (240), */
+ 0x09, 0x47, /* Usage (47h), */
+ 0x95, 0x3F, /* Report Count (63), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xF1, /* Report ID (241), */
+ 0x09, 0x48, /* Usage (48h), */
+ 0x95, 0x3F, /* Report Count (63), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xF2, /* Report ID (242), */
+ 0x09, 0x49, /* Usage (49h), */
+ 0x95, 0x0F, /* Report Count (15), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x11, /* Report ID (17), */
+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+ 0x09, 0x20, /* Usage (20h), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x09, 0x32, /* Usage (Z), */
+ 0x09, 0x35, /* Usage (Rz), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x04, /* Report Count (4), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x39, /* Usage (Hat Switch), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x25, 0x07, /* Logical Maximum (7), */
+ 0x75, 0x04, /* Report Size (4), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x42, /* Input (Variable, Null State), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x0E, /* Usage Maximum (0Eh), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x0E, /* Report Count (14), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x75, 0x06, /* Report Size (6), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x33, /* Usage (Rx), */
+ 0x09, 0x34, /* Usage (Ry), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+ 0x09, 0x20, /* Usage (20h), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x19, 0x40, /* Usage Minimum (40h), */
+ 0x29, 0x42, /* Usage Maximum (42h), */
+ 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
+ 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x19, 0x43, /* Usage Minimum (43h), */
+ 0x29, 0x45, /* Usage Maximum (45h), */
+ 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */
+ 0x26, 0x00, 0x40, /* Logical Maximum (16384), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+ 0x09, 0x20, /* Usage (20h), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x31, /* Report Count (51), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x21, /* Usage (21h), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x4D, /* Report Count (77), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x12, /* Report ID (18), */
+ 0x09, 0x22, /* Usage (22h), */
+ 0x95, 0x8D, /* Report Count (141), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x23, /* Usage (23h), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x13, /* Report ID (19), */
+ 0x09, 0x24, /* Usage (24h), */
+ 0x95, 0xCD, /* Report Count (205), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x25, /* Usage (25h), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x14, /* Report ID (20), */
+ 0x09, 0x26, /* Usage (26h), */
+ 0x96, 0x0D, 0x01, /* Report Count (269), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x27, /* Usage (27h), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x15, /* Report ID (21), */
+ 0x09, 0x28, /* Usage (28h), */
+ 0x96, 0x4D, 0x01, /* Report Count (333), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x29, /* Usage (29h), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x16, /* Report ID (22), */
+ 0x09, 0x2A, /* Usage (2Ah), */
+ 0x96, 0x8D, 0x01, /* Report Count (397), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x2B, /* Usage (2Bh), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x17, /* Report ID (23), */
+ 0x09, 0x2C, /* Usage (2Ch), */
+ 0x96, 0xCD, 0x01, /* Report Count (461), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x2D, /* Usage (2Dh), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x18, /* Report ID (24), */
+ 0x09, 0x2E, /* Usage (2Eh), */
+ 0x96, 0x0D, 0x02, /* Report Count (525), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x2F, /* Usage (2Fh), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x85, 0x19, /* Report ID (25), */
+ 0x09, 0x30, /* Usage (30h), */
+ 0x96, 0x22, 0x02, /* Report Count (546), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (31h), */
+ 0x91, 0x02, /* Output (Variable), */
+ 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */
+ 0x85, 0x82, /* Report ID (130), */
+ 0x09, 0x22, /* Usage (22h), */
+ 0x95, 0x3F, /* Report Count (63), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x83, /* Report ID (131), */
+ 0x09, 0x23, /* Usage (23h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x84, /* Report ID (132), */
+ 0x09, 0x24, /* Usage (24h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x90, /* Report ID (144), */
+ 0x09, 0x30, /* Usage (30h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x91, /* Report ID (145), */
+ 0x09, 0x31, /* Usage (31h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x92, /* Report ID (146), */
+ 0x09, 0x32, /* Usage (32h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0x93, /* Report ID (147), */
+ 0x09, 0x33, /* Usage (33h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xA0, /* Report ID (160), */
+ 0x09, 0x40, /* Usage (40h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0x85, 0xA4, /* Report ID (164), */
+ 0x09, 0x44, /* Usage (44h), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0xC0 /* End Collection */
+};
+
static __u8 ps3remote_rdesc[] = {
0x05, 0x01, /* GUsagePage Generic Desktop */
0x09, 0x05, /* LUsage 0x05 [Game Pad] */
@@ -591,6 +801,10 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
rdesc = dualshock4_usb_rdesc;
*rsize = sizeof(dualshock4_usb_rdesc);
+ } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
+ hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
+ rdesc = dualshock4_bt_rdesc;
+ *rsize = sizeof(dualshock4_bt_rdesc);
}
/* The HID descriptor exposed over BT has a trailing zero byte */
--
1.8.5.3
^ permalink raw reply related
* [PATCH 3/7] HID: sony: Add Bluetooth output report formatting for the Dualshock 4
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1391016797-12842-1-git-send-email-frank.praznik@oh.rr.com>
When connected via Bluetooth the Dualshock 4 wants rumble and LED data sent in
report 17, which is 77 bytes.
The format of the rumble and LED data is identical to running over USB, but the
starting offset is at 6 bytes instead of 4.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 8e82073f..b35535e 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1268,11 +1268,18 @@ static void dualshock4_state_worker(struct work_struct *work)
struct hid_device *hdev = sc->hdev;
int offset;
- __u8 buf[32] = { 0 };
+ __u8 buf[78] = { 0 };
- buf[0] = 0x05;
- buf[1] = 0x03;
- offset = 4;
+ if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
+ buf[0] = 0x05;
+ buf[1] = 0x03;
+ offset = 4;
+ } else {
+ buf[0] = 0x11;
+ buf[1] = 0xB0;
+ buf[3] = 0x0F;
+ offset = 6;
+ }
#ifdef CONFIG_SONY_FF
buf[offset++] = sc->right;
@@ -1285,7 +1292,11 @@ static void dualshock4_state_worker(struct work_struct *work)
buf[offset++] = sc->led_state[1];
buf[offset++] = sc->led_state[2];
- hdev->ll_driver->output_report(hdev, buf, sizeof(buf));
+ if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
+ hdev->ll_driver->output_report(hdev, buf, 32);
+ else
+ hdev->ll_driver->raw_request(hdev, 0x11, buf, 78,
+ HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
}
#ifdef CONFIG_SONY_FF
--
1.8.5.3
^ permalink raw reply related
* [PATCH 5/7] HID: sony: Set inital battery level to 100% to avoid false low battery warnings
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1391016797-12842-1-git-send-email-frank.praznik@oh.rr.com>
Set the inital battery level to 100% to avoid false low battery warnings if the
battery level is polled before a device report is received.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 7005086..cee752f 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1404,6 +1404,11 @@ static int sony_battery_probe(struct sony_sc *sc)
struct hid_device *hdev = sc->hdev;
int ret;
+ /* Set the default battery level to 100% to avoid low battery warnings
+ * if the battery is polled before the first device report is received.
+ */
+ sc->battery_capacity = 100;
+
power_id = (unsigned long)atomic_inc_return(&power_id_seq);
sc->battery.properties = sony_battery_props;
--
1.8.5.3
^ permalink raw reply related
* [PATCH 4/7] HID: sony: Add offsets and battery calculations for parsing Dualshock 4 reports sent via Bluetooth.
From: Frank Praznik @ 2014-01-29 17:33 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1391016797-12842-1-git-send-email-frank.praznik@oh.rr.com>
The battery and touch data starts at offset 32 instead of 30 in the Bluetooth
reports.
When the controller isn't connected to a power source and the battery is
discharging, the battery level is reported from 0 to 9 instead of 1 to 11.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index b35535e..e243c3d 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -861,25 +861,34 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
unsigned long flags;
- int n, offset = 35;
+ int n, offset;
__u8 cable_state, battery_capacity, battery_charging;
+ /* Battery and touchpad data starts at byte 30 in the USB report and
+ * 32 in Bluetooth report.
+ */
+ offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
+
/* The lower 4 bits of byte 30 contain the battery level
* and the 5th bit contains the USB cable state.
*/
- cable_state = (rd[30] >> 4) & 0x01;
- battery_capacity = rd[30] & 0x0F;
+ cable_state = (rd[offset] >> 4) & 0x01;
+ battery_capacity = rd[offset] & 0x0F;
- /* On USB the Dualshock 4 battery level goes from 0 to 11.
- * A battery level of 11 means fully charged.
+ /* When a USB power source is connected the battery level ranges from
+ * 0 to 11, and when running on battery power it ranges from 0 to 9.
+ * A battery level of 11 means charge completed.
*/
- if (cable_state && battery_capacity == 11)
+ if (!cable_state || battery_capacity == 11)
battery_charging = 0;
else
battery_charging = 1;
+ if (!cable_state)
+ battery_capacity++;
if (battery_capacity > 10)
battery_capacity--;
+
battery_capacity *= 10;
spin_lock_irqsave(&sc->lock, flags);
@@ -888,7 +897,10 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
sc->battery_charging = battery_charging;
spin_unlock_irqrestore(&sc->lock, flags);
- /* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB.
+ offset += 5;
+
+ /* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
+ * and 37 on Bluetooth.
* The first 7 bits of the first byte is a counter and bit 8 is a touch
* indicator that is 0 when pressed and 1 when not pressed.
* The next 3 bytes are two 12 bit touch coordinates, X and Y.
--
1.8.5.3
^ 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