* Re: [PATCH] Input: pmic8xxx-pwrkey - Set sane default for debounce time
From: Josh Cartwright @ 2014-03-31 18:23 UTC (permalink / raw)
To: Stephen Boyd
Cc: Dmitry Torokhov, linux-kernel, linux-arm-msm, linux-arm-kernel,
linux-input, Arnd Bergmann
In-Reply-To: <1396289664-31893-1-git-send-email-sboyd@codeaurora.org>
On Mon, Mar 31, 2014 at 11:14:24AM -0700, Stephen Boyd wrote:
> If the debounce time is 0 our usage of ilog2() later on in this
> driver will cause undefined behavior. If CONFIG_OF=n this fact is
> evident to the compiler, and it emits a call to ____ilog2_NaN()
> which doesn't exist. Fix this by setting a sane default for
> debounce.
>
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
> drivers/input/misc/pmic8xxx-pwrkey.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
> index 1cb8fda7a166..27add04676e1 100644
> --- a/drivers/input/misc/pmic8xxx-pwrkey.c
> +++ b/drivers/input/misc/pmic8xxx-pwrkey.c
> @@ -92,7 +92,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
> bool pull_up;
>
> if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
> - kpd_delay = 0;
> + kpd_delay = 15625;
Should "debounce" even be optional? I'm wondering if we should just
make it required...
At the very least this default value should be documented in the DT
binding.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH] Input: pmic8xxx-pwrkey - Set sane default for debounce time
From: Stephen Boyd @ 2014-03-31 18:29 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, linux-input,
Arnd Bergmann
In-Reply-To: <20140331182315.GA9198@core.coreip.homeip.net>
On 03/31/14 11:23, Dmitry Torokhov wrote:
> On Mon, Mar 31, 2014 at 11:14:24AM -0700, Stephen Boyd wrote:
>> If the debounce time is 0 our usage of ilog2() later on in this
>> driver will cause undefined behavior. If CONFIG_OF=n this fact is
>> evident to the compiler, and it emits a call to ____ilog2_NaN()
>> which doesn't exist. Fix this by setting a sane default for
>> debounce.
>>
>> Reported-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
>> ---
>> drivers/input/misc/pmic8xxx-pwrkey.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
>> index 1cb8fda7a166..27add04676e1 100644
>> --- a/drivers/input/misc/pmic8xxx-pwrkey.c
>> +++ b/drivers/input/misc/pmic8xxx-pwrkey.c
>> @@ -92,7 +92,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
>> bool pull_up;
>>
>> if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
>> - kpd_delay = 0;
>> + kpd_delay = 15625;
> What if somebody supplied 0 via DT? Can we check and return -EINVAL?
Sure. Here's a v2.
-----8<------
From: Stephen Boyd <sboyd@codeaurora.org>
Subject: [PATCH v2] Input: pmic8xxx-pwrkey - Set sane default for debounce
time
If the debounce time is 0 our usage of ilog2() later on in this
driver will cause undefined behavior. If CONFIG_OF=n this fact is
evident to the compiler, and it emits a call to ____ilog2_NaN()
which doesn't exist. Fix this by setting a sane default for
debounce and failing to probe if debounce is 0 in the DT.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/input/misc/pmic8xxx-pwrkey.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index 1cb8fda7a166..3fb161902cc6 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -92,11 +92,11 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
bool pull_up;
if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
- kpd_delay = 0;
+ kpd_delay = 15625;
pull_up = of_property_read_bool(pdev->dev.of_node, "pull-up");
- if (kpd_delay > 62500) {
+ if (kpd_delay > 62500 || kpd_delay == 0) {
dev_err(&pdev->dev, "invalid power key trigger delay\n");
return -EINVAL;
}
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* Re: [PATCH] Input: pmic8xxx-pwrkey - Set sane default for debounce time
From: Stephen Boyd @ 2014-03-31 18:48 UTC (permalink / raw)
To: Josh Cartwright
Cc: Dmitry Torokhov, linux-kernel, linux-arm-msm, linux-arm-kernel,
linux-input, Arnd Bergmann
In-Reply-To: <20140331182342.GD28265@joshc.qualcomm.com>
On 03/31/14 11:23, Josh Cartwright wrote:
> On Mon, Mar 31, 2014 at 11:14:24AM -0700, Stephen Boyd wrote:
>> If the debounce time is 0 our usage of ilog2() later on in this
>> driver will cause undefined behavior. If CONFIG_OF=n this fact is
>> evident to the compiler, and it emits a call to ____ilog2_NaN()
>> which doesn't exist. Fix this by setting a sane default for
>> debounce.
>>
>> Reported-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
>> ---
>> drivers/input/misc/pmic8xxx-pwrkey.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
>> index 1cb8fda7a166..27add04676e1 100644
>> --- a/drivers/input/misc/pmic8xxx-pwrkey.c
>> +++ b/drivers/input/misc/pmic8xxx-pwrkey.c
>> @@ -92,7 +92,7 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
>> bool pull_up;
>>
>> if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay))
>> - kpd_delay = 0;
>> + kpd_delay = 15625;
> Should "debounce" even be optional? I'm wondering if we should just
> make it required...
Hmm maybe. It's not like things won't work without it set though.
>
> At the very least this default value should be documented in the DT
> binding.
>
I never understood this. The default value is something that is entirely
software driven. It could change at any time. If DT implementers aren't
specifying it they're saying "I don't care what the value is, let the
driver decide if they care". They're not saying, "Oh, that default value
in the binding is good enough for me so I don't need to specify this".
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH v3 2/8] HID: sony: Set the quriks flag for Bluetooth controllers
From: andrea @ 2014-03-31 19:14 UTC (permalink / raw)
To: Frank Praznik, linux-input; +Cc: jkosina
In-Reply-To: <1394890882-2039-3-git-send-email-frank.praznik@oh.rr.com>
On 15/03/14 13:41, Frank Praznik wrote:
> The Sixaxis and DualShock 4 want HID output reports sent on the control
> endpoint when connected via Bluetooth. Set the
> HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP flag for these devices so hidraw write()
> works properly.
>
> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
> ---
> drivers/hid/hid-sony.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
> index 4c445a0..908de27 100644
> --- a/drivers/hid/hid-sony.c
> +++ b/drivers/hid/hid-sony.c
> @@ -1632,11 +1632,21 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
> sc->worker_initialized = 1;
> INIT_WORK(&sc->state_worker, sixaxis_state_worker);
> } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
> + /*
> + * The Sixaxis wants output reports sent on the ctrl endpoint
> + * when connected via Bluetooth.
> + */
> + hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
> ret = sixaxis_set_operational_bt(hdev);
> sc->worker_initialized = 1;
> INIT_WORK(&sc->state_worker, sixaxis_state_worker);
> } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
> if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
> + /*
> + * The DualShock 4 wants output reports sent on the ctrl
> + * endpoint when connected via Bluetooth.
> + */
> + hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
> ret = dualshock4_set_operational_bt(hdev);
> if (ret < 0) {
> hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
>
I am simply a user of a Sixaxis via Bluetooth and it would be super to have this patch applied and
merged in 3.15
We always need to modify the BT stack in the vanilla kernel using an old hack Frank proposed.
This would make things a lot simpler and less painful.
I don't know about the other 7, but this one would get my vote (if I had one...)
Andrea
^ permalink raw reply
* Re: ti_am33x_adc sampling bugs
From: Jonathan Cameron @ 2014-03-31 20:59 UTC (permalink / raw)
To: Rob Mosher, Zubair Lutfullah
Cc: Sebastian Andrzej Siewior, robertcnelson, Samuel Ortiz,
Dmitry Torokhov, Felipe Balbi, linux-iio, linux-input, Lee Jones
In-Reply-To: <53399C3A.9040007@countercultured.net>
On March 31, 2014 5:47:54 PM GMT+01:00, Rob Mosher <nyt@countercultured.net> wrote:
>I believe the AIN files came from
>0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch.
Ouch that is an 'unusual' patch... No more recent patches in mainline appear related to what you are seeing unfortunately.
>The bug is the
>same
>reading from in_voltageX_raw files.
>
>On 3/31/2014 12:14 PM, Jonathan Cameron wrote:
>>
>>
>> On March 31, 2014 9:17:53 AM GMT+01:00, Rob Mosher
><nyt@countercultured.net> wrote:
>>> The following patches were removed and behavior returned to normal.
>>>
>>> 0019-iio-ti_am335x_adc-Add-continuous-sampling-and-trigge.patch
>>> 0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch
>>>
>>> Once 19 was re-applied, the bug returned.
>>>
>>> It would appear that patch19 is the problem. On an unrelated note,
>the
>>>
>>> continuous sampling patch seems to still be missing the mode file to
>>> tell it to sample continuously or oneshot in the sysfs directory as
>>> referenced at
>>> http://processors.wiki.ti.com/index.php/AM335x_ADC_Driver%27s_Guide.
>> Someone should update that wiki page.
>> Such an attribute was not and will not be
>> part of the mainline kernel ABI. Drivers can play fast and loose in
>staging but to move
>> out the ABI must conform to existing definitions or be proposed
>reviewed and accepted.
>>
>> I am somewhat confused. Where did the AIN sysfs attributes come from?
>>
>>> Maybe this should be moved to the beta kernel until stable?
>>
>>>
>>> Cheers.
>>>
>>> On 3/31/2014 12:04 AM, Rob Mosher wrote:
>>>> (sorry for the duplicate, got bounces due to HTML encoding)
>>>>
>>>> The specified patch is already included. The system was running
>the
>>>> latest kernel from Robert Nelson's repo. Any suggestions? I'll
>try
>>>> removing some of the patches to see if it fixes this behavior. I
>>> have a
>>>> feeling I know which one is doing it.
>>>>
>>>> Thanks.
>>>>
>>>> output from running patch.sh with source pulled from
>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>
>>>>
>>>
>/home/bbuild/comp/kernel/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch:
>>>> applied
>>>>
>>>> Just in case, I built and installed the kernel and the same
>behavior
>>>> persisted.
>>>>
>>>> root@rbone:/# uname -a
>>>> Linux rbone 3.8.13-00737-g7dfad77 #1 SMP Sun Mar 30 22:11:44 EDT
>2014
>>>> armv7l GNU/Linux
>>>>
>>>> gpio30 is connected to AIN4 using a voltage divider
>>>>
>>>> root@rbone:/# cd /sys/class/gpio/
>>>> root@rbone:/sys/class/gpio# echo 30 > export
>>>> root@rbone:/sys/class/gpio# echo BB-ADC >
>>> /sys/devices/bone_capemgr.9/slots
>>>> root@rbone:/sys/class/gpio# cd /sys/devices/ocp.3/helper.11/
>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo out >
>>>> /sys/class/gpio/gpio30/direction
>>>>
>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>> /sys/class/gpio/gpio30/value
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 1460
>>>>
>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 0 >
>>>> /sys/class/gpio/gpio30/value
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>>
>>>> root@rbone:/sys/devices/ocp.3/helper.11# grep . AIN[0-3] AIN[5-7]
>>>> AIN0:1550
>>>> AIN1:1213
>>>> AIN2:1485
>>>> AIN3:795
>>>> AIN5:513
>>>> AIN6:744
>>>> AIN7:1698
>>>>
>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>> /sys/class/gpio/gpio30/value
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 0
>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>> 1460
>>>>
>>>> On 3/30/2014 9:16 AM, Zubair Lutfullah wrote:
>>>>>
>>>
>https://github.com/beagleboard/kernel/blob/3.8/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
>>>>>
>>>>> IIRC, this patch fixes this issue
>>>>>
>>>>> Can you compile the kernel from the sources and check?
>>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>>
>>>>> Regards
>>>>> ZubairLK
>>>>>
>>>>> On Sun, Mar 30, 2014 at 7:04 AM, Rob Mosher
><nyt@countercultured.net
>>>>> <mailto:nyt@countercultured.net>> wrote:
>>>>>
>>>>> Just a note, the same behavior persists with BB-ADC dtb and
>>>>> reading from in_voltage4_raw
>>>>>
>>>>>
>>>>> On 3/30/2014 12:30 AM, Rob Mosher wrote:
>>>>>
>>>>> Hello fine developers,
>>>>>
>>>>> It seems I've stumbled upon a problem while developing a
>>> full
>>>>> featured Ruby gem for the Beaglebone.
>>>>>
>>>>> It seems a patch included in the beaglebone kernel causes
>>> some
>>>>> issues while reading analog inputs. Apparently the
>samples
>>>>> get backlogged by the number of adc pins in use. I'm not
>>> sure
>>>>> which patch exactly as there are a number that affect adc
>>>>> buffering and I'm not currently setup for kernel
>building,
>>>>> however the below output should detail the problem.
>>>>>
>>>>> Using the official Debian image.
>>>>> Linux rbone 3.8.13-bone43 #1 SMP Wed Mar 26 14:21:39 UTC
>>> 2014
>>>>> armv7l GNU/Linux
>>>>>
>>>>> Distributor ID: Debian
>>>>> Description: Debian GNU/Linux 7.4 (wheezy)
>>>>> Release: 7.4
>>>>> Codename: wheezy
>>>>>
>>>>> root@rbone:~# echo cape-bone-iio >
>>>>> /sys/devices/bone_capemgr.9/slots
>>>>>
>>>>> This is the normal and expected behavior.
>>>>>
>>>>> 1.8v applied to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>>
>>>>> 0v applied to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>>
>>>>> 1.8v applied to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>>
>>>>> 0v applied to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>>
>>>>> So far working as intended.... Now reading from the
>other
>>> pins.
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep . AIN[0-3]
>>> AIN[5-7]
>>>>> AIN0:1563
>>>>> AIN1:1221
>>>>> AIN2:1487
>>>>> AIN3:789
>>>>> AIN5:514
>>>>> AIN6:743
>>>>> AIN7:1698
>>>>>
>>>>> Now applying 1.8v to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>>
>>>>> Now applying 0v to AIN4
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>>
>>>>>
>>>>>
>>>>> And another example, showing relation to the number of
>pins
>>> in
>>>>> use.
>>>>>
>>>>> 1.8v to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep . AIN[0-3]
>>>>> AIN0:1697
>>>>> AIN1:1298
>>>>> AIN2:1524
>>>>> AIN3:816
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>>
>>>>> 0v to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1460
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>>
>>>>> 1.8v to AIN4
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>> 1798
>>>>>
>>>>> -- Rob Mosher
>>>>> Senior Network and Software Engineer
>>>>> Hurricane Electric / AS6939
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-iio"
>in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
^ permalink raw reply
* Re: [PATCH 2/2] HID: core: do not scan constant input report
From: Reyad Attiyat @ 2014-03-31 20:59 UTC (permalink / raw)
To: linux-kernel, linux-input, derya.kiran
In-Reply-To: <CA+BWVUSS7VdiswgjXEMYHCed1xzz4ubCi89t7SF-1qG5=GzDUA@mail.gmail.com>
Tested on Surface Pro 2 Type Cover 2 on kernel 3.15/multitouch rebased
on 3.14. The device is now handled by hid-generic and hid-sensor-hub
as expected.
There is a newer UEFI and touch cover firmware that I have not tried,
as you need windows update to get drivers for this device. I will try
and update my device to make sure we don't need any
quirks.
> On Mon, Mar 31, 2014 at 12:27 PM, Benjamin Tissoires
> <benjamin.tissoires@redhat.com> wrote:
>> The Microsoft Surface Type/Touch Cover 2 is a fancy device which advertised
>> itself as a multitouch device but with constant input reports.
>> This way, hid_scan_report() gives the group MULTITOUCH to it, but
>> hid-multitouch can not handle it due to the constant collection ignored
>> by hid-input.
>>
>> To prevent such crap in the future, and while we do not fix this particular
>> device, make the scan_report coherent with hid-input.c, and ignore constant
>> input reports.
>>
>> CC: stable@vger.kernel.org # 3.12+
>> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>> ---
>> drivers/hid/hid-core.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
>> index bb5c494..8a5384c 100644
>> --- a/drivers/hid/hid-core.c
>> +++ b/drivers/hid/hid-core.c
>> @@ -718,6 +718,9 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
>> case HID_MAIN_ITEM_TAG_END_COLLECTION:
>> break;
>> case HID_MAIN_ITEM_TAG_INPUT:
>> + /* ignore constant inputs, they will be ignored by hid-input */
>> + if (data & HID_MAIN_ITEM_CONSTANT)
>> + break;
>> for (i = 0; i < parser->local.usage_index; i++)
>> hid_scan_input_usage(parser, parser->local.usage[i]);
>> break;
>> --
>> 1.9.0
>>
^ permalink raw reply
* Re: ti_am33x_adc sampling bugs
From: Rob Mosher @ 2014-03-31 21:03 UTC (permalink / raw)
To: Jonathan Cameron, Zubair Lutfullah
Cc: Sebastian Andrzej Siewior, robertcnelson, Samuel Ortiz,
Dmitry Torokhov, Felipe Balbi, linux-iio, linux-input, Lee Jones
In-Reply-To: <ab74c908-a1d0-417c-836b-8d4b093a942b@email.android.com>
I'm not quite aware of what's in mainline or not, this list was CC'd by
Zubair Lutfullah who authored the patches in question. Hopefully he can
provide more insight or a possible fix.
0019-iio-ti_am335x_adc-Add-continuous-sampling-and-trigge.patch
Subject: [PATCH 19/21] iio: ti_am335x_adc: Add continuous sampling and
trigger support
Previously the driver had only one-shot reading functionality.
This patch adds triggered buffer support to the driver.
A buffer of samples can now be read via /dev/iio.
On 3/31/2014 4:59 PM, Jonathan Cameron wrote:
>
>
> On March 31, 2014 5:47:54 PM GMT+01:00, Rob Mosher <nyt@countercultured.net> wrote:
>> I believe the AIN files came from
>> 0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch.
>
> Ouch that is an 'unusual' patch... No more recent patches in mainline appear related to what you are seeing unfortunately.
>
>
>
>> The bug is the
>> same
>> reading from in_voltageX_raw files.
>>
>> On 3/31/2014 12:14 PM, Jonathan Cameron wrote:
>>>
>>>
>>> On March 31, 2014 9:17:53 AM GMT+01:00, Rob Mosher
>> <nyt@countercultured.net> wrote:
>>>> The following patches were removed and behavior returned to normal.
>>>>
>>>> 0019-iio-ti_am335x_adc-Add-continuous-sampling-and-trigge.patch
>>>> 0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch
>>>>
>>>> Once 19 was re-applied, the bug returned.
>>>>
>>>> It would appear that patch19 is the problem. On an unrelated note,
>> the
>>>>
>>>> continuous sampling patch seems to still be missing the mode file to
>>>> tell it to sample continuously or oneshot in the sysfs directory as
>>>> referenced at
>>>> http://processors.wiki.ti.com/index.php/AM335x_ADC_Driver%27s_Guide.
>>> Someone should update that wiki page.
>>> Such an attribute was not and will not be
>>> part of the mainline kernel ABI. Drivers can play fast and loose in
>> staging but to move
>>> out the ABI must conform to existing definitions or be proposed
>> reviewed and accepted.
>>>
>>> I am somewhat confused. Where did the AIN sysfs attributes come from?
>>>
>>>> Maybe this should be moved to the beta kernel until stable?
>>>
>>>>
>>>> Cheers.
>>>>
>>>> On 3/31/2014 12:04 AM, Rob Mosher wrote:
>>>>> (sorry for the duplicate, got bounces due to HTML encoding)
>>>>>
>>>>> The specified patch is already included. The system was running
>> the
>>>>> latest kernel from Robert Nelson's repo. Any suggestions? I'll
>> try
>>>>> removing some of the patches to see if it fixes this behavior. I
>>>> have a
>>>>> feeling I know which one is doing it.
>>>>>
>>>>> Thanks.
>>>>>
>>>>> output from running patch.sh with source pulled from
>>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>>
>>>>>
>>>>
>> /home/bbuild/comp/kernel/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch:
>>>>> applied
>>>>>
>>>>> Just in case, I built and installed the kernel and the same
>> behavior
>>>>> persisted.
>>>>>
>>>>> root@rbone:/# uname -a
>>>>> Linux rbone 3.8.13-00737-g7dfad77 #1 SMP Sun Mar 30 22:11:44 EDT
>> 2014
>>>>> armv7l GNU/Linux
>>>>>
>>>>> gpio30 is connected to AIN4 using a voltage divider
>>>>>
>>>>> root@rbone:/# cd /sys/class/gpio/
>>>>> root@rbone:/sys/class/gpio# echo 30 > export
>>>>> root@rbone:/sys/class/gpio# echo BB-ADC >
>>>> /sys/devices/bone_capemgr.9/slots
>>>>> root@rbone:/sys/class/gpio# cd /sys/devices/ocp.3/helper.11/
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo out >
>>>>> /sys/class/gpio/gpio30/direction
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>>> /sys/class/gpio/gpio30/value
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 1460
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 0 >
>>>>> /sys/class/gpio/gpio30/value
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# grep . AIN[0-3] AIN[5-7]
>>>>> AIN0:1550
>>>>> AIN1:1213
>>>>> AIN2:1485
>>>>> AIN3:795
>>>>> AIN5:513
>>>>> AIN6:744
>>>>> AIN7:1698
>>>>>
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>>> /sys/class/gpio/gpio30/value
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 0
>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>> 1460
>>>>>
>>>>> On 3/30/2014 9:16 AM, Zubair Lutfullah wrote:
>>>>>>
>>>>
>> https://github.com/beagleboard/kernel/blob/3.8/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
>>>>>>
>>>>>> IIRC, this patch fixes this issue
>>>>>>
>>>>>> Can you compile the kernel from the sources and check?
>>>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>>>
>>>>>> Regards
>>>>>> ZubairLK
>>>>>>
>>>>>> On Sun, Mar 30, 2014 at 7:04 AM, Rob Mosher
>> <nyt@countercultured.net
>>>>>> <mailto:nyt@countercultured.net>> wrote:
>>>>>>
>>>>>> Just a note, the same behavior persists with BB-ADC dtb and
>>>>>> reading from in_voltage4_raw
>>>>>>
>>>>>>
>>>>>> On 3/30/2014 12:30 AM, Rob Mosher wrote:
>>>>>>
>>>>>> Hello fine developers,
>>>>>>
>>>>>> It seems I've stumbled upon a problem while developing a
>>>> full
>>>>>> featured Ruby gem for the Beaglebone.
>>>>>>
>>>>>> It seems a patch included in the beaglebone kernel causes
>>>> some
>>>>>> issues while reading analog inputs. Apparently the
>> samples
>>>>>> get backlogged by the number of adc pins in use. I'm not
>>>> sure
>>>>>> which patch exactly as there are a number that affect adc
>>>>>> buffering and I'm not currently setup for kernel
>> building,
>>>>>> however the below output should detail the problem.
>>>>>>
>>>>>> Using the official Debian image.
>>>>>> Linux rbone 3.8.13-bone43 #1 SMP Wed Mar 26 14:21:39 UTC
>>>> 2014
>>>>>> armv7l GNU/Linux
>>>>>>
>>>>>> Distributor ID: Debian
>>>>>> Description: Debian GNU/Linux 7.4 (wheezy)
>>>>>> Release: 7.4
>>>>>> Codename: wheezy
>>>>>>
>>>>>> root@rbone:~# echo cape-bone-iio >
>>>>>> /sys/devices/bone_capemgr.9/slots
>>>>>>
>>>>>> This is the normal and expected behavior.
>>>>>>
>>>>>> 1.8v applied to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>>
>>>>>> 0v applied to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>>
>>>>>> 1.8v applied to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>>
>>>>>> 0v applied to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>>
>>>>>> So far working as intended.... Now reading from the
>> other
>>>> pins.
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep . AIN[0-3]
>>>> AIN[5-7]
>>>>>> AIN0:1563
>>>>>> AIN1:1221
>>>>>> AIN2:1487
>>>>>> AIN3:789
>>>>>> AIN5:514
>>>>>> AIN6:743
>>>>>> AIN7:1698
>>>>>>
>>>>>> Now applying 1.8v to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>>
>>>>>> Now applying 0v to AIN4
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>>
>>>>>>
>>>>>>
>>>>>> And another example, showing relation to the number of
>> pins
>>>> in
>>>>>> use.
>>>>>>
>>>>>> 1.8v to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep . AIN[0-3]
>>>>>> AIN0:1697
>>>>>> AIN1:1298
>>>>>> AIN2:1524
>>>>>> AIN3:816
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>>
>>>>>> 0v to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1460
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>>
>>>>>> 1.8v to AIN4
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>> 1798
>>>>>>
>>>>>> -- Rob Mosher
>>>>>> Senior Network and Software Engineer
>>>>>> Hurricane Electric / AS6939
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-iio"
>> in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>
^ permalink raw reply
* [PATCH v2 1/3] Input: synaptics-rmi4 - add F11 capabilities for touchpads
From: Christopher Heiny @ 2014-03-31 21:11 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
Vivian Ly, Linus Walleij, Benjamin Tissoires, David Herrmann,
Jiri Kosina
When the device is a touchpad additional capabilities need to
be set and reported.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Acked-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Linux Walleij <linus.walleij@linaro.org>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/input/rmi4/rmi_f11.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 8709abe..92eac8a 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -717,7 +717,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
if (sensor->data.rel_pos)
rmi_f11_rel_pos_report(sensor, i);
}
- input_mt_sync(sensor->input);
+ input_mt_sync_frame(sensor->input);
input_sync(sensor->input);
}
@@ -1104,13 +1104,10 @@ static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
/* We assume touchscreen unless demonstrably a touchpad or specified
* as a touchpad in the platform data
*/
- if (sensor->sensor_type == rmi_f11_sensor_touchpad ||
- (sensor->sens_query.has_info2 &&
- !sensor->sens_query.is_clear))
- input_flags = INPUT_PROP_POINTER;
+ if (sensor->sensor_type == rmi_f11_sensor_touchpad)
+ input_flags = INPUT_MT_POINTER;
else
- input_flags = INPUT_PROP_DIRECT;
- set_bit(input_flags, input->propbit);
+ input_flags = INPUT_MT_DIRECT;
if (sensor->axis_align.swap_axes) {
int temp = device_x_max;
@@ -1220,11 +1217,20 @@ static int rmi_f11_initialize(struct rmi_function *fn)
return rc;
}
+ if (sensor->sens_query.has_info2) {
+ if (sensor->sens_query.is_clear)
+ sensor->sensor_type = rmi_f11_sensor_touchscreen;
+ else
+ sensor->sensor_type = rmi_f11_sensor_touchpad;
+ }
+
if (pdata->f11_sensor_data) {
sensor->axis_align =
pdata->f11_sensor_data->axis_align;
sensor->type_a = pdata->f11_sensor_data->type_a;
- sensor->sensor_type =
+
+ if (sensor->sensor_type == rmi_f11_sensor_default)
+ sensor->sensor_type =
pdata->f11_sensor_data->sensor_type;
}
@@ -1490,6 +1496,7 @@ static struct rmi_function_handler rmi_f11_handler = {
module_rmi_driver(rmi_f11_handler);
MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com");
+MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com");
MODULE_DESCRIPTION("RMI F11 module");
MODULE_LICENSE("GPL");
MODULE_VERSION(RMI_DRIVER_VERSION);
--
1.8.3.2
^ permalink raw reply related
* [PATCH v2 2/3] Input: synaptics-rmi4 - F11 abs or rel reporting
From: Christopher Heiny @ 2014-03-31 21:11 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
Vivian Ly, Linus Walleij, Benjamin Tissoires, David Herrmann,
Jiri Kosina
In-Reply-To: <1396300267-5108-1-git-send-email-cheiny@synaptics.com>
If the firmware provides reporting both relative and absolute
coordinates, reporting both can cause userspace confusion, so
default to reporting only the absolute coordinates. In certain
cases in may be desirable to force only reporting relative
coordinates so a mask is provided in the platform data for
disabling absolute reporting and falling back to reporting
relative coordinates.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Acked-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Linux Walleij <linus.walleij@linaro.org>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/input/rmi4/rmi_f11.c | 122 +++++++++++++++++++++----------------------
include/linux/rmi.h | 5 ++
2 files changed, 64 insertions(+), 63 deletions(-)
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index e98fa75..ee47b7e 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -499,9 +499,7 @@ struct f11_2d_data {
* assume we have one of those sensors and report events appropriately.
* @sensor_type - indicates whether we're touchscreen or touchpad.
* @input - input device for absolute pointing stream
- * @mouse_input - input device for relative pointing stream.
* @input_phys - buffer for the absolute phys name for this sensor.
- * @input_phys_mouse - buffer for the relative phys name for this sensor.
*/
struct f11_2d_sensor {
struct rmi_f11_2d_axis_alignment axis_align;
@@ -516,10 +514,10 @@ struct f11_2d_sensor {
u32 type_a; /* boolean but debugfs API requires u32 */
enum rmi_f11_sensor_type sensor_type;
struct input_dev *input;
- struct input_dev *mouse_input;
struct rmi_function *fn;
char input_phys[NAME_BUFFER_SIZE];
- char input_phys_mouse[NAME_BUFFER_SIZE];
+ u8 report_abs;
+ u8 report_rel;
};
/** Data pertaining to F11 in general. For per-sensor data, see struct
@@ -544,6 +542,9 @@ struct f11_data {
struct mutex dev_controls_mutex;
u16 rezero_wait_ms;
struct f11_2d_sensor sensor;
+ unsigned long *abs_mask;
+ unsigned long *rel_mask;
+ unsigned long *result_bits;
};
enum finger_state_values {
@@ -591,10 +592,7 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor *sensor, u8 n_finger)
if (x || y) {
input_report_rel(sensor->input, REL_X, x);
input_report_rel(sensor->input, REL_Y, y);
- input_report_rel(sensor->mouse_input, REL_X, x);
- input_report_rel(sensor->mouse_input, REL_Y, y);
}
- input_sync(sensor->mouse_input);
}
static void rmi_f11_abs_pos_report(struct f11_data *f11,
@@ -691,13 +689,17 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
}
static void rmi_f11_finger_handler(struct f11_data *f11,
- struct f11_2d_sensor *sensor)
+ struct f11_2d_sensor *sensor,
+ unsigned long *irq_bits, int num_irq_regs)
{
const u8 *f_state = sensor->data.f_state;
u8 finger_state;
u8 finger_pressed_count;
u8 i;
+ int rel_bits;
+ int abs_bits;
+
for (i = 0, finger_pressed_count = 0; i < sensor->nbr_fingers; i++) {
/* Possible of having 4 fingers per f_statet register */
finger_state = (f_state[i / 4] >> (2 * (i % 4))) &
@@ -711,10 +713,14 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
finger_pressed_count++;
}
- if (sensor->data.abs_pos)
+ abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask,
+ num_irq_regs);
+ if (abs_bits)
rmi_f11_abs_pos_report(f11, sensor, finger_state, i);
- if (sensor->data.rel_pos)
+ rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
+ num_irq_regs);
+ if (rel_bits)
rmi_f11_rel_pos_report(sensor, i);
}
input_mt_sync_frame(sensor->input);
@@ -1171,21 +1177,36 @@ static int rmi_f11_initialize(struct rmi_function *fn)
u16 max_x_pos, max_y_pos, temp;
int rc;
const struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
+ struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
struct f11_2d_sensor *sensor;
u8 buf;
+ int mask_size;
dev_dbg(&fn->dev, "Initializing F11 values for %s.\n",
pdata->sensor_name);
+ mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long);
+
/*
** init instance data, fill in values and create any sysfs files
*/
- f11 = devm_kzalloc(&fn->dev, sizeof(struct f11_data), GFP_KERNEL);
+ f11 = devm_kzalloc(&fn->dev, sizeof(struct f11_data) + mask_size * 3,
+ GFP_KERNEL);
if (!f11)
return -ENOMEM;
f11->rezero_wait_ms = pdata->f11_rezero_wait;
+ f11->abs_mask = (unsigned long*)((char *)f11
+ + sizeof(struct f11_data));
+ f11->rel_mask = (unsigned long*)((char *)f11
+ + sizeof(struct f11_data) + mask_size);
+ f11->result_bits = (unsigned long*)((char *)f11
+ + sizeof(struct f11_data) + mask_size * 2);
+
+ set_bit(fn->irq_pos, f11->abs_mask);
+ set_bit(fn->irq_pos + 1, f11->rel_mask);
+
query_base_addr = fn->fd.query_base_addr;
control_base_addr = fn->fd.control_base_addr;
@@ -1224,6 +1245,8 @@ static int rmi_f11_initialize(struct rmi_function *fn)
sensor->sensor_type = rmi_f11_sensor_touchpad;
}
+ sensor->report_abs = sensor->sens_query.has_abs;
+
if (pdata->f11_sensor_data) {
sensor->axis_align =
pdata->f11_sensor_data->axis_align;
@@ -1232,8 +1255,19 @@ static int rmi_f11_initialize(struct rmi_function *fn)
if (sensor->sensor_type == rmi_f11_sensor_default)
sensor->sensor_type =
pdata->f11_sensor_data->sensor_type;
+
+ sensor->report_abs = sensor->report_abs
+ && !(pdata->f11_sensor_data->disable_report_mask
+ & RMI_F11_DISABLE_ABS_REPORT);
}
+ if (!sensor->report_abs)
+ /*
+ * If device doesn't have abs or if it has been disables
+ * fallback to reporting rel data.
+ */
+ sensor->report_rel = sensor->sens_query.has_rel;
+
rc = rmi_read_block(rmi_dev,
control_base_addr + F11_CTRL_SENSOR_MAX_X_POS_OFFSET,
(u8 *)&max_x_pos, sizeof(max_x_pos));
@@ -1293,7 +1327,6 @@ static int rmi_f11_register_devices(struct rmi_function *fn)
struct rmi_device *rmi_dev = fn->rmi_dev;
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
struct input_dev *input_dev;
- struct input_dev *input_dev_mouse;
struct rmi_driver *driver = rmi_dev->driver;
struct f11_2d_sensor *sensor = &f11->sensor;
int rc;
@@ -1324,9 +1357,10 @@ static int rmi_f11_register_devices(struct rmi_function *fn)
set_bit(EV_ABS, input_dev->evbit);
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
- f11_set_abs_params(fn, f11);
+ if (sensor->report_abs)
+ f11_set_abs_params(fn, f11);
- if (sensor->sens_query.has_rel) {
+ if (sensor->report_rel) {
set_bit(EV_REL, input_dev->evbit);
set_bit(REL_X, input_dev->relbit);
set_bit(REL_Y, input_dev->relbit);
@@ -1338,56 +1372,10 @@ static int rmi_f11_register_devices(struct rmi_function *fn)
goto error_unregister;
}
- if (sensor->sens_query.has_rel) {
- /*create input device for mouse events */
- input_dev_mouse = input_allocate_device();
- if (!input_dev_mouse) {
- rc = -ENOMEM;
- goto error_unregister;
- }
-
- sensor->mouse_input = input_dev_mouse;
- if (driver->set_input_params) {
- rc = driver->set_input_params(rmi_dev,
- input_dev_mouse);
- if (rc < 0) {
- dev_err(&fn->dev,
- "%s: Error in setting input device.\n",
- __func__);
- goto error_unregister;
- }
- }
- sprintf(sensor->input_phys_mouse, "%s.rel/input0",
- dev_name(&fn->dev));
- set_bit(EV_REL, input_dev_mouse->evbit);
- set_bit(REL_X, input_dev_mouse->relbit);
- set_bit(REL_Y, input_dev_mouse->relbit);
-
- set_bit(BTN_MOUSE, input_dev_mouse->evbit);
- /* Register device's buttons and keys */
- set_bit(EV_KEY, input_dev_mouse->evbit);
- set_bit(BTN_LEFT, input_dev_mouse->keybit);
- set_bit(BTN_MIDDLE, input_dev_mouse->keybit);
- set_bit(BTN_RIGHT, input_dev_mouse->keybit);
-
- rc = input_register_device(input_dev_mouse);
- if (rc) {
- input_free_device(input_dev_mouse);
- sensor->mouse_input = NULL;
- goto error_unregister;
- }
-
- set_bit(BTN_RIGHT, input_dev_mouse->keybit);
- }
-
return 0;
error_unregister:
if (f11->sensor.input) {
- if (f11->sensor.mouse_input) {
- input_unregister_device(f11->sensor.mouse_input);
- f11->sensor.mouse_input = NULL;
- }
input_unregister_device(f11->sensor.input);
f11->sensor.input = NULL;
}
@@ -1398,8 +1386,16 @@ error_unregister:
static int rmi_f11_config(struct rmi_function *fn)
{
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
+ struct rmi_driver *drv = fn->rmi_dev->driver;
+ struct f11_2d_sensor *sensor = &f11->sensor;
int rc;
+ if (!sensor->report_abs)
+ drv->clear_irq_bits(fn->rmi_dev, f11->abs_mask);
+
+ if (!sensor->report_rel)
+ drv->clear_irq_bits(fn->rmi_dev, f11->rel_mask);
+
rc = f11_write_control_regs(fn, &f11->sensor.sens_query,
&f11->dev_controls, fn->fd.query_base_addr);
if (rc < 0)
@@ -1411,6 +1407,7 @@ static int rmi_f11_config(struct rmi_function *fn)
static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
{
struct rmi_device *rmi_dev = fn->rmi_dev;
+ struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
struct f11_data *f11 = dev_get_drvdata(&fn->dev);
u16 data_base_addr = fn->fd.data_base_addr;
u16 data_base_addr_offset = 0;
@@ -1423,7 +1420,8 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
if (error)
return error;
- rmi_f11_finger_handler(f11, &f11->sensor);
+ rmi_f11_finger_handler(f11, &f11->sensor, irq_bits,
+ drvdata->num_of_irq_regs);
data_base_addr_offset += f11->sensor.pkt_size;
return 0;
@@ -1477,8 +1475,6 @@ static void rmi_f11_remove(struct rmi_function *fn)
if (f11->sensor.input)
input_unregister_device(f11->sensor.input);
- if (f11->sensor.mouse_input)
- input_unregister_device(f11->sensor.mouse_input);
}
static struct rmi_function_handler rmi_f11_handler = {
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 735e978..164b813 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -76,6 +76,8 @@ enum rmi_f11_sensor_type {
rmi_f11_sensor_touchpad
};
+#define RMI_F11_DISABLE_ABS_REPORT BIT(0)
+
/**
* struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
* @axis_align - provides axis alignment overrides (see above).
@@ -86,11 +88,14 @@ enum rmi_f11_sensor_type {
* pointing device (touchpad) rather than a direct pointing device
* (touchscreen). This is useful when F11_2D_QUERY14 register is not
* available.
+ * @disable_report_mask - Force data to not be reported even if it is supported
+ * by the firware.
*/
struct rmi_f11_sensor_data {
struct rmi_f11_2d_axis_alignment axis_align;
bool type_a;
enum rmi_f11_sensor_type sensor_type;
+ int disable_report_mask;
};
/**
--
1.8.3.2
^ permalink raw reply related
* [PATCH v2 3/3] Input: synaptics-rmi4 - report sensor resolution
From: Christopher Heiny @ 2014-03-31 21:11 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Linux Input, Christopher Heiny, Andrew Duggan, Vincent Huang,
Vivian Ly, Linus Walleij, Benjamin Tissoires, David Herrmann,
Jiri Kosina
In-Reply-To: <1396300267-5108-1-git-send-email-cheiny@synaptics.com>
Reports the sensor resolution by reading the size of the sensor
from F11 query registers or from the platform data if the firmware
does not contain the appropriate query registers.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Acked-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Linux Walleij <linus.walleij@linaro.org>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/input/rmi4/rmi_f11.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/rmi.h | 2 ++
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index ee47b7e..9c682f0 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -408,6 +408,10 @@ struct f11_2d_sensor_queries {
u8 clickpad_props;
u8 mouse_buttons;
bool has_advanced_gestures;
+
+ /* Query 15 - 18 */
+ u16 x_sensor_size_mm;
+ u16 y_sensor_size_mm;
};
/* Defs for Ctrl0. */
@@ -518,6 +522,8 @@ struct f11_2d_sensor {
char input_phys[NAME_BUFFER_SIZE];
u8 report_abs;
u8 report_rel;
+ u8 x_mm;
+ u8 y_mm;
};
/** Data pertaining to F11 in general. For per-sensor data, see struct
@@ -1064,7 +1070,7 @@ static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
query_size++;
}
- if (f11->has_query12 && sensor_query->has_info2) {
+ if (sensor_query->has_info2) {
rc = rmi_read(rmi_dev, query_base_addr + query_size, query_buf);
if (rc < 0)
return rc;
@@ -1085,6 +1091,20 @@ static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
query_size++;
}
+ if (sensor_query->has_physical_props) {
+ rc = rmi_read_block(rmi_dev, query_base_addr
+ + query_size, query_buf, 4);
+ if (rc < 0)
+ return rc;
+
+ sensor_query->x_sensor_size_mm =
+ (query_buf[0] | (query_buf[1] << 8)) / 10;
+ sensor_query->y_sensor_size_mm =
+ (query_buf[2] | (query_buf[3] << 8)) / 10;
+
+ query_size += 4;
+ }
+
return query_size;
}
@@ -1106,6 +1126,7 @@ static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
((f11->dev_controls.ctrl0_9[9] & 0x0F) << 8);
u16 x_min, x_max, y_min, y_max;
unsigned int input_flags;
+ int res_x, res_y;
/* We assume touchscreen unless demonstrably a touchpad or specified
* as a touchpad in the platform data
@@ -1156,6 +1177,18 @@ static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
x_min, x_max, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y,
y_min, y_max, 0, 0);
+
+ if (sensor->x_mm && sensor->y_mm) {
+ res_x = (x_max - x_min) / sensor->x_mm;
+ res_y = (y_max - y_min) / sensor->y_mm;
+
+ input_abs_set_res(input, ABS_X, res_x);
+ input_abs_set_res(input, ABS_Y, res_y);
+
+ input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
+ input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
+ }
+
if (!sensor->type_a)
input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
if (IS_ENABLED(CONFIG_RMI4_F11_PEN) && sensor->sens_query.has_pen)
@@ -1252,6 +1285,14 @@ static int rmi_f11_initialize(struct rmi_function *fn)
pdata->f11_sensor_data->axis_align;
sensor->type_a = pdata->f11_sensor_data->type_a;
+ if (sensor->sens_query.has_physical_props) {
+ sensor->x_mm = sensor->sens_query.x_sensor_size_mm;
+ sensor->y_mm = sensor->sens_query.y_sensor_size_mm;
+ } else if (pdata->f11_sensor_data) {
+ sensor->x_mm = pdata->f11_sensor_data->x_mm;
+ sensor->y_mm = pdata->f11_sensor_data->y_mm;
+ }
+
if (sensor->sensor_type == rmi_f11_sensor_default)
sensor->sensor_type =
pdata->f11_sensor_data->sensor_type;
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 164b813..ca35b2f 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -95,6 +95,8 @@ struct rmi_f11_sensor_data {
struct rmi_f11_2d_axis_alignment axis_align;
bool type_a;
enum rmi_f11_sensor_type sensor_type;
+ int x_mm;
+ int y_mm;
int disable_report_mask;
};
--
1.8.3.2
^ permalink raw reply related
* Re: ti_am33x_adc sampling bugs
From: Jonathan Cameron @ 2014-03-31 21:20 UTC (permalink / raw)
To: Rob Mosher, Zubair Lutfullah
Cc: Sebastian Andrzej Siewior, robertcnelson, Samuel Ortiz,
Dmitry Torokhov, Felipe Balbi, linux-iio, linux-input, Lee Jones
In-Reply-To: <5339D810.2030400@countercultured.net>
On March 31, 2014 10:03:12 PM GMT+01:00, Rob Mosher <nyt@countercultured.net> wrote:
>I'm not quite aware of what's in mainline or not, this list was CC'd by
>
Sure. I just thought I would save anyone else who was going to look the effort!
>Zubair Lutfullah who authored the patches in question. Hopefully he
>can
>provide more insight or a possible fix.
Indeed.
>
>0019-iio-ti_am335x_adc-Add-continuous-sampling-and-trigge.patch
>Subject: [PATCH 19/21] iio: ti_am335x_adc: Add continuous sampling and
> trigger support
>
>Previously the driver had only one-shot reading functionality.
>This patch adds triggered buffer support to the driver.
>A buffer of samples can now be read via /dev/iio.
>
>
>On 3/31/2014 4:59 PM, Jonathan Cameron wrote:
>>
>>
>> On March 31, 2014 5:47:54 PM GMT+01:00, Rob Mosher
><nyt@countercultured.net> wrote:
>>> I believe the AIN files came from
>>> 0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch.
>>
>> Ouch that is an 'unusual' patch... No more recent patches in mainline
>appear related to what you are seeing unfortunately.
>>
>>
>>
>>> The bug is the
>>> same
>>> reading from in_voltageX_raw files.
>>>
>>> On 3/31/2014 12:14 PM, Jonathan Cameron wrote:
>>>>
>>>>
>>>> On March 31, 2014 9:17:53 AM GMT+01:00, Rob Mosher
>>> <nyt@countercultured.net> wrote:
>>>>> The following patches were removed and behavior returned to
>normal.
>>>>>
>>>>> 0019-iio-ti_am335x_adc-Add-continuous-sampling-and-trigge.patch
>>>>> 0020-iio-ti_am335x_adc-Add-IIO-map-interface.patch
>>>>>
>>>>> Once 19 was re-applied, the bug returned.
>>>>>
>>>>> It would appear that patch19 is the problem. On an unrelated
>note,
>>> the
>>>>>
>>>>> continuous sampling patch seems to still be missing the mode file
>to
>>>>> tell it to sample continuously or oneshot in the sysfs directory
>as
>>>>> referenced at
>>>>>
>http://processors.wiki.ti.com/index.php/AM335x_ADC_Driver%27s_Guide.
>>>> Someone should update that wiki page.
>>>> Such an attribute was not and will not be
>>>> part of the mainline kernel ABI. Drivers can play fast and loose
>in
>>> staging but to move
>>>> out the ABI must conform to existing definitions or be proposed
>>> reviewed and accepted.
>>>>
>>>> I am somewhat confused. Where did the AIN sysfs attributes come
>from?
>>>>
>>>>> Maybe this should be moved to the beta kernel until stable?
>>>>
>>>>>
>>>>> Cheers.
>>>>>
>>>>> On 3/31/2014 12:04 AM, Rob Mosher wrote:
>>>>>> (sorry for the duplicate, got bounces due to HTML encoding)
>>>>>>
>>>>>> The specified patch is already included. The system was running
>>> the
>>>>>> latest kernel from Robert Nelson's repo. Any suggestions? I'll
>>> try
>>>>>> removing some of the patches to see if it fixes this behavior. I
>>>>> have a
>>>>>> feeling I know which one is doing it.
>>>>>>
>>>>>> Thanks.
>>>>>>
>>>>>> output from running patch.sh with source pulled from
>>>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>>>
>>>>>>
>>>>>
>>>
>/home/bbuild/comp/kernel/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch:
>>>>>> applied
>>>>>>
>>>>>> Just in case, I built and installed the kernel and the same
>>> behavior
>>>>>> persisted.
>>>>>>
>>>>>> root@rbone:/# uname -a
>>>>>> Linux rbone 3.8.13-00737-g7dfad77 #1 SMP Sun Mar 30 22:11:44 EDT
>>> 2014
>>>>>> armv7l GNU/Linux
>>>>>>
>>>>>> gpio30 is connected to AIN4 using a voltage divider
>>>>>>
>>>>>> root@rbone:/# cd /sys/class/gpio/
>>>>>> root@rbone:/sys/class/gpio# echo 30 > export
>>>>>> root@rbone:/sys/class/gpio# echo BB-ADC >
>>>>> /sys/devices/bone_capemgr.9/slots
>>>>>> root@rbone:/sys/class/gpio# cd /sys/devices/ocp.3/helper.11/
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo out >
>>>>>> /sys/class/gpio/gpio30/direction
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>>>> /sys/class/gpio/gpio30/value
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 1460
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 0 >
>>>>>> /sys/class/gpio/gpio30/value
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# grep . AIN[0-3] AIN[5-7]
>>>>>> AIN0:1550
>>>>>> AIN1:1213
>>>>>> AIN2:1485
>>>>>> AIN3:795
>>>>>> AIN5:513
>>>>>> AIN6:744
>>>>>> AIN7:1698
>>>>>>
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# echo 1 >
>>>>>> /sys/class/gpio/gpio30/value
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 0
>>>>>> root@rbone:/sys/devices/ocp.3/helper.11# cat AIN4
>>>>>> 1460
>>>>>>
>>>>>> On 3/30/2014 9:16 AM, Zubair Lutfullah wrote:
>>>>>>>
>>>>>
>>>
>https://github.com/beagleboard/kernel/blob/3.8/patches/adc/0017-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
>>>>>>>
>>>>>>> IIRC, this patch fixes this issue
>>>>>>>
>>>>>>> Can you compile the kernel from the sources and check?
>>>>>>> https://github.com/beagleboard/kernel/tree/3.8
>>>>>>>
>>>>>>> Regards
>>>>>>> ZubairLK
>>>>>>>
>>>>>>> On Sun, Mar 30, 2014 at 7:04 AM, Rob Mosher
>>> <nyt@countercultured.net
>>>>>>> <mailto:nyt@countercultured.net>> wrote:
>>>>>>>
>>>>>>> Just a note, the same behavior persists with BB-ADC dtb
>and
>>>>>>> reading from in_voltage4_raw
>>>>>>>
>>>>>>>
>>>>>>> On 3/30/2014 12:30 AM, Rob Mosher wrote:
>>>>>>>
>>>>>>> Hello fine developers,
>>>>>>>
>>>>>>> It seems I've stumbled upon a problem while developing
>a
>>>>> full
>>>>>>> featured Ruby gem for the Beaglebone.
>>>>>>>
>>>>>>> It seems a patch included in the beaglebone kernel
>causes
>>>>> some
>>>>>>> issues while reading analog inputs. Apparently the
>>> samples
>>>>>>> get backlogged by the number of adc pins in use. I'm
>not
>>>>> sure
>>>>>>> which patch exactly as there are a number that affect
>adc
>>>>>>> buffering and I'm not currently setup for kernel
>>> building,
>>>>>>> however the below output should detail the problem.
>>>>>>>
>>>>>>> Using the official Debian image.
>>>>>>> Linux rbone 3.8.13-bone43 #1 SMP Wed Mar 26 14:21:39
>UTC
>>>>> 2014
>>>>>>> armv7l GNU/Linux
>>>>>>>
>>>>>>> Distributor ID: Debian
>>>>>>> Description: Debian GNU/Linux 7.4 (wheezy)
>>>>>>> Release: 7.4
>>>>>>> Codename: wheezy
>>>>>>>
>>>>>>> root@rbone:~# echo cape-bone-iio >
>>>>>>> /sys/devices/bone_capemgr.9/slots
>>>>>>>
>>>>>>> This is the normal and expected behavior.
>>>>>>>
>>>>>>> 1.8v applied to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>>
>>>>>>> 0v applied to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>>
>>>>>>> 1.8v applied to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>>
>>>>>>> 0v applied to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>>
>>>>>>> So far working as intended.... Now reading from the
>>> other
>>>>> pins.
>>>>>>>
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep .
>AIN[0-3]
>>>>> AIN[5-7]
>>>>>>> AIN0:1563
>>>>>>> AIN1:1221
>>>>>>> AIN2:1487
>>>>>>> AIN3:789
>>>>>>> AIN5:514
>>>>>>> AIN6:743
>>>>>>> AIN7:1698
>>>>>>>
>>>>>>> Now applying 1.8v to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>>
>>>>>>> Now applying 0v to AIN4
>>>>>>>
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> And another example, showing relation to the number of
>>> pins
>>>>> in
>>>>>>> use.
>>>>>>>
>>>>>>> 1.8v to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# grep .
>AIN[0-3]
>>>>>>> AIN0:1697
>>>>>>> AIN1:1298
>>>>>>> AIN2:1524
>>>>>>> AIN3:816
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>>
>>>>>>> 0v to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1460
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>>
>>>>>>> 1.8v to AIN4
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 0
>>>>>>> root@rbone:/sys/devices/ocp.3/helper.12# cat AIN4
>>>>>>> 1798
>>>>>>>
>>>>>>> -- Rob Mosher
>>>>>>> Senior Network and Software Engineer
>>>>>>> Hurricane Electric / AS6939
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe
>linux-iio"
>>> in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>>
>>
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
^ permalink raw reply
* Re: ti_am33x_adc sampling bugs
From: Zubair Lutfullah : @ 2014-04-01 5:42 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Rob Mosher, Zubair Lutfullah, Sebastian Andrzej Siewior,
robertcnelson-Re5JQEeQqe8AvxtiuMwx3w, Samuel Ortiz,
Dmitry Torokhov, Felipe Balbi, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA, Lee Jones
In-Reply-To: <c21be082-4ad8-46e2-a5f3-ad29b4239d94-2ueSQiBKiTY7tOexoI0I+QC/G2K4zDHf@public.gmane.org>
Sorry for taking this long to reply.
The confusion here is due to vendor/mainline trees for the kernel.
This discussion should have been carried out on
https://github.com/beagleboard/kernel/issues
instead of the kernel mailing lists.
Sorry Jonathan.
The IIO-map-interface patch is in the vendor tree for the Beaglebone.
And it is not intended to be mainlined. Just like the other TI wiki stuff.
But it used to make life a little easier before the IIO sysfs entries were fixed
for the am335x ADC.
The patch was kept as it is because of the ton of guides/wikis out there for the
Beaglebone asking for AIN0/AIN7 pins.
And iirc capemgr (another out of tree module which is being mainlined) used it.
Which made it necessary to keep this.
As far as patch 19 (Add continuous sampling) is concerned, I didn't observe it
causing these bugs. But it is good that you have pointed them out.
Thank-you.
Could you please go through the patch and suggest a fix as well?
Seems like a FIFO isn't cleared somewhere..
Hope this clears the confusion.
Again, this discussion should have been carried out
https://github.com/beagleboard/kernel/issues
Not the kernel mailing list.
Regards
ZubairLK
>
^ permalink raw reply
* Re: [PATCH] Route keyboard LEDs through the generic LEDs layer.
From: Pali Rohár @ 2014-04-01 7:02 UTC (permalink / raw)
To: Samuel Thibault, Dmitry Torokhov, Pavel Machek, David Herrmann,
Andrew Morton, jslaby, Bryan Wu, Richard Purdie, LKML,
Evan Broder, Arnaud Patard, Peter Korsgaard, Sascha Hauer,
Matt Sealey, Rob Clark, Niels de Vos, linux-arm-kernel,
Steev Klimaszewski, blogic, Pali Rohár, linux-input
In-Reply-To: <20140331122323.GC6044@type.bordeaux.inria.fr>
2014-03-31 14:23 GMT+02:00 Samuel Thibault <samuel.thibault@ens-lyon.org>:
> This permits to reassign keyboard LEDs to something else than keyboard "leds"
> state, by adding keyboard led and modifier triggers connected to a series
> of VT input LEDs, themselves connected to VT input triggers, which
> per-input device LEDs use by default. Userland can thus easily change the LED
> behavior of (a priori) all input devices, or of particular input devices.
>
> This also permits to fix #7063 from userland by using a modifier to implement
> proper CapsLock behavior and have the keyboard caps lock led show that modifier
> state.
>
> [ebroder@mokafive.com: Rebased to 3.2-rc1 or so, cleaned up some includes, and fixed some constants]
> [blogic@openwrt.org: CONFIG_INPUT_LEDS stubs should be static inline]
> [akpm@linux-foundation.org: remove unneeded `extern', fix comment layout]
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> Signed-off-by: Evan Broder <evan@ebroder.net>
> Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
> Tested-by: Pavel Machek <pavel@ucw.cz>
> Acked-by: Peter Korsgaard <jacmet@sunsite.dk>
> Signed-off-by: John Crispin <blogic@openwrt.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
> Changed in this version:
> - fixes symbol dependencies between input.c and leds.c (notably
> input_led_connect/disconnect) by stuffing them together in input.ko.
> - documents the new leds field of struct input_dev.
>
> --- a/Documentation/leds/leds-class.txt
> +++ b/Documentation/leds/leds-class.txt
> @@ -2,9 +2,6 @@
> LED handling under Linux
> ========================
>
> -If you're reading this and thinking about keyboard leds, these are
> -handled by the input subsystem and the led class is *not* needed.
> -
> In its simplest form, the LED class just allows control of LEDs from
> userspace. LEDs appear in /sys/class/leds/. The maximum brightness of the
> LED is defined in max_brightness file. The brightness file will set the brightness
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -708,6 +708,9 @@ static void input_disconnect_device(stru
> handle->open = 0;
>
> spin_unlock_irq(&dev->event_lock);
> +
> + if (is_event_supported(EV_LED, dev->evbit, EV_MAX))
> + input_led_disconnect(dev);
> }
>
> /**
> @@ -2134,6 +2137,9 @@ int input_register_device(struct input_d
>
> list_add_tail(&dev->node, &input_dev_list);
>
> + if (is_event_supported(EV_LED, dev->evbit, EV_MAX))
> + input_led_connect(dev);
> +
> list_for_each_entry(handler, &input_handler_list, node)
> input_attach_handler(dev, handler);
>
> --- a/drivers/input/Kconfig
> +++ b/drivers/input/Kconfig
> @@ -178,6 +178,15 @@ comment "Input Device Drivers"
>
> source "drivers/input/keyboard/Kconfig"
>
> +config INPUT_LEDS
> + bool "LED Support"
> + depends on LEDS_CLASS = INPUT || LEDS_CLASS = y
> + select LEDS_TRIGGERS
> + default y
> + help
> + This option enables support for LEDs on keyboards managed
> + by the input layer.
> +
> source "drivers/input/mouse/Kconfig"
>
> source "drivers/input/joystick/Kconfig"
> --- a/drivers/input/Makefile
> +++ b/drivers/input/Makefile
> @@ -6,6 +6,9 @@
>
> obj-$(CONFIG_INPUT) += input-core.o
> input-core-y := input.o input-compat.o input-mt.o ff-core.o
> +ifeq ($(CONFIG_INPUT_LEDS),y)
> +input-core-y += leds.o
> +endif
>
> obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
> obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -11,9 +11,6 @@ menuconfig NEW_LEDS
> Say Y to enable Linux LED support. This allows control of supported
> LEDs from both userspace and optionally, by kernel events (triggers).
>
> - This is not related to standard keyboard LEDs which are controlled
> - via the input system.
> -
> if NEW_LEDS
>
> config LEDS_CLASS
> --- a/drivers/tty/Kconfig
> +++ b/drivers/tty/Kconfig
> @@ -13,6 +13,10 @@ config VT
> bool "Virtual terminal" if EXPERT
> depends on !S390 && !UML
> select INPUT
> + select NEW_LEDS
> + select LEDS_CLASS
> + select LEDS_TRIGGERS
> + select INPUT_LEDS
> default y
> ---help---
> If you say Y here, you will get support for terminal devices with
> --- a/drivers/tty/vt/keyboard.c
> +++ b/drivers/tty/vt/keyboard.c
> @@ -33,6 +33,7 @@
> #include <linux/string.h>
> #include <linux/init.h>
> #include <linux/slab.h>
> +#include <linux/leds.h>
>
> #include <linux/kbd_kern.h>
> #include <linux/kbd_diacr.h>
> @@ -130,6 +131,7 @@ static char rep; /* flag telling cha
> static int shift_state = 0;
>
> static unsigned char ledstate = 0xff; /* undefined */
> +static unsigned char lockstate = 0xff; /* undefined */
> static unsigned char ledioctl;
>
> /*
> @@ -961,6 +963,41 @@ static void k_brl(struct vc_data *vc, un
> }
> }
>
> +/* We route VT keyboard "leds" through triggers */
> +static void kbd_ledstate_trigger_activate(struct led_classdev *cdev);
> +
> +static struct led_trigger ledtrig_ledstate[] = {
> +#define DEFINE_LEDSTATE_TRIGGER(kbd_led, nam) \
> + [kbd_led] = { \
> + .name = nam, \
> + .activate = kbd_ledstate_trigger_activate, \
> + }
> + DEFINE_LEDSTATE_TRIGGER(VC_SCROLLOCK, "kbd-scrollock"),
> + DEFINE_LEDSTATE_TRIGGER(VC_NUMLOCK, "kbd-numlock"),
> + DEFINE_LEDSTATE_TRIGGER(VC_CAPSLOCK, "kbd-capslock"),
> + DEFINE_LEDSTATE_TRIGGER(VC_KANALOCK, "kbd-kanalock"),
> +#undef DEFINE_LEDSTATE_TRIGGER
> +};
> +
> +static void kbd_lockstate_trigger_activate(struct led_classdev *cdev);
> +
> +static struct led_trigger ledtrig_lockstate[] = {
> +#define DEFINE_LOCKSTATE_TRIGGER(kbd_led, nam) \
> + [kbd_led] = { \
> + .name = nam, \
> + .activate = kbd_lockstate_trigger_activate, \
> + }
> + DEFINE_LOCKSTATE_TRIGGER(VC_SHIFTLOCK, "kbd-shiftlock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_ALTGRLOCK, "kbd-altgrlock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_CTRLLOCK, "kbd-ctrllock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_ALTLOCK, "kbd-altlock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_SHIFTLLOCK, "kbd-shiftllock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_SHIFTRLOCK, "kbd-shiftrlock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_CTRLLLOCK, "kbd-ctrlllock"),
> + DEFINE_LOCKSTATE_TRIGGER(VC_CTRLRLOCK, "kbd-ctrlrlock"),
> +#undef DEFINE_LOCKSTATE_TRIGGER
> +};
> +
> /*
> * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
> * or (ii) whatever pattern of lights people want to show using KDSETLED,
> @@ -995,18 +1032,25 @@ static inline unsigned char getleds(void
> return kbd->ledflagstate;
> }
>
> -static int kbd_update_leds_helper(struct input_handle *handle, void *data)
> +/* Called on trigger connection, to set initial state */
> +static void kbd_ledstate_trigger_activate(struct led_classdev *cdev)
> {
> - unsigned char leds = *(unsigned char *)data;
> + struct led_trigger *trigger = cdev->trigger;
> + int led = trigger - ledtrig_ledstate;
>
> - if (test_bit(EV_LED, handle->dev->evbit)) {
> - input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
> - input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
> - input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
> - input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
> - }
> + tasklet_disable(&keyboard_tasklet);
> + led_trigger_event(trigger, ledstate & (1 << led) ? LED_FULL : LED_OFF);
> + tasklet_enable(&keyboard_tasklet);
> +}
>
> - return 0;
> +static void kbd_lockstate_trigger_activate(struct led_classdev *cdev)
> +{
> + struct led_trigger *trigger = cdev->trigger;
> + int led = trigger - ledtrig_lockstate;
> +
> + tasklet_disable(&keyboard_tasklet);
> + led_trigger_event(trigger, lockstate & (1 << led) ? LED_FULL : LED_OFF);
> + tasklet_enable(&keyboard_tasklet);
> }
>
> /**
> @@ -1095,16 +1139,29 @@ static void kbd_bh(unsigned long dummy)
> {
> unsigned char leds;
> unsigned long flags;
> -
> + int i;
> +
> spin_lock_irqsave(&led_lock, flags);
> leds = getleds();
> spin_unlock_irqrestore(&led_lock, flags);
>
> if (leds != ledstate) {
> - input_handler_for_each_handle(&kbd_handler, &leds,
> - kbd_update_leds_helper);
> + for (i = 0; i < ARRAY_SIZE(ledtrig_ledstate); i++)
> + if ((leds ^ ledstate) & (1 << i))
> + led_trigger_event(&ledtrig_ledstate[i],
> + leds & (1 << i)
> + ? LED_FULL : LED_OFF);
> ledstate = leds;
> }
> +
> + if (kbd->lockstate != lockstate) {
> + for (i = 0; i < ARRAY_SIZE(ledtrig_lockstate); i++)
> + if ((kbd->lockstate ^ lockstate) & (1 << i))
> + led_trigger_event(&ledtrig_lockstate[i],
> + kbd->lockstate & (1 << i)
> + ? LED_FULL : LED_OFF);
> + lockstate = kbd->lockstate;
> + }
> }
>
> DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
> @@ -1442,20 +1499,6 @@ static void kbd_disconnect(struct input_
> kfree(handle);
> }
>
> -/*
> - * Start keyboard handler on the new keyboard by refreshing LED state to
> - * match the rest of the system.
> - */
> -static void kbd_start(struct input_handle *handle)
> -{
> - tasklet_disable(&keyboard_tasklet);
> -
> - if (ledstate != 0xff)
> - kbd_update_leds_helper(handle, &ledstate);
> -
> - tasklet_enable(&keyboard_tasklet);
> -}
> -
> static const struct input_device_id kbd_ids[] = {
> {
> .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
> @@ -1477,7 +1520,6 @@ static struct input_handler kbd_handler
> .match = kbd_match,
> .connect = kbd_connect,
> .disconnect = kbd_disconnect,
> - .start = kbd_start,
> .name = "kbd",
> .id_table = kbd_ids,
> };
> @@ -1501,6 +1543,20 @@ int __init kbd_init(void)
> if (error)
> return error;
>
> + for (i = 0; i < ARRAY_SIZE(ledtrig_ledstate); i++) {
> + error = led_trigger_register(&ledtrig_ledstate[i]);
> + if (error)
> + pr_err("error %d while registering trigger %s\n",
> + error, ledtrig_ledstate[i].name);
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(ledtrig_lockstate); i++) {
> + error = led_trigger_register(&ledtrig_lockstate[i]);
> + if (error)
> + pr_err("error %d while registering trigger %s\n",
> + error, ledtrig_lockstate[i].name);
> + }
> +
> tasklet_enable(&keyboard_tasklet);
> tasklet_schedule(&keyboard_tasklet);
>
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -79,6 +79,7 @@ struct input_value {
> * @led: reflects current state of device's LEDs
> * @snd: reflects current state of sound effects
> * @sw: reflects current state of device's switches
> + * @leds: leds objects for the device's LEDs
> * @open: this method is called when the very first user calls
> * input_open_device(). The driver must prepare the device
> * to start generating events (start polling thread,
> @@ -164,6 +165,8 @@ struct input_dev {
> unsigned long snd[BITS_TO_LONGS(SND_CNT)];
> unsigned long sw[BITS_TO_LONGS(SW_CNT)];
>
> + struct led_classdev *leds;
> +
> int (*open)(struct input_dev *dev);
> void (*close)(struct input_dev *dev);
> int (*flush)(struct input_dev *dev, struct file *file);
> @@ -531,4 +534,22 @@ int input_ff_erase(struct input_dev *dev
> int input_ff_create_memless(struct input_dev *dev, void *data,
> int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
>
> +#ifdef CONFIG_INPUT_LEDS
> +
> +int input_led_connect(struct input_dev *dev);
> +void input_led_disconnect(struct input_dev *dev);
> +
> +#else
> +
> +static inline int input_led_connect(struct input_dev *dev)
> +{
> + return 0;
> +}
> +
> +static inline void input_led_disconnect(struct input_dev *dev)
> +{
> +}
> +
> +#endif
> +
> #endif
> --- /dev/null
> +++ b/drivers/input/leds.c
> @@ -0,0 +1,249 @@
> +/*
> + * LED support for the input layer
> + *
> + * Copyright 2010-2014 Samuel Thibault <samuel.thibault@ens-lyon.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/leds.h>
> +#include <linux/input.h>
> +
> +/*
> + * Keyboard LEDs are propagated by default like the following example:
> + *
> + * VT keyboard numlock trigger
> + * -> vt::numl VT LED
> + * -> vt-numl VT trigger
> + * -> per-device inputX::numl LED
> + *
> + * Userland can however choose the trigger for the vt::numl LED, or
> + * independently choose the trigger for any inputx::numl LED.
> + *
> + *
> + * VT LED classes and triggers are registered on-demand according to
> + * existing LED devices
> + */
> +
> +/* Handler for VT LEDs, just triggers the corresponding VT trigger. */
> +static void vt_led_set(struct led_classdev *cdev,
> + enum led_brightness brightness);
> +static struct led_classdev vt_leds[LED_CNT] = {
> +#define DEFINE_INPUT_LED(vt_led, nam, deftrig) \
> + [vt_led] = { \
> + .name = "vt::"nam, \
> + .max_brightness = 1, \
> + .brightness_set = vt_led_set, \
> + .default_trigger = deftrig, \
> + }
> +/* Default triggers for the VT LEDs just correspond to the legacy
> + * usage. */
> + DEFINE_INPUT_LED(LED_NUML, "numl", "kbd-numlock"),
> + DEFINE_INPUT_LED(LED_CAPSL, "capsl", "kbd-capslock"),
> + DEFINE_INPUT_LED(LED_SCROLLL, "scrolll", "kbd-scrollock"),
> + DEFINE_INPUT_LED(LED_COMPOSE, "compose", NULL),
> + DEFINE_INPUT_LED(LED_KANA, "kana", "kbd-kanalock"),
> + DEFINE_INPUT_LED(LED_SLEEP, "sleep", NULL),
> + DEFINE_INPUT_LED(LED_SUSPEND, "suspend", NULL),
> + DEFINE_INPUT_LED(LED_MUTE, "mute", NULL),
> + DEFINE_INPUT_LED(LED_MISC, "misc", NULL),
> + DEFINE_INPUT_LED(LED_MAIL, "mail", NULL),
> + DEFINE_INPUT_LED(LED_CHARGING, "charging", NULL),
> +};
> +static const char *const vt_led_names[LED_CNT] = {
> + [LED_NUML] = "numl",
> + [LED_CAPSL] = "capsl",
> + [LED_SCROLLL] = "scrolll",
> + [LED_COMPOSE] = "compose",
> + [LED_KANA] = "kana",
> + [LED_SLEEP] = "sleep",
> + [LED_SUSPEND] = "suspend",
> + [LED_MUTE] = "mute",
> + [LED_MISC] = "misc",
> + [LED_MAIL] = "mail",
> + [LED_CHARGING] = "charging",
> +};
> +/* Handler for hotplug initialization */
> +static void vt_led_trigger_activate(struct led_classdev *cdev);
> +/* VT triggers */
> +static struct led_trigger vt_led_triggers[LED_CNT] = {
> +#define DEFINE_INPUT_LED_TRIGGER(vt_led, nam) \
> + [vt_led] = { \
> + .name = "vt-"nam, \
> + .activate = vt_led_trigger_activate, \
> + }
> + DEFINE_INPUT_LED_TRIGGER(LED_NUML, "numl"),
> + DEFINE_INPUT_LED_TRIGGER(LED_CAPSL, "capsl"),
> + DEFINE_INPUT_LED_TRIGGER(LED_SCROLLL, "scrolll"),
> + DEFINE_INPUT_LED_TRIGGER(LED_COMPOSE, "compose"),
> + DEFINE_INPUT_LED_TRIGGER(LED_KANA, "kana"),
> + DEFINE_INPUT_LED_TRIGGER(LED_SLEEP, "sleep"),
> + DEFINE_INPUT_LED_TRIGGER(LED_SUSPEND, "suspend"),
> + DEFINE_INPUT_LED_TRIGGER(LED_MUTE, "mute"),
> + DEFINE_INPUT_LED_TRIGGER(LED_MISC, "misc"),
> + DEFINE_INPUT_LED_TRIGGER(LED_MAIL, "mail"),
> + DEFINE_INPUT_LED_TRIGGER(LED_CHARGING, "charging"),
> +};
> +
> +/* Lock for registration coherency */
> +static DEFINE_MUTEX(vt_led_registered_lock);
> +
> +/* Which VT LED classes and triggers are registered */
> +static unsigned long vt_led_registered[BITS_TO_LONGS(LED_CNT)];
> +
> +/* Number of input devices having each LED */
> +static int vt_led_references[LED_CNT];
> +
> +/* VT LED state change, tell the VT trigger. */
> +static void vt_led_set(struct led_classdev *cdev,
> + enum led_brightness brightness)
> +{
> + int led = cdev - vt_leds;
> +
> + led_trigger_event(&vt_led_triggers[led], !!brightness);
> +}
> +
> +/* LED state change for some keyboard, notify that keyboard. */
> +static void perdevice_input_led_set(struct led_classdev *cdev,
> + enum led_brightness brightness)
> +{
> + struct input_dev *dev;
> + struct led_classdev *leds;
> + int led;
> +
> + dev = cdev->dev->platform_data;
> + if (!dev)
> + /* Still initializing */
> + return;
> + leds = dev->leds;
> + led = cdev - leds;
> +
> + input_event(dev, EV_LED, led, !!brightness);
> + input_event(dev, EV_SYN, SYN_REPORT, 0);
> +}
> +
> +/* Keyboard hotplug, initialize its LED status */
> +static void vt_led_trigger_activate(struct led_classdev *cdev)
> +{
> + struct led_trigger *trigger = cdev->trigger;
> + int led = trigger - vt_led_triggers;
> +
> + if (cdev->brightness_set)
> + cdev->brightness_set(cdev, vt_leds[led].brightness);
> +}
> +
> +/* Free led stuff from input device, used at abortion and disconnection. */
> +static void input_led_delete(struct input_dev *dev)
> +{
> + if (dev) {
> + struct led_classdev *leds = dev->leds;
> + if (leds) {
> + int i;
> + for (i = 0; i < LED_CNT; i++)
> + kfree(leds[i].name);
> + kfree(leds);
> + dev->leds = NULL;
> + }
> + }
> +}
> +
> +/* A new input device with potential LEDs to connect. */
> +int input_led_connect(struct input_dev *dev)
> +{
> + int i, error = 0;
> + struct led_classdev *leds;
> +
> + dev->leds = leds = kcalloc(LED_CNT, sizeof(*leds), GFP_KERNEL);
> + if (!dev->leds)
> + return -ENOMEM;
> +
> + /* lazily register missing VT LEDs */
> + mutex_lock(&vt_led_registered_lock);
> + for (i = 0; i < LED_CNT; i++)
> + if (vt_leds[i].name && test_bit(i, dev->ledbit)) {
> + if (!vt_led_references[i]) {
> + led_trigger_register(&vt_led_triggers[i]);
> + /* This keyboard is first to have led i,
> + * try to register it */
> + if (!led_classdev_register(NULL, &vt_leds[i]))
> + vt_led_references[i] = 1;
> + else
> + led_trigger_unregister(&vt_led_triggers[i]);
> + } else
> + vt_led_references[i]++;
> + }
> + mutex_unlock(&vt_led_registered_lock);
> +
> + /* and register this device's LEDs */
> + for (i = 0; i < LED_CNT; i++)
> + if (vt_leds[i].name && test_bit(i, dev->ledbit)) {
> + leds[i].name = kasprintf(GFP_KERNEL, "%s::%s",
> + dev_name(&dev->dev),
> + vt_led_names[i]);
> + if (!leds[i].name) {
> + error = -ENOMEM;
> + goto err;
> + }
> + leds[i].max_brightness = 1;
> + leds[i].brightness_set = perdevice_input_led_set;
> + leds[i].default_trigger = vt_led_triggers[i].name;
> + }
> +
> + /* No issue so far, we can register for real. */
> + for (i = 0; i < LED_CNT; i++)
> + if (leds[i].name) {
> + led_classdev_register(&dev->dev, &leds[i]);
> + leds[i].dev->platform_data = dev;
> + perdevice_input_led_set(&leds[i],
> + vt_leds[i].brightness);
> + }
> +
> + return 0;
> +
> +err:
> + input_led_delete(dev);
> + return error;
> +}
> +
> +/*
> + * Disconnected input device. Clean it, and deregister now-useless VT LEDs
> + * and triggers.
> + */
> +void input_led_disconnect(struct input_dev *dev)
> +{
> + int i;
> + struct led_classdev *leds = dev->leds;
> +
> + for (i = 0; i < LED_CNT; i++)
> + if (leds[i].name)
> + led_classdev_unregister(&leds[i]);
> +
> + input_led_delete(dev);
> +
> + mutex_lock(&vt_led_registered_lock);
> + for (i = 0; i < LED_CNT; i++) {
> + if (!vt_leds[i].name || !test_bit(i, dev->ledbit))
> + continue;
> +
> + vt_led_references[i]--;
> + if (vt_led_references[i]) {
> + /* Still some devices needing it */
> + continue;
> + }
> +
> + led_classdev_unregister(&vt_leds[i]);
> + led_trigger_unregister(&vt_led_triggers[i]);
> + clear_bit(i, vt_led_registered);
> + }
> + mutex_unlock(&vt_led_registered_lock);
> +}
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("User LED support for input layer");
> +MODULE_AUTHOR("Samuel Thibault <samuel.thibault@ens-lyon.org>");
>
Dmitry, can you review this patch and include it into 3.15?
--
Pali Rohár
pali.rohar@gmail.com
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] Input: w90p910_ts - depend on ARCH_W90X900
From: Jean Delvare @ 2014-04-01 12:20 UTC (permalink / raw)
To: linux-input, linux-arm-kernel; +Cc: Wan ZongShun, Dmitry Torokhov
The w90p910_ts touchscreen driver is heavily architecture dependent,
so there is no point in letting it be built on other architectures
than it was written for.
All other W90P910/W90X900 drivers already have that dependency, so it
makes things more consistent and configuration easier.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/touchscreen/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-3.14-rc8.orig/drivers/input/touchscreen/Kconfig 2014-02-09 16:53:02.945634113 +0100
+++ linux-3.14-rc8/drivers/input/touchscreen/Kconfig 2014-04-01 14:10:08.936933702 +0200
@@ -867,7 +867,7 @@ config TOUCHSCREEN_TSC2007
config TOUCHSCREEN_W90X900
tristate "W90P910 touchscreen driver"
- depends on HAVE_CLK
+ depends on ARCH_W90X900
help
Say Y here if you have a W90P910 based touchscreen.
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply
* Re: [PATCH] Input: w90p910_ts - depend on ARCH_W90X900
From: Wan ZongShun @ 2014-04-01 13:17 UTC (permalink / raw)
To: Jean Delvare; +Cc: linux-input, linux-arm-kernel, Dmitry Torokhov
In-Reply-To: <20140401142046.14d4bb8c@endymion.delvare>
---------- Forwarded message ----------
From: Jean Delvare <jdelvare@suse.de>
Date: 2014-04-01 20:20 GMT+08:00
Subject: [PATCH] Input: w90p910_ts - depend on ARCH_W90X900
To: linux-input@vger.kernel.org, linux-arm-kernel@lists.infradead.org
抄送: Wan ZongShun <mcuos.com@gmail.com>, Dmitry Torokhov
<dmitry.torokhov@gmail.com>
The w90p910_ts touchscreen driver is heavily architecture dependent,
so there is no point in letting it be built on other architectures
than it was written for.
All other W90P910/W90X900 drivers already have that dependency, so it
makes things more consistent and configuration easier.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/touchscreen/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-3.14-rc8.orig/drivers/input/touchscreen/Kconfig
2014-02-09 16:53:02.945634113 +0100
+++ linux-3.14-rc8/drivers/input/touchscreen/Kconfig 2014-04-01
14:10:08.936933702 +0200
@@ -867,7 +867,7 @@ config TOUCHSCREEN_TSC2007
config TOUCHSCREEN_W90X900
tristate "W90P910 touchscreen driver"
- depends on HAVE_CLK
+ depends on ARCH_W90X900
help
Say Y here if you have a W90P910 based touchscreen.
Sure, your idea is reasonable.
Acked-by Wan Zongshun <mcuos.com@gmail.com>
--
Jean Delvare
SUSE L3 Support
--
Wan ZongShun.
www.mcuos.com
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] HID: uhid: Add UHID_CREATE2 + UHID_INPUT2
From: Jiri Kosina @ 2014-04-01 16:30 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-input, dh.herrmann
In-Reply-To: <20140324205001.981DD100D4F@puck.mtv.corp.google.com>
On Mon, 24 Mar 2014, Petri Gynther wrote:
> UHID_CREATE2:
> HID report descriptor data (rd_data) is an array in struct uhid_create2_req,
> instead of a pointer. Enables use from languages that don't support pointers,
> e.g. Python.
>
> UHID_INPUT2:
> Data array is the last field of struct uhid_input2_req. Enables userspace to
> write only the required bytes to kernel (ev.type + ev.u.input2.size + the part
> of the data array that matters), instead of the entire struct uhid_input2_req.
>
> Note:
> UHID_CREATE2 increases the total size of struct uhid_event slightly, thus
> increasing the size of messages that are queued for userspace. However, this
> won't affect the userspace processing of these events.
>
> Signed-off-by: Petri Gynther <pgynther@google.com>
> Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
I have adjusted it slightly to accomodate the hid_get_raw_report() and
hid_output_raw_report() API changes and pushed it out.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: HID vendor access from user space
From: Nestor Lopez Casado @ 2014-04-02 7:05 UTC (permalink / raw)
To: David Herrmann
Cc: Jiri Kosina, Dmitry Torokhov, Andrew de los Reyes,
open list:HID CORE LAYER, Olivier Gay, Benjamin Tissoires
In-Reply-To: <CANq1E4Sn4QZN4vPzBkv8zxuGD+xcdgHeMS9sTB45ACknmwaxEA@mail.gmail.com>
Hi, let me resuscitate this thread as we will have some resources to
work on this within a few weeks. I suggest re-reading the previous
emails to refresh the context of this discussion.
On Tue, May 21, 2013 at 3:12 PM, David Herrmann <dh.herrmann@gmail.com> wrote:
> Hi
>
> On Fri, May 17, 2013 at 1:47 PM, Nestor Lopez Casado
> <nlopezcasad@logitech.com> wrote:
>> Hi,
>>
>> In today's linux HID subsystem, a HID device can be accessed for
>> control and configuration via dev/hidraw, via a hid-specific driver,
>> as well as /dev/input (setting leds on a kbd for instance)
>>
>> Some HID devices share multiple functionality in the same HID
>> interface, think of a keyboard with a touchpad and a vendor specific
>> collection for configuration, special status, etc.
>>
>> For such device, there will be one hidraw node, and hid-input will
>> take care of parsing the keyboard/mouse collections into the proper
>> input objects.
>>
>> The vendor collection will be ignored.
>>
>> If a user wants to configure/control the device there are two choices,
>> either write a hid-specific driver to deal with the vendor specific
>> collection, or open the corresponding /hidraw node from userspace.
>>
>> But a hidraw node that carries system input data requires root priviledges.
>>
>> I'm interested in hearing your opinions on how to add the capability
>> for a normal user process to control/configure a HID device via
>> reports exchanged with a vendor collection.
>>
>> I have one proposal, which is to create, say "/dev/hidvendorX", nodes
>> for all top level HID collections which are today ignored by hid-input
>> and/or other subsystems.
>>
>> These nodes would not require root priviledge by default and thus,
>> users could control/reconfigure their devices from a standard
>> application while keeping the "standard" input functionality intact.
>
> Why not write a kernel driver? We have a pretty nice infrastructure
> for all this.
Do you mean a "hid-specific" driver for certain vid & pid devices ?
>
> If it's a license-issue, I recommend using udev rules to change
> permissions on the requested devices directly during setup. You can
> then use hidraw.
It is not a license issue, it is a security issue.
Every hid class interface, (either usb, bluetooth, i2c, etc) has an
associated hidraw node, and that node aggregates all reports sent from
the device.
Say that for example, the device has a keyboard collection and a
vendor collection, then changing permissions on the associated hidraw
node (so as to give any desktop user unrestricted access to the vendor
collection) would open the door to malicious code that could log the
keyboard activity (as both the vendor reports and input reports are
seen on the same hidraw node)
What we really want, is that vendor reports which come from hid vendor
collections not claimed by hid-input, are made available in separate
device nodes.
> It would also help if you could describe the driver design. Do you run
> it as daemon and feed data back into the kernel? Or do you forward it
> to the xserver? Or what kind of setup do you have? For instance, a
> library design would require dynamic permission setup, while a
> daemon-design would allow static file-system permissions.
> Furthermore, is it still an input driver? Or do you tunnel non-input
> data via HID?
I see this proposal as an extension to hidraw.c.
The functionality offered would be similar to that proposed by hidraw,
but instead of providing access to all device reports, only those
tagged as being "vendor usage" would be exposed.
Let's take a concrete device example based on the following hid
interface descriptor:
0x05 , 0x01, // USAGE_PAGE (Generic Desktop)
0x09 , 0x06, // USAGE (Keyboard)
0xA1 , 0x01, // COLLECTION (Application)
0x85 , 0x01, // REPORT_ID (1)
0x75 , 0x01, // REPORT_SIZE (1)
0x95 , 0x08, // REPORT_COUNT (8)
0x05 , 0x07, // USAGE_PAGE (Keyboard)
[snip]
0x19 , 0x00, // USAGE_MINIMUM (Reserved (no
event indicated))
0x29 , 0xFF, // USAGE_MAXIMUM (Reserved (no
event indicated))
0x81 , 0x00, // INPUT (Data,Ary,Abs)
0xC0, // END_COLLECTION
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined Page 1)
0x09, 0x02, // Usage (Vendor Usage 2)
0xA1, 0x01, // Collection (Application)
0x85, 0x11, // REPORT_ID (17)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x13, // REPORT_COUNT (19)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM (255)
0x09, 0x02, // USAGE (Vendor Usage 2)
0x81, 0x00, // INPUT (data,Ary,Abs)
0x09, 0x02, // USAGE (Vendor Usage 2)
0x91, 0x00, // OUTPUT (data,Ary,Abs)
0xC0, // End Collection
In today's context, this would create one device node:
/dev/hidrawX
After the proposal has been implemented, it would create:
/dev/hidrawX (access to the full hid interface including reports IDs
1 and 17, no change compared to today)
/dev/hidvendorX (access to reportID 17 only)
Full user rights can be granted to all desktop users for
/dev/hidvendorX while keeping the input reports (report ID 1) secure.
>
> Regards
> David
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
-nestor
^ permalink raw reply
* [PATCH v4 1/7] HID: sony: Fix cancel_work_sync mismerge
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Remove redundant cancel_work_sync() call caused by mismerge.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Apply against jikos/hid.git/for-linus to fix mismerge code duplication
drivers/hid/hid-sony.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 69204af..908de27 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1721,8 +1721,6 @@ static void sony_remove(struct hid_device *hdev)
if (sc->quirks & SONY_LED_SUPPORT)
sony_leds_remove(hdev);
- if (sc->worker_initialized)
- cancel_work_sync(&sc->state_worker);
if (sc->quirks & SONY_BATTERY_SUPPORT) {
hid_hw_close(hdev);
sony_battery_remove(sc);
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 2/7] HID: sony: Use inliners for work queue initialization and cancellation
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Use inliners to make sure that the work queue initialization flag is always
checked and set correctly when initializing or cancelling the work queue.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
v2 doesn't set worker_initialized to 0 when cancelling work since
cancel_work_sync doesn't actually deinitialize the work queue.
drivers/hid/hid-sony.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 908de27..3df3306 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1578,6 +1578,20 @@ static int sony_check_add(struct sony_sc *sc)
return sony_check_add_dev_list(sc);
}
+static inline void sony_init_work(struct sony_sc *sc,
+ void(*worker)(struct work_struct *))
+{
+ if (!sc->worker_initialized)
+ INIT_WORK(&sc->state_worker, worker);
+
+ sc->worker_initialized = 1;
+}
+
+static inline void sony_cancel_work_sync(struct sony_sc *sc)
+{
+ if (sc->worker_initialized)
+ cancel_work_sync(&sc->state_worker);
+}
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
@@ -1629,8 +1643,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
ret = sixaxis_set_operational_usb(hdev);
- sc->worker_initialized = 1;
- INIT_WORK(&sc->state_worker, sixaxis_state_worker);
+ sony_init_work(sc, sixaxis_state_worker);
} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
/*
* The Sixaxis wants output reports sent on the ctrl endpoint
@@ -1638,8 +1651,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
*/
hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
ret = sixaxis_set_operational_bt(hdev);
- sc->worker_initialized = 1;
- INIT_WORK(&sc->state_worker, sixaxis_state_worker);
+ sony_init_work(sc, sixaxis_state_worker);
} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
/*
@@ -1661,8 +1673,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret < 0)
goto err_stop;
- sc->worker_initialized = 1;
- INIT_WORK(&sc->state_worker, dualshock4_state_worker);
+ sony_init_work(sc, dualshock4_state_worker);
} else {
ret = 0;
}
@@ -1707,8 +1718,7 @@ err_stop:
sony_leds_remove(hdev);
if (sc->quirks & SONY_BATTERY_SUPPORT)
sony_battery_remove(sc);
- if (sc->worker_initialized)
- cancel_work_sync(&sc->state_worker);
+ sony_cancel_work_sync(sc);
sony_remove_dev_list(sc);
hid_hw_stop(hdev);
return ret;
@@ -1726,8 +1736,7 @@ static void sony_remove(struct hid_device *hdev)
sony_battery_remove(sc);
}
- if (sc->worker_initialized)
- cancel_work_sync(&sc->state_worker);
+ sony_cancel_work_sync(sc);
sony_remove_dev_list(sc);
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 0/7] HID: sony: More Sony controller fixes and improvements.
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
v4 of this series has been rebased against jikos/hid.git/for-linus
There was another bit of mismerge code duplication in for-linus that caused
merge conflicts with patches 3 and above in v3 of the series.
The first patch in v4 fixes the mismerge and the remaining patches now apply
cleanly.
Patch 1 should be queued for 3.15 as soon as possible.
^ permalink raw reply
* [PATCH v4 3/7] HID: sony: Use a struct for the Sixaxis output report.
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Use a struct for the Sixaxis output report that uses named members to set the
report fields.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 66 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 3df3306..ed68962 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -717,6 +717,36 @@ static enum power_supply_property sony_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
};
+struct sixaxis_led {
+ __u8 time_enabled; /* the total time the led is active (0xff means forever) */
+ __u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */
+ __u8 enabled;
+ __u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
+ __u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */
+} __packed;
+
+struct sixaxis_rumble {
+ __u8 padding;
+ __u8 right_duration; /* Right motor duration (0xff means forever) */
+ __u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
+ __u8 left_duration; /* Left motor duration (0xff means forever) */
+ __u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
+} __packed;
+
+struct sixaxis_output_report {
+ __u8 report_id;
+ struct sixaxis_rumble rumble;
+ __u8 padding[4];
+ __u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
+ struct sixaxis_led led[4]; /* LEDx at (4 - x) */
+ struct sixaxis_led _reserved; /* LED5, not actually soldered */
+} __packed;
+
+union sixaxis_output_report_01 {
+ struct sixaxis_output_report data;
+ __u8 buf[36];
+};
+
static spinlock_t sony_dev_list_lock;
static LIST_HEAD(sony_device_list);
@@ -1244,29 +1274,31 @@ error_leds:
static void sixaxis_state_worker(struct work_struct *work)
{
struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
- unsigned char buf[] = {
- 0x01,
- 0x00, 0xff, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00
+ union sixaxis_output_report_01 report = {
+ .buf = {
+ 0x01,
+ 0x00, 0xff, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ }
};
#ifdef CONFIG_SONY_FF
- buf[3] = sc->right ? 1 : 0;
- buf[5] = sc->left;
+ report.data.rumble.right_motor_on = sc->right ? 1 : 0;
+ report.data.rumble.left_motor_force = sc->left;
#endif
- buf[10] |= sc->led_state[0] << 1;
- buf[10] |= sc->led_state[1] << 2;
- buf[10] |= sc->led_state[2] << 3;
- buf[10] |= sc->led_state[3] << 4;
+ report.data.leds_bitmap |= sc->led_state[0] << 1;
+ report.data.leds_bitmap |= sc->led_state[1] << 2;
+ report.data.leds_bitmap |= sc->led_state[2] << 3;
+ report.data.leds_bitmap |= sc->led_state[3] << 4;
- hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf), HID_OUTPUT_REPORT,
- HID_REQ_SET_REPORT);
+ hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
+ sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
}
static void dualshock4_state_worker(struct work_struct *work)
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 4/7] HID: sony: Convert startup and shutdown functions to use a uniform parameter type
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Convert all of the local initialization and shutdown functions to take a
parameter type of struct sony_sc* instead of using a mix of struct sony_sc* and
struct hid_device*.
Allows for the removal of some calls to hid_get_drvdata().
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 67 ++++++++++++++++++++++++--------------------------
1 file changed, 32 insertions(+), 35 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index ed68962..a86542a 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1096,19 +1096,18 @@ static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
}
-static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count)
+static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count)
{
- struct sony_sc *drv_data = hid_get_drvdata(hdev);
int n;
BUG_ON(count > MAX_LEDS);
- if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {
- buzz_set_leds(hdev, leds);
+ if (sc->quirks & BUZZ_CONTROLLER && count == 4) {
+ buzz_set_leds(sc->hdev, leds);
} else {
for (n = 0; n < count; n++)
- drv_data->led_state[n] = leds[n];
- schedule_work(&drv_data->state_worker);
+ sc->led_state[n] = leds[n];
+ schedule_work(&sc->state_worker);
}
}
@@ -1131,7 +1130,8 @@ static void sony_led_set_brightness(struct led_classdev *led,
if (led == drv_data->leds[n]) {
if (value != drv_data->led_state[n]) {
drv_data->led_state[n] = value;
- sony_set_leds(hdev, drv_data->led_state, drv_data->led_count);
+ sony_set_leds(drv_data, drv_data->led_state,
+ drv_data->led_count);
}
break;
}
@@ -1160,30 +1160,28 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
return LED_OFF;
}
-static void sony_leds_remove(struct hid_device *hdev)
+static void sony_leds_remove(struct sony_sc *sc)
{
- struct sony_sc *drv_data;
struct led_classdev *led;
int n;
- drv_data = hid_get_drvdata(hdev);
- BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
+ BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
- for (n = 0; n < drv_data->led_count; n++) {
- led = drv_data->leds[n];
- drv_data->leds[n] = NULL;
+ for (n = 0; n < sc->led_count; n++) {
+ led = sc->leds[n];
+ sc->leds[n] = NULL;
if (!led)
continue;
led_classdev_unregister(led);
kfree(led);
}
- drv_data->led_count = 0;
+ sc->led_count = 0;
}
-static int sony_leds_init(struct hid_device *hdev)
+static int sony_leds_init(struct sony_sc *sc)
{
- struct sony_sc *drv_data;
+ struct hid_device *hdev = sc->hdev;
int n, ret = 0;
int max_brightness;
int use_colors;
@@ -1195,11 +1193,10 @@ static int sony_leds_init(struct hid_device *hdev)
static const char * const color_str[] = { "red", "green", "blue" };
static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
- drv_data = hid_get_drvdata(hdev);
- BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
+ BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
- if (drv_data->quirks & BUZZ_CONTROLLER) {
- drv_data->led_count = 4;
+ if (sc->quirks & BUZZ_CONTROLLER) {
+ sc->led_count = 4;
max_brightness = 1;
use_colors = 0;
name_len = strlen("::buzz#");
@@ -1207,14 +1204,14 @@ static int sony_leds_init(struct hid_device *hdev)
/* Validate expected report characteristics. */
if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
return -ENODEV;
- } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
- drv_data->led_count = 3;
+ } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
+ sc->led_count = 3;
max_brightness = 255;
use_colors = 1;
name_len = 0;
name_fmt = "%s:%s";
} else {
- drv_data->led_count = 4;
+ sc->led_count = 4;
max_brightness = 1;
use_colors = 0;
name_len = strlen("::sony#");
@@ -1226,11 +1223,11 @@ static int sony_leds_init(struct hid_device *hdev)
* only relevant if the driver is loaded after somebody actively set the
* LEDs to on
*/
- sony_set_leds(hdev, initial_values, drv_data->led_count);
+ sony_set_leds(sc, initial_values, sc->led_count);
name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
- for (n = 0; n < drv_data->led_count; n++) {
+ for (n = 0; n < sc->led_count; n++) {
if (use_colors)
name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2;
@@ -1260,13 +1257,13 @@ static int sony_leds_init(struct hid_device *hdev)
goto error_leds;
}
- drv_data->leds[n] = led;
+ sc->leds[n] = led;
}
return ret;
error_leds:
- sony_leds_remove(hdev);
+ sony_leds_remove(sc);
return ret;
}
@@ -1355,9 +1352,9 @@ static int sony_play_effect(struct input_dev *dev, void *data,
return 0;
}
-static int sony_init_ff(struct hid_device *hdev)
+static int sony_init_ff(struct sony_sc *sc)
{
- struct hid_input *hidinput = list_entry(hdev->inputs.next,
+ struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
@@ -1366,7 +1363,7 @@ static int sony_init_ff(struct hid_device *hdev)
}
#else
-static int sony_init_ff(struct hid_device *hdev)
+static int sony_init_ff(struct sony_sc *sc)
{
return 0;
}
@@ -1718,7 +1715,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop;
if (sc->quirks & SONY_LED_SUPPORT) {
- ret = sony_leds_init(hdev);
+ ret = sony_leds_init(sc);
if (ret < 0)
goto err_stop;
}
@@ -1737,7 +1734,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
if (sc->quirks & SONY_FF_SUPPORT) {
- ret = sony_init_ff(hdev);
+ ret = sony_init_ff(sc);
if (ret < 0)
goto err_close;
}
@@ -1747,7 +1744,7 @@ err_close:
hid_hw_close(hdev);
err_stop:
if (sc->quirks & SONY_LED_SUPPORT)
- sony_leds_remove(hdev);
+ sony_leds_remove(sc);
if (sc->quirks & SONY_BATTERY_SUPPORT)
sony_battery_remove(sc);
sony_cancel_work_sync(sc);
@@ -1761,7 +1758,7 @@ static void sony_remove(struct hid_device *hdev)
struct sony_sc *sc = hid_get_drvdata(hdev);
if (sc->quirks & SONY_LED_SUPPORT)
- sony_leds_remove(hdev);
+ sony_leds_remove(sc);
if (sc->quirks & SONY_BATTERY_SUPPORT) {
hid_hw_close(hdev);
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 6/7] HID: sony: Initialize the controller LEDs with a device ID value
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Add an IDA id allocator to assign unique, sequential device ids to Sixaxis and
DualShock 4 controllers.
Use the device ID to initialize the Sixaxis and DualShock 4 controller LEDs to
default values. The number or color of the controller is set relative to other
connected Sony controllers.
Set the LED class brightness values to the initial values and add the new led to
the array before calling led_classdev_register so that the correct brightness
value shows up in the LED sysfs entry.
Use explicit module init and exit functions since the IDA allocator must be
manually destroyed when the module is unloaded.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 114 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c709161..f26f8fa 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -33,6 +33,7 @@
#include <linux/power_supply.h>
#include <linux/spinlock.h>
#include <linux/list.h>
+#include <linux/idr.h>
#include <linux/input/mt.h>
#include "hid-ids.h"
@@ -749,6 +750,7 @@ union sixaxis_output_report_01 {
static spinlock_t sony_dev_list_lock;
static LIST_HEAD(sony_device_list);
+static DEFINE_IDA(sony_device_id_allocator);
struct sony_sc {
spinlock_t lock;
@@ -758,6 +760,7 @@ struct sony_sc {
unsigned long quirks;
struct work_struct state_worker;
struct power_supply battery;
+ int device_id;
#ifdef CONFIG_SONY_FF
__u8 left;
@@ -1078,6 +1081,52 @@ static int dualshock4_set_operational_bt(struct hid_device *hdev)
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
}
+static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS])
+{
+ static const __u8 sixaxis_leds[10][4] = {
+ { 0x01, 0x00, 0x00, 0x00 },
+ { 0x00, 0x01, 0x00, 0x00 },
+ { 0x00, 0x00, 0x01, 0x00 },
+ { 0x00, 0x00, 0x00, 0x01 },
+ { 0x01, 0x00, 0x00, 0x01 },
+ { 0x00, 0x01, 0x00, 0x01 },
+ { 0x00, 0x00, 0x01, 0x01 },
+ { 0x01, 0x00, 0x01, 0x01 },
+ { 0x00, 0x01, 0x01, 0x01 },
+ { 0x01, 0x01, 0x01, 0x01 }
+ };
+
+ BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
+
+ if (id < 0)
+ return;
+
+ id %= 10;
+ memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
+}
+
+static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS])
+{
+ /* The first 4 color/index entries match what the PS4 assigns */
+ static const __u8 color_code[7][3] = {
+ /* Blue */ { 0x00, 0x00, 0x01 },
+ /* Red */ { 0x01, 0x00, 0x00 },
+ /* Green */ { 0x00, 0x01, 0x00 },
+ /* Pink */ { 0x02, 0x00, 0x01 },
+ /* Orange */ { 0x02, 0x01, 0x00 },
+ /* Teal */ { 0x00, 0x01, 0x01 },
+ /* White */ { 0x01, 0x01, 0x01 }
+ };
+
+ BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
+
+ if (id < 0)
+ return;
+
+ id %= 7;
+ memcpy(values, color_code[id], sizeof(color_code[id]));
+}
+
static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
{
struct list_head *report_list =
@@ -1191,7 +1240,7 @@ static int sony_leds_init(struct sony_sc *sc)
size_t name_len;
const char *name_fmt;
static const char * const color_str[] = { "red", "green", "blue" };
- static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
+ __u8 initial_values[MAX_LEDS] = { 0 };
BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
@@ -1205,12 +1254,14 @@ static int sony_leds_init(struct sony_sc *sc)
if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
return -ENODEV;
} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
+ dualshock4_set_leds_from_id(sc->device_id, initial_values);
sc->led_count = 3;
max_brightness = 255;
use_colors = 1;
name_len = 0;
name_fmt = "%s:%s";
} else {
+ sixaxis_set_leds_from_id(sc->device_id, initial_values);
sc->led_count = 4;
max_brightness = 1;
use_colors = 0;
@@ -1245,14 +1296,17 @@ static int sony_leds_init(struct sony_sc *sc)
else
snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
led->name = name;
- led->brightness = 0;
+ led->brightness = initial_values[n];
led->max_brightness = max_brightness;
led->brightness_get = sony_led_get_brightness;
led->brightness_set = sony_led_set_brightness;
+ sc->leds[n] = led;
+
ret = led_classdev_register(&hdev->dev, led);
if (ret) {
hid_err(hdev, "Failed to register LED %d\n", n);
+ sc->leds[n] = NULL;
kfree(led);
goto error_leds;
}
@@ -1603,6 +1657,38 @@ static int sony_check_add(struct sony_sc *sc)
return sony_check_add_dev_list(sc);
}
+static int sony_set_device_id(struct sony_sc *sc)
+{
+ int ret;
+
+ /*
+ * Only DualShock 4 or Sixaxis controllers get an id.
+ * All others are set to -1.
+ */
+ if ((sc->quirks & SIXAXIS_CONTROLLER) ||
+ (sc->quirks & DUALSHOCK4_CONTROLLER)) {
+ ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
+ GFP_KERNEL);
+ if (ret < 0) {
+ sc->device_id = -1;
+ return ret;
+ }
+ sc->device_id = ret;
+ } else {
+ sc->device_id = -1;
+ }
+
+ return 0;
+}
+
+static void sony_release_device_id(struct sony_sc *sc)
+{
+ if (sc->device_id >= 0) {
+ ida_simple_remove(&sony_device_id_allocator, sc->device_id);
+ sc->device_id = -1;
+ }
+}
+
static inline void sony_init_work(struct sony_sc *sc,
void(*worker)(struct work_struct *))
{
@@ -1654,6 +1740,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
+ ret = sony_set_device_id(sc);
+ if (ret < 0) {
+ hid_err(hdev, "failed to allocate the device id\n");
+ goto err_stop;
+ }
+
if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
/*
* The Sony Sixaxis does not handle HID Output Reports on the
@@ -1745,6 +1837,7 @@ err_stop:
sony_battery_remove(sc);
sony_cancel_work_sync(sc);
sony_remove_dev_list(sc);
+ sony_release_device_id(sc);
hid_hw_stop(hdev);
return ret;
}
@@ -1765,6 +1858,8 @@ static void sony_remove(struct hid_device *hdev)
sony_remove_dev_list(sc);
+ sony_release_device_id(sc);
+
hid_hw_stop(hdev);
}
@@ -1809,6 +1904,22 @@ static struct hid_driver sony_driver = {
.report_fixup = sony_report_fixup,
.raw_event = sony_raw_event
};
-module_hid_driver(sony_driver);
+
+static int __init sony_init(void)
+{
+ dbg_hid("Sony:%s\n", __func__);
+
+ return hid_register_driver(&sony_driver);
+}
+
+static void __exit sony_exit(void)
+{
+ dbg_hid("Sony:%s\n", __func__);
+
+ ida_destroy(&sony_device_id_allocator);
+ hid_unregister_driver(&sony_driver);
+}
+module_init(sony_init);
+module_exit(sony_exit);
MODULE_LICENSE("GPL");
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 7/7] HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Add support for setting the blink rate of the LEDs. The Sixaxis allows control
over each individual LED, but the Dualshock 4 only has one global control for
the light bar so changing any individual color changes the global blink rate.
Setting the brightness cancels the blinking as per the LED class specifications.
The Sixaxis and Dualshock 4 controllers accept delays in decisecond increments
from 0 to 255 (2550 milliseconds).
The value at index 1 of the DualShock 4 USB output report must be 0xFF or the
light bar won't blink.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 113 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 104 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f26f8fa..aa5ece5 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -773,6 +773,8 @@ struct sony_sc {
__u8 battery_charging;
__u8 battery_capacity;
__u8 led_state[MAX_LEDS];
+ __u8 led_delay_on[MAX_LEDS];
+ __u8 led_delay_off[MAX_LEDS];
__u8 led_count;
};
@@ -1167,7 +1169,7 @@ static void sony_led_set_brightness(struct led_classdev *led,
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
struct sony_sc *drv_data;
- int n;
+ int n, blink_index;
drv_data = hid_get_drvdata(hdev);
if (!drv_data) {
@@ -1176,14 +1178,31 @@ static void sony_led_set_brightness(struct led_classdev *led,
}
for (n = 0; n < drv_data->led_count; n++) {
- if (led == drv_data->leds[n]) {
- if (value != drv_data->led_state[n]) {
- drv_data->led_state[n] = value;
- sony_set_leds(drv_data, drv_data->led_state,
- drv_data->led_count);
- }
+ if (led == drv_data->leds[n])
break;
- }
+ }
+
+ /* This LED is not registered on this device */
+ if (n >= drv_data->led_count)
+ return;
+
+ /* The DualShock 4 has a global blink setting and always uses index 0 */
+ if (drv_data->quirks & DUALSHOCK4_CONTROLLER)
+ blink_index = 0;
+ else
+ blink_index = n;
+
+ if ((value != drv_data->led_state[n]) ||
+ drv_data->led_delay_on[blink_index] ||
+ drv_data->led_delay_off[blink_index]) {
+ drv_data->led_state[n] = value;
+
+ /* Setting the brightness stops the blinking */
+ drv_data->led_delay_on[blink_index] = 0;
+ drv_data->led_delay_off[blink_index] = 0;
+
+ sony_set_leds(drv_data, drv_data->led_state,
+ drv_data->led_count);
}
}
@@ -1209,6 +1228,58 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
return LED_OFF;
}
+static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct device *dev = led->dev->parent;
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct sony_sc *drv_data = hid_get_drvdata(hdev);
+ int n;
+ __u8 new_on, new_off;
+
+ if (!drv_data) {
+ hid_err(hdev, "No device data\n");
+ return -EINVAL;
+ }
+
+ /* Max delay is 255 deciseconds or 2550 milliseconds */
+ if (*delay_on > 2550)
+ *delay_on = 2550;
+ if (*delay_off > 2550)
+ *delay_off = 2550;
+
+ /* Blink at 1 Hz if both values are zero */
+ if (!*delay_on && !*delay_off)
+ *delay_on = *delay_off = 1000;
+
+ new_on = *delay_on / 10;
+ new_off = *delay_off / 10;
+
+ /* The DualShock 4 has a global blink setting and always uses index 0 */
+ if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
+ n = 0;
+ } else {
+ for (n = 0; n < drv_data->led_count; n++) {
+ if (led == drv_data->leds[n])
+ break;
+ }
+ }
+
+ /* This LED is not registered on this device */
+ if (n >= drv_data->led_count)
+ return -EINVAL;
+
+ /* Don't schedule work if the values didn't change */
+ if (new_on != drv_data->led_delay_on[n] ||
+ new_off != drv_data->led_delay_off[n]) {
+ drv_data->led_delay_on[n] = new_on;
+ drv_data->led_delay_off[n] = new_off;
+ schedule_work(&drv_data->state_worker);
+ }
+
+ return 0;
+}
+
static void sony_leds_remove(struct sony_sc *sc)
{
struct led_classdev *led;
@@ -1301,6 +1372,9 @@ static int sony_leds_init(struct sony_sc *sc)
led->brightness_get = sony_led_get_brightness;
led->brightness_set = sony_led_set_brightness;
+ if (!(sc->quirks & BUZZ_CONTROLLER))
+ led->blink_set = sony_led_blink_set;
+
sc->leds[n] = led;
ret = led_classdev_register(&hdev->dev, led);
@@ -1325,6 +1399,7 @@ error_leds:
static void sixaxis_state_worker(struct work_struct *work)
{
struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
+ int n;
union sixaxis_output_report_01 report = {
.buf = {
0x01,
@@ -1348,6 +1423,22 @@ static void sixaxis_state_worker(struct work_struct *work)
report.data.leds_bitmap |= sc->led_state[2] << 3;
report.data.leds_bitmap |= sc->led_state[3] << 4;
+ /*
+ * The LEDs in the report are indexed in reverse order to their
+ * corresponding light on the controller.
+ * Index 0 = LED 4, index 1 = LED 3, etc...
+ *
+ * In the case of both delay values being zero (blinking disabled) the
+ * default report values should be used or the controller LED will be
+ * always off.
+ */
+ for (n = 0; n < 4; n++) {
+ if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
+ report.data.led[3 - n].duty_off = sc->led_delay_off[n];
+ report.data.led[3 - n].duty_on = sc->led_delay_on[n];
+ }
+ }
+
hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
}
@@ -1362,7 +1453,7 @@ static void dualshock4_state_worker(struct work_struct *work)
if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
buf[0] = 0x05;
- buf[1] = 0x03;
+ buf[1] = 0xFF;
offset = 4;
} else {
buf[0] = 0x11;
@@ -1382,6 +1473,10 @@ static void dualshock4_state_worker(struct work_struct *work)
buf[offset++] = sc->led_state[1];
buf[offset++] = sc->led_state[2];
+ /* If both delay values are zero the DualShock 4 disables blinking. */
+ buf[offset++] = sc->led_delay_on[0];
+ buf[offset++] = sc->led_delay_off[0];
+
if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
hid_hw_output_report(hdev, buf, 32);
else
--
1.8.3.2
^ permalink raw reply related
* [PATCH v4 5/7] HID: sony: Use the controller Bluetooth MAC address as the unique value in the battery name string
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>
Use the controller Bluetooth MAC address as the unique identifier in the
battery name string instead of the atomic integer that was used before.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
drivers/hid/hid-sony.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index a86542a..c709161 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1413,8 +1413,6 @@ static int sony_battery_get_property(struct power_supply *psy,
static int sony_battery_probe(struct sony_sc *sc)
{
- static atomic_t power_id_seq = ATOMIC_INIT(0);
- unsigned long power_id;
struct hid_device *hdev = sc->hdev;
int ret;
@@ -1424,15 +1422,13 @@ static int sony_battery_probe(struct sony_sc *sc)
*/
sc->battery_capacity = 100;
- power_id = (unsigned long)atomic_inc_return(&power_id_seq);
-
sc->battery.properties = sony_battery_props;
sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
sc->battery.get_property = sony_battery_get_property;
sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
sc->battery.use_for_apm = 0;
- sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",
- power_id);
+ sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR",
+ sc->mac_address);
if (!sc->battery.name)
return -ENOMEM;
--
1.8.3.2
^ 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