forked from luck/tmp_suning_uos_patched
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - Lenovo X1 Tablet support improvements from Mikael Wikström - "heartbeat" report fix for several Wacom devices from Jason Gerecke - bounds checking fix in hid-roccat from Dan Carpenter - stylus battery reporting fix from Dmitry Torokhov - i2c-hid support for wakeup from suspend-to-idle from Kai-Heng Feng - new driver for Vivaldi devices from Sean O'Brien - other assorted small fixes and device ID additions * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: i2c-hid: Enable wakeup capability from Suspend-to-Idle HID: add vivaldi HID driver HID: hid-input: fix stylus battery reporting HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery HID: i2c-hid: fix kerneldoc warnings in i2c-hid-core.c HID: core: fix kerneldoc warnings in hid-core.c HID: multitouch: Lenovo X1 Tablet Gen2 trackpoint and buttons HID: multitouch: Lenovo X1 Tablet Gen3 trackpoint and buttons HID: alps: clean up indentation issue HID: intel-ish-hid: simplify the return expression of ishtp_bus_remove_device() HID: hid-debug: fix nonblocking read semantics wrt EIO/ERESTARTSYS HID: i2c-hid: Prefer asynchronous probe HID: ite: Add USB id match for Acer One S1003 keyboard dock HID: roccat: add bounds checking in kone_sysfs_write_settings() HID: wiimote: narrow spinlock range in wiimote_hid_event() HID: wiimote: make handlers[] const HID: apple: Add support for Matias wireless keyboard HID: cp2112: Use irqchip template
This commit is contained in:
commit
bf36c6b946
|
@ -397,6 +397,15 @@ config HID_GOOGLE_HAMMER
|
|||
help
|
||||
Say Y here if you have a Google Hammer device.
|
||||
|
||||
config HID_VIVALDI
|
||||
tristate "Vivaldi Keyboard"
|
||||
depends on HID
|
||||
help
|
||||
Say Y here if you want to enable support for Vivaldi keyboards.
|
||||
|
||||
Vivaldi keyboards use a vendor-specific (Google) HID usage to report
|
||||
how the keys in the top row are physically ordered.
|
||||
|
||||
config HID_GT683R
|
||||
tristate "MSI GT68xR LED support"
|
||||
depends on LEDS_CLASS && USB_HID
|
||||
|
|
|
@ -50,6 +50,7 @@ obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
|
|||
obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
|
||||
obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o
|
||||
obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o
|
||||
obj-$(CONFIG_HID_VIVALDI) += hid-vivaldi.o
|
||||
obj-$(CONFIG_HID_GT683R) += hid-gt683r.o
|
||||
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
|
||||
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
|
||||
|
|
|
@ -526,7 +526,7 @@ static int u1_init(struct hid_device *hdev, struct alps_dev *pri_data)
|
|||
|
||||
ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y,
|
||||
&sen_line_num_y, 0, true);
|
||||
if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
@ -503,6 +503,8 @@ static const struct hid_device_id apple_devices[] = {
|
|||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
|
||||
|
|
|
@ -814,6 +814,13 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
|
|||
|
||||
if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR)
|
||||
parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC;
|
||||
|
||||
if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR)
|
||||
for (i = 0; i < parser->local.usage_index; i++)
|
||||
if (parser->local.usage[i] ==
|
||||
(HID_UP_GOOGLEVENDOR | 0x0001))
|
||||
parser->device->group =
|
||||
HID_GROUP_VIVALDI;
|
||||
}
|
||||
|
||||
static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
||||
|
@ -920,7 +927,7 @@ static int hid_scan_report(struct hid_device *hid)
|
|||
/**
|
||||
* hid_parse_report - parse device report
|
||||
*
|
||||
* @device: hid device
|
||||
* @hid: hid device
|
||||
* @start: report start
|
||||
* @size: report size
|
||||
*
|
||||
|
@ -945,7 +952,7 @@ static const char * const hid_report_names[] = {
|
|||
/**
|
||||
* hid_validate_values - validate existing device report's value indexes
|
||||
*
|
||||
* @device: hid device
|
||||
* @hid: hid device
|
||||
* @type: which report type to examine
|
||||
* @id: which report ID to examine (0 for first)
|
||||
* @field_index: which report field to examine
|
||||
|
@ -1444,7 +1451,7 @@ static int search(__s32 *array, __s32 value, unsigned n)
|
|||
* hid_match_report - check if driver's raw_event should be called
|
||||
*
|
||||
* @hid: hid device
|
||||
* @report_type: type to match against
|
||||
* @report: hid report to match against
|
||||
*
|
||||
* compare hid->driver->report_table->report_type to report->type
|
||||
*/
|
||||
|
@ -2120,7 +2127,7 @@ struct hid_dynid {
|
|||
|
||||
/**
|
||||
* store_new_id - add a new HID device ID to this driver and re-probe devices
|
||||
* @driver: target device driver
|
||||
* @drv: target device driver
|
||||
* @buf: buffer for scanning device ID data
|
||||
* @count: input size
|
||||
*
|
||||
|
|
|
@ -1235,6 +1235,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
struct cp2112_device *dev;
|
||||
u8 buf[3];
|
||||
struct cp2112_smbus_config_report config;
|
||||
struct gpio_irq_chip *girq;
|
||||
int ret;
|
||||
|
||||
dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
|
@ -1338,6 +1339,15 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
dev->gc.can_sleep = 1;
|
||||
dev->gc.parent = &hdev->dev;
|
||||
|
||||
girq = &dev->gc.irq;
|
||||
girq->chip = &cp2112_gpio_irqchip;
|
||||
/* The event comes from the outside so no parent handler */
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
|
||||
ret = gpiochip_add_data(&dev->gc, dev);
|
||||
if (ret < 0) {
|
||||
hid_err(hdev, "error registering gpio chip\n");
|
||||
|
@ -1353,17 +1363,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
chmod_sysfs_attrs(hdev);
|
||||
hid_hw_power(hdev, PM_HINT_NORMAL);
|
||||
|
||||
ret = gpiochip_irqchip_add(&dev->gc, &cp2112_gpio_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_err(dev->gc.parent, "failed to add IRQ chip\n");
|
||||
goto err_sysfs_remove;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_sysfs_remove:
|
||||
sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group);
|
||||
err_gpiochip_remove:
|
||||
gpiochip_remove(&dev->gc);
|
||||
err_free_i2c:
|
||||
|
|
|
@ -1101,11 +1101,6 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
|
|||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while (kfifo_is_empty(&list->hid_debug_fifo)) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
@ -1122,6 +1117,11 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* allow O_NONBLOCK from other threads */
|
||||
mutex_unlock(&list->read_mutex);
|
||||
schedule();
|
||||
|
|
|
@ -727,6 +727,8 @@
|
|||
#define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062
|
||||
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
|
||||
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
|
||||
|
@ -1123,6 +1125,7 @@
|
|||
#define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968
|
||||
#define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7
|
||||
|
||||
#define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
|
||||
|
|
|
@ -797,7 +797,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|||
case 0x3b: /* Battery Strength */
|
||||
hidinput_setup_battery(device, HID_INPUT_REPORT, field);
|
||||
usage->type = EV_PWR;
|
||||
goto ignore;
|
||||
return;
|
||||
|
||||
case 0x3c: /* Invert */
|
||||
map_key_clear(BTN_TOOL_RUBBER);
|
||||
|
@ -1059,7 +1059,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|||
case HID_DC_BATTERYSTRENGTH:
|
||||
hidinput_setup_battery(device, HID_INPUT_REPORT, field);
|
||||
usage->type = EV_PWR;
|
||||
goto ignore;
|
||||
return;
|
||||
}
|
||||
goto unknown;
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ static const struct hid_device_id ite_devices[] = {
|
|||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) },
|
||||
/* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ite_devices);
|
||||
|
|
|
@ -1973,6 +1973,18 @@ static const struct hid_device_id mt_devices[] = {
|
|||
HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) },
|
||||
|
||||
/* Lenovo X1 TAB Gen 2 */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X1_TAB) },
|
||||
|
||||
/* Lenovo X1 TAB Gen 3 */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X1_TAB3) },
|
||||
|
||||
/* MosArt panels */
|
||||
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
|
||||
|
|
|
@ -294,31 +294,40 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
|
|||
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
|
||||
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
|
||||
int retval = 0, difference, old_profile;
|
||||
struct kone_settings *settings = (struct kone_settings *)buf;
|
||||
|
||||
/* I need to get my data in one piece */
|
||||
if (off != 0 || count != sizeof(struct kone_settings))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kone->kone_lock);
|
||||
difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings));
|
||||
difference = memcmp(settings, &kone->settings,
|
||||
sizeof(struct kone_settings));
|
||||
if (difference) {
|
||||
retval = kone_set_settings(usb_dev,
|
||||
(struct kone_settings const *)buf);
|
||||
if (retval) {
|
||||
mutex_unlock(&kone->kone_lock);
|
||||
return retval;
|
||||
if (settings->startup_profile < 1 ||
|
||||
settings->startup_profile > 5) {
|
||||
retval = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
retval = kone_set_settings(usb_dev, settings);
|
||||
if (retval)
|
||||
goto unlock;
|
||||
|
||||
old_profile = kone->settings.startup_profile;
|
||||
memcpy(&kone->settings, buf, sizeof(struct kone_settings));
|
||||
memcpy(&kone->settings, settings, sizeof(struct kone_settings));
|
||||
|
||||
kone_profile_activated(kone, kone->settings.startup_profile);
|
||||
|
||||
if (kone->settings.startup_profile != old_profile)
|
||||
kone_profile_report(kone, kone->settings.startup_profile);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&kone->kone_lock);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sizeof(struct kone_settings);
|
||||
}
|
||||
static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
|
||||
|
|
144
drivers/hid/hid-vivaldi.c
Normal file
144
drivers/hid/hid-vivaldi.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* HID support for Vivaldi Keyboard
|
||||
*
|
||||
* Copyright 2020 Google LLC.
|
||||
* Author: Sean O'Brien <seobrien@chromium.org>
|
||||
*/
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define MIN_FN_ROW_KEY 1
|
||||
#define MAX_FN_ROW_KEY 24
|
||||
#define HID_VD_FN_ROW_PHYSMAP 0x00000001
|
||||
#define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP)
|
||||
|
||||
static struct hid_driver hid_vivaldi;
|
||||
|
||||
struct vivaldi_data {
|
||||
u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1];
|
||||
int max_function_row_key;
|
||||
};
|
||||
|
||||
static ssize_t function_row_physmap_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
|
||||
ssize_t size = 0;
|
||||
int i;
|
||||
|
||||
if (!drvdata->max_function_row_key)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < drvdata->max_function_row_key; i++)
|
||||
size += sprintf(buf + size, "%02X ",
|
||||
drvdata->function_row_physmap[i]);
|
||||
size += sprintf(buf + size, "\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
DEVICE_ATTR_RO(function_row_physmap);
|
||||
static struct attribute *sysfs_attrs[] = {
|
||||
&dev_attr_function_row_physmap.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group input_attribute_group = {
|
||||
.attrs = sysfs_attrs
|
||||
};
|
||||
|
||||
static int vivaldi_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
struct vivaldi_data *drvdata;
|
||||
int ret;
|
||||
|
||||
drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
hid_set_drvdata(hdev, drvdata);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
static void vivaldi_feature_mapping(struct hid_device *hdev,
|
||||
struct hid_field *field,
|
||||
struct hid_usage *usage)
|
||||
{
|
||||
struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
|
||||
int fn_key;
|
||||
int ret;
|
||||
u32 report_len;
|
||||
u8 *buf;
|
||||
|
||||
if (field->logical != HID_USAGE_FN_ROW_PHYSMAP ||
|
||||
(usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL)
|
||||
return;
|
||||
|
||||
fn_key = (usage->hid & HID_USAGE);
|
||||
if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY)
|
||||
return;
|
||||
if (fn_key > drvdata->max_function_row_key)
|
||||
drvdata->max_function_row_key = fn_key;
|
||||
|
||||
buf = hid_alloc_report_buf(field->report, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
report_len = hid_report_len(field->report);
|
||||
ret = hid_hw_raw_request(hdev, field->report->id, buf,
|
||||
report_len, HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
if (ret < 0) {
|
||||
dev_warn(&hdev->dev, "failed to fetch feature %d\n",
|
||||
field->report->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
|
||||
report_len, 0);
|
||||
if (ret) {
|
||||
dev_warn(&hdev->dev, "failed to report feature %d\n",
|
||||
field->report->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
drvdata->function_row_physmap[fn_key - MIN_FN_ROW_KEY] =
|
||||
field->value[usage->usage_index];
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static int vivaldi_input_configured(struct hid_device *hdev,
|
||||
struct hid_input *hidinput)
|
||||
{
|
||||
return sysfs_create_group(&hdev->dev.kobj, &input_attribute_group);
|
||||
}
|
||||
|
||||
static const struct hid_device_id vivaldi_table[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_VIVALDI, HID_ANY_ID,
|
||||
HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(hid, vivaldi_table);
|
||||
|
||||
static struct hid_driver hid_vivaldi = {
|
||||
.name = "hid-vivaldi",
|
||||
.id_table = vivaldi_table,
|
||||
.probe = vivaldi_probe,
|
||||
.feature_mapping = vivaldi_feature_mapping,
|
||||
.input_configured = vivaldi_input_configured,
|
||||
};
|
||||
|
||||
module_hid_driver(hid_vivaldi);
|
||||
|
||||
MODULE_AUTHOR("Sean O'Brien");
|
||||
MODULE_DESCRIPTION("HID vivaldi driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -1586,7 +1586,7 @@ struct wiiproto_handler {
|
|||
void (*func)(struct wiimote_data *wdata, const __u8 *payload);
|
||||
};
|
||||
|
||||
static struct wiiproto_handler handlers[] = {
|
||||
static const struct wiiproto_handler handlers[] = {
|
||||
{ .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
|
||||
{ .id = WIIPROTO_REQ_STATUS, .size = 2, .func = handler_status_K },
|
||||
{ .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data },
|
||||
|
@ -1618,19 +1618,19 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
u8 *raw_data, int size)
|
||||
{
|
||||
struct wiimote_data *wdata = hid_get_drvdata(hdev);
|
||||
struct wiiproto_handler *h;
|
||||
const struct wiiproto_handler *h;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
if (size < 1)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
|
||||
for (i = 0; handlers[i].id; ++i) {
|
||||
h = &handlers[i];
|
||||
if (h->id == raw_data[0] && h->size < size) {
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
h->func(wdata, &raw_data[1]);
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1639,8 +1639,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0],
|
||||
size);
|
||||
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType,
|
|||
* @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT
|
||||
* @reportID: the report ID
|
||||
* @buf: the actual data to transfer, without the report ID
|
||||
* @len: size of buf
|
||||
* @data_len: size of buf
|
||||
* @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report
|
||||
*/
|
||||
static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType,
|
||||
|
@ -935,6 +935,14 @@ static void i2c_hid_acpi_fix_up_power(struct device *dev)
|
|||
acpi_device_fix_up_power(adev);
|
||||
}
|
||||
|
||||
static void i2c_hid_acpi_enable_wakeup(struct device *dev)
|
||||
{
|
||||
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
|
||||
device_set_wakeup_capable(dev, true);
|
||||
device_set_wakeup_enable(dev, false);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct acpi_device_id i2c_hid_acpi_match[] = {
|
||||
{"ACPI0C50", 0 },
|
||||
{"PNP0C50", 0 },
|
||||
|
@ -949,6 +957,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
|
|||
}
|
||||
|
||||
static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {}
|
||||
|
||||
static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
@ -1076,6 +1086,8 @@ static int i2c_hid_probe(struct i2c_client *client,
|
|||
|
||||
i2c_hid_acpi_fix_up_power(&client->dev);
|
||||
|
||||
i2c_hid_acpi_enable_wakeup(&client->dev);
|
||||
|
||||
device_enable_async_suspend(&client->dev);
|
||||
|
||||
/* Make sure there is something at this address */
|
||||
|
@ -1268,6 +1280,7 @@ static struct i2c_driver i2c_hid_driver = {
|
|||
.driver = {
|
||||
.name = "i2c_hid",
|
||||
.pm = &i2c_hid_pm,
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
|
||||
.of_match_table = of_match_ptr(i2c_hid_of_match),
|
||||
},
|
||||
|
|
|
@ -502,8 +502,6 @@ static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
|
|||
int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
|
||||
struct module *owner)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!ishtp_device_ready)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -511,11 +509,7 @@ int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
|
|||
driver->driver.owner = owner;
|
||||
driver->driver.bus = &ishtp_cl_bus_type;
|
||||
|
||||
err = driver_register(&driver->driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
return driver_register(&driver->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(ishtp_cl_driver_register);
|
||||
|
||||
|
|
|
@ -2773,7 +2773,9 @@ static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *repo
|
|||
if (report->type != HID_INPUT_REPORT)
|
||||
return -1;
|
||||
|
||||
if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
||||
if (WACOM_PAD_FIELD(field))
|
||||
return 0;
|
||||
else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
||||
wacom_wac_pen_report(hdev, report);
|
||||
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
|
||||
wacom_wac_finger_report(hdev, report);
|
||||
|
|
|
@ -163,6 +163,7 @@ struct hid_item {
|
|||
#define HID_UP_LNVENDOR 0xffa00000
|
||||
#define HID_UP_SENSOR 0x00200000
|
||||
#define HID_UP_ASUSVENDOR 0xff310000
|
||||
#define HID_UP_GOOGLEVENDOR 0xffd10000
|
||||
|
||||
#define HID_USAGE 0x0000ffff
|
||||
|
||||
|
@ -371,6 +372,7 @@ struct hid_item {
|
|||
#define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102
|
||||
#define HID_GROUP_STEAM 0x0103
|
||||
#define HID_GROUP_LOGITECH_27MHZ_DEVICE 0x0104
|
||||
#define HID_GROUP_VIVALDI 0x0105
|
||||
|
||||
/*
|
||||
* HID protocol status
|
||||
|
|
Loading…
Reference in New Issue
Block a user