| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2013 Andrew Duggan <aduggan@synaptics.com> |
|---|
| 3 | 4 | * Copyright (c) 2013 Synaptics Incorporated |
|---|
| 4 | 5 | * Copyright (c) 2014 Benjamin Tissoires <benjamin.tissoires@gmail.com> |
|---|
| 5 | 6 | * Copyright (c) 2014 Red Hat, Inc |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 8 | | - * under the terms of the GNU General Public License as published by the Free |
|---|
| 9 | | - * Software Foundation; either version 2 of the License, or (at your option) |
|---|
| 10 | | - * any later version. |
|---|
| 11 | 7 | */ |
|---|
| 12 | 8 | |
|---|
| 13 | 9 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 39 | 35 | /* device flags */ |
|---|
| 40 | 36 | #define RMI_DEVICE BIT(0) |
|---|
| 41 | 37 | #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) |
|---|
| 38 | +#define RMI_DEVICE_OUTPUT_SET_REPORT BIT(2) |
|---|
| 42 | 39 | |
|---|
| 43 | 40 | /* |
|---|
| 44 | 41 | * retrieve the ctrl registers |
|---|
| .. | .. |
|---|
| 167 | 164 | |
|---|
| 168 | 165 | static int rmi_write_report(struct hid_device *hdev, u8 *report, int len) |
|---|
| 169 | 166 | { |
|---|
| 167 | + struct rmi_data *data = hid_get_drvdata(hdev); |
|---|
| 170 | 168 | int ret; |
|---|
| 171 | 169 | |
|---|
| 172 | | - ret = hid_hw_output_report(hdev, (void *)report, len); |
|---|
| 170 | + if (data->device_flags & RMI_DEVICE_OUTPUT_SET_REPORT) { |
|---|
| 171 | + /* |
|---|
| 172 | + * Talk to device by using SET_REPORT requests instead. |
|---|
| 173 | + */ |
|---|
| 174 | + ret = hid_hw_raw_request(hdev, report[0], report, |
|---|
| 175 | + len, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
|---|
| 176 | + } else { |
|---|
| 177 | + ret = hid_hw_output_report(hdev, (void *)report, len); |
|---|
| 178 | + } |
|---|
| 179 | + |
|---|
| 173 | 180 | if (ret < 0) { |
|---|
| 174 | 181 | dev_err(&hdev->dev, "failed to write hid report (%d)\n", ret); |
|---|
| 175 | 182 | return ret; |
|---|
| .. | .. |
|---|
| 210 | 217 | ret = rmi_write_report(hdev, data->writeReport, |
|---|
| 211 | 218 | data->output_report_size); |
|---|
| 212 | 219 | if (ret != data->output_report_size) { |
|---|
| 213 | | - clear_bit(RMI_READ_REQUEST_PENDING, &data->flags); |
|---|
| 214 | 220 | dev_err(&hdev->dev, |
|---|
| 215 | 221 | "failed to write request output report (%d)\n", |
|---|
| 216 | 222 | ret); |
|---|
| .. | .. |
|---|
| 422 | 428 | |
|---|
| 423 | 429 | switch (report->id) { |
|---|
| 424 | 430 | case RMI_READ_DATA_REPORT_ID: |
|---|
| 425 | | - /* fall-through */ |
|---|
| 426 | 431 | case RMI_ATTN_REPORT_ID: |
|---|
| 427 | 432 | return; |
|---|
| 428 | 433 | } |
|---|
| .. | .. |
|---|
| 715 | 720 | } |
|---|
| 716 | 721 | |
|---|
| 717 | 722 | if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) |
|---|
| 718 | | - rmi_hid_pdata.f30_data.disable = true; |
|---|
| 723 | + rmi_hid_pdata.gpio_data.disable = true; |
|---|
| 719 | 724 | |
|---|
| 720 | 725 | data->xport.dev = hdev->dev.parent; |
|---|
| 721 | 726 | data->xport.pdata = rmi_hid_pdata; |
|---|
| .. | .. |
|---|
| 752 | 757 | .driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS }, |
|---|
| 753 | 758 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) }, |
|---|
| 754 | 759 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) }, |
|---|
| 760 | + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5), |
|---|
| 761 | + .driver_data = RMI_DEVICE_OUTPUT_SET_REPORT }, |
|---|
| 755 | 762 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) }, |
|---|
| 756 | 763 | { } |
|---|
| 757 | 764 | }; |
|---|