Input updates for v6.15-rc7
- even more Xbox controllers added to xpad driver: Turtle Beach Recon Wired Controller, Turtle Beach Stealth Ultra, and PowerA Wired Controller - a fix to Synaptics RMI driver to not crash if controller reports unsupported version of F34 (firmware flash) function. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQST2eWILY88ieB2DOtAj56VGEWXnAUCaDJzrQAKCRBAj56VGEWX nJLwAP4zeNCtEIMex8lAmVcLe9smcHuin+kEAKeIwTY3Y3VhKgD9G46WKFz2Ft3A Zc1CVi333GiMNlt0iiW+n+oQAYRPHAk= =X3Z5 -----END PGP SIGNATURE----- Merge tag 'input-for-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input Pull input fixes from Dmitry Torokhov: - even more Xbox controllers added to xpad driver: Turtle Beach Recon Wired Controller, Turtle Beach Stealth Ultra, and PowerA Wired Controller - a fix to Synaptics RMI driver to not crash if controller reports unsupported version of F34 (firmware flash) function * tag 'input-for-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: synaptics-rmi - fix crash with unsupported versions of F34 Input: xpad - add more controllers
This commit is contained in:
commit
d0c22de999
2 changed files with 78 additions and 58 deletions
|
@ -290,6 +290,8 @@ static const struct xpad_device {
|
|||
{ 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
||||
{ 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
|
||||
{ 0x10f5, 0x7005, "Turtle Beach Recon Controller", 0, XTYPE_XBOXONE },
|
||||
{ 0x10f5, 0x7008, "Turtle Beach Recon Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
||||
{ 0x10f5, 0x7073, "Turtle Beach Stealth Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
||||
{ 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
|
||||
{ 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 },
|
||||
{ 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
|
||||
|
@ -354,6 +356,7 @@ static const struct xpad_device {
|
|||
{ 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
|
||||
{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
|
||||
{ 0x20d6, 0x400b, "PowerA FUSION Pro 4 Wired Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
||||
{ 0x20d6, 0x890b, "PowerA MOGA XP-Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (C) 2016 Zodiac Inflight Innovations
|
||||
*/
|
||||
|
||||
#include "linux/device.h"
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/rmi.h>
|
||||
#include <linux/firmware.h>
|
||||
|
@ -289,39 +290,30 @@ static int rmi_f34_update_firmware(struct f34_data *f34,
|
|||
return rmi_f34_flash_firmware(f34, syn_fw);
|
||||
}
|
||||
|
||||
static int rmi_f34_status(struct rmi_function *fn)
|
||||
{
|
||||
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
||||
|
||||
/*
|
||||
* The status is the percentage complete, or once complete,
|
||||
* zero for success or a negative return code.
|
||||
*/
|
||||
return f34->update_status;
|
||||
}
|
||||
|
||||
static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct rmi_function *fn = data->f34_container;
|
||||
struct rmi_function *fn;
|
||||
struct f34_data *f34;
|
||||
|
||||
if (fn) {
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
fn = data->f34_container;
|
||||
if (!fn)
|
||||
return -ENODEV;
|
||||
|
||||
if (f34->bl_version == 5)
|
||||
return sysfs_emit(buf, "%c%c\n",
|
||||
f34->bootloader_id[0],
|
||||
f34->bootloader_id[1]);
|
||||
else
|
||||
return sysfs_emit(buf, "V%d.%d\n",
|
||||
f34->bootloader_id[1],
|
||||
f34->bootloader_id[0]);
|
||||
}
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
if (!f34)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
if (f34->bl_version == 5)
|
||||
return sysfs_emit(buf, "%c%c\n",
|
||||
f34->bootloader_id[0],
|
||||
f34->bootloader_id[1]);
|
||||
else
|
||||
return sysfs_emit(buf, "V%d.%d\n",
|
||||
f34->bootloader_id[1],
|
||||
f34->bootloader_id[0]);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
|
||||
|
@ -334,13 +326,16 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev,
|
|||
struct rmi_function *fn = data->f34_container;
|
||||
struct f34_data *f34;
|
||||
|
||||
if (fn) {
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
fn = data->f34_container;
|
||||
if (!fn)
|
||||
return -ENODEV;
|
||||
|
||||
return sysfs_emit(buf, "%s\n", f34->configuration_id);
|
||||
}
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
if (!f34)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
|
||||
return sysfs_emit(buf, "%s\n", f34->configuration_id);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(configuration_id, 0444,
|
||||
|
@ -356,10 +351,14 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
|
|||
|
||||
if (!data->f34_container) {
|
||||
dev_warn(dev, "%s: No F34 present!\n", __func__);
|
||||
return -EINVAL;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
f34 = dev_get_drvdata(&data->f34_container->dev);
|
||||
if (!f34) {
|
||||
dev_warn(dev, "%s: No valid F34 present!\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (f34->bl_version >= 7) {
|
||||
if (data->pdt_props & HAS_BSR) {
|
||||
|
@ -485,10 +484,18 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
int update_status = 0;
|
||||
struct f34_data *f34;
|
||||
int update_status = -ENODEV;
|
||||
|
||||
if (data->f34_container)
|
||||
update_status = rmi_f34_status(data->f34_container);
|
||||
/*
|
||||
* The status is the percentage complete, or once complete,
|
||||
* zero for success or a negative return code.
|
||||
*/
|
||||
if (data->f34_container) {
|
||||
f34 = dev_get_drvdata(&data->f34_container->dev);
|
||||
if (f34)
|
||||
update_status = f34->update_status;
|
||||
}
|
||||
|
||||
return sysfs_emit(buf, "%d\n", update_status);
|
||||
}
|
||||
|
@ -508,33 +515,21 @@ static const struct attribute_group rmi_firmware_attr_group = {
|
|||
.attrs = rmi_firmware_attrs,
|
||||
};
|
||||
|
||||
static int rmi_f34_probe(struct rmi_function *fn)
|
||||
static int rmi_f34v5_probe(struct f34_data *f34)
|
||||
{
|
||||
struct f34_data *f34;
|
||||
unsigned char f34_queries[9];
|
||||
struct rmi_function *fn = f34->fn;
|
||||
u8 f34_queries[9];
|
||||
bool has_config_id;
|
||||
u8 version = fn->fd.function_version;
|
||||
int ret;
|
||||
|
||||
f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
|
||||
if (!f34)
|
||||
return -ENOMEM;
|
||||
|
||||
f34->fn = fn;
|
||||
dev_set_drvdata(&fn->dev, f34);
|
||||
|
||||
/* v5 code only supported version 0, try V7 probe */
|
||||
if (version > 0)
|
||||
return rmi_f34v7_probe(f34);
|
||||
int error;
|
||||
|
||||
f34->bl_version = 5;
|
||||
|
||||
ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
|
||||
f34_queries, sizeof(f34_queries));
|
||||
if (ret) {
|
||||
error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
|
||||
f34_queries, sizeof(f34_queries));
|
||||
if (error) {
|
||||
dev_err(&fn->dev, "%s: Failed to query properties\n",
|
||||
__func__);
|
||||
return ret;
|
||||
return error;
|
||||
}
|
||||
|
||||
snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
|
||||
|
@ -560,11 +555,11 @@ static int rmi_f34_probe(struct rmi_function *fn)
|
|||
f34->v5.config_blocks);
|
||||
|
||||
if (has_config_id) {
|
||||
ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
|
||||
f34_queries, sizeof(f34_queries));
|
||||
if (ret) {
|
||||
error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
|
||||
f34_queries, sizeof(f34_queries));
|
||||
if (error) {
|
||||
dev_err(&fn->dev, "Failed to read F34 config ID\n");
|
||||
return ret;
|
||||
return error;
|
||||
}
|
||||
|
||||
snprintf(f34->configuration_id, sizeof(f34->configuration_id),
|
||||
|
@ -573,12 +568,34 @@ static int rmi_f34_probe(struct rmi_function *fn)
|
|||
f34_queries[2], f34_queries[3]);
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n",
|
||||
f34->configuration_id);
|
||||
f34->configuration_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f34_probe(struct rmi_function *fn)
|
||||
{
|
||||
struct f34_data *f34;
|
||||
u8 version = fn->fd.function_version;
|
||||
int error;
|
||||
|
||||
f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
|
||||
if (!f34)
|
||||
return -ENOMEM;
|
||||
|
||||
f34->fn = fn;
|
||||
|
||||
/* v5 code only supported version 0 */
|
||||
error = version == 0 ? rmi_f34v5_probe(f34) : rmi_f34v7_probe(f34);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
dev_set_drvdata(&fn->dev, f34);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
|
||||
{
|
||||
return sysfs_create_group(&rmi_dev->dev.kobj, &rmi_firmware_attr_group);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue