^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ISHTP-HID glue driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2012-2016, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/intel-ish-client-if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <uapi/linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "ishtp-hid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * ishtp_hid_parse() - hid-core .parse() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @hid: hid device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * This function gets called during call to hid_add_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Return: 0 on success and non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int ishtp_hid_parse(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct ishtp_cl_data *client_data = hid_data->client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) rv = hid_parse_report(hid, client_data->report_descr[hid_data->index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) client_data->report_descr_size[hid_data->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Empty callbacks with success return code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int ishtp_hid_start(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static void ishtp_hid_stop(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int ishtp_hid_open(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void ishtp_hid_close(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int ishtp_raw_request(struct hid_device *hid, unsigned char reportnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __u8 *buf, size_t len, unsigned char rtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int reqtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) char *ishtp_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) size_t ishtp_buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int header_size = sizeof(struct hostif_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (rtype == HID_OUTPUT_REPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) hid_data->request_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) switch (reqtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case HID_REQ_GET_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) hid_data->raw_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) hid_data->raw_buf_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) hid_data->raw_get_req = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) hid_ishtp_get_report(hid, reportnum, rtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case HID_REQ_SET_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Spare 7 bytes for 64b accesses through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * get/put_unaligned_le64()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ishtp_buf_len = len + header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ishtp_buf = kzalloc(ishtp_buf_len + 7, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!ishtp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) memcpy(ishtp_buf + header_size, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) hid_ishtp_set_feature(hid, ishtp_buf, ishtp_buf_len, reportnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) kfree(ishtp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) hid_hw_wait(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * ishtp_hid_request() - hid-core .request() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @hid: hid device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @rep: pointer to hid_report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @reqtype: type of req. [GET|SET]_REPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * This function is used to set/get feaure/input report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void ishtp_hid_request(struct hid_device *hid, struct hid_report *rep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int reqtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* the specific report length, just HID part of it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int len = ((rep->size - 1) >> 3) + 1 + (rep->id > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int header_size = sizeof(struct hostif_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) len += header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) hid_data->request_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) switch (reqtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) case HID_REQ_GET_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) hid_data->raw_get_req = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) hid_ishtp_get_report(hid, rep->id, rep->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case HID_REQ_SET_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * Spare 7 bytes for 64b accesses through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * get/put_unaligned_le64()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) buf = kzalloc(len + 7, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) hid_output_report(rep, buf + header_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) hid_ishtp_set_feature(hid, buf, len, rep->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * ishtp_wait_for_response() - hid-core .wait() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @hid: hid device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * This function is used to wait after get feaure/input report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Return: 0 on success and non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int ishtp_wait_for_response(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) hid_ishtp_trace(client_data, "%s hid %p\n", __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rv = ishtp_hid_link_ready_wait(hid_data->client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!hid_data->request_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) wait_event_interruptible_timeout(hid_data->hid_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hid_data->request_done, 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (!hid_data->request_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hid_err(hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "timeout waiting for response from ISHTP device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) hid_ishtp_trace(client_data, "%s hid %p done\n", __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) hid_data->request_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * ishtp_hid_wakeup() - Wakeup caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @hid: hid device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * This function will wakeup caller waiting for Get/Set feature report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) void ishtp_hid_wakeup(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) hid_data->request_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) wake_up_interruptible(&hid_data->hid_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static struct hid_ll_driver ishtp_hid_ll_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .parse = ishtp_hid_parse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .start = ishtp_hid_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .stop = ishtp_hid_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .open = ishtp_hid_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .close = ishtp_hid_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .request = ishtp_hid_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .wait = ishtp_wait_for_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .raw_request = ishtp_raw_request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * ishtp_hid_probe() - hid register ll driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @cur_hid_dev: Index of hid device calling to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @client_data: Client data pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * This function is used to allocate and add HID device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ishtp_hid_probe(unsigned int cur_hid_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct ishtp_cl_data *client_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct ishtp_hid_data *hid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) hid = hid_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (IS_ERR(hid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) rv = PTR_ERR(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) hid_data = kzalloc(sizeof(*hid_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!hid_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rv = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto err_hid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) hid_data->index = cur_hid_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) hid_data->client_data = client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) init_waitqueue_head(&hid_data->hid_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) hid->driver_data = hid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) client_data->hid_sensor_hubs[cur_hid_dev] = hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) hid->ll_driver = &ishtp_hid_ll_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) hid->bus = BUS_INTEL_ISHTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) hid->dev.parent = ishtp_device(client_data->cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) hid->version = le16_to_cpu(ISH_HID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) hid->vendor = le16_to_cpu(client_data->hid_devices[cur_hid_dev].vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) hid->product = le16_to_cpu(client_data->hid_devices[cur_hid_dev].pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-ishtp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) hid->vendor, hid->product);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rv = hid_add_device(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto err_hid_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) hid_ishtp_trace(client_data, "%s allocated hid %p\n", __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) err_hid_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) kfree(hid_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) err_hid_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) hid_destroy_device(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * ishtp_hid_probe() - Remove registered hid device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @client_data: client data pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * This function is used to destroy allocatd HID device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) void ishtp_hid_remove(struct ishtp_cl_data *client_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (client_data->hid_sensor_hubs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) kfree(client_data->hid_sensor_hubs[i]->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) hid_destroy_device(client_data->hid_sensor_hubs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) client_data->hid_sensor_hubs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }