* Re: [PATCH v1 1/2] HID: i2c-hid: acpi: Drop unneded NULL check of adev
From: Andy Shevchenko @ 2023-01-10 13:59 UTC (permalink / raw)
To: linux-input, linux-kernel; +Cc: Jiri Kosina, Benjamin Tissoires
In-Reply-To: <Y6wNX12SyXpU5UKI@smile.fi.intel.com>
On Wed, Dec 28, 2022 at 11:33:19AM +0200, Andy Shevchenko wrote:
> On Tue, Nov 22, 2022 at 09:18:20PM +0200, Andy Shevchenko wrote:
> > The driver is enumerated on ACPI platforms, so adev is valid.
> > Since there is no valid I²C ID table provided, there is no
> > possibility to bind a device to this driver via user space.
> > Hence, drop unneeded NULL check of adev.
>
> Is there any comment on this?
> Can it be applied?
Whom should I ask about this series?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH] Input: i8042 - add Clevo PCX0DX to i8042 quirk table
From: Werner Sembach @ 2023-01-10 13:45 UTC (permalink / raw)
To: dmitry.torokhov, hdegoede, wse, mkorpershoek, chenhuacai, tiwai,
wsa+renesas, linux-input, linux-kernel
The Clevo PCX0DX/TUXEDO XP1511, need quirks for the keyboard to not be
occasionally unresponsive after resume.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Cc: stable@vger.kernel.org
---
drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
index 46f8a694291ed..efc61736099b9 100644
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -1238,6 +1238,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
--
2.34.1
^ permalink raw reply related
* Re: [RESEND PATCH 1/2] HID: Add driver for RC Simulator Controllers
From: Marcus Folkesson @ 2023-01-10 14:48 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jonathan Corbet, Jiri Kosina, Linux Doc Mailing List, lkml,
open list:HID CORE LAYER
In-Reply-To: <d4b420a0-23da-6ab6-886a-7342f7e63651@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]
Hi Benjamin,
On Mon, Sep 19, 2022 at 03:32:37PM +0200, Benjamin Tissoires wrote:
>
>
[...]
>
> I am back home, and I just tested that. I had a doubt, and it is indeed
> failing. You need the following change for this to be working (I need to
> send it as a proper patch after assessing it hasn't side effects)
Did it come up with any side effects? :-)
>
> ---
>
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index 13cce286247e..f37ffe2bd488 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -275,6 +275,7 @@ static void hid_irq_in(struct urb *urb)
> int status;
> switch (urb->status) {
> + case -EOVERFLOW: /* happens with modified report descriptors */
> case 0: /* success */
> usbhid->retry_delay = 0;
> if (!test_bit(HID_OPENED, &usbhid->iofl))
> ---
>
> Cheers,
> Benjamin
>
Best regards,
Marcus Folkesson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH] HID: Ignore battery for Elan touchscreen on Asus TP420IA
From: marco.rodolfi @ 2023-01-10 14:54 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, Linux Input, Linux Kernel; +Cc: Marco Rodolfi
This device has a touchscreen thats report a battery even if it doesn't
have one.
Ask Linux to ignore the battery so it will not always report it as low.
Signed-off-by: Marco Rodolfi <marco.rodolfi@tuta.io>
---
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-input.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8f58c3c1bec3..0f525b946cd1 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -413,6 +413,7 @@
#define I2C_DEVICE_ID_HP_ENVY_X360_15 0x2d05
#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100 0x29CF
#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
+#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 859aeb07542e..54e2d4066d9b 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -369,6 +369,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN)
,
+ HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN)
,
--
2.39.0
^ permalink raw reply related
* [PATCH v3 0/2] Input: cap11xx add support for cap1203, cap1293 and cap1298
From: Jiri Valek - 2N @ 2023-01-10 15:28 UTC (permalink / raw)
To: linux-input
Cc: devicetree, dmitry.torokhov, krzysztof.kozlowski+dt, linux-kernel,
robh+dt, u.kleine-koenig, jiriv
PATCH 1 - add compatible string for new models
PATCH 2 - add support for new models into driver
Changes in v2:
- Fixed if statement in PATCH 2.
Changes in v3:
- Model names sorted alphabetically in PATCH 2.
Jiri Valek - 2N (2):
dt-bindings: input: microchip,cap11xx: add cap1203, cap1293 and
cap1298
Input: cap11xx - add support for cap1203, cap1293 and cap1298
.../bindings/input/microchip,cap11xx.yaml | 3 +++
drivers/input/keyboard/cap11xx.c | 19 +++++++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: input: microchip,cap11xx: add cap1203, cap1293 and cap1298
From: Jiri Valek - 2N @ 2023-01-10 15:28 UTC (permalink / raw)
To: linux-input
Cc: devicetree, dmitry.torokhov, krzysztof.kozlowski+dt, linux-kernel,
robh+dt, u.kleine-koenig, jiriv
In-Reply-To: <20230110152859.295881-1-jiriv@axis.com>
Add support for cap1203, cap1293 and cap1298.
Signed-off-by: Jiri Valek - 2N <jiriv@axis.com>
---
No changes since v1
Documentation/devicetree/bindings/input/microchip,cap11xx.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/microchip,cap11xx.yaml b/Documentation/devicetree/bindings/input/microchip,cap11xx.yaml
index 67d4d8f86a2d..08ca993b94c4 100644
--- a/Documentation/devicetree/bindings/input/microchip,cap11xx.yaml
+++ b/Documentation/devicetree/bindings/input/microchip,cap11xx.yaml
@@ -20,6 +20,9 @@ properties:
- microchip,cap1126
- microchip,cap1188
- microchip,cap1206
+ - microchip,cap1203
+ - microchip,cap1293
+ - microchip,cap1298
reg:
maxItems: 1
--
2.25.1
^ permalink raw reply related
* [PATCH v3 2/2] Input: cap11xx - add support for cap1203, cap1293 and cap1298
From: Jiri Valek - 2N @ 2023-01-10 15:28 UTC (permalink / raw)
To: linux-input
Cc: devicetree, dmitry.torokhov, krzysztof.kozlowski+dt, linux-kernel,
robh+dt, u.kleine-koenig, jiriv
In-Reply-To: <20230110152859.295881-1-jiriv@axis.com>
Add basic support for more CAP1xxx sensors.
All models from CAP1xxx family are register-compatible.
Some advanced features are not used and disabled by default.
Reported-by: kernel test robot <lkp@xxxxxxxxx>
Signed-off-by: Jiri Valek - 2N <jiriv@axis.com>
---
Changes in v2:
- Fixed if statement.
Changes in v3:
- Model names sorted alphabetically.
drivers/input/keyboard/cap11xx.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 79afd0386e3f..ce27168302a8 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -98,14 +98,20 @@ enum {
CAP1106,
CAP1126,
CAP1188,
+ CAP1203,
CAP1206,
+ CAP1293,
+ CAP1298
};
static const struct cap11xx_hw_model cap11xx_devices[] = {
[CAP1106] = { .product_id = 0x55, .num_channels = 6, .num_leds = 0, .no_gain = false },
[CAP1126] = { .product_id = 0x53, .num_channels = 6, .num_leds = 2, .no_gain = false },
[CAP1188] = { .product_id = 0x50, .num_channels = 8, .num_leds = 8, .no_gain = false },
+ [CAP1203] = { .product_id = 0x6d, .num_channels = 3, .num_leds = 0, .no_gain = true },
[CAP1206] = { .product_id = 0x67, .num_channels = 6, .num_leds = 0, .no_gain = true },
+ [CAP1293] = { .product_id = 0x6f, .num_channels = 3, .num_leds = 0, .no_gain = false },
+ [CAP1298] = { .product_id = 0x71, .num_channels = 8, .num_leds = 0, .no_gain = false },
};
static const struct reg_default cap11xx_reg_defaults[] = {
@@ -377,7 +383,8 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client)
if (error < 0)
return error;
- dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev);
+ dev_info(dev, "CAP11XX detected, model %s, revision 0x%02x\n",
+ id->name, rev);
node = dev->of_node;
if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) {
@@ -390,7 +397,9 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client)
dev_err(dev, "Invalid sensor-gain value %d\n", gain32);
}
- if (id->driver_data != CAP1206) {
+ if ((id->driver_data == CAP1106) ||
+ (id->driver_data == CAP1126) ||
+ (id->driver_data == CAP1188)) {
if (of_property_read_bool(node, "microchip,irq-active-high")) {
error = regmap_update_bits(priv->regmap,
CAP11XX_REG_CONFIG2,
@@ -483,7 +492,10 @@ static const struct of_device_id cap11xx_dt_ids[] = {
{ .compatible = "microchip,cap1106", },
{ .compatible = "microchip,cap1126", },
{ .compatible = "microchip,cap1188", },
+ { .compatible = "microchip,cap1203", },
{ .compatible = "microchip,cap1206", },
+ { .compatible = "microchip,cap1293", },
+ { .compatible = "microchip,cap1298", },
{}
};
MODULE_DEVICE_TABLE(of, cap11xx_dt_ids);
@@ -492,7 +504,10 @@ static const struct i2c_device_id cap11xx_i2c_ids[] = {
{ "cap1106", CAP1106 },
{ "cap1126", CAP1126 },
{ "cap1188", CAP1188 },
+ { "cap1203", CAP1203 },
{ "cap1206", CAP1206 },
+ { "cap1293", CAP1293 },
+ { "cap1298", CAP1298 },
{}
};
MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids);
--
2.25.1
^ permalink raw reply related
* Re: (subset) [PATCH v3 0/9] fix reset line polarity for Goodix touchscreen controllers
From: Bjorn Andersson @ 2023-01-10 16:17 UTC (permalink / raw)
To: samuel, agx, megous, heiko, hdegoede, robh+dt, wens,
michael.riesch, lukma, icenowy, kernel, david, shawnguo,
foss+kernel, linux-imx, festevam, pgwipeout, jagan, agross,
hadess, dmitry.torokhov, jernej.skrabec,
angelogioacchino.delregno, mamlinav, frieder.schrempf, angus,
Sascha Hauer, konrad.dybcio, krzysztof.kozlowski+dt
Cc: linux-kernel, devicetree, linux-input, linux-arm-kernel,
linux-sunxi, quentin.schulz, linux-arm-msm, linux-rockchip
In-Reply-To: <20221103-upstream-goodix-reset-v3-0-0975809eb183@theobroma-systems.com>
On Mon, 5 Dec 2022 14:40:29 +0100, Quentin Schulz wrote:
> From: Quentin Schulz <quentin.schulz@theobroma-systems.com>
>
> The Goodix touchscreen controller has a reset line active low. It happens to
> also be used to configure its i2c address at runtime. If the reset line is
> incorrectly asserted, the address will be wrongly configured. This cost me a few
> hours, trying to figure out why the touchscreen wouldn't work.
>
> [...]
Applied, thanks!
[8/9] arm64: dts: qcom: msm8998-fxtec: fix touchscreen reset GPIO polarity
commit: 8a0721dae68fdb4534e220fc9faae7a0ef2f3785
Best regards,
--
Bjorn Andersson <andersson@kernel.org>
^ permalink raw reply
* Re: [PATCH] Input: i8042 - add Clevo PCX0DX to i8042 quirk table
From: Mattijs Korpershoek @ 2023-01-10 16:32 UTC (permalink / raw)
To: Werner Sembach, dmitry.torokhov, hdegoede, wse, chenhuacai, tiwai,
wsa+renesas, linux-input, linux-kernel
In-Reply-To: <20230110134524.553620-1-wse@tuxedocomputers.com>
On Tue, Jan 10, 2023 at 14:45, Werner Sembach <wse@tuxedocomputers.com> wrote:
> The Clevo PCX0DX/TUXEDO XP1511, need quirks for the keyboard to not be
> occasionally unresponsive after resume.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> Cc: stable@vger.kernel.org
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
> ---
> drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
> index 46f8a694291ed..efc61736099b9 100644
> --- a/drivers/input/serio/i8042-acpipnpio.h
> +++ b/drivers/input/serio/i8042-acpipnpio.h
> @@ -1238,6 +1238,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
> .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
> SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
> },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"),
> + },
> + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
> + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
> + },
> {
> .matches = {
> DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
> --
> 2.34.1
^ permalink raw reply
* Re: [PATCH HID for-next v1 1/9] selftests: hid: add vmtest.sh
From: Stanislav Fomichev @ 2023-01-10 18:52 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Greg KH, Jiri Kosina, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Dmitry Torokhov, Tero Kristo, linux-kernel,
linux-input, netdev, bpf, linux-kselftest
In-Reply-To: <CAO-hwJJr1eAvR++V3Tv6cL8chj05PE_-vF+J8OoB1GpP2VQGig@mail.gmail.com>
On Tue, Jan 10, 2023 at 1:43 AM Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
>
> On Mon, Jan 9, 2023 at 6:56 PM <sdf@google.com> wrote:
> >
> > On 01/09, Stanislav Fomichev wrote:
> > > On 01/06, Benjamin Tissoires wrote:
> > > > Similar-ish in many points from the script in selftests/bpf, with a few
> > > > differences:
> > > > - relies on boot2container instead of a plain qemu image (meaning that
> > > > we can take any container in a registry as a base)
> > > > - runs in the hid selftest dir, and such uses the test program from
> > > there
> > > > - the working directory to store the config is in
> > > > tools/selftests/hid/results
> > > >
> > > > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> >
> > > Sorry, I've completely missed this. I wasn't on CC and assumed
> > > that was some sort of a repost. Going through the changes right now.
> >
> > Hmmm, or maybe I shouldn't? This seems to be bases on some other tree;
> > can't find tools/testing/selftests/hid/Makefile (from patch #2) in neither
> > bpf nor bpf-next.
>
>
> These changes are based on
> https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git/ branch
> for-6.3/hid-bpf, so going through the HID tree, not the bpf one.
>
> I Cce-ed the bpf mailing list for visibility, in case I made an
> obvious error, but this doesn't impact bpf core, so reviews are
> appreciated, but not mandatory from the bpf side of things :)
Cool, thanks, in this case I'm not feeling guilty about missing it on Friday :-)
> >
> > Alexei/Daniel/Andrii, what's the process with these series?
> >
> > > One question here: is it worth it extending bpf/vmtest.sh instead
> > > to support boot2container? Why new script with a bunch of copy-paste
> > > is a better deal?
>
> Good question. There were a few things that made me copy/paste part of
> the script:
> - the bpf one is relying on the bpf rootfs image that, as a subsystem
> maintainer of another subsystem than bpf don't control
> - the bpf one is hardcoding which program to launch, and I want another one
> - the bpf one is in a different directory which would feel weird to
> call when running selftests/hid
> - I want a minimum control over the script so that a change in the bpf
> tree doesn't accidentally break the hid tree
>
> I think using the boot2container initramfs solves the rootfs issue,
> because the initramfs is generic and just consists of a script around
> podman to start a container. This way I can run the test suite on any
> distribution without having to build any distro image. I should also
> be able to start a scratch container without anything in it given that
> the only thing that matters is the binary we start as a command
> (though we won't be able to start a shell in the target VM).
>
> Solving the second and third point could probably be done by
> encapsulating the call to bpf/vmtest.sh from hid.
>
> But for the fourth point, I believe that the bpf script is not generic
> enough to be reused by other subsystems as it relies on the bpf CI,
> mostly to generate the rootfs.
>
> Also note that boot2container is a little bit more verbose in terms of
> logs, as it's not just a plain qemu boot to a known rootfs, but it
> starts podman and another container at the end to gather the results.
[..]
> So maybe a solution would be to add a vmtest make target at the
> selftests root directory, that would be generic enough to be run in
> any subsystem. There are a few other users of qemu in selftests, but
> each of them has a slightly different use of qemu.
Agreed, that seems like the ideal place to put it. Maybe we can unify
them all at some point. And maybe the bpf subsystem can also benefit
by simplifying our images, idk.
(but, obviously, not willing to block your changes, this is all "nice
to have" category)
> Also, FWIW, boot2container is currently only providing initramfs for
> x86_64 and arm64. Thus, using boot2container now for bpf means that we
> would drop s390x, which is probably not the best move forward. We can
> surely extend the targets, but not sure what plans Martin has on this
> side.
Noted. Although I have no background on why we run s390x and whether
we really want to continue to run it..
> For reference, boot2container project:
> https://gitlab.freedesktop.org/mupuf/boot2container/
>
> Cheers,
> Benjamin
>
> >
> > > > ---
> > > > tools/testing/selftests/hid/.gitignore | 1 +
> > > > tools/testing/selftests/hid/config.common | 241 ++++++++++++++++++
> > > > tools/testing/selftests/hid/config.x86_64 | 4 +
> > > > tools/testing/selftests/hid/vmtest.sh | 284 ++++++++++++++++++++++
> > > > 4 files changed, 530 insertions(+)
> > > > create mode 100644 tools/testing/selftests/hid/config.common
> > > > create mode 100644 tools/testing/selftests/hid/config.x86_64
> > > > create mode 100755 tools/testing/selftests/hid/vmtest.sh
> > > >
> > > > diff --git a/tools/testing/selftests/hid/.gitignore
> > > b/tools/testing/selftests/hid/.gitignore
> > > > index a462ca6ab2c0..995af0670f69 100644
> > > > --- a/tools/testing/selftests/hid/.gitignore
> > > > +++ b/tools/testing/selftests/hid/.gitignore
> > > > @@ -2,3 +2,4 @@ bpftool
> > > > *.skel.h
> > > > /tools
> > > > hid_bpf
> > > > +results
> > > > diff --git a/tools/testing/selftests/hid/config.common
> > > b/tools/testing/selftests/hid/config.common
> > > > new file mode 100644
> > > > index 000000000000..0617275d93cc
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/hid/config.common
> > > > @@ -0,0 +1,241 @@
> > > > +CONFIG_9P_FS_POSIX_ACL=y
> > > > +CONFIG_9P_FS_SECURITY=y
> > > > +CONFIG_9P_FS=y
> > > > +CONFIG_AUDIT=y
> > > > +CONFIG_BINFMT_MISC=y
> > > > +CONFIG_BLK_CGROUP_IOLATENCY=y
> > > > +CONFIG_BLK_CGROUP=y
> > > > +CONFIG_BLK_DEV_BSGLIB=y
> > > > +CONFIG_BLK_DEV_IO_TRACE=y
> > > > +CONFIG_BLK_DEV_RAM_SIZE=16384
> > > > +CONFIG_BLK_DEV_RAM=y
> > > > +CONFIG_BLK_DEV_THROTTLING=y
> > > > +CONFIG_BONDING=y
> > > > +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
> > > > +CONFIG_BOOTTIME_TRACING=y
> > > > +CONFIG_BSD_DISKLABEL=y
> > > > +CONFIG_BSD_PROCESS_ACCT=y
> > > > +CONFIG_CFS_BANDWIDTH=y
> > > > +CONFIG_CGROUP_CPUACCT=y
> > > > +CONFIG_CGROUP_DEBUG=y
> > > > +CONFIG_CGROUP_DEVICE=y
> > > > +CONFIG_CGROUP_FREEZER=y
> > > > +CONFIG_CGROUP_HUGETLB=y
> > > > +CONFIG_CGROUP_NET_CLASSID=y
> > > > +CONFIG_CGROUP_NET_PRIO=y
> > > > +CONFIG_CGROUP_PERF=y
> > > > +CONFIG_CGROUP_PIDS=y
> > > > +CONFIG_CGROUP_RDMA=y
> > > > +CONFIG_CGROUP_SCHED=y
> > > > +CONFIG_CGROUPS=y
> > > > +CONFIG_CGROUP_WRITEBACK=y
> > > > +CONFIG_CMA_AREAS=7
> > > > +CONFIG_CMA=y
> > > > +CONFIG_COMPAT_32BIT_TIME=y
> > > > +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
> > > > +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
> > > > +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
> > > > +CONFIG_CPU_FREQ_GOV_USERSPACE=y
> > > > +CONFIG_CPU_FREQ_STAT=y
> > > > +CONFIG_CPU_IDLE_GOV_LADDER=y
> > > > +CONFIG_CPUSETS=y
> > > > +CONFIG_CRC_T10DIF=y
> > > > +CONFIG_CRYPTO_BLAKE2B=y
> > > > +CONFIG_CRYPTO_DEV_VIRTIO=y
> > > > +CONFIG_CRYPTO_SEQIV=y
> > > > +CONFIG_CRYPTO_XXHASH=y
> > > > +CONFIG_DCB=y
> > > > +CONFIG_DEBUG_ATOMIC_SLEEP=y
> > > > +CONFIG_DEBUG_CREDENTIALS=y
> > > > +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
> > > > +CONFIG_DEBUG_MEMORY_INIT=y
> > > > +CONFIG_DEFAULT_FQ_CODEL=y
> > > > +CONFIG_DEFAULT_RENO=y
> > > > +CONFIG_DEFAULT_SECURITY_DAC=y
> > > > +CONFIG_DEVTMPFS_MOUNT=y
> > > > +CONFIG_DEVTMPFS=y
> > > > +CONFIG_DMA_CMA=y
> > > > +CONFIG_DNS_RESOLVER=y
> > > > +CONFIG_EFI_STUB=y
> > > > +CONFIG_EFI=y
> > > > +CONFIG_EXPERT=y
> > > > +CONFIG_EXT4_FS_POSIX_ACL=y
> > > > +CONFIG_EXT4_FS_SECURITY=y
> > > > +CONFIG_EXT4_FS=y
> > > > +CONFIG_FAIL_FUNCTION=y
> > > > +CONFIG_FAULT_INJECTION_DEBUG_FS=y
> > > > +CONFIG_FAULT_INJECTION=y
> > > > +CONFIG_FB_MODE_HELPERS=y
> > > > +CONFIG_FB_TILEBLITTING=y
> > > > +CONFIG_FB_VESA=y
> > > > +CONFIG_FB=y
> > > > +CONFIG_FONT_8x16=y
> > > > +CONFIG_FONT_MINI_4x6=y
> > > > +CONFIG_FONTS=y
> > > > +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
> > > > +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
> > > > +CONFIG_FRAMEBUFFER_CONSOLE=y
> > > > +CONFIG_FUSE_FS=y
> > > > +CONFIG_FW_LOADER_USER_HELPER=y
> > > > +CONFIG_GART_IOMMU=y
> > > > +CONFIG_GENERIC_PHY=y
> > > > +CONFIG_HARDLOCKUP_DETECTOR=y
> > > > +CONFIG_HIGH_RES_TIMERS=y
> > > > +CONFIG_HPET=y
> > > > +CONFIG_HUGETLBFS=y
> > > > +CONFIG_HUGETLB_PAGE=y
> > > > +CONFIG_HWPOISON_INJECT=y
> > > > +CONFIG_HZ_1000=y
> > > > +CONFIG_INET=y
> > > > +CONFIG_INTEL_POWERCLAMP=y
> > > > +CONFIG_IP6_NF_FILTER=y
> > > > +CONFIG_IP6_NF_IPTABLES=y
> > > > +CONFIG_IP6_NF_NAT=y
> > > > +CONFIG_IP6_NF_TARGET_MASQUERADE=y
> > > > +CONFIG_IP_ADVANCED_ROUTER=y
> > > > +CONFIG_IP_MROUTE=y
> > > > +CONFIG_IP_MULTICAST=y
> > > > +CONFIG_IP_MULTIPLE_TABLES=y
> > > > +CONFIG_IP_NF_FILTER=y
> > > > +CONFIG_IP_NF_IPTABLES=y
> > > > +CONFIG_IP_NF_NAT=y
> > > > +CONFIG_IP_NF_TARGET_MASQUERADE=y
> > > > +CONFIG_IP_PIMSM_V1=y
> > > > +CONFIG_IP_PIMSM_V2=y
> > > > +CONFIG_IP_ROUTE_MULTIPATH=y
> > > > +CONFIG_IP_ROUTE_VERBOSE=y
> > > > +CONFIG_IPV6_MIP6=y
> > > > +CONFIG_IPV6_ROUTE_INFO=y
> > > > +CONFIG_IPV6_ROUTER_PREF=y
> > > > +CONFIG_IPV6_SEG6_LWTUNNEL=y
> > > > +CONFIG_IPV6_SUBTREES=y
> > > > +CONFIG_IRQ_POLL=y
> > > > +CONFIG_JUMP_LABEL=y
> > > > +CONFIG_KARMA_PARTITION=y
> > > > +CONFIG_KEXEC=y
> > > > +CONFIG_KPROBES=y
> > > > +CONFIG_KSM=y
> > > > +CONFIG_LEGACY_VSYSCALL_NONE=y
> > > > +CONFIG_LOG_BUF_SHIFT=21
> > > > +CONFIG_LOG_CPU_MAX_BUF_SHIFT=0
> > > > +CONFIG_LOGO=y
> > > > +CONFIG_LSM="selinux,bpf,integrity"
> > > > +CONFIG_MAC_PARTITION=y
> > > > +CONFIG_MAGIC_SYSRQ=y
> > > > +CONFIG_MCORE2=y
> > > > +CONFIG_MEMCG=y
> > > > +CONFIG_MEMORY_FAILURE=y
> > > > +CONFIG_MINIX_SUBPARTITION=y
> > > > +CONFIG_MODULES=y
> > > > +CONFIG_NAMESPACES=y
> > > > +CONFIG_NET_9P_VIRTIO=y
> > > > +CONFIG_NET_9P=y
> > > > +CONFIG_NET_ACT_BPF=y
> > > > +CONFIG_NET_CLS_CGROUP=y
> > > > +CONFIG_NETDEVICES=y
> > > > +CONFIG_NET_EMATCH=y
> > > > +CONFIG_NETFILTER_NETLINK_LOG=y
> > > > +CONFIG_NETFILTER_NETLINK_QUEUE=y
> > > > +CONFIG_NETFILTER_XTABLES=y
> > > > +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
> > > > +CONFIG_NETFILTER_XT_MATCH_BPF=y
> > > > +CONFIG_NETFILTER_XT_MATCH_COMMENT=y
> > > > +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
> > > > +CONFIG_NETFILTER_XT_MATCH_MARK=y
> > > > +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
> > > > +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
> > > > +CONFIG_NETFILTER_XT_NAT=y
> > > > +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
> > > > +CONFIG_NET_IPGRE_BROADCAST=y
> > > > +CONFIG_NET_L3_MASTER_DEV=y
> > > > +CONFIG_NETLABEL=y
> > > > +CONFIG_NET_SCH_DEFAULT=y
> > > > +CONFIG_NET_SCHED=y
> > > > +CONFIG_NET_SCH_FQ_CODEL=y
> > > > +CONFIG_NET_TC_SKB_EXT=y
> > > > +CONFIG_NET_VRF=y
> > > > +CONFIG_NET=y
> > > > +CONFIG_NF_CONNTRACK=y
> > > > +CONFIG_NF_NAT_MASQUERADE=y
> > > > +CONFIG_NF_NAT=y
> > > > +CONFIG_NLS_ASCII=y
> > > > +CONFIG_NLS_CODEPAGE_437=y
> > > > +CONFIG_NLS_DEFAULT="utf8"
> > > > +CONFIG_NO_HZ=y
> > > > +CONFIG_NR_CPUS=128
> > > > +CONFIG_NUMA_BALANCING=y
> > > > +CONFIG_NUMA=y
> > > > +CONFIG_NVMEM=y
> > > > +CONFIG_OSF_PARTITION=y
> > > > +CONFIG_OVERLAY_FS_INDEX=y
> > > > +CONFIG_OVERLAY_FS_METACOPY=y
> > > > +CONFIG_OVERLAY_FS_XINO_AUTO=y
> > > > +CONFIG_OVERLAY_FS=y
> > > > +CONFIG_PACKET=y
> > > > +CONFIG_PANIC_ON_OOPS=y
> > > > +CONFIG_PARTITION_ADVANCED=y
> > > > +CONFIG_PCIEPORTBUS=y
> > > > +CONFIG_PCI_IOV=y
> > > > +CONFIG_PCI_MSI=y
> > > > +CONFIG_PCI=y
> > > > +CONFIG_PHYSICAL_ALIGN=0x1000000
> > > > +CONFIG_POSIX_MQUEUE=y
> > > > +CONFIG_POWER_SUPPLY=y
> > > > +CONFIG_PREEMPT=y
> > > > +CONFIG_PRINTK_TIME=y
> > > > +CONFIG_PROC_KCORE=y
> > > > +CONFIG_PROFILING=y
> > > > +CONFIG_PROVE_LOCKING=y
> > > > +CONFIG_PTP_1588_CLOCK=y
> > > > +CONFIG_RC_DEVICES=y
> > > > +CONFIG_RC_LOOPBACK=y
> > > > +CONFIG_RCU_CPU_STALL_TIMEOUT=60
> > > > +CONFIG_SCHED_STACK_END_CHECK=y
> > > > +CONFIG_SCHEDSTATS=y
> > > > +CONFIG_SECURITY_NETWORK=y
> > > > +CONFIG_SECURITY_SELINUX=y
> > > > +CONFIG_SERIAL_8250_CONSOLE=y
> > > > +CONFIG_SERIAL_8250_DETECT_IRQ=y
> > > > +CONFIG_SERIAL_8250_EXTENDED=y
> > > > +CONFIG_SERIAL_8250_MANY_PORTS=y
> > > > +CONFIG_SERIAL_8250_NR_UARTS=32
> > > > +CONFIG_SERIAL_8250_RSA=y
> > > > +CONFIG_SERIAL_8250_SHARE_IRQ=y
> > > > +CONFIG_SERIAL_8250=y
> > > > +CONFIG_SERIAL_NONSTANDARD=y
> > > > +CONFIG_SERIO_LIBPS2=y
> > > > +CONFIG_SGI_PARTITION=y
> > > > +CONFIG_SMP=y
> > > > +CONFIG_SOCK_CGROUP_DATA=y
> > > > +CONFIG_SOLARIS_X86_PARTITION=y
> > > > +CONFIG_SUN_PARTITION=y
> > > > +CONFIG_SYNC_FILE=y
> > > > +CONFIG_SYSVIPC=y
> > > > +CONFIG_TASK_DELAY_ACCT=y
> > > > +CONFIG_TASK_IO_ACCOUNTING=y
> > > > +CONFIG_TASKSTATS=y
> > > > +CONFIG_TASK_XACCT=y
> > > > +CONFIG_TCP_CONG_ADVANCED=y
> > > > +CONFIG_TCP_MD5SIG=y
> > > > +CONFIG_TLS=y
> > > > +CONFIG_TMPFS_POSIX_ACL=y
> > > > +CONFIG_TMPFS=y
> > > > +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
> > > > +CONFIG_TRANSPARENT_HUGEPAGE=y
> > > > +CONFIG_TUN=y
> > > > +CONFIG_UNIXWARE_DISKLABEL=y
> > > > +CONFIG_UNIX=y
> > > > +CONFIG_USER_NS=y
> > > > +CONFIG_VALIDATE_FS_PARSER=y
> > > > +CONFIG_VETH=y
> > > > +CONFIG_VIRT_DRIVERS=y
> > > > +CONFIG_VIRTIO_BALLOON=y
> > > > +CONFIG_VIRTIO_BLK=y
> > > > +CONFIG_VIRTIO_CONSOLE=y
> > > > +CONFIG_VIRTIO_FS=y
> > > > +CONFIG_VIRTIO_NET=y
> > > > +CONFIG_VIRTIO_PCI=y
> > > > +CONFIG_VLAN_8021Q=y
> > > > +CONFIG_XFRM_SUB_POLICY=y
> > > > +CONFIG_XFRM_USER=y
> > > > +CONFIG_ZEROPLUS_FF=y
> > > > diff --git a/tools/testing/selftests/hid/config.x86_64
> > > b/tools/testing/selftests/hid/config.x86_64
> > > > new file mode 100644
> > > > index 000000000000..a8721f403c21
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/hid/config.x86_64
> > > > @@ -0,0 +1,4 @@
> > > > +CONFIG_X86_ACPI_CPUFREQ=y
> > > > +CONFIG_X86_CPUID=y
> > > > +CONFIG_X86_MSR=y
> > > > +CONFIG_X86_POWERNOW_K8=y
> > > > diff --git a/tools/testing/selftests/hid/vmtest.sh
> > > b/tools/testing/selftests/hid/vmtest.sh
> > > > new file mode 100755
> > > > index 000000000000..90f34150f257
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/hid/vmtest.sh
> > > > @@ -0,0 +1,284 @@
> > > > +#!/bin/bash
> > > > +# SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +set -u
> > > > +set -e
> > > > +
> > > > +# This script currently only works for x86_64
> > > > +ARCH="$(uname -m)"
> > > > +case "${ARCH}" in
> > > > +x86_64)
> > > > + QEMU_BINARY=qemu-system-x86_64
> > > > + BZIMAGE="arch/x86/boot/bzImage"
> > > > + ;;
> > > > +*)
> > > > + echo "Unsupported architecture"
> > > > + exit 1
> > > > + ;;
> > > > +esac
> > > > +DEFAULT_COMMAND="./hid_bpf"
> > > > +SCRIPT_DIR="$(dirname $(realpath $0))"
> > > > +OUTPUT_DIR="$SCRIPT_DIR/results"
> > > >
> > > +KCONFIG_REL_PATHS=("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" "${SCRIPT_DIR}/config.${ARCH}")
> > > >
> > > +B2C_URL="https://gitlab.freedesktop.org/mupuf/boot2container/-/raw/master/vm2c.py"
> > > > +NUM_COMPILE_JOBS="$(nproc)"
> > > > +LOG_FILE_BASE="$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")"
> > > > +LOG_FILE="${LOG_FILE_BASE}.log"
> > > > +EXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status"
> > > > +CONTAINER_IMAGE="registry.fedoraproject.org/fedora:36"
> > > > +
> > > > +usage()
> > > > +{
> > > > + cat <<EOF
> > > > +Usage: $0 [-i] [-s] [-d <output_dir>] -- [<command>]
> > > > +
> > > > +<command> is the command you would normally run when you are in
> > > > +tools/testing/selftests/bpf. e.g:
> > > > +
> > > > + $0 -- ./hid_bpf
> > > > +
> > > > +If no command is specified and a debug shell (-s) is not requested,
> > > > +"${DEFAULT_COMMAND}" will be run by default.
> > > > +
> > > > +If you build your kernel using KBUILD_OUTPUT= or O= options, these
> > > > +can be passed as environment variables to the script:
> > > > +
> > > > + O=<kernel_build_path> $0 -- ./hid_bpf
> > > > +
> > > > +or
> > > > +
> > > > + KBUILD_OUTPUT=<kernel_build_path> $0 -- ./hid_bpf
> > > > +
> > > > +Options:
> > > > +
> > > > + -u) Update the boot2container script to a newer version.
> > > > + -d) Update the output directory (default: ${OUTPUT_DIR})
> > > > + -j) Number of jobs for compilation, similar to -j in make
> > > > + (default: ${NUM_COMPILE_JOBS})
> > > > + -s) Instead of powering off the VM, start an interactive
> > > > + shell. If <command> is specified, the shell runs after
> > > > + the command finishes executing
> > > > +EOF
> > > > +}
> > > > +
> > > > +download()
> > > > +{
> > > > + local file="$1"
> > > > +
> > > > + echo "Downloading $file..." >&2
> > > > + curl -Lsf "$file" -o "${@:2}"
> > > > +}
> > > > +
> > > > +recompile_kernel()
> > > > +{
> > > > + local kernel_checkout="$1"
> > > > + local make_command="$2"
> > > > +
> > > > + cd "${kernel_checkout}"
> > > > +
> > > > + ${make_command} olddefconfig
> > > > + ${make_command}
> > > > +}
> > > > +
> > > > +update_selftests()
> > > > +{
> > > > + local kernel_checkout="$1"
> > > > + local selftests_dir="${kernel_checkout}/tools/testing/selftests/hid"
> > > > +
> > > > + cd "${selftests_dir}"
> > > > + ${make_command}
> > > > +}
> > > > +
> > > > +run_vm()
> > > > +{
> > > > + local b2c="$1"
> > > > + local kernel_bzimage="$2"
> > > > + local command="$3"
> > > > + local post_command=""
> > > > +
> > > > + if ! which "${QEMU_BINARY}" &> /dev/null; then
> > > > + cat <<EOF
> > > > +Could not find ${QEMU_BINARY}
> > > > +Please install qemu or set the QEMU_BINARY environment variable.
> > > > +EOF
> > > > + exit 1
> > > > + fi
> > > > +
> > > > + # alpine (used in post-container requires the PATH to have /bin
> > > > + export PATH=$PATH:/bin
> > > > +
> > > > + if [[ "${debug_shell}" != "yes" ]]
> > > > + then
> > > > + touch ${OUTPUT_DIR}/${LOG_FILE}
> > > > + command="mount bpffs -t bpf /sys/fs/bpf/; set -o pipefail ;
> > > ${command} 2>&1 | tee ${OUTPUT_DIR}/${LOG_FILE}"
> > > > + post_command="cat ${OUTPUT_DIR}/${LOG_FILE}"
> > > > + else
> > > > + command="mount bpffs -t bpf /sys/fs/bpf/; ${command}"
> > > > + fi
> > > > +
> > > > + set +e
> > > > + $b2c --command "${command}" \
> > > > + --kernel ${kernel_bzimage} \
> > > > + --workdir ${OUTPUT_DIR} \
> > > > + --image ${CONTAINER_IMAGE}
> > > > +
> > > > + echo $? > ${OUTPUT_DIR}/${EXIT_STATUS_FILE}
> > > > +
> > > > + set -e
> > > > +
> > > > + ${post_command}
> > > > +}
> > > > +
> > > > +is_rel_path()
> > > > +{
> > > > + local path="$1"
> > > > +
> > > > + [[ ${path:0:1} != "/" ]]
> > > > +}
> > > > +
> > > > +do_update_kconfig()
> > > > +{
> > > > + local kernel_checkout="$1"
> > > > + local kconfig_file="$2"
> > > > +
> > > > + rm -f "$kconfig_file" 2> /dev/null
> > > > +
> > > > + for config in "${KCONFIG_REL_PATHS[@]}"; do
> > > > + local kconfig_src="${config}"
> > > > + cat "$kconfig_src" >> "$kconfig_file"
> > > > + done
> > > > +}
> > > > +
> > > > +update_kconfig()
> > > > +{
> > > > + local kernel_checkout="$1"
> > > > + local kconfig_file="$2"
> > > > +
> > > > + if [[ -f "${kconfig_file}" ]]; then
> > > > + local local_modified="$(stat -c %Y "${kconfig_file}")"
> > > > +
> > > > + for config in "${KCONFIG_REL_PATHS[@]}"; do
> > > > + local kconfig_src="${config}"
> > > > + local src_modified="$(stat -c %Y "${kconfig_src}")"
> > > > + # Only update the config if it has been updated after the
> > > > + # previously cached config was created. This avoids
> > > > + # unnecessarily compiling the kernel and selftests.
> > > > + if [[ "${src_modified}" -gt "${local_modified}" ]]; then
> > > > + do_update_kconfig "$kernel_checkout" "$kconfig_file"
> > > > + # Once we have found one outdated configuration
> > > > + # there is no need to check other ones.
> > > > + break
> > > > + fi
> > > > + done
> > > > + else
> > > > + do_update_kconfig "$kernel_checkout" "$kconfig_file"
> > > > + fi
> > > > +}
> > > > +
> > > > +main()
> > > > +{
> > > > + local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" &&
> > > pwd -P)"
> > > > + local kernel_checkout=$(realpath "${script_dir}"/../../../../)
> > > > + # By default the script searches for the kernel in the checkout
> > > directory but
> > > > + # it also obeys environment variables O= and KBUILD_OUTPUT=
> > > > + local kernel_bzimage="${kernel_checkout}/${BZIMAGE}"
> > > > + local command="${DEFAULT_COMMAND}"
> > > > + local update_b2c="no"
> > > > + local debug_shell="no"
> > > > +
> > > > + while getopts ':hsud:j:' opt; do
> > > > + case ${opt} in
> > > > + u)
> > > > + update_b2c="yes"
> > > > + ;;
> > > > + d)
> > > > + OUTPUT_DIR="$OPTARG"
> > > > + ;;
> > > > + j)
> > > > + NUM_COMPILE_JOBS="$OPTARG"
> > > > + ;;
> > > > + s)
> > > > + command="/bin/sh"
> > > > + debug_shell="yes"
> > > > + ;;
> > > > + h)
> > > > + usage
> > > > + exit 0
> > > > + ;;
> > > > + \? )
> > > > + echo "Invalid Option: -$OPTARG"
> > > > + usage
> > > > + exit 1
> > > > + ;;
> > > > + : )
> > > > + echo "Invalid Option: -$OPTARG requires an argument"
> > > > + usage
> > > > + exit 1
> > > > + ;;
> > > > + esac
> > > > + done
> > > > + shift $((OPTIND -1))
> > > > +
> > > > + # trap 'catch "$?"' EXIT
> > > > +
> > > > + if [[ "${debug_shell}" == "no" ]]; then
> > > > + if [[ $# -eq 0 ]]; then
> > > > + echo "No command specified, will run ${DEFAULT_COMMAND} in the vm"
> > > > + else
> > > > + command="$@"
> > > > +
> > > > + if [[ "${command}" == "/bin/bash" || "${command}" == "bash" ]]
> > > > + then
> > > > + debug_shell="yes"
> > > > + fi
> > > > + fi
> > > > + fi
> > > > +
> > > > + local kconfig_file="${OUTPUT_DIR}/latest.config"
> > > > + local make_command="make -j ${NUM_COMPILE_JOBS}
> > > KCONFIG_CONFIG=${kconfig_file}"
> > > > +
> > > > + # Figure out where the kernel is being built.
> > > > + # O takes precedence over KBUILD_OUTPUT.
> > > > + if [[ "${O:=""}" != "" ]]; then
> > > > + if is_rel_path "${O}"; then
> > > > + O="$(realpath "${PWD}/${O}")"
> > > > + fi
> > > > + kernel_bzimage="${O}/${BZIMAGE}"
> > > > + make_command="${make_command} O=${O}"
> > > > + elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then
> > > > + if is_rel_path "${KBUILD_OUTPUT}"; then
> > > > + KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")"
> > > > + fi
> > > > + kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}"
> > > > + make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}"
> > > > + fi
> > > > +
> > > > + local b2c="${OUTPUT_DIR}/vm2c.py"
> > > > +
> > > > + echo "Output directory: ${OUTPUT_DIR}"
> > > > +
> > > > + mkdir -p "${OUTPUT_DIR}"
> > > > + update_kconfig "${kernel_checkout}" "${kconfig_file}"
> > > > +
> > > > + recompile_kernel "${kernel_checkout}" "${make_command}"
> > > > +
> > > > + if [[ "${update_b2c}" == "no" && ! -f "${b2c}" ]]; then
> > > > + echo "vm2c script not found in ${b2c}"
> > > > + update_b2c="yes"
> > > > + fi
> > > > +
> > > > + if [[ "${update_b2c}" == "yes" ]]; then
> > > > + download $B2C_URL $b2c
> > > > + chmod +x $b2c
> > > > + fi
> > > > +
> > > > + update_selftests "${kernel_checkout}" "${make_command}"
> > > > + run_vm $b2c "${kernel_bzimage}" "${command}"
> > > > + if [[ "${debug_shell}" != "yes" ]]; then
> > > > + echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}"
> > > > + fi
> > > > +
> > > > + exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE})
> > > > +}
> > > > +
> > > > +main "$@"
> > > > --
> > > > 2.38.1
> > > >
> >
>
^ permalink raw reply
* [PATCH v6 RESEND] HID: multitouch: Add quirks for flipped axes
From: Allen Ballway @ 2023-01-10 20:25 UTC (permalink / raw)
To: ballway
Cc: benjamin.tissoires, dmitry.torokhov, dtor, jikos, linux-input,
linux-kernel, rydberg
In-Reply-To: <20221215172644.688044-1-ballway@chromium.org>
Certain touchscreen devices, such as the ELAN9034, are oriented
incorrectly and report touches on opposite points on the X and Y axes.
For example, a 100x200 screen touched at (10,20) would report (90, 180)
and vice versa.
This is fixed by adding device quirks to transform the touch points
into the correct spaces, from X -> MAX(X) - X, and Y -> MAX(Y) - Y.
Signed-off-by: Allen Ballway <ballway@chromium.org>
---
V5 -> V6: Add another IS_ENABLED check for CONFIG_I2C_DMI_CORE because
the module may not be there at all.
V4 -> V5: Add IS_ENABLED check for CONFIG_DMI to prevent linker error.
V3 -> V4: Move quirk logic to i2c_hid_get_dmi_quirks and remove
duplicate quirks from hid-multitouch.
V2 -> V3: Use existing HID_QUIRK_*_INVERT and match the quirk in
hid-quirk, passing down to hid-multitouch through the hid device.
V1 -> V2: Address review comments, change to use DMI match. Confirmed
MT_TOOL_X/Y require transformation and update orientation based on
flipped axes.
drivers/hid/hid-multitouch.c | 39 ++++++++++++++++++---
drivers/hid/hid-quirks.c | 6 ++++
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 43 ++++++++++++++++++++++++
drivers/hid/i2c-hid/i2c-hid.h | 3 ++
4 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 91a4d3fc30e08..622fe6928104c 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -71,6 +71,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_SEPARATE_APP_REPORT BIT(19)
#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20)
#define MT_QUIRK_DISABLE_WAKEUP BIT(21)
+#define MT_QUIRK_ORIENTATION_INVERT BIT(22)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -1009,6 +1010,7 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
struct mt_usages *slot)
{
struct input_mt *mt = input->mt;
+ struct hid_device *hdev = td->hdev;
__s32 quirks = app->quirks;
bool valid = true;
bool confidence_state = true;
@@ -1086,6 +1088,10 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
int orientation = wide;
int max_azimuth;
int azimuth;
+ int x;
+ int y;
+ int cx;
+ int cy;
if (slot->a != DEFAULT_ZERO) {
/*
@@ -1104,6 +1110,9 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
if (azimuth > max_azimuth * 2)
azimuth -= max_azimuth * 4;
orientation = -azimuth;
+ if (quirks & MT_QUIRK_ORIENTATION_INVERT)
+ orientation = -orientation;
+
}
if (quirks & MT_QUIRK_TOUCH_SIZE_SCALING) {
@@ -1115,10 +1124,23 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
minor = minor >> 1;
}
- input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y);
- input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx);
- input_event(input, EV_ABS, ABS_MT_TOOL_Y, *slot->cy);
+ x = hdev->quirks & HID_QUIRK_X_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_X) - *slot->x :
+ *slot->x;
+ y = hdev->quirks & HID_QUIRK_Y_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_Y) - *slot->y :
+ *slot->y;
+ cx = hdev->quirks & HID_QUIRK_X_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_X) - *slot->cx :
+ *slot->cx;
+ cy = hdev->quirks & HID_QUIRK_Y_INVERT ?
+ input_abs_get_max(input, ABS_MT_POSITION_Y) - *slot->cy :
+ *slot->cy;
+
+ input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
+ input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
+ input_event(input, EV_ABS, ABS_MT_TOOL_X, cx);
+ input_event(input, EV_ABS, ABS_MT_TOOL_Y, cy);
input_event(input, EV_ABS, ABS_MT_DISTANCE, !*slot->tip_state);
input_event(input, EV_ABS, ABS_MT_ORIENTATION, orientation);
input_event(input, EV_ABS, ABS_MT_PRESSURE, *slot->p);
@@ -1735,6 +1757,15 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
td->serial_maybe = true;
+
+ /* Orientation is inverted if the X or Y axes are
+ * flipped, but normalized if both are inverted.
+ */
+ if (hdev->quirks & (HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT) &&
+ !((hdev->quirks & HID_QUIRK_X_INVERT)
+ && (hdev->quirks & HID_QUIRK_Y_INVERT)))
+ td->mtclass.quirks = MT_QUIRK_ORIENTATION_INVERT;
+
/* This allows the driver to correctly support devices
* that emit events over several HID messages.
*/
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 0e9702c7f7d6c..78452faf3c9b4 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -19,6 +19,7 @@
#include <linux/input/elan-i2c-ids.h>
#include "hid-ids.h"
+#include "i2c-hid/i2c-hid.h"
/*
* Alphabetically sorted by vendor then product.
@@ -1298,6 +1299,11 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev)
quirks = hid_gets_squirk(hdev);
mutex_unlock(&dquirks_lock);
+ /* Get quirks specific to I2C devices */
+ if (IS_ENABLED(CONFIG_I2C_DMI_CORE) && IS_ENABLED(CONFIG_DMI) &&
+ hdev->bus == BUS_I2C)
+ quirks |= i2c_hid_get_dmi_quirks(hdev->vendor, hdev->product);
+
return quirks;
}
EXPORT_SYMBOL_GPL(hid_lookup_quirk);
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
index 8e0f67455c098..554a7dc285365 100644
--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -10,8 +10,10 @@
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/mod_devicetable.h>
+#include <linux/hid.h>
#include "i2c-hid.h"
+#include "../hid-ids.h"
struct i2c_hid_desc_override {
@@ -416,6 +418,28 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
{ } /* Terminate list */
};
+static const struct hid_device_id i2c_hid_elan_flipped_quirks = {
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd),
+ HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT
+};
+
+/*
+ * This list contains devices which have specific issues based on the system
+ * they're on and not just the device itself. The driver_data will have a
+ * specific hid device to match against.
+ */
+static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = {
+ {
+ .ident = "DynaBook K50/FR",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"),
+ },
+ .driver_data = (void *)&i2c_hid_elan_flipped_quirks,
+ },
+ { } /* Terminate list */
+};
+
struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
{
@@ -450,3 +474,22 @@ char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
*size = override->hid_report_desc_size;
return override->hid_report_desc;
}
+
+u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
+{
+ u32 quirks = 0;
+ const struct dmi_system_id *system_id =
+ dmi_first_match(i2c_hid_dmi_quirk_table);
+
+ if (system_id) {
+ const struct hid_device_id *device_id =
+ (struct hid_device_id *)(system_id->driver_data);
+
+ if (device_id && device_id->vendor == vendor &&
+ device_id->product == product)
+ quirks = device_id->driver_data;
+ }
+
+ return quirks;
+}
+EXPORT_SYMBOL_GPL(i2c_hid_get_dmi_quirks);
diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h
index 96c75510ad3f1..2c7b66d5caa0f 100644
--- a/drivers/hid/i2c-hid/i2c-hid.h
+++ b/drivers/hid/i2c-hid/i2c-hid.h
@@ -9,6 +9,7 @@
struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name);
char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
unsigned int *size);
+u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product);
#else
static inline struct i2c_hid_desc
*i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
@@ -16,6 +17,8 @@ static inline struct i2c_hid_desc
static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
unsigned int *size)
{ return NULL; }
+static inline u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
+{ return 0; }
#endif
/**
--
2.39.0.rc1.256.g54fd8350bd-goog
^ permalink raw reply related
* Re: [PATCH v2] HID: Recognize sensors with application collections too.
From: srinivas pandruvada @ 2023-01-10 22:16 UTC (permalink / raw)
To: Aditya Garg, Jiri Kosina, jkosina@suse.cz,
benjamin.tissoires@redhat.com, jic23@kernel.org,
linux-input@vger.kernel.org, LKML, linux-iio@vger.kernel.org
Cc: orlandoch.dev@gmail.com, ronald@innovation.ch
In-Reply-To: <EFCEA45A-C6F4-477A-B011-9C9E6E61E488@live.com>
Don't add full stop at the end.
HID: Recognize sensors with application collection
On Tue, 2023-01-10 at 08:57 +0000, Aditya Garg wrote:
> From: Ronald Tschalär <ronald@innovation.ch>
>
> According to HUTRR39 logical sensor devices may be nested inside
> physical collections or may be specified in multiple top-level
> application collections (see page 59, strategies 1 and 2). However,
> the current code was only recognizing those with physical
> collections.
>
> This issue turned up in the T2 MacBook Pro's which define the ALS in
> a top-level application collection.
>
> Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
> Signed-off-by: Aditya Garg <gargaditya08@live.com>
> —
> V2 :- Add missing signed-off-by
> drivers/hid/hid-core.c | 3 ++-
> drivers/hid/hid-sensor-hub.c | 6 ++++--
> 2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index b7f5566e338d..8fcd663b10e2 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -804,7 +804,8 @@ static void hid_scan_collection(struct hid_parser
> *parser, unsigned type)
> int i;
>
> if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
> - type == HID_COLLECTION_PHYSICAL)
> + (type == HID_COLLECTION_PHYSICAL ||
> + type == HID_COLLECTION_APPLICATION))
> hid->group = HID_GROUP_SENSOR_HUB;
>
> if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
> diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-
> hub.c
> index 6abd3e2a9094..d03dc4ca095f 100644
> --- a/drivers/hid/hid-sensor-hub.c
> +++ b/drivers/hid/hid-sensor-hub.c
> @@ -397,7 +397,8 @@ int sensor_hub_input_get_attribute_info(struct
> hid_sensor_hub_device *hsdev,
> for (i = 0; i < report->maxfield; ++i) {
> field = report->field[i];
> if (field->maxusage) {
> - if (field->physical == usage_id &&
> + if ((field->physical == usage_id ||
> + field->application == usage_id)
> &&
> (field->logical ==
> attr_usage_id ||
> field->usage[0].hid ==
> attr_usage_id
> ) &&
> @@ -506,7 +507,8 @@ static int sensor_hub_raw_event(struct hid_device
> *hdev,
> collection->usage);
>
> callback = sensor_hub_get_callback(hdev,
> - report->field[i]->physical,
> + report->field[i]->physical ?:
> + report->field[i]->application
Better not use language extensions. Simple to use
report->field[i]->physical ? report->field[i]->physical : report-
>field[i]->application
Otherwise patch is fine.
Thanks,
Srinivas
> ,
> report->field[i]-
> >usage[0].collection_index,
> &hsdev, &priv);
> if (!callback) {
> --
> 2.38.1
>
^ permalink raw reply
* Re: [PATCH 00/69] Input: Switch to DEFINE_SIMPLE_DEV_PM_OP() set 2
From: Dmitry Torokhov @ 2023-01-11 0:54 UTC (permalink / raw)
To: Jonathan Cameron
Cc: linux-input, Jonathan Cameron, Paul Cercueil, Roy Im,
Moritz Fischer, Luca Weiss, Jeff LaBundy, Krzysztof Kozlowski,
Geert Uytterhoeven, Stephen Boyd, Damien Riegel,
Lars-Peter Clausen, Pascal Paillet, Tony Lindgren, Raul E Rangel,
Hans de Goede, Michael Hennerich, Nicolas Ferre,
Alexandre Belloni, Claudiu Beznea, Heiko Stuebner, Linus Walleij,
Zhu Yi, Mark Jonas, Michael Trimarchi, Dario Binacchi,
Daniel Mack, Jonathan Neuschäfer, Douglas Anderson,
Bastien Nocera, Anthony Kim, Joe Hung, Markuss Broks, Haibo Chen,
Sangwon Jee, Vincent Knecht, Fabio Estevam, John Keeping,
Stephen Just, Benjamin Tissoires, Dario Binacchi,
Alistair Francis
In-Reply-To: <20230102181842.718010-1-jic23@kernel.org>
On Mon, Jan 02, 2023 at 06:17:33PM +0000, Jonathan Cameron wrote:
> From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> This 2nd set is a continuation from:
> https://lore.kernel.org/all/20221204180841.2211588-1-jic23@kernel.org/
>
> A 3rd set (maybe more than one) will cover the remaining more
> complex cases in Input that go beyond a straight forward switch.
> Those will need more careful review than this (hopefully) simple
> set.
>
> As part of recent changes to the macros in linux/pm.h, the
> SIMPLE_DEV_PM_OPS() macro is deprecated in favor of the combination
> of DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr().
> More details in the relevant commit message.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1a3c7bb088266fa2db017be299f91f1c1894c857
>
> The main advantage of the new versions is that they allow the compiler
> to 'see' the callbacks registered, thus avoiding the need to either
> protect them with ifdef guards or to mark them __maybe_unused.
> The compiler then removes the structure and the callbacks as dead code
> in event of !CONFIG_PM_SLEEP.
>
> Ultimately to clean up the old macros the change needs to be done to
> all instances of the SIMPLE_DEV_PM_OPS() in the kernel. There are similar
> changes to be done for runtime PM macros and more complex PM handling.
> This set is just meant to switch over some of the low hanging fruit in
> a bite sized chunk.
Applied the lot, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2 0/5] Miscellaneous fixes for Azoteq IQS269A
From: Dmitry Torokhov @ 2023-01-11 1:18 UTC (permalink / raw)
To: Jeff LaBundy; +Cc: linux-input
In-Reply-To: <Y7RsTqhYJOZs11sK@nixie71>
On Tue, Jan 03, 2023 at 11:56:30AM -0600, Jeff LaBundy wrote:
> This series comprises a handful of minor fixes that result from
> continued testing and updated guidance from the vendor.
>
> Jeff LaBundy (5):
> Input: iqs269a - drop unused device node references
> Input: iqs269a - increase interrupt handler return delay
> Input: iqs269a - configure device with a single block write
> Input: iqs269a - do not poll during suspend or resume
> Input: iqs269a - do not poll during ATI
>
> drivers/input/misc/iqs269a.c | 327 ++++++++++++++---------------------
> 1 file changed, 128 insertions(+), 199 deletions(-)
Applied the lot, thank you.
--
Dmitry
^ permalink raw reply
* [PATCH 2/2] HID: hid-steam: Add rumble on Deck
From: Vicki Pfau @ 2023-01-11 1:23 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau
In-Reply-To: <20230111012336.2915827-1-vi@endrift.com>
The Steam Deck includes a new report that allows for emulating XInput-style
rumble motors with the Deck's actuators. This adds support for passing these
values directly to the Deck.
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/hid/Kconfig | 8 ++++++
drivers/hid/hid-steam.c | 55 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e2a5d30c8895..e9de0a2d3cd3 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -1025,6 +1025,14 @@ config HID_STEAM
without running the Steam Client. It supports both the wired and
the wireless adaptor.
+config STEAM_FF
+ bool "Steam Deck force feedback support"
+ depends on HID_STEAM
+ select INPUT_FF_MEMLESS
+ help
+ Say Y here if you want to enable force feedback support for the Steam
+ Deck.
+
config HID_STEELSERIES
tristate "Steelseries SRW-S1 steering wheel support"
help
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index efd192d6c51a..788b5baaf145 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -91,6 +91,7 @@ static LIST_HEAD(steam_devices);
#define STEAM_CMD_FORCEFEEDBAK 0x8f
#define STEAM_CMD_REQUEST_COMM_STATUS 0xb4
#define STEAM_CMD_GET_SERIAL 0xae
+#define STEAM_CMD_HAPTIC_RUMBLE 0xeb
/* Some useful register ids */
#define STEAM_REG_LPAD_MODE 0x07
@@ -134,6 +135,9 @@ struct steam_device {
u8 battery_charge;
u16 voltage;
struct delayed_work heartbeat;
+ struct work_struct rumble_work;
+ u16 rumble_left;
+ u16 rumble_right;
};
static int steam_recv_report(struct steam_device *steam,
@@ -290,6 +294,45 @@ static inline int steam_request_conn_status(struct steam_device *steam)
return steam_send_report_byte(steam, STEAM_CMD_REQUEST_COMM_STATUS);
}
+static inline int steam_haptic_rumble(struct steam_device *steam,
+ u16 intensity, u16 left_speed, u16 right_speed,
+ u8 left_gain, u8 right_gain)
+{
+ u8 report[11] = {STEAM_CMD_HAPTIC_RUMBLE, 9};
+
+ report[3] = intensity & 0xFF;
+ report[4] = intensity >> 8;
+ report[5] = left_speed & 0xFF;
+ report[6] = left_speed >> 8;
+ report[7] = right_speed & 0xFF;
+ report[8] = right_speed >> 8;
+ report[9] = left_gain;
+ report[10] = right_gain;
+
+ return steam_send_report(steam, report, sizeof(report));
+}
+
+static void steam_haptic_rumble_cb(struct work_struct *work)
+{
+ struct steam_device *steam = container_of(work, struct steam_device,
+ rumble_work);
+ steam_haptic_rumble(steam, 0, steam->rumble_left,
+ steam->rumble_right, 2, 0);
+}
+
+#ifdef CONFIG_STEAM_FF
+static int steam_play_effect(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct steam_device *steam = input_get_drvdata(dev);
+
+ steam->rumble_left = effect->u.rumble.strong_magnitude;
+ steam->rumble_right = effect->u.rumble.weak_magnitude;
+
+ return schedule_work(&steam->rumble_work);
+}
+#endif
+
static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
{
if (enable) {
@@ -541,6 +584,15 @@ static int steam_input_register(struct steam_device *steam)
input_abs_set_res(input, ABS_HAT0X, STEAM_PAD_RESOLUTION);
input_abs_set_res(input, ABS_HAT0Y, STEAM_PAD_RESOLUTION);
+#ifdef CONFIG_STEAM_FF
+ if (steam->quirks & STEAM_QUIRK_DECK) {
+ input_set_capability(input, EV_FF, FF_RUMBLE);
+ ret = input_ff_create_memless(input, NULL, steam_play_effect);
+ if (ret)
+ goto init_ff_fail;
+ }
+#endif
+
ret = input_register_device(input);
if (ret)
goto input_register_fail;
@@ -549,6 +601,7 @@ static int steam_input_register(struct steam_device *steam)
return 0;
input_register_fail:
+init_ff_fail:
input_free_device(input);
return ret;
}
@@ -842,6 +895,7 @@ static int steam_probe(struct hid_device *hdev,
INIT_WORK(&steam->work_connect, steam_work_connect_cb);
INIT_LIST_HEAD(&steam->list);
INIT_DEFERRABLE_WORK(&steam->heartbeat, steam_lizard_mode_heartbeat);
+ INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb);
steam->client_hdev = steam_create_client_hid(hdev);
if (IS_ERR(steam->client_hdev)) {
@@ -898,6 +952,7 @@ static int steam_probe(struct hid_device *hdev,
client_hdev_fail:
cancel_work_sync(&steam->work_connect);
cancel_delayed_work_sync(&steam->heartbeat);
+ cancel_work_sync(&steam->rumble_work);
steam_alloc_fail:
hid_err(hdev, "%s: failed with error %d\n",
__func__, ret);
--
2.39.0
^ permalink raw reply related
* [PATCH 1/2] HID: hid-steam: Add Steam Deck support
From: Vicki Pfau @ 2023-01-11 1:23 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau
Add preliminary support for the Steam Deck's controller interface. Currently,
this only supports the controller inputs and toggling lizard mode. It does not
support any of the advanced features, such as the motion sensors or
force-feedback.
The Steam Deck also includes a heartbeat for lizard mode that switches it back
on if no reports have been received within a few milliseconds. The official
Steam client handles this by sending a handful of configuration reports every
few ms, so we copy this behavior by sending configuration reports to disable
the mouse and reset the digital mappings every 5ms. As this isn't needed for
the older Steam Controller, this is only done on the Steam Deck.
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-steam.c | 335 ++++++++++++++++++++++++++++++++++++----
2 files changed, 306 insertions(+), 30 deletions(-)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 82713ef3aaa6..33269113acc7 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1183,6 +1183,7 @@
#define USB_VENDOR_ID_VALVE 0x28de
#define USB_DEVICE_ID_STEAM_CONTROLLER 0x1102
#define USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS 0x1142
+#define USB_DEVICE_ID_STEAM_DECK 0x1205
#define USB_VENDOR_ID_STEELSERIES 0x1038
#define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 8ee43cb225fc..efd192d6c51a 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -3,6 +3,7 @@
* HID driver for Valve Steam Controller
*
* Copyright (c) 2018 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
+ * Copyright (c) 2022 Valve Software
*
* Supports both the wired and wireless interfaces.
*
@@ -53,6 +54,7 @@ static DEFINE_MUTEX(steam_devices_lock);
static LIST_HEAD(steam_devices);
#define STEAM_QUIRK_WIRELESS BIT(0)
+#define STEAM_QUIRK_DECK BIT(1)
/* Touch pads are 40 mm in diameter and 65535 units */
#define STEAM_PAD_RESOLUTION 1638
@@ -60,6 +62,10 @@ static LIST_HEAD(steam_devices);
#define STEAM_TRIGGER_RESOLUTION 51
/* Joystick runs are about 5 mm and 256 units */
#define STEAM_JOYSTICK_RESOLUTION 51
+/* Trigger runs are about 6 mm and 32768 units */
+#define STEAM_DECK_TRIGGER_RESOLUTION 5461
+/* Joystick runs are about 5 mm and 32768 units */
+#define STEAM_DECK_JOYSTICK_RESOLUTION 6553
#define STEAM_PAD_FUZZ 256
@@ -92,11 +98,14 @@ static LIST_HEAD(steam_devices);
#define STEAM_REG_RPAD_MARGIN 0x18
#define STEAM_REG_LED 0x2d
#define STEAM_REG_GYRO_MODE 0x30
+#define STEAM_REG_LPAD_CLICK_PRESSURE 0x34
+#define STEAM_REG_RPAD_CLICK_PRESSURE 0x35
/* Raw event identifiers */
#define STEAM_EV_INPUT_DATA 0x01
#define STEAM_EV_CONNECT 0x03
#define STEAM_EV_BATTERY 0x04
+#define STEAM_EV_DECK_INPUT_DATA 0x09
/* Values for GYRO_MODE (bitmask) */
#define STEAM_GYRO_MODE_OFF 0x0000
@@ -124,6 +133,7 @@ struct steam_device {
struct power_supply __rcu *battery;
u8 battery_charge;
u16 voltage;
+ struct delayed_work heartbeat;
};
static int steam_recv_report(struct steam_device *steam,
@@ -193,7 +203,7 @@ static int steam_send_report(struct steam_device *steam,
*/
do {
ret = hid_hw_raw_request(steam->hdev, 0,
- buf, size + 1,
+ buf, max(size, 64) + 1,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret != -EPIPE)
break;
@@ -219,6 +229,7 @@ static int steam_write_registers(struct steam_device *steam,
u8 reg;
u16 val;
u8 cmd[64] = {STEAM_CMD_WRITE_REGISTER, 0x00};
+ int ret;
va_list args;
va_start(args, steam);
@@ -234,7 +245,16 @@ static int steam_write_registers(struct steam_device *steam,
}
va_end(args);
- return steam_send_report(steam, cmd, 2 + cmd[1]);
+ ret = steam_send_report(steam, cmd, 2 + cmd[1]);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Sometimes a lingering report for this command can
+ * get read back instead of the last set report if
+ * this isn't explicitly queried
+ */
+ return steam_recv_report(steam, cmd, 2 + cmd[1]);
}
static int steam_get_serial(struct steam_device *steam)
@@ -280,13 +300,32 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
steam_write_registers(steam,
STEAM_REG_RPAD_MARGIN, 0x01, /* enable margin */
0);
+
+ cancel_delayed_work_sync(&steam->heartbeat);
} else {
/* disable esc, enter, cursor */
steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS);
- steam_write_registers(steam,
- STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */
- STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */
- 0);
+
+ if (steam->quirks & STEAM_QUIRK_DECK) {
+ steam_write_registers(steam,
+ STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */
+ STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */
+ STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */
+ STEAM_REG_LPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */
+ STEAM_REG_RPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */
+ 0);
+ /*
+ * The Steam Deck has a watchdog that automatically enables
+ * lizard mode if it doesn't see any traffic for too long
+ */
+ schedule_delayed_work(&steam->heartbeat, 5 * HZ);
+ } else {
+ steam_write_registers(steam,
+ STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */
+ STEAM_REG_LPAD_MODE, 0x07, /* disable mouse */
+ STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */
+ 0);
+ }
}
}
@@ -413,8 +452,8 @@ static int steam_input_register(struct steam_device *steam)
input->open = steam_input_open;
input->close = steam_input_close;
- input->name = (steam->quirks & STEAM_QUIRK_WIRELESS) ?
- "Wireless Steam Controller" :
+ input->name = (steam->quirks & STEAM_QUIRK_WIRELESS) ? "Wireless Steam Controller" :
+ (steam->quirks & STEAM_QUIRK_DECK) ? "Steam Deck" :
"Steam Controller";
input->phys = hdev->phys;
input->uniq = steam->serial_no;
@@ -438,33 +477,69 @@ static int steam_input_register(struct steam_device *steam)
input_set_capability(input, EV_KEY, BTN_SELECT);
input_set_capability(input, EV_KEY, BTN_MODE);
input_set_capability(input, EV_KEY, BTN_START);
- input_set_capability(input, EV_KEY, BTN_GEAR_DOWN);
- input_set_capability(input, EV_KEY, BTN_GEAR_UP);
input_set_capability(input, EV_KEY, BTN_THUMBR);
input_set_capability(input, EV_KEY, BTN_THUMBL);
input_set_capability(input, EV_KEY, BTN_THUMB);
input_set_capability(input, EV_KEY, BTN_THUMB2);
+ if (steam->quirks & STEAM_QUIRK_DECK) {
+ input_set_capability(input, EV_KEY, BTN_BASE);
+ input_set_capability(input, EV_KEY, BTN_TRIGGER_HAPPY1);
+ input_set_capability(input, EV_KEY, BTN_TRIGGER_HAPPY2);
+ input_set_capability(input, EV_KEY, BTN_TRIGGER_HAPPY3);
+ input_set_capability(input, EV_KEY, BTN_TRIGGER_HAPPY4);
+ } else {
+ input_set_capability(input, EV_KEY, BTN_GEAR_DOWN);
+ input_set_capability(input, EV_KEY, BTN_GEAR_UP);
+ }
- input_set_abs_params(input, ABS_HAT2Y, 0, 255, 0, 0);
- input_set_abs_params(input, ABS_HAT2X, 0, 255, 0, 0);
input_set_abs_params(input, ABS_X, -32767, 32767, 0, 0);
input_set_abs_params(input, ABS_Y, -32767, 32767, 0, 0);
- input_set_abs_params(input, ABS_RX, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_RY, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_abs_set_res(input, ABS_X, STEAM_JOYSTICK_RESOLUTION);
- input_abs_set_res(input, ABS_Y, STEAM_JOYSTICK_RESOLUTION);
- input_abs_set_res(input, ABS_RX, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_RY, STEAM_PAD_RESOLUTION);
+ if (steam->quirks & STEAM_QUIRK_DECK) {
+ input_set_abs_params(input, ABS_HAT2Y, 0, 32767, 0, 0);
+ input_set_abs_params(input, ABS_HAT2X, 0, 32767, 0, 0);
+
+ input_set_abs_params(input, ABS_RX, -32767, 32767, 0, 0);
+ input_set_abs_params(input, ABS_RY, -32767, 32767, 0, 0);
+
+ input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT1X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT1Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+
+ input_abs_set_res(input, ABS_X, STEAM_DECK_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_Y, STEAM_DECK_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RX, STEAM_DECK_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RY, STEAM_DECK_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT1X, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT1Y, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2Y, STEAM_DECK_TRIGGER_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2X, STEAM_DECK_TRIGGER_RESOLUTION);
+ } else {
+ input_set_abs_params(input, ABS_HAT2Y, 0, 255, 0, 0);
+ input_set_abs_params(input, ABS_HAT2X, 0, 255, 0, 0);
+
+ input_set_abs_params(input, ABS_RX, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_RY, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+
+ input_abs_set_res(input, ABS_X, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_Y, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RX, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_RY, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2Y, STEAM_TRIGGER_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2X, STEAM_TRIGGER_RESOLUTION);
+ }
input_abs_set_res(input, ABS_HAT0X, STEAM_PAD_RESOLUTION);
input_abs_set_res(input, ABS_HAT0Y, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_HAT2Y, STEAM_TRIGGER_RESOLUTION);
- input_abs_set_res(input, ABS_HAT2X, STEAM_TRIGGER_RESOLUTION);
ret = input_register_device(input);
if (ret)
@@ -612,6 +687,22 @@ static bool steam_is_valve_interface(struct hid_device *hdev)
return !list_empty(&rep_enum->report_list);
}
+static void steam_lizard_mode_heartbeat(struct work_struct *work)
+{
+ struct steam_device *steam = container_of(work, struct steam_device,
+ heartbeat.work);
+
+ mutex_lock(&steam->mutex);
+ if (!steam->client_opened) {
+ steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS);
+ steam_write_registers(steam,
+ STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */
+ 0);
+ schedule_delayed_work(&steam->heartbeat, 5 * HZ);
+ }
+ mutex_unlock(&steam->mutex);
+}
+
static int steam_client_ll_parse(struct hid_device *hdev)
{
struct steam_device *steam = hdev->driver_data;
@@ -750,6 +841,7 @@ static int steam_probe(struct hid_device *hdev,
steam->quirks = id->driver_data;
INIT_WORK(&steam->work_connect, steam_work_connect_cb);
INIT_LIST_HEAD(&steam->list);
+ INIT_DEFERRABLE_WORK(&steam->heartbeat, steam_lizard_mode_heartbeat);
steam->client_hdev = steam_create_client_hid(hdev);
if (IS_ERR(steam->client_hdev)) {
@@ -805,6 +897,7 @@ static int steam_probe(struct hid_device *hdev,
hid_destroy_device(steam->client_hdev);
client_hdev_fail:
cancel_work_sync(&steam->work_connect);
+ cancel_delayed_work_sync(&steam->heartbeat);
steam_alloc_fail:
hid_err(hdev, "%s: failed with error %d\n",
__func__, ret);
@@ -823,6 +916,7 @@ static void steam_remove(struct hid_device *hdev)
hid_destroy_device(steam->client_hdev);
steam->client_opened = false;
cancel_work_sync(&steam->work_connect);
+ cancel_delayed_work_sync(&steam->heartbeat);
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
hid_info(hdev, "Steam wireless receiver disconnected");
}
@@ -906,10 +1000,10 @@ static inline s16 steam_le16(u8 *data)
* 8.5 | BTN_B | button B
* 8.6 | BTN_X | button X
* 8.7 | BTN_A | button A
- * 9.0 | BTN_DPAD_UP | lef-pad up
- * 9.1 | BTN_DPAD_RIGHT | lef-pad right
- * 9.2 | BTN_DPAD_LEFT | lef-pad left
- * 9.3 | BTN_DPAD_DOWN | lef-pad down
+ * 9.0 | BTN_DPAD_UP | left-pad up
+ * 9.1 | BTN_DPAD_RIGHT | left-pad right
+ * 9.2 | BTN_DPAD_LEFT | left-pad left
+ * 9.3 | BTN_DPAD_DOWN | left-pad down
* 9.4 | BTN_SELECT | menu left
* 9.5 | BTN_MODE | steam logo
* 9.6 | BTN_START | menu right
@@ -993,6 +1087,172 @@ static void steam_do_input_event(struct steam_device *steam,
input_sync(input);
}
+/*
+ * The size for this message payload is 56.
+ * The known values are:
+ * Offset| Type | Mapped to |Meaning
+ * -------+-------+-----------+--------------------------
+ * 4-7 | u32 | -- | sequence number
+ * 8-15 | u64 | see below | buttons
+ * 16-17 | s16 | ABS_HAT0X | left-pad X value
+ * 18-19 | s16 | ABS_HAT0Y | left-pad Y value
+ * 20-21 | s16 | ABS_HAT1X | right-pad X value
+ * 22-23 | s16 | ABS_HAT1Y | right-pad Y value
+ * 24-25 | s16 | -- | accelerometer X value
+ * 26-27 | s16 | -- | accelerometer Y value
+ * 28-29 | s16 | -- | accelerometer Z value
+ * 30-31 | s16 | -- | gyro X value
+ * 32-33 | s16 | -- | gyro Y value
+ * 34-35 | s16 | -- | gyro Z value
+ * 36-37 | s16 | -- | quaternion W value
+ * 38-39 | s16 | -- | quaternion X value
+ * 40-41 | s16 | -- | quaternion Y value
+ * 42-43 | s16 | -- | quaternion Z value
+ * 44-45 | u16 | ABS_HAT2Y | left trigger (uncalibrated)
+ * 46-47 | u16 | ABS_HAT2X | right trigger (uncalibrated)
+ * 48-49 | s16 | ABS_X | left joystick X
+ * 50-51 | s16 | ABS_Y | left joystick Y
+ * 52-53 | s16 | ABS_RX | right joystick X
+ * 54-55 | s16 | ABS_RY | right joystick Y
+ * 56-57 | u16 | -- | left pad pressure
+ * 58-59 | u16 | -- | right pad pressure
+ *
+ * The buttons are:
+ * Bit | Mapped to | Description
+ * ------+------------+--------------------------------
+ * 8.0 | BTN_TR2 | right trigger fully pressed
+ * 8.1 | BTN_TL2 | left trigger fully pressed
+ * 8.2 | BTN_TR | right shoulder
+ * 8.3 | BTN_TL | left shoulder
+ * 8.4 | BTN_Y | button Y
+ * 8.5 | BTN_B | button B
+ * 8.6 | BTN_X | button X
+ * 8.7 | BTN_A | button A
+ * 9.0 | BTN_DPAD_UP | left-pad up
+ * 9.1 | BTN_DPAD_RIGHT | left-pad right
+ * 9.2 | BTN_DPAD_LEFT | left-pad left
+ * 9.3 | BTN_DPAD_DOWN | left-pad down
+ * 9.4 | BTN_SELECT | menu left
+ * 9.5 | BTN_MODE | steam logo
+ * 9.6 | BTN_START | menu right
+ * 9.7 | BTN_TRIGGER_HAPPY3 | left bottom grip button
+ * 10.0 | BTN_TRIGGER_HAPPY4 | right bottom grip button
+ * 10.1 | BTN_THUMB | left pad pressed
+ * 10.2 | BTN_THUMB2 | right pad pressed
+ * 10.3 | -- | left pad touched
+ * 10.4 | -- | right pad touched
+ * 10.5 | -- | unknown
+ * 10.6 | BTN_THUMBL | left joystick clicked
+ * 10.7 | -- | unknown
+ * 11.0 | -- | unknown
+ * 11.1 | -- | unknown
+ * 11.2 | BTN_THUMBR | right joystick clicked
+ * 11.3 | -- | unknown
+ * 11.4 | -- | unknown
+ * 11.5 | -- | unknown
+ * 11.6 | -- | unknown
+ * 11.7 | -- | unknown
+ * 12.0 | -- | unknown
+ * 12.1 | -- | unknown
+ * 12.2 | -- | unknown
+ * 12.3 | -- | unknown
+ * 12.4 | -- | unknown
+ * 12.5 | -- | unknown
+ * 12.6 | -- | unknown
+ * 12.7 | -- | unknown
+ * 13.0 | -- | unknown
+ * 13.1 | BTN_TRIGGER_HAPPY1 | left top grip button
+ * 13.2 | BTN_TRIGGER_HAPPY2 | right top grip button
+ * 13.3 | -- | unknown
+ * 13.4 | -- | unknown
+ * 13.5 | -- | unknown
+ * 13.6 | -- | left joystick touched
+ * 13.7 | -- | right joystick touched
+ * 14.0 | -- | unknown
+ * 14.1 | -- | unknown
+ * 14.2 | BTN_BASE | quick access button
+ * 14.3 | -- | unknown
+ * 14.4 | -- | unknown
+ * 14.5 | -- | unknown
+ * 14.6 | -- | unknown
+ * 14.7 | -- | unknown
+ * 15.0 | -- | unknown
+ * 15.1 | -- | unknown
+ * 15.2 | -- | unknown
+ * 15.3 | -- | unknown
+ * 15.4 | -- | unknown
+ * 15.5 | -- | unknown
+ * 15.6 | -- | unknown
+ * 15.7 | -- | unknown
+ */
+static void steam_do_deck_input_event(struct steam_device *steam,
+ struct input_dev *input, u8 *data)
+{
+ u8 b8, b9, b10, b11, b13, b14;
+ bool lpad_touched, rpad_touched;
+
+ b8 = data[8];
+ b9 = data[9];
+ b10 = data[10];
+ b11 = data[11];
+ b13 = data[13];
+ b14 = data[14];
+
+ lpad_touched = b10 & BIT(3);
+ rpad_touched = b10 & BIT(4);
+
+ if (lpad_touched) {
+ input_report_abs(input, ABS_HAT0X, steam_le16(data + 16));
+ input_report_abs(input, ABS_HAT0Y, steam_le16(data + 18));
+ } else {
+ input_report_abs(input, ABS_HAT0X, 0);
+ input_report_abs(input, ABS_HAT0Y, 0);
+ }
+
+ if (rpad_touched) {
+ input_report_abs(input, ABS_HAT1X, steam_le16(data + 20));
+ input_report_abs(input, ABS_HAT1Y, steam_le16(data + 22));
+ } else {
+ input_report_abs(input, ABS_HAT1X, 0);
+ input_report_abs(input, ABS_HAT1Y, 0);
+ }
+
+ input_report_abs(input, ABS_X, steam_le16(data + 48));
+ input_report_abs(input, ABS_Y, -steam_le16(data + 50));
+ input_report_abs(input, ABS_RX, steam_le16(data + 52));
+ input_report_abs(input, ABS_RY, -steam_le16(data + 54));
+
+ input_report_abs(input, ABS_HAT2Y, steam_le16(data + 44));
+ input_report_abs(input, ABS_HAT2X, steam_le16(data + 46));
+
+ input_event(input, EV_KEY, BTN_TR2, !!(b8 & BIT(0)));
+ input_event(input, EV_KEY, BTN_TL2, !!(b8 & BIT(1)));
+ input_event(input, EV_KEY, BTN_TR, !!(b8 & BIT(2)));
+ input_event(input, EV_KEY, BTN_TL, !!(b8 & BIT(3)));
+ input_event(input, EV_KEY, BTN_Y, !!(b8 & BIT(4)));
+ input_event(input, EV_KEY, BTN_B, !!(b8 & BIT(5)));
+ input_event(input, EV_KEY, BTN_X, !!(b8 & BIT(6)));
+ input_event(input, EV_KEY, BTN_A, !!(b8 & BIT(7)));
+ input_event(input, EV_KEY, BTN_SELECT, !!(b9 & BIT(4)));
+ input_event(input, EV_KEY, BTN_MODE, !!(b9 & BIT(5)));
+ input_event(input, EV_KEY, BTN_START, !!(b9 & BIT(6)));
+ input_event(input, EV_KEY, BTN_TRIGGER_HAPPY3, !!(b9 & BIT(7)));
+ input_event(input, EV_KEY, BTN_TRIGGER_HAPPY4, !!(b10 & BIT(0)));
+ input_event(input, EV_KEY, BTN_THUMBL, !!(b10 & BIT(6)));
+ input_event(input, EV_KEY, BTN_THUMBR, !!(b11 & BIT(2)));
+ input_event(input, EV_KEY, BTN_DPAD_UP, !!(b9 & BIT(0)));
+ input_event(input, EV_KEY, BTN_DPAD_RIGHT, !!(b9 & BIT(1)));
+ input_event(input, EV_KEY, BTN_DPAD_LEFT, !!(b9 & BIT(2)));
+ input_event(input, EV_KEY, BTN_DPAD_DOWN, !!(b9 & BIT(3)));
+ input_event(input, EV_KEY, BTN_THUMB, !!(b10 & BIT(1)));
+ input_event(input, EV_KEY, BTN_THUMB2, !!(b10 & BIT(2)));
+ input_event(input, EV_KEY, BTN_TRIGGER_HAPPY1, !!(b13 & BIT(1)));
+ input_event(input, EV_KEY, BTN_TRIGGER_HAPPY2, !!(b13 & BIT(2)));
+ input_event(input, EV_KEY, BTN_BASE, !!(b14 & BIT(2)));
+
+ input_sync(input);
+}
+
/*
* The size for this message payload is 11.
* The known values are:
@@ -1052,6 +1312,7 @@ static int steam_raw_event(struct hid_device *hdev,
* 0x01: input data (60 bytes)
* 0x03: wireless connect/disconnect (1 byte)
* 0x04: battery status (11 bytes)
+ * 0x09: Steam Deck input data (56 bytes)
*/
if (size != 64 || data[0] != 1 || data[1] != 0)
@@ -1067,6 +1328,15 @@ static int steam_raw_event(struct hid_device *hdev,
steam_do_input_event(steam, input, data);
rcu_read_unlock();
break;
+ case STEAM_EV_DECK_INPUT_DATA:
+ if (steam->client_opened)
+ return 0;
+ rcu_read_lock();
+ input = rcu_dereference(steam->input);
+ if (likely(input))
+ steam_do_deck_input_event(steam, input, data);
+ rcu_read_unlock();
+ break;
case STEAM_EV_CONNECT:
/*
* The payload of this event is a single byte:
@@ -1141,6 +1411,11 @@ static const struct hid_device_id steam_controllers[] = {
USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS),
.driver_data = STEAM_QUIRK_WIRELESS
},
+ { /* Steam Deck */
+ HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
+ USB_DEVICE_ID_STEAM_DECK),
+ .driver_data = STEAM_QUIRK_DECK
+ },
{}
};
--
2.39.0
^ permalink raw reply related
* Re: [PATCH] Input: i8042 - add Clevo PCX0DX to i8042 quirk table
From: Dmitry Torokhov @ 2023-01-11 3:42 UTC (permalink / raw)
To: Werner Sembach
Cc: hdegoede, mkorpershoek, chenhuacai, tiwai, wsa+renesas,
linux-input, linux-kernel
In-Reply-To: <20230110134524.553620-1-wse@tuxedocomputers.com>
On Tue, Jan 10, 2023 at 02:45:24PM +0100, Werner Sembach wrote:
> The Clevo PCX0DX/TUXEDO XP1511, need quirks for the keyboard to not be
> occasionally unresponsive after resume.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> Cc: stable@vger.kernel.org
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH HID for-next v1 6/9] HID: bpf: rework how programs are attached and stored in the kernel
From: Alexei Starovoitov @ 2023-01-11 6:10 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Greg KH, Jiri Kosina, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Dmitry Torokhov, Tero Kristo, linux-kernel,
linux-input, netdev, bpf, linux-kselftest
In-Reply-To: <20230106102332.1019632-7-benjamin.tissoires@redhat.com>
On Fri, Jan 06, 2023 at 11:23:29AM +0100, Benjamin Tissoires wrote:
>
> +static void hid_bpf_link_release(struct bpf_link *link)
> +{
> + struct hid_bpf_link *hid_link =
> + container_of(link, struct hid_bpf_link, link);
> +
> + __clear_bit(hid_link->index, jmp_table.enabled);
> + schedule_work(&release_work);
> +}
...
> + link->index = prog_idx;
I was super confused that you use prog_idx as a bit in jmp_table
and had to look into your tree what hid_bpf_jmp_table.c is doing.
Looks like it's not prog_id (which is prog->aux->id) that we know.
It's hid specific prog idx in that jmp table.
Maybe would be good to rename your prog_idx to something with 'hid' suffix or prefix?
or 'table' suffix or prefix ?
prog_table_idx ?
Other than that the patch set looking great.
I'm assuming removing call_hid_bpf_prog_put_deferred() and everything related
comes in the next set?
^ permalink raw reply
* Re: [PATCH HID for-next v1 6/9] HID: bpf: rework how programs are attached and stored in the kernel
From: Benjamin Tissoires @ 2023-01-11 9:47 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Greg KH, Jiri Kosina, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Dmitry Torokhov, Tero Kristo, linux-kernel,
linux-input, netdev, bpf, linux-kselftest
In-Reply-To: <20230111061054.dqduab66plb6uzg2@macbook-pro-6.dhcp.thefacebook.com>
On Wed, Jan 11, 2023 at 7:11 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Jan 06, 2023 at 11:23:29AM +0100, Benjamin Tissoires wrote:
> >
> > +static void hid_bpf_link_release(struct bpf_link *link)
> > +{
> > + struct hid_bpf_link *hid_link =
> > + container_of(link, struct hid_bpf_link, link);
> > +
> > + __clear_bit(hid_link->index, jmp_table.enabled);
> > + schedule_work(&release_work);
> > +}
>
> ...
>
> > + link->index = prog_idx;
>
> I was super confused that you use prog_idx as a bit in jmp_table
> and had to look into your tree what hid_bpf_jmp_table.c is doing.
> Looks like it's not prog_id (which is prog->aux->id) that we know.
> It's hid specific prog idx in that jmp table.
> Maybe would be good to rename your prog_idx to something with 'hid' suffix or prefix?
> or 'table' suffix or prefix ?
> prog_table_idx ?
prog_table_idx sounds good :)
>
> Other than that the patch set looking great.
great, thanks!
> I'm assuming removing call_hid_bpf_prog_put_deferred() and everything related
> comes in the next set?
>
Yep. I'll probably send it tomorrow. I have a bunch of urgent
corporate stuff to do today so won't have time for the fun part of the
job :(
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: input: microchip,cap11xx: add cap1203, cap1293 and cap1298
From: Krzysztof Kozlowski @ 2023-01-11 9:49 UTC (permalink / raw)
To: Jiri Valek - 2N, linux-input
Cc: devicetree, dmitry.torokhov, krzysztof.kozlowski+dt, linux-kernel,
robh+dt, u.kleine-koenig
In-Reply-To: <20230110152859.295881-2-jiriv@axis.com>
On 10/01/2023 16:28, Jiri Valek - 2N wrote:
> Add support for cap1203, cap1293 and cap1298.
>
> Signed-off-by: Jiri Valek - 2N <jiriv@axis.com>
> ---
> No changes since v1
>
Really?
This is a friendly reminder during the review process.
It seems my previous comments were not fully addressed. Maybe my
feedback got lost between the quotes, maybe you just forgot to apply it.
Please go back to the previous discussion and either implement all
requested changes or keep discussing them.
Thank you.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 3/5] driver core: make struct device_type.uevent() take a const *
From: Greg Kroah-Hartman @ 2023-01-11 9:51 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: linux-kernel, Jens Axboe, Len Brown, Stefan Richter, Wolfram Sang,
Alexandre Belloni, Dmitry Torokhov, Sean Young,
Mauro Carvalho Chehab, Rob Herring, Frank Rowand, Maximilian Luz,
Hans de Goede, Mark Gross, Vinod Koul, Bard Liao,
Pierre-Louis Bossart, Sanyog Kale, Andreas Noever, Michael Jamet,
Mika Westerberg, Yehezkel Bernat, Jiri Slaby, Heikki Krogerus,
Matthew Wilcox (Oracle), Martin K. Petersen, Chaitanya Kulkarni,
Ming Lei, Jilin Yuan, Alan Stern, Andy Shevchenko, Sakari Ailus,
Jason Gunthorpe, Thomas Gleixner, Ira Weiny, Dan Williams,
Won Chung, alsa-devel, devicetree, linux-acpi, linux-block,
linux-i2c, linux-i3c, linux-input, linux-media, linux-serial,
linux-usb, linux1394-devel, platform-driver-x86
In-Reply-To: <CAJZ5v0gqD_TW3iGLAiH=us1B0-JLGtv2VGTJjQwiWxCmris9ag@mail.gmail.com>
On Wed, Nov 23, 2022 at 01:38:05PM +0100, Rafael J. Wysocki wrote:
> On Wed, Nov 23, 2022 at 1:25 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > The uevent() callback in struct device_type should not be modifying the
> > device that is passed into it, so mark it as a const * and propagate the
> > function signature changes out into all relevant subsystems that use
> > this callback.
> >
> > Cc: Jens Axboe <axboe@kernel.dk>
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Cc: Len Brown <lenb@kernel.org>
> > Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
> > Cc: Wolfram Sang <wsa@kernel.org>
> > Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> > Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > Cc: Sean Young <sean@mess.org>
> > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Frank Rowand <frowand.list@gmail.com>
> > Cc: Maximilian Luz <luzmaximilian@gmail.com>
> > Cc: Hans de Goede <hdegoede@redhat.com>
> > Cc: Mark Gross <markgross@kernel.org>
> > Cc: Vinod Koul <vkoul@kernel.org>
> > Cc: Bard Liao <yung-chuan.liao@linux.intel.com>
> > Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > Cc: Sanyog Kale <sanyog.r.kale@intel.com>
> > Cc: Andreas Noever <andreas.noever@gmail.com>
> > Cc: Michael Jamet <michael.jamet@intel.com>
> > Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Cc: Yehezkel Bernat <YehezkelShB@gmail.com>
> > Cc: Jiri Slaby <jirislaby@kernel.org>
> > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> > Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
> > Cc: Chaitanya Kulkarni <kch@nvidia.com>
> > Cc: Ming Lei <ming.lei@redhat.com>
> > Cc: Jilin Yuan <yuanjilin@cdjrlc.com>
> > Cc: Alan Stern <stern@rowland.harvard.edu>
> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
> > Cc: Jason Gunthorpe <jgg@ziepe.ca>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Ira Weiny <ira.weiny@intel.com>
> > Cc: Dan Williams <dan.j.williams@intel.com>
> > Cc: Won Chung <wonchung@google.com>
> > Cc: alsa-devel@alsa-project.org
> > Cc: devicetree@vger.kernel.org
> > Cc: linux-acpi@vger.kernel.org
> > Cc: linux-block@vger.kernel.org
> > Cc: linux-i2c@vger.kernel.org
> > Cc: linux-i3c@lists.infradead.org
> > Cc: linux-input@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-media@vger.kernel.org
> > Cc: linux-serial@vger.kernel.org
> > Cc: linux-usb@vger.kernel.org
> > Cc: linux1394-devel@lists.sourceforge.net
> > Cc: platform-driver-x86@vger.kernel.org
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> (which my ACPI maintainer hat on).
thanks for the review, I'll add it to the v2 patch.
greg k-h
^ permalink raw reply
* Re: [PATCH 3/5] driver core: make struct device_type.uevent() take a const *
From: Greg Kroah-Hartman @ 2023-01-11 9:52 UTC (permalink / raw)
To: Mika Westerberg
Cc: linux-kernel, Jens Axboe, Rafael J. Wysocki, Len Brown,
Stefan Richter, Wolfram Sang, Alexandre Belloni, Dmitry Torokhov,
Sean Young, Mauro Carvalho Chehab, Rob Herring, Frank Rowand,
Maximilian Luz, Hans de Goede, Mark Gross, Vinod Koul, Bard Liao,
Pierre-Louis Bossart, Sanyog Kale, Andreas Noever, Michael Jamet,
Yehezkel Bernat, Jiri Slaby, Heikki Krogerus,
Matthew Wilcox (Oracle), Martin K. Petersen, Chaitanya Kulkarni,
Ming Lei, Jilin Yuan, Alan Stern, Andy Shevchenko, Sakari Ailus,
Jason Gunthorpe, Thomas Gleixner, Ira Weiny, Dan Williams,
Won Chung, alsa-devel, devicetree, linux-acpi, linux-block,
linux-i2c, linux-i3c, linux-input, linux-media, linux-serial,
linux-usb, linux1394-devel, platform-driver-x86
In-Reply-To: <Y34mpkqds3NEZclU@black.fi.intel.com>
On Wed, Nov 23, 2022 at 03:56:54PM +0200, Mika Westerberg wrote:
> On Wed, Nov 23, 2022 at 01:25:21PM +0100, Greg Kroah-Hartman wrote:
> > The uevent() callback in struct device_type should not be modifying the
> > device that is passed into it, so mark it as a const * and propagate the
> > function signature changes out into all relevant subsystems that use
> > this callback.
> >
> > Cc: Jens Axboe <axboe@kernel.dk>
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Cc: Len Brown <lenb@kernel.org>
> > Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
> > Cc: Wolfram Sang <wsa@kernel.org>
> > Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> > Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > Cc: Sean Young <sean@mess.org>
> > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Frank Rowand <frowand.list@gmail.com>
> > Cc: Maximilian Luz <luzmaximilian@gmail.com>
> > Cc: Hans de Goede <hdegoede@redhat.com>
> > Cc: Mark Gross <markgross@kernel.org>
> > Cc: Vinod Koul <vkoul@kernel.org>
> > Cc: Bard Liao <yung-chuan.liao@linux.intel.com>
> > Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > Cc: Sanyog Kale <sanyog.r.kale@intel.com>
> > Cc: Andreas Noever <andreas.noever@gmail.com>
> > Cc: Michael Jamet <michael.jamet@intel.com>
> > Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
>
> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> # for Thunderbolt
Thanks for the review.
^ permalink raw reply
* Re: [PATCH 3/5] driver core: make struct device_type.uevent() take a const *
From: Greg Kroah-Hartman @ 2023-01-11 9:52 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: linux-kernel, Jens Axboe, Rafael J. Wysocki, Len Brown,
Stefan Richter, Wolfram Sang, Alexandre Belloni, Dmitry Torokhov,
Sean Young, Rob Herring, Frank Rowand, Maximilian Luz,
Hans de Goede, Mark Gross, Vinod Koul, Bard Liao,
Pierre-Louis Bossart, Sanyog Kale, Andreas Noever, Michael Jamet,
Mika Westerberg, Yehezkel Bernat, Jiri Slaby, Heikki Krogerus,
Matthew Wilcox (Oracle), Martin K. Petersen, Chaitanya Kulkarni,
Ming Lei, Jilin Yuan, Alan Stern, Andy Shevchenko, Sakari Ailus,
Jason Gunthorpe, Thomas Gleixner, Ira Weiny, Dan Williams,
Won Chung, alsa-devel, devicetree, linux-acpi, linux-block,
linux-i2c, linux-i3c, linux-input, linux-media, linux-serial,
linux-usb, linux1394-devel, platform-driver-x86
In-Reply-To: <20221125115618.14ef8167@sal.lan>
On Fri, Nov 25, 2022 at 11:56:18AM +0000, Mauro Carvalho Chehab wrote:
> Em Wed, 23 Nov 2022 13:25:21 +0100
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> escreveu:
>
> > The uevent() callback in struct device_type should not be modifying the
> > device that is passed into it, so mark it as a const * and propagate the
> > function signature changes out into all relevant subsystems that use
> > this callback.
>
> Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Thanks for the review.
^ permalink raw reply
* Re: [PATCH v2] HID: Recognize sensors with application collections too.
From: Aditya Garg @ 2023-01-11 10:06 UTC (permalink / raw)
To: srinivas pandruvada
Cc: Jiri Kosina, jkosina@suse.cz, benjamin.tissoires@redhat.com,
jic23@kernel.org, linux-input@vger.kernel.org, LKML,
linux-iio@vger.kernel.org, orlandoch.dev@gmail.com,
ronald@innovation.ch
In-Reply-To: <74fbf0eb19ebdb964397d8f8d9b5fc12a06128cf.camel@linux.intel.com>
> On 11-Jan-2023, at 3:46 AM, srinivas pandruvada <srinivas.pandruvada@linux.intel.com> wrote:
>
>
> Don't add full stop at the end.
>
> HID: Recognize sensors with application collection
>
> Better not use language extensions. Simple to use
>
> report->field[i]->physical ? report->field[i]->physical : report-
>> field[i]->application
>
>
Sending a v3 with the changes.
^ permalink raw reply
* [PATCH v3] HID: Recognize sensors with application collections
From: Aditya Garg @ 2023-01-11 10:07 UTC (permalink / raw)
To: Jiri Kosina, jkosina@suse.cz, benjamin.tissoires@redhat.com,
jic23@kernel.org, srinivas.pandruvada@linux.intel.com,
linux-input@vger.kernel.org, LKML, linux-iio@vger.kernel.org
Cc: orlandoch.dev@gmail.com, ronald@innovation.ch
In-Reply-To: <EFCEA45A-C6F4-477A-B011-9C9E6E61E488@live.com>
From: Ronald Tschalär <ronald@innovation.ch>
According to HUTRR39 logical sensor devices may be nested inside
physical collections or may be specified in multiple top-level
application collections (see page 59, strategies 1 and 2). However,
the current code was only recognizing those with physical collections.
This issue turned up in the T2 MacBook Pros which define the ALS in
a top-level application collection.
Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
V2 :- Add missing signed-off-by
V3 :- Avoid using language extensions
drivers/hid/hid-core.c | 3 ++-
drivers/hid/hid-sensor-hub.c | 6 ++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index bd47628da..8ff08e6c2 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -804,7 +804,8 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
int i;
if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
- type == HID_COLLECTION_PHYSICAL)
+ (type == HID_COLLECTION_PHYSICAL ||
+ type == HID_COLLECTION_APPLICATION))
hid->group = HID_GROUP_SENSOR_HUB;
if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 6abd3e2a9..83237b86c 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -397,7 +397,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
for (i = 0; i < report->maxfield; ++i) {
field = report->field[i];
if (field->maxusage) {
- if (field->physical == usage_id &&
+ if ((field->physical == usage_id ||
+ field->application == usage_id) &&
(field->logical == attr_usage_id ||
field->usage[0].hid ==
attr_usage_id) &&
@@ -506,7 +507,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
collection->usage);
callback = sensor_hub_get_callback(hdev,
- report->field[i]->physical,
+ report->field[i]->physical ? report->field[i]->physical :
+ report->field[i]->application,
report->field[i]->usage[0].collection_index,
&hsdev, &priv);
if (!callback) {
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox