hid-for-linus-2024031301
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIVAwUAZfIL8qZi849r7WBJAQLR8g/9Hm98IBegxv9cnAEt2Kq5Ge071GxTHRLG T6EHdwttmWmZmMPEBeXE/PGWcMDi1GG7RpAbAMHW7NE4urgJ1ehn/s7Eet8hxuh6 0iZwbNBph3Jwa1TobyKDuIbX1Z9e6x2TLNZqHhzmppW2NSbMamN9SiOGcR3c9PJy q39cG6aAw0cHRpqQ/7n2s8Ixi+Cg79Q9H9BfEOG3q2OTwYYFqpUyPMQy0b0NIISg /RCC8MuEGwSrGCusZlFzMHudF4sBLTHMNaAkgZdHxtmP6V3jtLyv/jTJiafwwSDq fQ49sCfkO88NLOPo/8RkrRxUwQSDCQhn89bV2Mnsk4n9m4u1gvrnvZz1mXh8orAc YvtHJdP8UUHpTFMqFhRgIMBkRwRUVG0XRYMSwlzPKXnpPGt1tx9br1S1KvauhCiw zexY64DMNF9bO8AF4f4Ic0adGlWk8jz0Ith8QTkGDTyNRVPrX96u/pfYZvUD4BJF Xxb4War5be2oYQWT23vjadHKXpmVwD3bCfd1enY+ODYBEG8XKbbTHU8FyHND1A9v zrk3xH6dMVVXFdchrA4WNWsZJ+MmC9dRpmVyBUzVq3r+F/R1wKPCeuVRHUAFnuIu uHB7FY+KO8aNqN9Yd0TUkSS15YgrFEeIa/rF/FMunG1HUtI/n0lXqFbVlZ8RTSDY 9cu2HJNLKWI= =+55b -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2024031301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID updates from Jiri Kosina: - support for the following Bluetooth devices from Samsung: Samsung wireless {Keyboard, GamePad, Action Mouse, Book Cover, Universal Keyboard, HOGP Keyboard} (Sandeep C S) - second version of code for applying proper quirk depending on firmware version for lenovo/cptkbd (Mikhail Khvainitski) - lenovo/cptkbd firmware-dependent quirk (Mikhail Khvainitski) - assorted fixes and optimizations for amd-sfh (Basavaraj Natikar) - dead code and dead data structures removal (Jiri Slaby, Jiapeng Chong) * tag 'hid-for-linus-2024031301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (25 commits) HID: amd_sfh: Set the AMD SFH driver to depend on x86 HID: input: avoid polling stylus battery on Chromebook Pompom HID: amd_sfh: Extend MP2 register access to SFH HID: amd_sfh: Improve boot time when SFH is available HID: amd_sfh: Avoid disabling the interrupt HID: amd_sfh: Update HPD sensor structure elements HID: amd_sfh: Increase sensor command timeout HID: intel-ish-hid: ipc: Add Arrow Lake PCI device ID HID: nintendo: Remove some unused functions HID: hid-prodikeys: remove struct pk_device HID: hid-prodikeys: remove unused struct pcmidi_snd members HID: hid-multitouch: remove unused mt_application::dev_time HID: hid-lg3ff: remove unused struct lg3ff_device HID: protect hid_device::bpf by CONFIG_HID_BPF HID: wacom: remove unused hid_data::pressure HID: apple: remove unused members from struct apple_sc_backlight HID: wacom: Clean up use of struct->wacom_wac HID: samsung: Add Samsung wireless bookcover and universal keyboard support HID: samsung: Add Samsung wireless action mouse support HID: samsung: Add Samsung wireless gamepad support ...
This commit is contained in:
commit
3e78a6c0d3
@ -6,6 +6,7 @@ menu "AMD SFH HID Support"
|
||||
config AMD_SFH_HID
|
||||
tristate "AMD Sensor Fusion Hub"
|
||||
depends on HID
|
||||
depends on X86
|
||||
help
|
||||
If you say yes to this option, support will be included for the
|
||||
AMD Sensor Fusion Hub.
|
||||
|
@ -19,6 +19,9 @@
|
||||
#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
|
||||
#define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
|
||||
|
||||
#define AMD_C2P_MSG_V1(regno) (0x10900 + ((regno) * 4))
|
||||
#define AMD_P2C_MSG_V1(regno) (0x10500 + ((regno) * 4))
|
||||
|
||||
#define SENSOR_ENABLED 4
|
||||
#define SENSOR_DISABLED 5
|
||||
|
||||
@ -53,6 +56,9 @@ struct amd_mp2_dev {
|
||||
/* mp2 active control status */
|
||||
u32 mp2_acs;
|
||||
struct sfh_dev_status dev_en;
|
||||
struct work_struct work;
|
||||
u8 init_done;
|
||||
u8 rver;
|
||||
};
|
||||
|
||||
struct amd_mp2_ops {
|
||||
@ -79,4 +85,14 @@ void amd_sfh_clear_intr_v2(struct amd_mp2_dev *privdata);
|
||||
int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata);
|
||||
void amd_sfh_clear_intr(struct amd_mp2_dev *privdata);
|
||||
int amd_sfh_irq_init(struct amd_mp2_dev *privdata);
|
||||
|
||||
static inline u64 amd_get_c2p_val(struct amd_mp2_dev *mp2, u32 idx)
|
||||
{
|
||||
return mp2->rver == 1 ? AMD_C2P_MSG_V1(idx) : AMD_C2P_MSG(idx);
|
||||
}
|
||||
|
||||
static inline u64 amd_get_p2c_val(struct amd_mp2_dev *mp2, u32 idx)
|
||||
{
|
||||
return mp2->rver == 1 ? AMD_P2C_MSG_V1(idx) : AMD_P2C_MSG(idx);
|
||||
}
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/devm-helpers.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -35,15 +36,17 @@ static int sensor_mask_override = -1;
|
||||
module_param_named(sensor_mask, sensor_mask_override, int, 0444);
|
||||
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
|
||||
|
||||
static bool intr_disable = true;
|
||||
|
||||
static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
|
||||
{
|
||||
union cmd_response cmd_resp;
|
||||
|
||||
/* Get response with status within a max of 1600 ms timeout */
|
||||
/* Get response with status within a max of 10 seconds timeout */
|
||||
if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
|
||||
(cmd_resp.response_v2.response == sensor_sts &&
|
||||
cmd_resp.response_v2.status == 0 && (sid == 0xff ||
|
||||
cmd_resp.response_v2.sensor_id == sid)), 500, 1600000))
|
||||
cmd_resp.response_v2.sensor_id == sid)), 500, 10000000))
|
||||
return cmd_resp.response_v2.response;
|
||||
|
||||
return SENSOR_DISABLED;
|
||||
@ -55,7 +58,7 @@ static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sen
|
||||
|
||||
cmd_base.ul = 0;
|
||||
cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR;
|
||||
cmd_base.cmd_v2.intr_disable = 1;
|
||||
cmd_base.cmd_v2.intr_disable = intr_disable;
|
||||
cmd_base.cmd_v2.period = info.period;
|
||||
cmd_base.cmd_v2.sensor_id = info.sensor_idx;
|
||||
cmd_base.cmd_v2.length = 16;
|
||||
@ -73,7 +76,7 @@ static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx)
|
||||
|
||||
cmd_base.ul = 0;
|
||||
cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR;
|
||||
cmd_base.cmd_v2.intr_disable = 1;
|
||||
cmd_base.cmd_v2.intr_disable = intr_disable;
|
||||
cmd_base.cmd_v2.period = 0;
|
||||
cmd_base.cmd_v2.sensor_id = sensor_idx;
|
||||
cmd_base.cmd_v2.length = 16;
|
||||
@ -87,7 +90,7 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
|
||||
union sfh_cmd_base cmd_base;
|
||||
|
||||
cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS;
|
||||
cmd_base.cmd_v2.intr_disable = 1;
|
||||
cmd_base.cmd_v2.intr_disable = intr_disable;
|
||||
cmd_base.cmd_v2.period = 0;
|
||||
cmd_base.cmd_v2.sensor_id = 0;
|
||||
|
||||
@ -96,9 +99,9 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
|
||||
|
||||
void amd_sfh_clear_intr_v2(struct amd_mp2_dev *privdata)
|
||||
{
|
||||
if (readl(privdata->mmio + AMD_P2C_MSG(4))) {
|
||||
writel(0, privdata->mmio + AMD_P2C_MSG(4));
|
||||
writel(0xf, privdata->mmio + AMD_P2C_MSG(5));
|
||||
if (readl(privdata->mmio + amd_get_p2c_val(privdata, 4))) {
|
||||
writel(0, privdata->mmio + amd_get_p2c_val(privdata, 4));
|
||||
writel(0xf, privdata->mmio + amd_get_p2c_val(privdata, 5));
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,6 +295,26 @@ int amd_sfh_irq_init(struct amd_mp2_dev *privdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp2_disable_intr(const struct dmi_system_id *id)
|
||||
{
|
||||
intr_disable = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id dmi_sfh_table[] = {
|
||||
{
|
||||
/*
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=218104
|
||||
*/
|
||||
.callback = mp2_disable_intr,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct dmi_system_id dmi_nodevs[] = {
|
||||
{
|
||||
/*
|
||||
@ -307,6 +330,48 @@ static const struct dmi_system_id dmi_nodevs[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static void sfh1_1_init_work(struct work_struct *work)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work);
|
||||
struct pci_dev *pdev = mp2->pdev;
|
||||
int rc;
|
||||
|
||||
rc = mp2->sfh1_1_ops->init(mp2);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "sfh1_1_init failed err %d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
amd_sfh_clear_intr(mp2);
|
||||
mp2->init_done = 1;
|
||||
}
|
||||
|
||||
static void sfh_init_work(struct work_struct *work)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work);
|
||||
struct pci_dev *pdev = mp2->pdev;
|
||||
int rc;
|
||||
|
||||
rc = amd_sfh_hid_client_init(mp2);
|
||||
if (rc) {
|
||||
amd_sfh_clear_intr(mp2);
|
||||
dev_err(&pdev->dev, "amd_sfh_hid_client_init failed err %d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
amd_sfh_clear_intr(mp2);
|
||||
mp2->init_done = 1;
|
||||
}
|
||||
|
||||
static void amd_sfh_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
|
||||
|
||||
flush_work(&mp2->work);
|
||||
if (mp2->init_done)
|
||||
mp2->mp2_ops->remove(mp2);
|
||||
}
|
||||
|
||||
static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct amd_mp2_dev *privdata;
|
||||
@ -315,6 +380,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
||||
if (dmi_first_match(dmi_nodevs))
|
||||
return -ENODEV;
|
||||
|
||||
dmi_check_system(dmi_sfh_table);
|
||||
|
||||
privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL);
|
||||
if (!privdata)
|
||||
return -ENOMEM;
|
||||
@ -343,10 +410,15 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
||||
|
||||
privdata->sfh1_1_ops = (const struct amd_sfh1_1_ops *)id->driver_data;
|
||||
if (privdata->sfh1_1_ops) {
|
||||
rc = privdata->sfh1_1_ops->init(privdata);
|
||||
if (boot_cpu_data.x86 >= 0x1A)
|
||||
privdata->rver = 1;
|
||||
|
||||
rc = devm_work_autocancel(&pdev->dev, &privdata->work, sfh1_1_init_work);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto init_done;
|
||||
|
||||
schedule_work(&privdata->work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mp2_select_ops(privdata);
|
||||
@ -357,33 +429,34 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = amd_sfh_hid_client_init(privdata);
|
||||
rc = devm_work_autocancel(&pdev->dev, &privdata->work, sfh_init_work);
|
||||
if (rc) {
|
||||
amd_sfh_clear_intr(privdata);
|
||||
if (rc != -EOPNOTSUPP)
|
||||
dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
init_done:
|
||||
amd_sfh_clear_intr(privdata);
|
||||
|
||||
return devm_add_action_or_reset(&pdev->dev, privdata->mp2_ops->remove, privdata);
|
||||
schedule_work(&privdata->work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amd_sfh_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
|
||||
|
||||
if (mp2 && mp2->mp2_ops)
|
||||
mp2->mp2_ops->stop_all(mp2);
|
||||
if (mp2) {
|
||||
flush_work(&mp2->work);
|
||||
if (mp2->init_done)
|
||||
mp2->mp2_ops->stop_all(mp2);
|
||||
}
|
||||
}
|
||||
|
||||
static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
|
||||
|
||||
mp2->mp2_ops->resume(mp2);
|
||||
flush_work(&mp2->work);
|
||||
if (mp2->init_done)
|
||||
mp2->mp2_ops->resume(mp2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -392,7 +465,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
|
||||
|
||||
mp2->mp2_ops->suspend(mp2);
|
||||
flush_work(&mp2->work);
|
||||
if (mp2->init_done)
|
||||
mp2->mp2_ops->suspend(mp2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -414,6 +489,7 @@ static struct pci_driver amd_mp2_pci_driver = {
|
||||
.probe = amd_mp2_pci_probe,
|
||||
.driver.pm = &amd_mp2_pm_ops,
|
||||
.shutdown = amd_sfh_shutdown,
|
||||
.remove = amd_sfh_remove,
|
||||
};
|
||||
module_pci_driver(amd_mp2_pci_driver);
|
||||
|
||||
|
@ -90,10 +90,10 @@ enum mem_use_type {
|
||||
struct hpd_status {
|
||||
union {
|
||||
struct {
|
||||
u32 human_presence_report : 4;
|
||||
u32 human_presence_actual : 4;
|
||||
u32 probablity : 8;
|
||||
u32 object_distance : 16;
|
||||
u32 probablity : 8;
|
||||
u32 human_presence_actual : 4;
|
||||
u32 human_presence_report : 4;
|
||||
} shpd;
|
||||
u32 val;
|
||||
};
|
||||
|
@ -251,7 +251,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id,
|
||||
break;
|
||||
case HPD_IDX:
|
||||
get_common_inputs(&hpd_input.common_property, report_id);
|
||||
hpdstatus.val = readl(mp2->mmio + AMD_C2P_MSG(4));
|
||||
hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4));
|
||||
hpd_input.human_presence = hpdstatus.shpd.presence;
|
||||
report_size = sizeof(hpd_input);
|
||||
memcpy(input_report, &hpd_input, sizeof(hpd_input));
|
||||
|
@ -172,7 +172,7 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
|
||||
if (rc)
|
||||
goto cleanup;
|
||||
|
||||
writel(0, privdata->mmio + AMD_P2C_MSG(0));
|
||||
writel(0, privdata->mmio + amd_get_p2c_val(privdata, 0));
|
||||
mp2_ops->start(privdata, info);
|
||||
status = amd_sfh_wait_for_response
|
||||
(privdata, cl_data->sensor_idx[i], ENABLE_SENSOR);
|
||||
@ -298,7 +298,7 @@ static void amd_sfh_set_ops(struct amd_mp2_dev *mp2)
|
||||
|
||||
int amd_sfh1_1_init(struct amd_mp2_dev *mp2)
|
||||
{
|
||||
u32 phy_base = readl(mp2->mmio + AMD_C2P_MSG(22));
|
||||
u32 phy_base = readl(mp2->mmio + amd_get_c2p_val(mp2, 22));
|
||||
struct device *dev = &mp2->pdev->dev;
|
||||
struct sfh_base_info binfo;
|
||||
int rc;
|
||||
|
@ -20,7 +20,7 @@ static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
|
||||
struct sfh_cmd_response cmd_resp;
|
||||
|
||||
/* Get response with status within a max of 10000 ms timeout */
|
||||
if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
|
||||
if (!readl_poll_timeout(mp2->mmio + amd_get_p2c_val(mp2, 0), cmd_resp.resp,
|
||||
(cmd_resp.response.response == 0 &&
|
||||
cmd_resp.response.cmd_id == cmd_id && (sid == 0xff ||
|
||||
cmd_resp.response.sensor_id == sid)), 500, 10000000))
|
||||
@ -39,7 +39,7 @@ static void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor
|
||||
cmd_base.cmd.sub_cmd_value = 1;
|
||||
cmd_base.cmd.sensor_id = info.sensor_idx;
|
||||
|
||||
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
|
||||
writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
|
||||
}
|
||||
|
||||
static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
|
||||
@ -52,8 +52,8 @@ static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
|
||||
cmd_base.cmd.sub_cmd_value = 1;
|
||||
cmd_base.cmd.sensor_id = sensor_idx;
|
||||
|
||||
writeq(0x0, privdata->mmio + AMD_C2P_MSG(1));
|
||||
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
|
||||
writeq(0x0, privdata->mmio + amd_get_c2p_val(privdata, 1));
|
||||
writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
|
||||
}
|
||||
|
||||
static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
|
||||
@ -66,7 +66,7 @@ static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
|
||||
/* 0xf indicates all sensors */
|
||||
cmd_base.cmd.sensor_id = 0xf;
|
||||
|
||||
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
|
||||
writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
|
||||
}
|
||||
|
||||
static struct amd_mp2_ops amd_sfh_ops = {
|
||||
|
@ -79,7 +79,6 @@ struct apple_non_apple_keyboard {
|
||||
struct apple_sc_backlight {
|
||||
struct led_classdev cdev;
|
||||
struct hid_device *hdev;
|
||||
unsigned short backlight_off, backlight_on_min, backlight_on_max;
|
||||
};
|
||||
|
||||
struct apple_sc {
|
||||
|
@ -430,6 +430,7 @@
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1 0x2BED
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2 0x2BEE
|
||||
#define I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG 0x2D02
|
||||
#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81
|
||||
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
|
||||
@ -1146,8 +1147,15 @@
|
||||
#define USB_DEVICE_ID_SAITEK_X65 0x0b6a
|
||||
|
||||
#define USB_VENDOR_ID_SAMSUNG 0x0419
|
||||
#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS 0x04e8
|
||||
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD 0x7021
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD 0xa000
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE 0xa004
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER 0xa005
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006
|
||||
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064
|
||||
|
||||
#define USB_VENDOR_ID_SEMICO 0x1a2c
|
||||
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023
|
||||
|
@ -411,6 +411,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM),
|
||||
HID_BATTERY_QUIRK_AVOID_QUERY },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -54,10 +54,10 @@ struct lenovo_drvdata {
|
||||
/* 0: Up
|
||||
* 1: Down (undecided)
|
||||
* 2: Scrolling
|
||||
* 3: Patched firmware, disable workaround
|
||||
*/
|
||||
u8 middlebutton_state;
|
||||
bool fn_lock;
|
||||
bool middleclick_workaround_cptkbd;
|
||||
};
|
||||
|
||||
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||
@ -621,6 +621,36 @@ static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n",
|
||||
cptkbd_data->middleclick_workaround_cptkbd);
|
||||
}
|
||||
|
||||
static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
|
||||
int value;
|
||||
|
||||
if (kstrtoint(buf, 10, &value))
|
||||
return -EINVAL;
|
||||
if (value < 0 || value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
cptkbd_data->middleclick_workaround_cptkbd = !!value;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static struct device_attribute dev_attr_fn_lock =
|
||||
__ATTR(fn_lock, S_IWUSR | S_IRUGO,
|
||||
@ -632,10 +662,16 @@ static struct device_attribute dev_attr_sensitivity_cptkbd =
|
||||
attr_sensitivity_show_cptkbd,
|
||||
attr_sensitivity_store_cptkbd);
|
||||
|
||||
static struct device_attribute dev_attr_middleclick_workaround_cptkbd =
|
||||
__ATTR(middleclick_workaround, S_IWUSR | S_IRUGO,
|
||||
attr_middleclick_workaround_show_cptkbd,
|
||||
attr_middleclick_workaround_store_cptkbd);
|
||||
|
||||
|
||||
static struct attribute *lenovo_attributes_cptkbd[] = {
|
||||
&dev_attr_fn_lock.attr,
|
||||
&dev_attr_sensitivity_cptkbd.attr,
|
||||
&dev_attr_middleclick_workaround_cptkbd.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -686,23 +722,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
|
||||
{
|
||||
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
|
||||
|
||||
if (cptkbd_data->middlebutton_state != 3) {
|
||||
/* REL_X and REL_Y events during middle button pressed
|
||||
* are only possible on patched, bug-free firmware
|
||||
* so set middlebutton_state to 3
|
||||
* to never apply workaround anymore
|
||||
*/
|
||||
if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD &&
|
||||
cptkbd_data->middlebutton_state == 1 &&
|
||||
usage->type == EV_REL &&
|
||||
(usage->code == REL_X || usage->code == REL_Y)) {
|
||||
cptkbd_data->middlebutton_state = 3;
|
||||
/* send middle button press which was hold before */
|
||||
input_event(field->hidinput->input,
|
||||
EV_KEY, BTN_MIDDLE, 1);
|
||||
input_sync(field->hidinput->input);
|
||||
}
|
||||
|
||||
if (cptkbd_data->middleclick_workaround_cptkbd) {
|
||||
/* "wheel" scroll events */
|
||||
if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
|
||||
usage->code == REL_HWHEEL)) {
|
||||
@ -1166,6 +1186,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
|
||||
cptkbd_data->middlebutton_state = 0;
|
||||
cptkbd_data->fn_lock = true;
|
||||
cptkbd_data->sensitivity = 0x05;
|
||||
cptkbd_data->middleclick_workaround_cptkbd = true;
|
||||
lenovo_features_set_cptkbd(hdev);
|
||||
|
||||
ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
|
||||
|
@ -41,10 +41,6 @@
|
||||
* I'm sure these are effects that I don't know enough about them
|
||||
*/
|
||||
|
||||
struct lg3ff_device {
|
||||
struct hid_report *report;
|
||||
};
|
||||
|
||||
static int hid_lg3ff_play(struct input_dev *dev, void *data,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
|
@ -130,7 +130,6 @@ struct mt_application {
|
||||
* > 1 means hybrid (multitouch) protocol
|
||||
*/
|
||||
|
||||
__s32 dev_time; /* the scan time provided by the device */
|
||||
unsigned long jiffies; /* the frame's jiffies */
|
||||
int timestamp; /* the timestamp to be sent */
|
||||
int prev_scantime; /* scantime reported previously */
|
||||
|
@ -667,16 +667,6 @@ struct joycon_ctlr {
|
||||
* These helpers are most useful early during the HID probe or in conjunction
|
||||
* with the capability helpers below.
|
||||
*/
|
||||
static inline bool joycon_device_is_left_joycon(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return ctlr->hdev->product == USB_DEVICE_ID_NINTENDO_JOYCONL;
|
||||
}
|
||||
|
||||
static inline bool joycon_device_is_right_joycon(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return ctlr->hdev->product == USB_DEVICE_ID_NINTENDO_JOYCONR;
|
||||
}
|
||||
|
||||
static inline bool joycon_device_is_procon(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return ctlr->hdev->product == USB_DEVICE_ID_NINTENDO_PROCON;
|
||||
@ -764,18 +754,6 @@ static inline bool joycon_type_is_right_nescon(struct joycon_ctlr *ctlr)
|
||||
return ctlr->ctlr_type == JOYCON_CTLR_TYPE_NESR;
|
||||
}
|
||||
|
||||
static inline bool joycon_type_has_left_controls(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return joycon_type_is_left_joycon(ctlr) ||
|
||||
joycon_type_is_procon(ctlr);
|
||||
}
|
||||
|
||||
static inline bool joycon_type_has_right_controls(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return joycon_type_is_right_joycon(ctlr) ||
|
||||
joycon_type_is_procon(ctlr);
|
||||
}
|
||||
|
||||
static inline bool joycon_type_is_any_joycon(struct joycon_ctlr *ctlr)
|
||||
{
|
||||
return joycon_type_is_left_joycon(ctlr) ||
|
||||
|
@ -32,13 +32,6 @@
|
||||
|
||||
struct pcmidi_snd;
|
||||
|
||||
struct pk_device {
|
||||
unsigned long quirks;
|
||||
|
||||
struct hid_device *hdev;
|
||||
struct pcmidi_snd *pm; /* pcmidi device context */
|
||||
};
|
||||
|
||||
struct pcmidi_sustain {
|
||||
unsigned long in_use;
|
||||
struct pcmidi_snd *pm;
|
||||
@ -50,7 +43,7 @@ struct pcmidi_sustain {
|
||||
|
||||
#define PCMIDI_SUSTAINED_MAX 32
|
||||
struct pcmidi_snd {
|
||||
struct pk_device *pk;
|
||||
struct hid_device *hdev;
|
||||
unsigned short ifnum;
|
||||
struct hid_report *pcmidi_report6;
|
||||
struct input_dev *input_ep82;
|
||||
@ -66,9 +59,7 @@ struct pcmidi_snd {
|
||||
struct snd_card *card;
|
||||
struct snd_rawmidi *rwmidi;
|
||||
struct snd_rawmidi_substream *in_substream;
|
||||
struct snd_rawmidi_substream *out_substream;
|
||||
unsigned long in_triggered;
|
||||
unsigned long out_active;
|
||||
};
|
||||
|
||||
#define PK_QUIRK_NOGET 0x00010000
|
||||
@ -100,11 +91,11 @@ static ssize_t show_channel(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
dbg_hid("pcmidi sysfs read channel=%u\n", pk->pm->midi_channel);
|
||||
dbg_hid("pcmidi sysfs read channel=%u\n", pm->midi_channel);
|
||||
|
||||
return sprintf(buf, "%u (min:%u, max:%u)\n", pk->pm->midi_channel,
|
||||
return sprintf(buf, "%u (min:%u, max:%u)\n", pm->midi_channel,
|
||||
PCMIDI_CHANNEL_MIN, PCMIDI_CHANNEL_MAX);
|
||||
}
|
||||
|
||||
@ -113,13 +104,13 @@ static ssize_t store_channel(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
unsigned channel = 0;
|
||||
|
||||
if (sscanf(buf, "%u", &channel) > 0 && channel <= PCMIDI_CHANNEL_MAX) {
|
||||
dbg_hid("pcmidi sysfs write channel=%u\n", channel);
|
||||
pk->pm->midi_channel = channel;
|
||||
pm->midi_channel = channel;
|
||||
return strlen(buf);
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -137,11 +128,11 @@ static ssize_t show_sustain(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
dbg_hid("pcmidi sysfs read sustain=%u\n", pk->pm->midi_sustain);
|
||||
dbg_hid("pcmidi sysfs read sustain=%u\n", pm->midi_sustain);
|
||||
|
||||
return sprintf(buf, "%u (off:%u, max:%u (ms))\n", pk->pm->midi_sustain,
|
||||
return sprintf(buf, "%u (off:%u, max:%u (ms))\n", pm->midi_sustain,
|
||||
PCMIDI_SUSTAIN_MIN, PCMIDI_SUSTAIN_MAX);
|
||||
}
|
||||
|
||||
@ -150,15 +141,14 @@ static ssize_t store_sustain(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
unsigned sustain = 0;
|
||||
|
||||
if (sscanf(buf, "%u", &sustain) > 0 && sustain <= PCMIDI_SUSTAIN_MAX) {
|
||||
dbg_hid("pcmidi sysfs write sustain=%u\n", sustain);
|
||||
pk->pm->midi_sustain = sustain;
|
||||
pk->pm->midi_sustain_mode =
|
||||
(0 == sustain || !pk->pm->midi_mode) ? 0 : 1;
|
||||
pm->midi_sustain = sustain;
|
||||
pm->midi_sustain_mode = (0 == sustain || !pm->midi_mode) ? 0 : 1;
|
||||
return strlen(buf);
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -176,11 +166,11 @@ static ssize_t show_octave(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
dbg_hid("pcmidi sysfs read octave=%d\n", pk->pm->midi_octave);
|
||||
dbg_hid("pcmidi sysfs read octave=%d\n", pm->midi_octave);
|
||||
|
||||
return sprintf(buf, "%d (min:%d, max:%d)\n", pk->pm->midi_octave,
|
||||
return sprintf(buf, "%d (min:%d, max:%d)\n", pm->midi_octave,
|
||||
PCMIDI_OCTAVE_MIN, PCMIDI_OCTAVE_MAX);
|
||||
}
|
||||
|
||||
@ -189,14 +179,14 @@ static ssize_t store_octave(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
int octave = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &octave) > 0 &&
|
||||
octave >= PCMIDI_OCTAVE_MIN && octave <= PCMIDI_OCTAVE_MAX) {
|
||||
dbg_hid("pcmidi sysfs write octave=%d\n", octave);
|
||||
pk->pm->midi_octave = octave;
|
||||
pm->midi_octave = octave;
|
||||
return strlen(buf);
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -270,7 +260,7 @@ static void stop_sustain_timers(struct pcmidi_snd *pm)
|
||||
|
||||
static int pcmidi_get_output_report(struct pcmidi_snd *pm)
|
||||
{
|
||||
struct hid_device *hdev = pm->pk->hdev;
|
||||
struct hid_device *hdev = pm->hdev;
|
||||
struct hid_report *report;
|
||||
|
||||
list_for_each_entry(report,
|
||||
@ -295,7 +285,7 @@ static int pcmidi_get_output_report(struct pcmidi_snd *pm)
|
||||
|
||||
static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state)
|
||||
{
|
||||
struct hid_device *hdev = pm->pk->hdev;
|
||||
struct hid_device *hdev = pm->hdev;
|
||||
struct hid_report *report = pm->pcmidi_report6;
|
||||
report->field[0]->value[0] = 0x01;
|
||||
report->field[0]->value[1] = state;
|
||||
@ -622,7 +612,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
|
||||
|
||||
/* Setup sound card */
|
||||
|
||||
err = snd_card_new(&pm->pk->hdev->dev, index[dev], id[dev],
|
||||
err = snd_card_new(&pm->hdev->dev, index[dev], id[dev],
|
||||
THIS_MODULE, 0, &card);
|
||||
if (err < 0) {
|
||||
pk_error("failed to create pc-midi sound card\n");
|
||||
@ -660,7 +650,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
|
||||
&pcmidi_in_ops);
|
||||
|
||||
/* create sysfs variables */
|
||||
err = device_create_file(&pm->pk->hdev->dev,
|
||||
err = device_create_file(&pm->hdev->dev,
|
||||
sysfs_device_attr_channel);
|
||||
if (err < 0) {
|
||||
pk_error("failed to create sysfs attribute channel: error %d\n",
|
||||
@ -668,7 +658,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = device_create_file(&pm->pk->hdev->dev,
|
||||
err = device_create_file(&pm->hdev->dev,
|
||||
sysfs_device_attr_sustain);
|
||||
if (err < 0) {
|
||||
pk_error("failed to create sysfs attribute sustain: error %d\n",
|
||||
@ -676,7 +666,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
|
||||
goto fail_attr_sustain;
|
||||
}
|
||||
|
||||
err = device_create_file(&pm->pk->hdev->dev,
|
||||
err = device_create_file(&pm->hdev->dev,
|
||||
sysfs_device_attr_octave);
|
||||
if (err < 0) {
|
||||
pk_error("failed to create sysfs attribute octave: error %d\n",
|
||||
@ -706,11 +696,11 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
|
||||
|
||||
fail_register:
|
||||
stop_sustain_timers(pm);
|
||||
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_octave);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_octave);
|
||||
fail_attr_octave:
|
||||
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_sustain);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_sustain);
|
||||
fail_attr_sustain:
|
||||
device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_channel);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_channel);
|
||||
fail:
|
||||
if (pm->card) {
|
||||
snd_card_free(pm->card);
|
||||
@ -724,12 +714,9 @@ static int pcmidi_snd_terminate(struct pcmidi_snd *pm)
|
||||
if (pm->card) {
|
||||
stop_sustain_timers(pm);
|
||||
|
||||
device_remove_file(&pm->pk->hdev->dev,
|
||||
sysfs_device_attr_channel);
|
||||
device_remove_file(&pm->pk->hdev->dev,
|
||||
sysfs_device_attr_sustain);
|
||||
device_remove_file(&pm->pk->hdev->dev,
|
||||
sysfs_device_attr_octave);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_channel);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_sustain);
|
||||
device_remove_file(&pm->hdev->dev, sysfs_device_attr_octave);
|
||||
|
||||
snd_card_disconnect(pm->card);
|
||||
snd_card_free_when_closed(pm->card);
|
||||
@ -759,10 +746,7 @@ static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm;
|
||||
|
||||
pm = pk->pm;
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
if (HID_UP_MSVENDOR == (usage->hid & HID_USAGE_PAGE) &&
|
||||
1 == pm->ifnum) {
|
||||
@ -777,16 +761,16 @@ static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
static int pk_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||
u8 *data, int size)
|
||||
{
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
int ret = 0;
|
||||
|
||||
if (1 == pk->pm->ifnum) {
|
||||
if (1 == pm->ifnum) {
|
||||
if (report->id == data[0])
|
||||
switch (report->id) {
|
||||
case 0x01: /* midi keys (qwerty)*/
|
||||
case 0x03: /* midi keyboard (musical)*/
|
||||
case 0x04: /* extra/midi keys (qwerty)*/
|
||||
ret = pcmidi_handle_report(pk->pm,
|
||||
ret = pcmidi_handle_report(pm,
|
||||
report->id, data, size);
|
||||
break;
|
||||
}
|
||||
@ -801,8 +785,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
struct usb_interface *intf;
|
||||
unsigned short ifnum;
|
||||
unsigned long quirks = id->driver_data;
|
||||
struct pk_device *pk;
|
||||
struct pcmidi_snd *pm = NULL;
|
||||
struct pcmidi_snd *pm;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
@ -810,26 +793,16 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
intf = to_usb_interface(hdev->dev.parent);
|
||||
ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
|
||||
if (pk == NULL) {
|
||||
pm = kzalloc(sizeof(*pm), GFP_KERNEL);
|
||||
if (pm == NULL) {
|
||||
hid_err(hdev, "can't alloc descriptor\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pk->hdev = hdev;
|
||||
|
||||
pm = kzalloc(sizeof(*pm), GFP_KERNEL);
|
||||
if (pm == NULL) {
|
||||
hid_err(hdev, "can't alloc descriptor\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_free_pk;
|
||||
}
|
||||
|
||||
pm->pk = pk;
|
||||
pk->pm = pm;
|
||||
pm->hdev = hdev;
|
||||
pm->ifnum = ifnum;
|
||||
|
||||
hid_set_drvdata(hdev, pk);
|
||||
hid_set_drvdata(hdev, pm);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
@ -856,26 +829,18 @@ err_stop:
|
||||
hid_hw_stop(hdev);
|
||||
err_free:
|
||||
kfree(pm);
|
||||
err_free_pk:
|
||||
kfree(pk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pk_remove(struct hid_device *hdev)
|
||||
{
|
||||
struct pk_device *pk = hid_get_drvdata(hdev);
|
||||
struct pcmidi_snd *pm;
|
||||
|
||||
pm = pk->pm;
|
||||
if (pm) {
|
||||
pcmidi_snd_terminate(pm);
|
||||
kfree(pm);
|
||||
}
|
||||
struct pcmidi_snd *pm = hid_get_drvdata(hdev);
|
||||
|
||||
pcmidi_snd_terminate(pm);
|
||||
hid_hw_stop(hdev);
|
||||
|
||||
kfree(pk);
|
||||
kfree(pm);
|
||||
}
|
||||
|
||||
static const struct hid_device_id pk_devices[] = {
|
||||
|
@ -58,33 +58,25 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev,
|
||||
static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
|
||||
rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
|
||||
rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
|
||||
if (*rsize == 184 && !memcmp(&rdesc[175], "\x25\x40\x75\x30\x95\x01", 6) &&
|
||||
rdesc[182] == 0x40) {
|
||||
samsung_irda_dev_trace(hdev, 184);
|
||||
rdesc[176] = 0xff;
|
||||
rdesc[178] = 0x08;
|
||||
rdesc[180] = 0x06;
|
||||
rdesc[182] = 0x42;
|
||||
} else
|
||||
if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
|
||||
rdesc[194] == 0x25 && rdesc[195] == 0x12) {
|
||||
} else if (*rsize == 203 && !memcmp(&rdesc[192], "\x15\x00\x25\x12", 4)) {
|
||||
samsung_irda_dev_trace(hdev, 203);
|
||||
rdesc[193] = 0x1;
|
||||
rdesc[195] = 0xf;
|
||||
} else
|
||||
if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
|
||||
rdesc[126] == 0x25 && rdesc[127] == 0x11) {
|
||||
rdesc[193] = 0x01;
|
||||
rdesc[195] = 0x0f;
|
||||
} else if (*rsize == 135 && !memcmp(&rdesc[124], "\x15\x00\x25\x11", 4)) {
|
||||
samsung_irda_dev_trace(hdev, 135);
|
||||
rdesc[125] = 0x1;
|
||||
rdesc[127] = 0xe;
|
||||
} else
|
||||
if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
|
||||
rdesc[162] == 0x25 && rdesc[163] == 0x01) {
|
||||
rdesc[125] = 0x01;
|
||||
rdesc[127] = 0x0e;
|
||||
} else if (*rsize == 171 && !memcmp(&rdesc[160], "\x15\x00\x25\x01", 4)) {
|
||||
samsung_irda_dev_trace(hdev, 171);
|
||||
rdesc[161] = 0x1;
|
||||
rdesc[163] = 0x3;
|
||||
rdesc[161] = 0x01;
|
||||
rdesc[163] = 0x03;
|
||||
}
|
||||
return rdesc;
|
||||
}
|
||||
@ -99,7 +91,7 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
if (1 != ifnum || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))
|
||||
if (ifnum != 1 || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))
|
||||
return 0;
|
||||
|
||||
dbg_hid("samsung wireless keyboard/mouse input mapping event [0x%x]\n",
|
||||
@ -107,17 +99,39 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
/* report 2 */
|
||||
case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
|
||||
case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL); break;
|
||||
case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
|
||||
case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
|
||||
case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
|
||||
case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
|
||||
case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
|
||||
case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
|
||||
case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
|
||||
case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
|
||||
case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
|
||||
case 0x183:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MEDIA);
|
||||
break;
|
||||
case 0x195:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_EMAIL);
|
||||
break;
|
||||
case 0x196:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_CALC);
|
||||
break;
|
||||
case 0x197:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_COMPUTER);
|
||||
break;
|
||||
case 0x22b:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
|
||||
break;
|
||||
case 0x22c:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_WWW);
|
||||
break;
|
||||
case 0x22d:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BACK);
|
||||
break;
|
||||
case 0x22e:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_FORWARD);
|
||||
break;
|
||||
case 0x22f:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_FAVORITES);
|
||||
break;
|
||||
case 0x230:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_REFRESH);
|
||||
break;
|
||||
case 0x231:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_STOP);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -125,10 +139,340 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int samsung_kbd_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
|
||||
HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
|
||||
return 0;
|
||||
|
||||
dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
|
||||
usage->hid & HID_USAGE);
|
||||
|
||||
if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
|
||||
set_bit(EV_REP, hi->input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x32:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
|
||||
break;
|
||||
case 0x64:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_102ND);
|
||||
break;
|
||||
/* Only for BR keyboard */
|
||||
case 0x87:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_RO);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
/* report 2 */
|
||||
/* MENU */
|
||||
case 0x040:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MENU);
|
||||
break;
|
||||
case 0x18a:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MAIL);
|
||||
break;
|
||||
case 0x196:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_WWW);
|
||||
break;
|
||||
case 0x19e:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
|
||||
break;
|
||||
case 0x221:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
|
||||
break;
|
||||
case 0x223:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
|
||||
break;
|
||||
/* Smtart Voice Key */
|
||||
case 0x300:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY13);
|
||||
break;
|
||||
/* RECENTAPPS */
|
||||
case 0x301:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
|
||||
break;
|
||||
/* APPLICATION */
|
||||
case 0x302:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
|
||||
break;
|
||||
/* Voice search */
|
||||
case 0x305:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
|
||||
break;
|
||||
/* QPANEL on/off */
|
||||
case 0x306:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
|
||||
break;
|
||||
/* SIP on/off */
|
||||
case 0x307:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
|
||||
break;
|
||||
/* LANG */
|
||||
case 0x308:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
|
||||
break;
|
||||
case 0x30a:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
|
||||
break;
|
||||
case 0x30b:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int samsung_gamepad_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if (!(HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE) ||
|
||||
HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)))
|
||||
return 0;
|
||||
|
||||
dbg_hid("samsung wireless gamepad input mapping event [0x%x], %ld, %ld, [0x%x]\n",
|
||||
usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0], usage->hid & HID_USAGE_PAGE);
|
||||
|
||||
if (HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE)) {
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x01:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_A);
|
||||
break;
|
||||
case 0x02:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_B);
|
||||
break;
|
||||
case 0x03:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_C);
|
||||
break;
|
||||
case 0x04:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_X);
|
||||
break;
|
||||
case 0x05:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_Y);
|
||||
break;
|
||||
case 0x06:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_Z);
|
||||
break;
|
||||
case 0x07:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TL);
|
||||
break;
|
||||
case 0x08:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TR);
|
||||
break;
|
||||
case 0x09:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TL2);
|
||||
break;
|
||||
case 0x0a:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TR2);
|
||||
break;
|
||||
case 0x0b:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_SELECT);
|
||||
break;
|
||||
case 0x0c:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_START);
|
||||
break;
|
||||
case 0x0d:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_MODE);
|
||||
break;
|
||||
case 0x0e:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_THUMBL);
|
||||
break;
|
||||
case 0x0f:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_THUMBR);
|
||||
break;
|
||||
case 0x10:
|
||||
samsung_kbd_mouse_map_key_clear(0x13f);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x040:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MENU);
|
||||
break;
|
||||
case 0x223:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
|
||||
break;
|
||||
case 0x224:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BACK);
|
||||
break;
|
||||
|
||||
/* Screen Capture */
|
||||
case 0x303:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int samsung_actionmouse_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
|
||||
dbg_hid("samsung wireless actionmouse input mapping event [0x%x], [0x%x], %ld, %ld, [0x%x]\n",
|
||||
usage->hid, usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0],
|
||||
usage->hid & HID_USAGE_PAGE);
|
||||
|
||||
if (((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) && ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON))
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x301:
|
||||
samsung_kbd_mouse_map_key_clear(254);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int samsung_universal_kbd_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
|
||||
HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
|
||||
return 0;
|
||||
|
||||
dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
|
||||
usage->hid & HID_USAGE);
|
||||
|
||||
if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
|
||||
set_bit(EV_REP, hi->input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x32:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
|
||||
break;
|
||||
case 0x64:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_102ND);
|
||||
break;
|
||||
/* Only for BR keyboard */
|
||||
case 0x87:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_RO);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
/* report 2 */
|
||||
/* MENU */
|
||||
case 0x040:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MENU);
|
||||
break;
|
||||
case 0x18a:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_MAIL);
|
||||
break;
|
||||
case 0x196:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_WWW);
|
||||
break;
|
||||
case 0x19e:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
|
||||
break;
|
||||
case 0x221:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
|
||||
break;
|
||||
case 0x223:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
|
||||
break;
|
||||
/* RECENTAPPS */
|
||||
case 0x301:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
|
||||
break;
|
||||
/* APPLICATION */
|
||||
case 0x302:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
|
||||
break;
|
||||
/* Voice search */
|
||||
case 0x305:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
|
||||
break;
|
||||
/* QPANEL on/off */
|
||||
case 0x306:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
|
||||
break;
|
||||
/* SIP on/off */
|
||||
case 0x307:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
|
||||
break;
|
||||
/* LANG */
|
||||
case 0x308:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
|
||||
break;
|
||||
case 0x30a:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
|
||||
break;
|
||||
case 0x070:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
|
||||
break;
|
||||
case 0x30b:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
|
||||
break;
|
||||
case 0x06f:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
|
||||
break;
|
||||
/* S-Finder */
|
||||
case 0x304:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY7);
|
||||
break;
|
||||
/* Screen Capture */
|
||||
case 0x303:
|
||||
samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
|
||||
break;
|
||||
/* Multi Window */
|
||||
case 0x309:
|
||||
samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY9);
|
||||
break;
|
||||
/* HotKey App 1 */
|
||||
case 0x071:
|
||||
samsung_kbd_mouse_map_key_clear(0x2f5);
|
||||
break;
|
||||
/* HotKey App 2 */
|
||||
case 0x072:
|
||||
samsung_kbd_mouse_map_key_clear(0x2f6);
|
||||
break;
|
||||
/* HotKey App 3 */
|
||||
case 0x073:
|
||||
samsung_kbd_mouse_map_key_clear(0x2f7);
|
||||
break;
|
||||
/* Dex */
|
||||
case 0x06e:
|
||||
samsung_kbd_mouse_map_key_clear(0x2bd);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
|
||||
if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE && hid_is_usb(hdev))
|
||||
rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
|
||||
return rdesc;
|
||||
}
|
||||
@ -139,9 +483,24 @@ static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
|
||||
if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE && hid_is_usb(hdev))
|
||||
ret = samsung_kbd_mouse_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD)
|
||||
ret = samsung_kbd_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD)
|
||||
ret = samsung_gamepad_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE)
|
||||
ret = samsung_actionmouse_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD)
|
||||
ret = samsung_universal_kbd_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD)
|
||||
ret = samsung_universal_kbd_input_mapping(hdev,
|
||||
hi, field, usage, bit, max);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -152,16 +511,17 @@ static int samsung_probe(struct hid_device *hdev,
|
||||
int ret;
|
||||
unsigned int cmask = HID_CONNECT_DEFAULT;
|
||||
|
||||
if (!hid_is_usb(hdev))
|
||||
return -EINVAL;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
|
||||
if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) {
|
||||
if (!hid_is_usb(hdev)) {
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
if (hdev->rsize == 184) {
|
||||
/* disable hidinput, force hiddev */
|
||||
cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
|
||||
@ -183,6 +543,11 @@ err_free:
|
||||
static const struct hid_device_id samsung_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, samsung_devices);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define RPL_S_DEVICE_ID 0x7A78
|
||||
#define MTL_P_DEVICE_ID 0x7E45
|
||||
#define ARL_H_DEVICE_ID 0x7745
|
||||
#define ARL_S_DEVICE_ID 0x7F78
|
||||
|
||||
#define REVISION_ID_CHT_A0 0x6
|
||||
#define REVISION_ID_CHT_Ax_SI 0x0
|
||||
|
@ -45,6 +45,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, RPL_S_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MTL_P_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, ARL_H_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, ARL_S_DEVICE_ID)},
|
||||
{0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
|
||||
|
@ -2990,11 +2990,11 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
|
||||
|
||||
wacom_wac_battery_pre_report(hdev, report);
|
||||
|
||||
if (pad_in_hid_field && wacom->wacom_wac.pad_input)
|
||||
if (pad_in_hid_field && wacom_wac->pad_input)
|
||||
wacom_wac_pad_pre_report(hdev, report);
|
||||
if (pen_in_hid_field && wacom->wacom_wac.pen_input)
|
||||
if (pen_in_hid_field && wacom_wac->pen_input)
|
||||
wacom_wac_pen_pre_report(hdev, report);
|
||||
if (finger_in_hid_field && wacom->wacom_wac.touch_input)
|
||||
if (finger_in_hid_field && wacom_wac->touch_input)
|
||||
wacom_wac_finger_pre_report(hdev, report);
|
||||
|
||||
for (r = 0; r < report->maxfield; r++) {
|
||||
@ -3010,7 +3010,7 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
|
||||
|
||||
wacom_wac_battery_report(hdev, report);
|
||||
|
||||
if (true_pad && wacom->wacom_wac.pad_input)
|
||||
if (true_pad && wacom_wac->pad_input)
|
||||
wacom_wac_pad_report(hdev, report, field);
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,6 @@ struct hid_data {
|
||||
bool confidence;
|
||||
int x;
|
||||
int y;
|
||||
int pressure;
|
||||
int width;
|
||||
int height;
|
||||
int id;
|
||||
|
@ -683,9 +683,9 @@ struct hid_device { /* device report descriptor */
|
||||
|
||||
unsigned int id; /* system unique id */
|
||||
|
||||
#ifdef CONFIG_BPF
|
||||
#ifdef CONFIG_HID_BPF
|
||||
struct hid_bpf bpf; /* hid-bpf data */
|
||||
#endif /* CONFIG_BPF */
|
||||
#endif /* CONFIG_HID_BPF */
|
||||
};
|
||||
|
||||
void hiddev_free(struct kref *ref);
|
||||
|
Loading…
x
Reference in New Issue
Block a user