| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ISHTP-HID glue driver. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2012-2016, Intel Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | #include <linux/hid.h> |
|---|
| 9 | +#include <linux/intel-ish-client-if.h> |
|---|
| 17 | 10 | #include <uapi/linux/input.h> |
|---|
| 18 | | -#include "ishtp/client.h" |
|---|
| 19 | 11 | #include "ishtp-hid.h" |
|---|
| 20 | 12 | |
|---|
| 21 | 13 | /** |
|---|
| .. | .. |
|---|
| 59 | 51 | { |
|---|
| 60 | 52 | } |
|---|
| 61 | 53 | |
|---|
| 62 | | -static int ishtp_raw_request(struct hid_device *hdev, unsigned char reportnum, |
|---|
| 63 | | - __u8 *buf, size_t len, unsigned char rtype, int reqtype) |
|---|
| 54 | +static int ishtp_raw_request(struct hid_device *hid, unsigned char reportnum, |
|---|
| 55 | + __u8 *buf, size_t len, unsigned char rtype, |
|---|
| 56 | + int reqtype) |
|---|
| 64 | 57 | { |
|---|
| 65 | | - return 0; |
|---|
| 58 | + struct ishtp_hid_data *hid_data = hid->driver_data; |
|---|
| 59 | + char *ishtp_buf = NULL; |
|---|
| 60 | + size_t ishtp_buf_len; |
|---|
| 61 | + unsigned int header_size = sizeof(struct hostif_msg); |
|---|
| 62 | + |
|---|
| 63 | + if (rtype == HID_OUTPUT_REPORT) |
|---|
| 64 | + return -EINVAL; |
|---|
| 65 | + |
|---|
| 66 | + hid_data->request_done = false; |
|---|
| 67 | + switch (reqtype) { |
|---|
| 68 | + case HID_REQ_GET_REPORT: |
|---|
| 69 | + hid_data->raw_buf = buf; |
|---|
| 70 | + hid_data->raw_buf_size = len; |
|---|
| 71 | + hid_data->raw_get_req = true; |
|---|
| 72 | + |
|---|
| 73 | + hid_ishtp_get_report(hid, reportnum, rtype); |
|---|
| 74 | + break; |
|---|
| 75 | + case HID_REQ_SET_REPORT: |
|---|
| 76 | + /* |
|---|
| 77 | + * Spare 7 bytes for 64b accesses through |
|---|
| 78 | + * get/put_unaligned_le64() |
|---|
| 79 | + */ |
|---|
| 80 | + ishtp_buf_len = len + header_size; |
|---|
| 81 | + ishtp_buf = kzalloc(ishtp_buf_len + 7, GFP_KERNEL); |
|---|
| 82 | + if (!ishtp_buf) |
|---|
| 83 | + return -ENOMEM; |
|---|
| 84 | + |
|---|
| 85 | + memcpy(ishtp_buf + header_size, buf, len); |
|---|
| 86 | + hid_ishtp_set_feature(hid, ishtp_buf, ishtp_buf_len, reportnum); |
|---|
| 87 | + kfree(ishtp_buf); |
|---|
| 88 | + break; |
|---|
| 89 | + } |
|---|
| 90 | + |
|---|
| 91 | + hid_hw_wait(hid); |
|---|
| 92 | + |
|---|
| 93 | + return len; |
|---|
| 66 | 94 | } |
|---|
| 67 | 95 | |
|---|
| 68 | 96 | /** |
|---|
| .. | .. |
|---|
| 87 | 115 | hid_data->request_done = false; |
|---|
| 88 | 116 | switch (reqtype) { |
|---|
| 89 | 117 | case HID_REQ_GET_REPORT: |
|---|
| 118 | + hid_data->raw_get_req = false; |
|---|
| 90 | 119 | hid_ishtp_get_report(hid, rep->id, rep->type); |
|---|
| 91 | 120 | break; |
|---|
| 92 | 121 | case HID_REQ_SET_REPORT: |
|---|
| .. | .. |
|---|
| 116 | 145 | static int ishtp_wait_for_response(struct hid_device *hid) |
|---|
| 117 | 146 | { |
|---|
| 118 | 147 | struct ishtp_hid_data *hid_data = hid->driver_data; |
|---|
| 119 | | - struct ishtp_cl_data *client_data = hid_data->client_data; |
|---|
| 120 | 148 | int rv; |
|---|
| 121 | 149 | |
|---|
| 122 | 150 | hid_ishtp_trace(client_data, "%s hid %p\n", __func__, hid); |
|---|
| .. | .. |
|---|
| 204 | 232 | |
|---|
| 205 | 233 | hid->ll_driver = &ishtp_hid_ll_driver; |
|---|
| 206 | 234 | hid->bus = BUS_INTEL_ISHTP; |
|---|
| 207 | | - hid->dev.parent = &client_data->cl_device->dev; |
|---|
| 235 | + hid->dev.parent = ishtp_device(client_data->cl_device); |
|---|
| 236 | + |
|---|
| 208 | 237 | hid->version = le16_to_cpu(ISH_HID_VERSION); |
|---|
| 209 | | - hid->vendor = le16_to_cpu(ISH_HID_VENDOR); |
|---|
| 210 | | - hid->product = le16_to_cpu(ISH_HID_PRODUCT); |
|---|
| 238 | + hid->vendor = le16_to_cpu(client_data->hid_devices[cur_hid_dev].vid); |
|---|
| 239 | + hid->product = le16_to_cpu(client_data->hid_devices[cur_hid_dev].pid); |
|---|
| 211 | 240 | snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-ishtp", |
|---|
| 212 | 241 | hid->vendor, hid->product); |
|---|
| 213 | 242 | |
|---|