summaryrefslogtreecommitdiff
path: root/drivers/hid/intel-ish-hid/ishtp-hid.h
blob: 5ffd0da3cf1faacb2d7d786b4446eead3cfcd428 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * ISHTP-HID glue driver's definitions.
 *
 * Copyright (c) 2014-2016, Intel Corporation.
 */
#ifndef ISHTP_HID__H
#define	ISHTP_HID__H

/* The fixed ISH product and vendor id */
#define	ISH_HID_VENDOR	0x8086
#define	ISH_HID_PRODUCT	0x22D8
#define	ISH_HID_VERSION	0x0200

#define	CMD_MASK	0x7F
#define	IS_RESPONSE	0x80

/* Used to dump to Linux trace buffer, if enabled */
extern void (*hid_print_trace)(void *unused, const char *format, ...);
#define hid_ishtp_trace(client, ...) \
		(hid_print_trace)(NULL, __VA_ARGS__)

/* ISH Transport protocol (ISHTP in short) GUID */
static const guid_t hid_ishtp_guid =
	GUID_INIT(0x33AECD58, 0xB679, 0x4E54,
		  0x9B, 0xD9, 0xA0, 0x4D, 0x34, 0xF0, 0xC2, 0x26);

/* ISH HID message structure */
struct hostif_msg_hdr {
	uint8_t	command; /* Bit 7: is_response */
	uint8_t	device_id;
	uint8_t	status;
	uint8_t	flags;
	uint16_t size;
} __packed;

struct hostif_msg {
	struct hostif_msg_hdr	hdr;
} __packed;

struct hostif_msg_to_sensor {
	struct hostif_msg_hdr	hdr;
	uint8_t	report_id;
} __packed;

struct device_info {
	uint32_t dev_id;
	uint8_t dev_class;
	uint16_t pid;
	uint16_t vid;
} __packed;

struct ishtp_version {
	uint8_t	major;
	uint8_t	minor;
	uint8_t	hotfix;
	uint16_t build;
} __packed;

/* struct for ISHTP aggregated input data */
struct report_list {
	uint16_t total_size;
	uint8_t	num_of_reports;
	uint8_t	flags;
	struct {
		uint16_t	size_of_report;
		uint8_t report[1];
	} __packed reports[1];
} __packed;

/* HOSTIF commands */
#define	HOSTIF_HID_COMMAND_BASE			0
#define	HOSTIF_GET_HID_DESCRIPTOR		0
#define	HOSTIF_GET_REPORT_DESCRIPTOR		1
#define HOSTIF_GET_FEATURE_REPORT		2
#define	HOSTIF_SET_FEATURE_REPORT		3
#define	HOSTIF_GET_INPUT_REPORT			4
#define	HOSTIF_PUBLISH_INPUT_REPORT		5
#define	HOSTIF_PUBLISH_INPUT_REPORT_LIST	6
#define	HOSTIF_DM_COMMAND_BASE			32
#define	HOSTIF_DM_ENUM_DEVICES			33
#define	HOSTIF_DM_ADD_DEVICE			34

#define	MAX_HID_DEVICES				32

/**
 * struct ishtp_cl_data - Encapsulate per ISH TP HID Client
 * @enum_device_done:	Enum devices response complete flag
 * @hid_descr_done:	HID descriptor complete flag
 * @report_descr_done:	Get report descriptor complete flag
 * @init_done:		Init process completed successfully
 * @suspended:		System is under suspend state or in progress
 * @num_hid_devices:	Number of HID devices enumerated in this client
 * @cur_hid_dev:	This keeps track of the device index for which
 *			initialization and registration with HID core
 *			in progress.
 * @hid_devices:	Store vid/pid/devid for each enumerated HID device
 * @report_descr:	Stores the raw report descriptors for each HID device
 * @report_descr_size:	Report description of size of above repo_descr[]
 * @hid_sensor_hubs:	Pointer to hid_device for all HID device, so that
 *			when clients are removed, they can be freed
 * @hid_descr:		Pointer to hid descriptor for each enumerated hid
 *			device
 * @hid_descr_size:	Size of each above report descriptor
 * @init_wait:		Wait queue to wait during initialization, where the
 *			client send message to ISH FW and wait for response
 * @ishtp_hid_wait:	The wait for get report during wait callback from hid
 *			core
 * @bad_recv_cnt:	Running count of packets received with error
 * @multi_packet_cnt:	Count of fragmented packet count
 *
 * This structure is used to store completion flags and per client data like
 * like report description, number of HID devices etc.
 */
struct ishtp_cl_data {
	/* completion flags */
	bool enum_devices_done;
	bool hid_descr_done;
	bool report_descr_done;
	bool init_done;
	bool suspended;

	unsigned int num_hid_devices;
	unsigned int cur_hid_dev;
	unsigned int hid_dev_count;

	struct device_info *hid_devices;
	unsigned char *report_descr[MAX_HID_DEVICES];
	int report_descr_size[MAX_HID_DEVICES];
	struct hid_device *hid_sensor_hubs[MAX_HID_DEVICES];
	unsigned char *hid_descr[MAX_HID_DEVICES];
	int hid_descr_size[MAX_HID_DEVICES];

	wait_queue_head_t init_wait;
	wait_queue_head_t ishtp_resume_wait;
	struct ishtp_cl *hid_ishtp_cl;

	/* Statistics */
	unsigned int bad_recv_cnt;
	int multi_packet_cnt;

	struct work_struct work;
	struct ishtp_cl_device *cl_device;
};

/**
 * struct ishtp_hid_data - Per instance HID data
 * @index:		Device index in the order of enumeration
 * @request_done:	Get Feature/Input report complete flag
 *			used during get/set request from hid core
 * @client_data:	Link to the client instance
 * @hid_wait:		Completion waitq
 *
 * @raw_get_req:	Flag indicating raw get request ongoing
 * @raw_buf:		raw request buffer filled on receiving get report
 * @raw_buf_size:	raw request buffer size
 * Used to tie hid hid->driver data to driver client instance
 */
struct ishtp_hid_data {
	int index;
	bool request_done;
	struct ishtp_cl_data *client_data;
	wait_queue_head_t hid_wait;

	/* raw request */
	bool raw_get_req;
	u8 *raw_buf;
	size_t raw_buf_size;
};

/* Interface functions between HID LL driver and ISH TP client */
void hid_ishtp_set_feature(struct hid_device *hid, char *buf, unsigned int len,
			   int report_id);
void hid_ishtp_get_report(struct hid_device *hid, int report_id,
			  int report_type);
int ishtp_hid_probe(unsigned int cur_hid_dev,
		    struct ishtp_cl_data *client_data);
void ishtp_hid_remove(struct ishtp_cl_data *client_data);
int ishtp_hid_link_ready_wait(struct ishtp_cl_data *client_data);
void ishtp_hid_wakeup(struct hid_device *hid);

#endif	/* ISHTP_HID__H */