^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 client driver for HID (ISH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2014-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/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/intel-ish-client-if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "ishtp-hid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* Rx ring buffer pool size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define HID_CL_RX_RING_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define HID_CL_TX_RING_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define cl_data_to_dev(client_data) ishtp_device(client_data->cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * report_bad_packets() - Report bad packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @hid_ishtp_cl: Client instance to get stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @recv_buf: Raw received host interface message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @cur_pos: Current position index in payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @payload_len: Length of payload expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Dumps error in case bad packet is received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static void report_bad_packet(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) size_t cur_pos, size_t payload_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct hostif_msg *recv_msg = recv_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) dev_err(cl_data_to_dev(client_data), "[hid-ish]: BAD packet %02X\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "total_bad=%u cur_pos=%u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "[%02X %02X %02X %02X]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "payload_len=%u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "multi_packet_cnt=%u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "is_response=%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) recv_msg->hdr.command, client_data->bad_recv_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (unsigned int)cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ((unsigned char *)recv_msg)[0], ((unsigned char *)recv_msg)[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ((unsigned char *)recv_msg)[2], ((unsigned char *)recv_msg)[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) (unsigned int)payload_len, client_data->multi_packet_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) recv_msg->hdr.command & ~CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^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) * process_recv() - Received and parse incoming packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @hid_ishtp_cl: Client instance to get stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @recv_buf: Raw received host interface message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @data_len: length of the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Parse the incoming packet. If it is a response packet then it will update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * per instance flags and wake up the caller waiting to for the response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) size_t data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct hostif_msg *recv_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned char *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct device_info *dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) size_t payload_len, total_len, cur_pos, raw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct report_list *reports_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) char *reports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) size_t report_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int curr_hid_dev = client_data->cur_hid_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ishtp_hid_data *hid_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct hid_device *hid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) payload = recv_buf + sizeof(struct hostif_msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) total_len = data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) cur_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (cur_pos + sizeof(struct hostif_msg) > total_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "[hid-ish]: error, received %u which is less than data header %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) (unsigned int)data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (unsigned int)sizeof(struct hostif_msg_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) recv_msg = (struct hostif_msg *)(recv_buf + cur_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) payload_len = recv_msg->hdr.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (cur_pos + payload_len + sizeof(struct hostif_msg) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) total_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) hid_ishtp_trace(client_data, "%s %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __func__, recv_msg->hdr.command & CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) switch (recv_msg->hdr.command & CMD_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case HOSTIF_DM_ENUM_DEVICES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) client_data->init_done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) report_bad_packet(hid_ishtp_cl, recv_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) client_data->hid_dev_count = (unsigned int)*payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!client_data->hid_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) client_data->hid_devices = devm_kcalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) client_data->hid_dev_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sizeof(struct device_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (!client_data->hid_devices) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "Mem alloc failed for hid device info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) wake_up_interruptible(&client_data->init_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (i = 0; i < client_data->hid_dev_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (1 + sizeof(struct device_info) * i >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) payload_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "[hid-ish]: [ENUM_DEVICES]: content size %zu is bigger than payload_len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 1 + sizeof(struct device_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * i, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (1 + sizeof(struct device_info) * i >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev_info = (struct device_info *)(payload + 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) sizeof(struct device_info) * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (client_data->hid_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) memcpy(client_data->hid_devices + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sizeof(struct device_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) client_data->enum_devices_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) wake_up_interruptible(&client_data->init_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case HOSTIF_GET_HID_DESCRIPTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) client_data->init_done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) report_bad_packet(hid_ishtp_cl, recv_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!client_data->hid_descr[curr_hid_dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) client_data->hid_descr[curr_hid_dev] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) devm_kmalloc(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) payload_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (client_data->hid_descr[curr_hid_dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memcpy(client_data->hid_descr[curr_hid_dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) payload, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) client_data->hid_descr_size[curr_hid_dev] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) client_data->hid_descr_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) wake_up_interruptible(&client_data->init_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case HOSTIF_GET_REPORT_DESCRIPTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) client_data->init_done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) report_bad_packet(hid_ishtp_cl, recv_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!client_data->report_descr[curr_hid_dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) client_data->report_descr[curr_hid_dev] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) devm_kmalloc(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) payload_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (client_data->report_descr[curr_hid_dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) memcpy(client_data->report_descr[curr_hid_dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) client_data->report_descr_size[curr_hid_dev] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) client_data->report_descr_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) wake_up_interruptible(&client_data->init_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case HOSTIF_GET_FEATURE_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) report_type = HID_FEATURE_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto do_get_report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case HOSTIF_GET_INPUT_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) report_type = HID_INPUT_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) do_get_report:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Get index of device that matches this id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (recv_msg->hdr.device_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) client_data->hid_devices[i].dev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) hid = client_data->hid_sensor_hubs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (hid_data->raw_get_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) raw_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) (hid_data->raw_buf_size <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) payload_len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) hid_data->raw_buf_size :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) memcpy(hid_data->raw_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) payload, raw_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) hid_input_report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) (hid, report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) payload, payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ishtp_hid_wakeup(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case HOSTIF_SET_FEATURE_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Get index of device that matches this id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (recv_msg->hdr.device_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) client_data->hid_devices[i].dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (client_data->hid_sensor_hubs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ishtp_hid_wakeup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) client_data->hid_sensor_hubs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case HOSTIF_PUBLISH_INPUT_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) report_type = HID_INPUT_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (i = 0; i < client_data->num_hid_devices; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (recv_msg->hdr.device_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) client_data->hid_devices[i].dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (client_data->hid_sensor_hubs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hid_input_report(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) client_data->hid_sensor_hubs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) report_type, payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) payload_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case HOSTIF_PUBLISH_INPUT_REPORT_LIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) report_type = HID_INPUT_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) reports_list = (struct report_list *)payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) reports = (char *)reports_list->reports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) for (j = 0; j < reports_list->num_of_reports; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) recv_msg = (struct hostif_msg *)(reports +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) sizeof(uint16_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) report_len = *(uint16_t *)reports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) payload = reports + sizeof(uint16_t) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sizeof(struct hostif_msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) payload_len = report_len -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sizeof(struct hostif_msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) for (i = 0; i < client_data->num_hid_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (recv_msg->hdr.device_id ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) client_data->hid_devices[i].dev_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) client_data->hid_sensor_hubs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) hid_input_report(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) client_data->hid_sensor_hubs[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) payload, payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) reports += sizeof(uint16_t) + report_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ++client_data->bad_recv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!cur_pos && cur_pos + payload_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sizeof(struct hostif_msg) < total_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ++client_data->multi_packet_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) cur_pos += payload_len + sizeof(struct hostif_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) payload += payload_len + sizeof(struct hostif_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) } while (cur_pos < total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * ish_cl_event_cb() - bus driver callback for incoming message/packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * @device: Pointer to the the ishtp client device for which this message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * is targeted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Remove the packet from the list and process the message by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * process_recv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static void ish_cl_event_cb(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct ishtp_cl_rb *rb_in_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) size_t r_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!hid_ishtp_cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) while ((rb_in_proc = ishtp_cl_rx_get_rb(hid_ishtp_cl)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!rb_in_proc->buffer.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) r_length = rb_in_proc->buf_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* decide what to do with received data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) process_recv(hid_ishtp_cl, rb_in_proc->buffer.data, r_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ishtp_cl_io_rb_recycle(rb_in_proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * hid_ishtp_set_feature() - send request to ISH FW to set a feature request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @hid: hid device instance for this request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @buf: feature buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @len: Length of feature buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @report_id: Report id for the feature set request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * This is called from hid core .request() callback. This function doesn't wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * for response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) void hid_ishtp_set_feature(struct hid_device *hid, char *buf, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int report_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct ishtp_cl_data *client_data = hid_data->client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct hostif_msg *msg = (struct hostif_msg *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) hid_ishtp_trace(client_data, "%s hid %p\n", __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rv = ishtp_hid_link_ready_wait(client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) hid_ishtp_trace(client_data, "%s hid %p link not ready\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) memset(msg, 0, sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) msg->hdr.command = HOSTIF_SET_FEATURE_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (hid == client_data->hid_sensor_hubs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) msg->hdr.device_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) client_data->hid_devices[i].dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (i == client_data->num_hid_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rv = ishtp_cl_send(client_data->hid_ishtp_cl, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) hid_ishtp_trace(client_data, "%s hid %p send failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * hid_ishtp_get_report() - request to get feature/input report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * @hid: hid device instance for this request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * @report_id: Report id for the get request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * @report_type: Report type for the this request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * This is called from hid core .request() callback. This function will send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * request to FW and return without waiting for response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) void hid_ishtp_get_report(struct hid_device *hid, int report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int report_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct ishtp_hid_data *hid_data = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ishtp_cl_data *client_data = hid_data->client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct hostif_msg_to_sensor msg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) hid_ishtp_trace(client_data, "%s hid %p\n", __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) rv = ishtp_hid_link_ready_wait(client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) hid_ishtp_trace(client_data, "%s hid %p link not ready\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) msg.hdr.command = (report_type == HID_FEATURE_REPORT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (hid == client_data->hid_sensor_hubs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) msg.hdr.device_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) client_data->hid_devices[i].dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (i == client_data->num_hid_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) msg.report_id = report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rv = ishtp_cl_send(client_data->hid_ishtp_cl, (uint8_t *)&msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) hid_ishtp_trace(client_data, "%s hid %p send failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __func__, hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * ishtp_hid_link_ready_wait() - Wait for link ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * @client_data: client data instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * If the transport link started suspend process, then wait, till either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * resumed or timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int ishtp_hid_link_ready_wait(struct ishtp_cl_data *client_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (client_data->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) hid_ishtp_trace(client_data, "wait for link ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rc = wait_event_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) client_data->ishtp_resume_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) !client_data->suspended,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) hid_ishtp_trace(client_data, "link not ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hid_ishtp_trace(client_data, "link ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * ishtp_enum_enum_devices() - Enumerate hid devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * @hid_ishtp_cl: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * Helper function to send request to firmware to enumerate HID devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static int ishtp_enum_enum_devices(struct ishtp_cl *hid_ishtp_cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct hostif_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Send HOSTIF_DM_ENUM_DEVICES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) memset(&msg, 0, sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) msg.hdr.command = HOSTIF_DM_ENUM_DEVICES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *)&msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) while (!client_data->enum_devices_done &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) retry_count < 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) wait_event_interruptible_timeout(client_data->init_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) client_data->enum_devices_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ++retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!client_data->enum_devices_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Send HOSTIF_DM_ENUM_DEVICES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) rv = ishtp_cl_send(hid_ishtp_cl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) (unsigned char *) &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (!client_data->enum_devices_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) "[hid-ish]: timed out waiting for enum_devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (!client_data->hid_devices) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) "[hid-ish]: failed to allocate HID dev structures\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) client_data->num_hid_devices = client_data->hid_dev_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) dev_info(ishtp_device(client_data->cl_device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) "[hid-ish]: enum_devices_done OK, num_hid_devices=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) client_data->num_hid_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * ishtp_get_hid_descriptor() - Get hid descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @hid_ishtp_cl: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @index: Index into the hid_descr array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * Helper function to send request to firmware get HID descriptor of a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int ishtp_get_hid_descriptor(struct ishtp_cl *hid_ishtp_cl, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct hostif_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* Get HID descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) client_data->hid_descr_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) memset(&msg, 0, sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) msg.hdr.command = HOSTIF_GET_HID_DESCRIPTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) msg.hdr.device_id = client_data->hid_devices[index].dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *) &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!client_data->hid_descr_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) wait_event_interruptible_timeout(client_data->init_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) client_data->hid_descr_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (!client_data->hid_descr_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) "[hid-ish]: timed out for hid_descr_done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!client_data->hid_descr[index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "[hid-ish]: allocation HID desc fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * ishtp_get_report_descriptor() - Get report descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * @hid_ishtp_cl: client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * @index: Index into the hid_descr array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * Helper function to send request to firmware get HID report descriptor of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int ishtp_get_report_descriptor(struct ishtp_cl *hid_ishtp_cl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct hostif_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* Get report descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) client_data->report_descr_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) memset(&msg, 0, sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) msg.hdr.command = HOSTIF_GET_REPORT_DESCRIPTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) msg.hdr.device_id = client_data->hid_devices[index].dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *) &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) sizeof(struct hostif_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!client_data->report_descr_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) wait_event_interruptible_timeout(client_data->init_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) client_data->report_descr_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!client_data->report_descr_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) "[hid-ish]: timed out for report descr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!client_data->report_descr[index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) "[hid-ish]: failed to alloc report descr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * hid_ishtp_cl_init() - Init function for ISHTP client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * @hid_ishtp_cl: ISHTP client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * @reset: true if called for init after reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * This function complete the initializtion of the client. The summary of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * processing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * - Send request to enumerate the hid clients
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * Get the HID descriptor for each enumearated device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Get report description of each device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * Register each device wik hid core by calling ishtp_hid_probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct ishtp_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct ishtp_fw_client *fw_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) dev_dbg(cl_data_to_dev(client_data), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) hid_ishtp_trace(client_data, "%s reset flag: %d\n", __func__, reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) rv = ishtp_cl_link(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) "ishtp_cl_link failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) client_data->init_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dev = ishtp_get_ishtp_device(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Connect to FW client */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ishtp_set_tx_ring_size(hid_ishtp_cl, HID_CL_TX_RING_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ishtp_set_rx_ring_size(hid_ishtp_cl, HID_CL_RX_RING_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_guid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (!fw_client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) "ish client uuid not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ishtp_cl_set_fw_client_id(hid_ishtp_cl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ishtp_get_fw_client_id(fw_client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_CONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) rv = ishtp_cl_connect(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) "client connect fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto err_cl_unlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) hid_ishtp_trace(client_data, "%s client connected\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* Register read callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ishtp_register_event_cb(client_data->cl_device, ish_cl_event_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) rv = ishtp_enum_enum_devices(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto err_cl_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) hid_ishtp_trace(client_data, "%s enumerated device count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) __func__, client_data->num_hid_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) for (i = 0; i < client_data->num_hid_devices; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) client_data->cur_hid_dev = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) rv = ishtp_get_hid_descriptor(hid_ishtp_cl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) goto err_cl_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) rv = ishtp_get_report_descriptor(hid_ishtp_cl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) goto err_cl_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) rv = ishtp_hid_probe(i, client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dev_err(cl_data_to_dev(client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) "[hid-ish]: HID probe for #%u failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) i, rv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto err_cl_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) } /* for() on all hid devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) client_data->init_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) client_data->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) wake_up_interruptible(&client_data->ishtp_resume_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) hid_ishtp_trace(client_data, "%s successful init\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) err_cl_disconnect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_DISCONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ishtp_cl_disconnect(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) err_cl_unlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ishtp_cl_unlink(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * hid_ishtp_cl_deinit() - Deinit function for ISHTP client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * @hid_ishtp_cl: ISHTP client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * Unlink and free hid client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static void hid_ishtp_cl_deinit(struct ishtp_cl *hid_ishtp_cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ishtp_cl_unlink(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ishtp_cl_flush_queues(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* disband and free all Tx and Rx client-level rings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ishtp_cl_free(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void hid_ishtp_cl_reset_handler(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct ishtp_cl_data *client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct ishtp_cl *hid_ishtp_cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct ishtp_cl_device *cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) int retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) client_data = container_of(work, struct ishtp_cl_data, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) hid_ishtp_cl = client_data->hid_ishtp_cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) cl_device = client_data->cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dev_dbg(ishtp_device(client_data->cl_device), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) hid_ishtp_cl_deinit(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) hid_ishtp_cl = ishtp_cl_allocate(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!hid_ishtp_cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ishtp_set_drvdata(cl_device, hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ishtp_set_client_data(hid_ishtp_cl, client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) client_data->hid_ishtp_cl = hid_ishtp_cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) client_data->num_hid_devices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) for (retry = 0; retry < 3; ++retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) rv = hid_ishtp_cl_init(hid_ishtp_cl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_err(cl_data_to_dev(client_data), "Retry reset init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) dev_err(cl_data_to_dev(client_data), "Reset Failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) hid_ishtp_trace(client_data, "%s Failed hid_ishtp_cl %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) __func__, hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) void (*hid_print_trace)(void *unused, const char *format, ...);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * hid_ishtp_cl_probe() - ISHTP client driver probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * @cl_device: ISHTP client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * This function gets called on device create on ISHTP bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * Return: 0 on success, non zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct ishtp_cl *hid_ishtp_cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct ishtp_cl_data *client_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) client_data = devm_kzalloc(ishtp_device(cl_device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) sizeof(*client_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (!client_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) hid_ishtp_cl = ishtp_cl_allocate(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (!hid_ishtp_cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ishtp_set_drvdata(cl_device, hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ishtp_set_client_data(hid_ishtp_cl, client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) client_data->hid_ishtp_cl = hid_ishtp_cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) client_data->cl_device = cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) init_waitqueue_head(&client_data->init_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) init_waitqueue_head(&client_data->ishtp_resume_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) INIT_WORK(&client_data->work, hid_ishtp_cl_reset_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) hid_print_trace = ishtp_trace_callback(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) rv = hid_ishtp_cl_init(hid_ishtp_cl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ishtp_cl_free(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ishtp_get_device(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * hid_ishtp_cl_remove() - ISHTP client driver remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * @cl_device: ISHTP client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * This function gets called on device remove on ISHTP bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev_dbg(ishtp_device(cl_device), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_DISCONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ishtp_cl_disconnect(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ishtp_put_device(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ishtp_hid_remove(client_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) hid_ishtp_cl_deinit(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) hid_ishtp_cl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) client_data->num_hid_devices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * hid_ishtp_cl_reset() - ISHTP client driver reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * @cl_device: ISHTP client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * This function gets called on device reset on ISHTP bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) schedule_work(&client_data->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * hid_ishtp_cl_suspend() - ISHTP client driver suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * @device: device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * This function gets called on system suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static int hid_ishtp_cl_suspend(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) client_data->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * hid_ishtp_cl_resume() - ISHTP client driver resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * @device: device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * This function gets called on system resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int hid_ishtp_cl_resume(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) hid_ishtp_cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) client_data->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static const struct dev_pm_ops hid_ishtp_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .suspend = hid_ishtp_cl_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .resume = hid_ishtp_cl_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static struct ishtp_cl_driver hid_ishtp_cl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .name = "ish-hid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .guid = &hid_ishtp_guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .probe = hid_ishtp_cl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .remove = hid_ishtp_cl_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .reset = hid_ishtp_cl_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .driver.pm = &hid_ishtp_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int __init ish_hid_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Register ISHTP client device driver with ISHTP Bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) rv = ishtp_cl_driver_register(&hid_ishtp_cl_driver, THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static void __exit ish_hid_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ishtp_cl_driver_unregister(&hid_ishtp_cl_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) late_initcall(ish_hid_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) module_exit(ish_hid_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) MODULE_DESCRIPTION("ISH ISHTP HID client driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* Primary author */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) MODULE_AUTHOR("Daniel Drubin <daniel.drubin@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Several modification for multi instance support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * suspend/resume and clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) MODULE_ALIAS("ishtp:*");