Merge tag 'hid-for-linus-2025060301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - support for Apple Magic Mouse 2 USB-C (Aditya Garg) - power management improvement for multitouch devices (Werner Sembach) - fix for ACPI initialization in intel-thc driver (Wentao Guan) - adaptation of HID drivers to use new gpio_chip's line setter callbacks (Bartosz Golaszewski) - fix potential OOB in usbhid_parse() (Terry Junge) - make it possible to set hid_mouse_ignore_list dynamically (the same way we handle other quirks) (Aditya Garg) - other small assorted fixes and device ID additions * tag 'hid-for-linus-2025060301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: multitouch: Disable touchpad on firmware level while not in use HID: core: Add functions for HID drivers to react on first open and last close call HID: HID_APPLETB_BL should depend on X86 HID: HID_APPLETB_KBD should depend on X86 HID: appletb-kbd: Use secs_to_jiffies() instead of msecs_to_jiffies() HID: intel-thc-hid: intel-thc: make read-only arrays static const HID: magicmouse: Apple Magic Mouse 2 USB-C support HID: mcp2221: use new line value setter callbacks HID: mcp2200: use new line value setter callbacks HID: cp2112: use new line value setter callbacks HID: cp2112: use lock guards HID: cp2112: hold the lock for the entire direction_output() call HID: cp2112: destroy mutex on driver detach HID: intel-thc-hid: intel-quicki2c: pass correct arguments to acpi_evaluate_object HID: corsair-void: Use to_delayed_work() HID: hid-logitech: use sysfs_emit_at() instead of scnprintf() HID: quirks: Add HID_QUIRK_IGNORE_MOUSE quirk HID: usbhid: Eliminate recurrent out-of-bounds bug in usbhid_parse() HID: Kysona: Add periodic online check
This commit is contained in:
commit
2043ae9019
19 files changed
+217
-111
No files matched your search
@@ -151,6 +151,7 @@ config HID_APPLEIR
|
||||
config HID_APPLETB_BL
|
||||
tristate "Apple Touch Bar Backlight"
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on X86 || COMPILE_TEST
|
||||
help
|
||||
Say Y here if you want support for the backlight of Touch Bars on x86
|
||||
MacBook Pros.
|
||||
@@ -163,6 +164,7 @@ config HID_APPLETB_KBD
|
||||
depends on USB_HID
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on INPUT
|
||||
depends on X86 || COMPILE_TEST
|
||||
select INPUT_SPARSEKMAP
|
||||
select HID_APPLETB_BL
|
||||
help
|
||||
|
||||
@@ -172,7 +172,8 @@ static void appletb_inactivity_timer(struct timer_list *t)
|
||||
if (!kbd->has_dimmed) {
|
||||
backlight_device_set_brightness(kbd->backlight_dev, 1);
|
||||
kbd->has_dimmed = true;
|
||||
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000));
|
||||
mod_timer(&kbd->inactivity_timer,
|
||||
jiffies + secs_to_jiffies(appletb_tb_idle_timeout));
|
||||
} else if (!kbd->has_turned_off) {
|
||||
backlight_device_set_brightness(kbd->backlight_dev, 0);
|
||||
kbd->has_turned_off = true;
|
||||
@@ -188,7 +189,8 @@ static void reset_inactivity_timer(struct appletb_kbd *kbd)
|
||||
kbd->has_dimmed = false;
|
||||
kbd->has_turned_off = false;
|
||||
}
|
||||
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
mod_timer(&kbd->inactivity_timer,
|
||||
jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +409,8 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
|
||||
} else {
|
||||
backlight_device_set_brightness(kbd->backlight_dev, 2);
|
||||
timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
|
||||
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
|
||||
mod_timer(&kbd->inactivity_timer,
|
||||
jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
|
||||
}
|
||||
|
||||
kbd->inp_handler.event = appletb_kbd_inp_event;
|
||||
|
||||
@@ -2396,6 +2396,9 @@ int hid_hw_open(struct hid_device *hdev)
|
||||
ret = hdev->ll_driver->open(hdev);
|
||||
if (ret)
|
||||
hdev->ll_open_count--;
|
||||
|
||||
if (hdev->driver->on_hid_hw_open)
|
||||
hdev->driver->on_hid_hw_open(hdev);
|
||||
}
|
||||
|
||||
mutex_unlock(&hdev->ll_open_lock);
|
||||
@@ -2415,8 +2418,12 @@ EXPORT_SYMBOL_GPL(hid_hw_open);
|
||||
void hid_hw_close(struct hid_device *hdev)
|
||||
{
|
||||
mutex_lock(&hdev->ll_open_lock);
|
||||
if (!--hdev->ll_open_count)
|
||||
if (!--hdev->ll_open_count) {
|
||||
hdev->ll_driver->close(hdev);
|
||||
|
||||
if (hdev->driver->on_hid_hw_close)
|
||||
hdev->driver->on_hid_hw_close(hdev);
|
||||
}
|
||||
mutex_unlock(&hdev->ll_open_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hid_hw_close);
|
||||
|
||||
@@ -507,7 +507,7 @@ static void corsair_void_status_work_handler(struct work_struct *work)
|
||||
struct delayed_work *delayed_work;
|
||||
int battery_ret;
|
||||
|
||||
delayed_work = container_of(work, struct delayed_work, work);
|
||||
delayed_work = to_delayed_work(work);
|
||||
drvdata = container_of(delayed_work, struct corsair_void_drvdata,
|
||||
delayed_status_work);
|
||||
|
||||
@@ -525,7 +525,7 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
|
||||
struct delayed_work *delayed_work;
|
||||
int firmware_ret;
|
||||
|
||||
delayed_work = container_of(work, struct delayed_work, work);
|
||||
delayed_work = to_delayed_work(work);
|
||||
drvdata = container_of(delayed_work, struct corsair_void_drvdata,
|
||||
delayed_firmware_work);
|
||||
|
||||
|
||||
+32
-34
@@ -17,11 +17,13 @@
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/hidraw.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/nls.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
@@ -185,7 +187,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
u8 *buf = dev->in_out_buffer;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
|
||||
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
|
||||
@@ -194,7 +196,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
hid_err(hdev, "error requesting GPIO config: %d\n", ret);
|
||||
if (ret >= 0)
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf[1] &= ~BIT(offset);
|
||||
@@ -207,25 +209,19 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
hid_err(hdev, "error setting GPIO config: %d\n", ret);
|
||||
if (ret >= 0)
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&dev->lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
static int cp2112_gpio_set_unlocked(struct cp2112_device *dev,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
struct cp2112_device *dev = gpiochip_get_data(chip);
|
||||
struct hid_device *hdev = dev->hdev;
|
||||
u8 *buf = dev->in_out_buffer;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
buf[0] = CP2112_GPIO_SET;
|
||||
buf[1] = value ? CP2112_GPIO_ALL_GPIO_MASK : 0;
|
||||
buf[2] = BIT(offset);
|
||||
@@ -236,7 +232,17 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
if (ret < 0)
|
||||
hid_err(hdev, "error setting GPIO values: %d\n", ret);
|
||||
|
||||
mutex_unlock(&dev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cp2112_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct cp2112_device *dev = gpiochip_get_data(chip);
|
||||
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
return cp2112_gpio_set_unlocked(dev, offset, value);
|
||||
}
|
||||
|
||||
static int cp2112_gpio_get_all(struct gpio_chip *chip)
|
||||
@@ -246,23 +252,17 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip)
|
||||
u8 *buf = dev->in_out_buffer;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf,
|
||||
CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
if (ret != CP2112_GPIO_GET_LENGTH) {
|
||||
hid_err(hdev, "error requesting GPIO values: %d\n", ret);
|
||||
ret = ret < 0 ? ret : -EIO;
|
||||
goto exit;
|
||||
return ret < 0 ? ret : -EIO;
|
||||
}
|
||||
|
||||
ret = buf[1];
|
||||
|
||||
exit:
|
||||
mutex_unlock(&dev->lock);
|
||||
|
||||
return ret;
|
||||
return buf[1];
|
||||
}
|
||||
|
||||
static int cp2112_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
@@ -284,14 +284,14 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
|
||||
u8 *buf = dev->in_out_buffer;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
|
||||
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
if (ret != CP2112_GPIO_CONFIG_LENGTH) {
|
||||
hid_err(hdev, "error requesting GPIO config: %d\n", ret);
|
||||
goto fail;
|
||||
return ret < 0 ? ret : -EIO;
|
||||
}
|
||||
|
||||
buf[1] |= 1 << offset;
|
||||
@@ -302,22 +302,16 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
|
||||
HID_REQ_SET_REPORT);
|
||||
if (ret < 0) {
|
||||
hid_err(hdev, "error setting GPIO config: %d\n", ret);
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->lock);
|
||||
|
||||
/*
|
||||
* Set gpio value when output direction is already set,
|
||||
* as specified in AN495, Rev. 0.2, cpt. 4.4
|
||||
*/
|
||||
cp2112_gpio_set(chip, offset, value);
|
||||
cp2112_gpio_set_unlocked(dev, offset, value);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
mutex_unlock(&dev->lock);
|
||||
return ret < 0 ? ret : -EIO;
|
||||
}
|
||||
|
||||
static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number,
|
||||
@@ -1205,7 +1199,11 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
if (!dev->in_out_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&dev->lock);
|
||||
ret = devm_mutex_init(&hdev->dev, &dev->lock);
|
||||
if (ret) {
|
||||
hid_err(hdev, "mutex init failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
@@ -1290,7 +1288,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
dev->gc.label = "cp2112_gpio";
|
||||
dev->gc.direction_input = cp2112_gpio_direction_input;
|
||||
dev->gc.direction_output = cp2112_gpio_direction_output;
|
||||
dev->gc.set = cp2112_gpio_set;
|
||||
dev->gc.set_rv = cp2112_gpio_set;
|
||||
dev->gc.get = cp2112_gpio_get;
|
||||
dev->gc.base = -1;
|
||||
dev->gc.ngpio = CP2112_GPIO_MAX_GPIO;
|
||||
|
||||
@@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
|
||||
goto cleanup;
|
||||
|
||||
input_device->report_desc_size = le16_to_cpu(
|
||||
desc->desc[0].wDescriptorLength);
|
||||
desc->rpt_desc.wDescriptorLength);
|
||||
if (input_device->report_desc_size == 0) {
|
||||
input_device->dev_info_status = -EINVAL;
|
||||
goto cleanup;
|
||||
@@ -210,7 +210,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
|
||||
|
||||
memcpy(input_device->report_desc,
|
||||
((unsigned char *)desc) + desc->bLength,
|
||||
le16_to_cpu(desc->desc[0].wDescriptorLength));
|
||||
le16_to_cpu(desc->rpt_desc.wDescriptorLength));
|
||||
|
||||
/* Send the ack */
|
||||
memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
|
||||
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
|
||||
#define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269
|
||||
#define USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC 0x0323
|
||||
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
|
||||
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
|
||||
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC 0x0324
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#define BATTERY_TIMEOUT_MS 5000
|
||||
|
||||
#define ONLINE_REPORT_ID 3
|
||||
#define BATTERY_REPORT_ID 4
|
||||
|
||||
struct kysona_drvdata {
|
||||
@@ -80,11 +81,46 @@ static int kysona_battery_get_property(struct power_supply *psy,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char kysona_online_request[] = {
|
||||
0x08, ONLINE_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a
|
||||
};
|
||||
|
||||
static const char kysona_battery_request[] = {
|
||||
0x08, BATTERY_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49
|
||||
};
|
||||
|
||||
static int kysona_m600_fetch_online(struct hid_device *hdev)
|
||||
{
|
||||
u8 *write_buf;
|
||||
int ret;
|
||||
|
||||
/* Request online information */
|
||||
write_buf = kmemdup(kysona_online_request, sizeof(kysona_online_request), GFP_KERNEL);
|
||||
if (!write_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = hid_hw_raw_request(hdev, kysona_online_request[0],
|
||||
write_buf, sizeof(kysona_online_request),
|
||||
HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
|
||||
if (ret < (int)sizeof(kysona_online_request)) {
|
||||
hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret);
|
||||
ret = -ENODATA;
|
||||
}
|
||||
kfree(write_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void kysona_fetch_online(struct hid_device *hdev)
|
||||
{
|
||||
int ret = kysona_m600_fetch_online(hdev);
|
||||
|
||||
if (ret < 0)
|
||||
hid_dbg(hdev,
|
||||
"Online query failed (err: %d)\n", ret);
|
||||
}
|
||||
|
||||
static int kysona_m600_fetch_battery(struct hid_device *hdev)
|
||||
{
|
||||
u8 *write_buf;
|
||||
@@ -121,6 +157,7 @@ static void kysona_battery_timer_tick(struct work_struct *work)
|
||||
struct kysona_drvdata, battery_work.work);
|
||||
struct hid_device *hdev = drv_data->hdev;
|
||||
|
||||
kysona_fetch_online(hdev);
|
||||
kysona_fetch_battery(hdev);
|
||||
schedule_delayed_work(&drv_data->battery_work,
|
||||
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
|
||||
@@ -160,6 +197,7 @@ static int kysona_battery_probe(struct hid_device *hdev)
|
||||
power_supply_powers(drv_data->battery, &hdev->dev);
|
||||
|
||||
INIT_DELAYED_WORK(&drv_data->battery_work, kysona_battery_timer_tick);
|
||||
kysona_fetch_online(hdev);
|
||||
kysona_fetch_battery(hdev);
|
||||
schedule_delayed_work(&drv_data->battery_work,
|
||||
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
|
||||
@@ -206,12 +244,16 @@ static int kysona_raw_event(struct hid_device *hdev,
|
||||
{
|
||||
struct kysona_drvdata *drv_data = hid_get_drvdata(hdev);
|
||||
|
||||
if (drv_data->battery && size == sizeof(kysona_battery_request) &&
|
||||
if (size == sizeof(kysona_online_request) &&
|
||||
data[0] == 8 && data[1] == ONLINE_REPORT_ID) {
|
||||
drv_data->online = data[6];
|
||||
}
|
||||
|
||||
if (size == sizeof(kysona_battery_request) &&
|
||||
data[0] == 8 && data[1] == BATTERY_REPORT_ID) {
|
||||
drv_data->battery_capacity = data[6];
|
||||
drv_data->battery_charging = data[7];
|
||||
drv_data->battery_voltage = (data[8] << 8) | data[9];
|
||||
drv_data->online = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -823,7 +823,7 @@ static ssize_t lg4ff_alternate_modes_show(struct device *dev, struct device_attr
|
||||
for (i = 0; i < LG4FF_MODE_MAX_IDX; i++) {
|
||||
if (entry->wdata.alternate_modes & BIT(i)) {
|
||||
/* Print tag and full name */
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count, "%s: %s",
|
||||
count += sysfs_emit_at(buf, count, "%s: %s",
|
||||
lg4ff_alternate_modes[i].tag,
|
||||
!lg4ff_alternate_modes[i].product_id ? entry->wdata.real_name : lg4ff_alternate_modes[i].name);
|
||||
if (count >= PAGE_SIZE - 1)
|
||||
@@ -832,9 +832,9 @@ static ssize_t lg4ff_alternate_modes_show(struct device *dev, struct device_attr
|
||||
/* Mark the currently active mode with an asterisk */
|
||||
if (lg4ff_alternate_modes[i].product_id == entry->wdata.product_id ||
|
||||
(lg4ff_alternate_modes[i].product_id == 0 && entry->wdata.product_id == entry->wdata.real_product_id))
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count, " *\n");
|
||||
count += sysfs_emit_at(buf, count, " *\n");
|
||||
else
|
||||
count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
|
||||
count += sysfs_emit_at(buf, count, "\n");
|
||||
|
||||
if (count >= PAGE_SIZE - 1)
|
||||
return count;
|
||||
|
||||
@@ -218,7 +218,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
|
||||
int pressure = 0;
|
||||
|
||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) {
|
||||
id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
|
||||
x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
|
||||
y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
|
||||
@@ -370,7 +371,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
|
||||
|
||||
if (report_undeciphered) {
|
||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)
|
||||
input_event(input, EV_MSC, MSC_RAW, tdata[7]);
|
||||
else if (input->id.product !=
|
||||
USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
|
||||
@@ -497,7 +499,8 @@ static int magicmouse_raw_event(struct hid_device *hdev,
|
||||
}
|
||||
|
||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) {
|
||||
magicmouse_emit_buttons(msc, clicks & 3);
|
||||
input_report_rel(input, REL_X, x);
|
||||
input_report_rel(input, REL_Y, y);
|
||||
@@ -519,7 +522,8 @@ static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
|
||||
if (msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
|
||||
if ((msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) &&
|
||||
field->report->id == MOUSE2_REPORT_ID) {
|
||||
/*
|
||||
* magic_mouse_raw_event has done all the work. Skip hidinput.
|
||||
@@ -540,7 +544,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
|
||||
__set_bit(EV_KEY, input->evbit);
|
||||
|
||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) {
|
||||
__set_bit(BTN_LEFT, input->keybit);
|
||||
__set_bit(BTN_RIGHT, input->keybit);
|
||||
if (emulate_3button)
|
||||
@@ -625,7 +630,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
|
||||
* inverse of the reported Y.
|
||||
*/
|
||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) {
|
||||
input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
|
||||
input_set_abs_params(input, ABS_MT_POSITION_X,
|
||||
MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
|
||||
@@ -741,19 +747,25 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev)
|
||||
int ret;
|
||||
int feature_size;
|
||||
|
||||
if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
|
||||
hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
|
||||
if (hdev->vendor == BT_VENDOR_ID_APPLE) {
|
||||
switch (hdev->product) {
|
||||
case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2:
|
||||
case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC:
|
||||
switch (hdev->vendor) {
|
||||
case BT_VENDOR_ID_APPLE:
|
||||
feature_size = sizeof(feature_mt_trackpad2_bt);
|
||||
feature = feature_mt_trackpad2_bt;
|
||||
} else { /* USB_VENDOR_ID_APPLE */
|
||||
break;
|
||||
default: /* USB_VENDOR_ID_APPLE */
|
||||
feature_size = sizeof(feature_mt_trackpad2_usb);
|
||||
feature = feature_mt_trackpad2_usb;
|
||||
}
|
||||
} else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
break;
|
||||
case USB_DEVICE_ID_APPLE_MAGICMOUSE2:
|
||||
case USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC:
|
||||
feature_size = sizeof(feature_mt_mouse2);
|
||||
feature = feature_mt_mouse2;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
feature_size = sizeof(feature_mt);
|
||||
feature = feature_mt;
|
||||
}
|
||||
@@ -787,6 +799,7 @@ static int magicmouse_fetch_battery(struct hid_device *hdev)
|
||||
|
||||
if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE ||
|
||||
(hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
|
||||
hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC &&
|
||||
hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
|
||||
hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC))
|
||||
return -1;
|
||||
@@ -857,6 +870,7 @@ static int magicmouse_probe(struct hid_device *hdev,
|
||||
|
||||
if (id->vendor == USB_VENDOR_ID_APPLE &&
|
||||
(id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
|
||||
((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
|
||||
id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
|
||||
hdev->type != HID_TYPE_USBMOUSE)))
|
||||
@@ -868,21 +882,27 @@ static int magicmouse_probe(struct hid_device *hdev,
|
||||
goto err_stop_hw;
|
||||
}
|
||||
|
||||
if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
MOUSE_REPORT_ID, 0);
|
||||
else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
MOUSE2_REPORT_ID, 0);
|
||||
else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
|
||||
id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
|
||||
if (id->vendor == BT_VENDOR_ID_APPLE)
|
||||
switch (id->product) {
|
||||
case USB_DEVICE_ID_APPLE_MAGICMOUSE:
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE_REPORT_ID, 0);
|
||||
break;
|
||||
case USB_DEVICE_ID_APPLE_MAGICMOUSE2:
|
||||
case USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC:
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE2_REPORT_ID, 0);
|
||||
break;
|
||||
case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2:
|
||||
case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC:
|
||||
switch (id->vendor) {
|
||||
case BT_VENDOR_ID_APPLE:
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
TRACKPAD2_BT_REPORT_ID, 0);
|
||||
else /* USB_VENDOR_ID_APPLE */
|
||||
break;
|
||||
default:
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
TRACKPAD2_USB_REPORT_ID, 0);
|
||||
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
|
||||
}
|
||||
break;
|
||||
default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
TRACKPAD_REPORT_ID, 0);
|
||||
report = hid_register_report(hdev, HID_INPUT_REPORT,
|
||||
@@ -909,7 +929,8 @@ static int magicmouse_probe(struct hid_device *hdev,
|
||||
hid_err(hdev, "unable to request touch data (%d)\n", ret);
|
||||
goto err_stop_hw;
|
||||
}
|
||||
if (ret == -EIO && id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
|
||||
if (ret == -EIO && (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) {
|
||||
schedule_delayed_work(&msc->work, msecs_to_jiffies(500));
|
||||
}
|
||||
|
||||
@@ -945,6 +966,7 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
*/
|
||||
if (hdev->vendor == USB_VENDOR_ID_APPLE &&
|
||||
(hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
|
||||
hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
|
||||
hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
|
||||
hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
|
||||
*rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
|
||||
@@ -971,6 +993,10 @@ static const struct hid_device_id magic_mice[] = {
|
||||
USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 },
|
||||
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC), .driver_data = 0 },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC), .driver_data = 0 },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
|
||||
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
|
||||
|
||||
@@ -127,8 +127,8 @@ static int mcp_cmd_read_all(struct mcp2200 *mcp)
|
||||
return mcp->status;
|
||||
}
|
||||
|
||||
static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
static int mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct mcp2200 *mcp = gpiochip_get_data(gc);
|
||||
u8 value;
|
||||
@@ -150,16 +150,20 @@ static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
|
||||
if (status == sizeof(struct mcp_set_clear_outputs))
|
||||
mcp->gpio_val = value;
|
||||
else
|
||||
status = -EIO;
|
||||
|
||||
mutex_unlock(&mcp->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value)
|
||||
static int mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value)
|
||||
{
|
||||
unsigned long mask = 1 << gpio_nr;
|
||||
unsigned long bmap_value = value << gpio_nr;
|
||||
|
||||
mcp_set_multiple(gc, &mask, &bmap_value);
|
||||
return mcp_set_multiple(gc, &mask, &bmap_value);
|
||||
}
|
||||
|
||||
static int mcp_get_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
@@ -263,9 +267,10 @@ static int mcp_direction_output(struct gpio_chip *gc, unsigned int gpio_nr,
|
||||
bmap_value = value << gpio_nr;
|
||||
|
||||
ret = mcp_set_direction(gc, gpio_nr, MCP2200_DIR_OUT);
|
||||
if (!ret)
|
||||
mcp_set_multiple(gc, &mask, &bmap_value);
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mcp_set_multiple(gc, &mask, &bmap_value);
|
||||
}
|
||||
|
||||
static const struct gpio_chip template_chip = {
|
||||
@@ -274,8 +279,8 @@ static const struct gpio_chip template_chip = {
|
||||
.get_direction = mcp_get_direction,
|
||||
.direction_input = mcp_direction_input,
|
||||
.direction_output = mcp_direction_output,
|
||||
.set = mcp_set,
|
||||
.set_multiple = mcp_set_multiple,
|
||||
.set_rv = mcp_set,
|
||||
.set_multiple_rv = mcp_set_multiple,
|
||||
.get = mcp_get,
|
||||
.get_multiple = mcp_get_multiple,
|
||||
.base = -1,
|
||||
|
||||
@@ -624,10 +624,10 @@ static int mcp_gpio_get(struct gpio_chip *gc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mcp_gpio_set(struct gpio_chip *gc,
|
||||
unsigned int offset, int value)
|
||||
static int mcp_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
|
||||
{
|
||||
struct mcp2221 *mcp = gpiochip_get_data(gc);
|
||||
int ret;
|
||||
|
||||
memset(mcp->txbuf, 0, 18);
|
||||
mcp->txbuf[0] = MCP2221_GPIO_SET;
|
||||
@@ -638,8 +638,10 @@ static void mcp_gpio_set(struct gpio_chip *gc,
|
||||
mcp->txbuf[mcp->gp_idx] = !!value;
|
||||
|
||||
mutex_lock(&mcp->lock);
|
||||
mcp_send_data_req_status(mcp, mcp->txbuf, 18);
|
||||
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 18);
|
||||
mutex_unlock(&mcp->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp_gpio_dir_set(struct mcp2221 *mcp,
|
||||
@@ -1206,7 +1208,7 @@ static int mcp2221_probe(struct hid_device *hdev,
|
||||
mcp->gc->direction_input = mcp_gpio_direction_input;
|
||||
mcp->gc->direction_output = mcp_gpio_direction_output;
|
||||
mcp->gc->get_direction = mcp_gpio_get_direction;
|
||||
mcp->gc->set = mcp_gpio_set;
|
||||
mcp->gc->set_rv = mcp_gpio_set;
|
||||
mcp->gc->get = mcp_gpio_get;
|
||||
mcp->gc->ngpio = MCP_NGPIO;
|
||||
mcp->gc->base = -1;
|
||||
|
||||
@@ -1887,6 +1887,16 @@ static void mt_remove(struct hid_device *hdev)
|
||||
hid_hw_stop(hdev);
|
||||
}
|
||||
|
||||
static void mt_on_hid_hw_open(struct hid_device *hdev)
|
||||
{
|
||||
mt_set_modes(hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_ALL);
|
||||
}
|
||||
|
||||
static void mt_on_hid_hw_close(struct hid_device *hdev)
|
||||
{
|
||||
mt_set_modes(hdev, HID_LATENCY_HIGH, TOUCHPAD_REPORT_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This list contains only:
|
||||
* - VID/PID of products not working with the default multitouch handling
|
||||
@@ -2354,5 +2364,7 @@ static struct hid_driver mt_driver = {
|
||||
.suspend = pm_ptr(mt_suspend),
|
||||
.reset_resume = pm_ptr(mt_reset_resume),
|
||||
.resume = pm_ptr(mt_resume),
|
||||
.on_hid_hw_open = mt_on_hid_hw_open,
|
||||
.on_hid_hw_close = mt_on_hid_hw_close,
|
||||
};
|
||||
module_hid_driver(mt_driver);
|
||||
@@ -1063,7 +1063,7 @@ bool hid_ignore(struct hid_device *hdev)
|
||||
}
|
||||
|
||||
if (hdev->type == HID_TYPE_USBMOUSE &&
|
||||
hid_match_id(hdev, hid_mouse_ignore_list))
|
||||
hdev->quirks & HID_QUIRK_IGNORE_MOUSE)
|
||||
return true;
|
||||
|
||||
return !!hid_match_id(hdev, hid_ignore_list);
|
||||
@@ -1267,6 +1267,9 @@ static unsigned long hid_gets_squirk(const struct hid_device *hdev)
|
||||
if (hid_match_id(hdev, hid_ignore_list))
|
||||
quirks |= HID_QUIRK_IGNORE;
|
||||
|
||||
if (hid_match_id(hdev, hid_mouse_ignore_list))
|
||||
quirks |= HID_QUIRK_IGNORE_MOUSE;
|
||||
|
||||
if (hid_match_id(hdev, hid_have_special_driver))
|
||||
quirks |= HID_QUIRK_HAVE_SPECIAL_DRIVER;
|
||||
|
||||
|
||||
@@ -82,15 +82,10 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
|
||||
{
|
||||
acpi_handle handle = acpi_device_handle(adev);
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object obj = { .type = type };
|
||||
struct acpi_object_list arg_list = {
|
||||
.count = 1,
|
||||
.pointer = &obj,
|
||||
};
|
||||
union acpi_object *ret_obj;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object(handle, dsd_method_name, &arg_list, &buffer);
|
||||
status = acpi_evaluate_object(handle, dsd_method_name, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_err(handle,
|
||||
"Can't evaluate %s method: %d\n", dsd_method_name, status);
|
||||
|
||||
@@ -1121,7 +1121,7 @@ EXPORT_SYMBOL_NS_GPL(thc_port_select, "INTEL_THC");
|
||||
|
||||
static u8 thc_get_spi_freq_div_val(struct thc_device *dev, u32 spi_freq_val)
|
||||
{
|
||||
int frequency[] = {
|
||||
static const int frequency[] = {
|
||||
THC_SPI_FREQUENCY_7M,
|
||||
THC_SPI_FREQUENCY_15M,
|
||||
THC_SPI_FREQUENCY_17M,
|
||||
@@ -1130,7 +1130,7 @@ static u8 thc_get_spi_freq_div_val(struct thc_device *dev, u32 spi_freq_val)
|
||||
THC_SPI_FREQUENCY_31M,
|
||||
THC_SPI_FREQUENCY_41M,
|
||||
};
|
||||
u8 frequency_div[] = {
|
||||
static const u8 frequency_div[] = {
|
||||
THC_SPI_FRQ_DIV_2,
|
||||
THC_SPI_FRQ_DIV_1,
|
||||
THC_SPI_FRQ_DIV_7,
|
||||
|
||||
@@ -984,12 +984,11 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
struct usb_host_interface *interface = intf->cur_altsetting;
|
||||
struct usb_device *dev = interface_to_usbdev (intf);
|
||||
struct hid_descriptor *hdesc;
|
||||
struct hid_class_descriptor *hcdesc;
|
||||
u32 quirks = 0;
|
||||
unsigned int rsize = 0;
|
||||
char *rdesc;
|
||||
int ret, n;
|
||||
int num_descriptors;
|
||||
size_t offset = offsetof(struct hid_descriptor, desc);
|
||||
int ret;
|
||||
|
||||
quirks = hid_lookup_quirk(hid);
|
||||
|
||||
@@ -1011,20 +1010,19 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (hdesc->bLength < sizeof(struct hid_descriptor)) {
|
||||
dbg_hid("hid descriptor is too short\n");
|
||||
if (!hdesc->bNumDescriptors ||
|
||||
hdesc->bLength != sizeof(*hdesc) +
|
||||
(hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
|
||||
dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
|
||||
hdesc->bLength, hdesc->bNumDescriptors);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hid->version = le16_to_cpu(hdesc->bcdHID);
|
||||
hid->country = hdesc->bCountryCode;
|
||||
|
||||
num_descriptors = min_t(int, hdesc->bNumDescriptors,
|
||||
(hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
|
||||
|
||||
for (n = 0; n < num_descriptors; n++)
|
||||
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
|
||||
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
|
||||
if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
|
||||
rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);
|
||||
|
||||
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
|
||||
dbg_hid("weird size of report descriptor (%u)\n", rsize);
|
||||
@@ -1052,6 +1050,11 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (hdesc->bNumDescriptors > 1)
|
||||
hid_warn(intf,
|
||||
"%u unsupported optional hid class descriptors\n",
|
||||
(int)(hdesc->bNumDescriptors - 1));
|
||||
|
||||
hid->quirks |= quirks;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -144,8 +144,8 @@ static struct hid_descriptor hidg_desc = {
|
||||
.bcdHID = cpu_to_le16(0x0101),
|
||||
.bCountryCode = 0x00,
|
||||
.bNumDescriptors = 0x1,
|
||||
/*.desc[0].bDescriptorType = DYNAMIC */
|
||||
/*.desc[0].wDescriptorLenght = DYNAMIC */
|
||||
/*.rpt_desc.bDescriptorType = DYNAMIC */
|
||||
/*.rpt_desc.wDescriptorLength = DYNAMIC */
|
||||
};
|
||||
|
||||
/* Super-Speed Support */
|
||||
@@ -939,8 +939,8 @@ static int hidg_setup(struct usb_function *f,
|
||||
struct hid_descriptor hidg_desc_copy = hidg_desc;
|
||||
|
||||
VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
|
||||
hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
|
||||
hidg_desc_copy.desc[0].wDescriptorLength =
|
||||
hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT;
|
||||
hidg_desc_copy.rpt_desc.wDescriptorLength =
|
||||
cpu_to_le16(hidg->report_desc_length);
|
||||
|
||||
length = min_t(unsigned short, length,
|
||||
@@ -1210,8 +1210,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
* We can use hidg_desc struct here but we should not relay
|
||||
* that its content won't change after returning from this function.
|
||||
*/
|
||||
hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
|
||||
hidg_desc.desc[0].wDescriptorLength =
|
||||
hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT;
|
||||
hidg_desc.rpt_desc.wDescriptorLength =
|
||||
cpu_to_le16(hidg->report_desc_length);
|
||||
|
||||
hidg_hs_in_ep_desc.bEndpointAddress =
|
||||
|
||||
+8
-1
@@ -357,6 +357,7 @@ struct hid_item {
|
||||
* | @HID_QUIRK_INPUT_PER_APP:
|
||||
* | @HID_QUIRK_X_INVERT:
|
||||
* | @HID_QUIRK_Y_INVERT:
|
||||
* | @HID_QUIRK_IGNORE_MOUSE:
|
||||
* | @HID_QUIRK_SKIP_OUTPUT_REPORTS:
|
||||
* | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID:
|
||||
* | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP:
|
||||
@@ -382,6 +383,7 @@ struct hid_item {
|
||||
#define HID_QUIRK_INPUT_PER_APP BIT(11)
|
||||
#define HID_QUIRK_X_INVERT BIT(12)
|
||||
#define HID_QUIRK_Y_INVERT BIT(13)
|
||||
#define HID_QUIRK_IGNORE_MOUSE BIT(14)
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
|
||||
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
|
||||
@@ -740,8 +742,9 @@ struct hid_descriptor {
|
||||
__le16 bcdHID;
|
||||
__u8 bCountryCode;
|
||||
__u8 bNumDescriptors;
|
||||
struct hid_class_descriptor rpt_desc;
|
||||
|
||||
struct hid_class_descriptor desc[1];
|
||||
struct hid_class_descriptor opt_descs[];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define HID_DEVICE(b, g, ven, prod) \
|
||||
@@ -792,6 +795,8 @@ struct hid_usage_id {
|
||||
* @suspend: invoked on suspend (NULL means nop)
|
||||
* @resume: invoked on resume if device was not reset (NULL means nop)
|
||||
* @reset_resume: invoked on resume if device was reset (NULL means nop)
|
||||
* @on_hid_hw_open: invoked when hid core opens first instance (NULL means nop)
|
||||
* @on_hid_hw_close: invoked when hid core closes last instance (NULL means nop)
|
||||
*
|
||||
* probe should return -errno on error, or 0 on success. During probe,
|
||||
* input will not be passed to raw_event unless hid_device_io_start is
|
||||
@@ -847,6 +852,8 @@ struct hid_driver {
|
||||
int (*suspend)(struct hid_device *hdev, pm_message_t message);
|
||||
int (*resume)(struct hid_device *hdev);
|
||||
int (*reset_resume)(struct hid_device *hdev);
|
||||
void (*on_hid_hw_open)(struct hid_device *hdev);
|
||||
void (*on_hid_hw_close)(struct hid_device *hdev);
|
||||
|
||||
/* private: */
|
||||
struct device_driver driver;
|
||||
|
||||
Reference in new issue
Block a user