source: mainline/uspace/drv/usbhid/hidreq.c@ 408ebc5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 408ebc5 was 3954a63b, checked in by Vojtech Horky <vojtechhorky@…>, 14 years ago

Rename usb_endpoint_pipe_*() ⇒ usb_pipe_*()

No change in functionality.

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/*
2 * Copyright (c) 2011 Lubos Slovak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbhid
30 * @{
31 */
32/** @file
33 * HID class-specific requests.
34 */
35
36#include <stdint.h>
37#include <errno.h>
38#include <str_error.h>
39
40#include <usb/classes/hid.h>
41#include <usb/debug.h>
42#include <usb/request.h>
43
44#include "hidreq.h"
45#include "hiddev.h"
46
47/*----------------------------------------------------------------------------*/
48/**
49 * Send Set Report request to the HID device.
50 *
51 * @param hid_dev HID device to send the request to.
52 * @param type Type of the report.
53 * @param buffer Report data.
54 * @param buf_size Report data size (in bytes).
55 *
56 * @retval EOK if successful.
57 * @retval EINVAL if no HID device is given.
58 * @return Other value inherited from one of functions
59 * usb_pipe_start_session(), usb_pipe_end_session(),
60 * usb_control_request_set().
61 */
62int usbhid_req_set_report(usbhid_dev_t *hid_dev,
63 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
64{
65 if (hid_dev == NULL) {
66 usb_log_error("usbhid_req_set_report(): no HID device structure"
67 " given.\n");
68 return EINVAL;
69 }
70
71 /*
72 * No need for checking other parameters, as they are checked in
73 * the called function (usb_control_request_set()).
74 */
75
76 int rc, sess_rc;
77
78 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
79 if (sess_rc != EOK) {
80 usb_log_warning("Failed to start a session: %s.\n",
81 str_error(sess_rc));
82 return sess_rc;
83 }
84
85 uint16_t value = 0;
86 value |= (type << 8);
87
88 usb_log_debug("Sending Set_Report request to the device.\n");
89
90 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
91 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
92 USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
93
94 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
95
96 if (rc != EOK) {
97 usb_log_warning("Error sending output report to the keyboard: "
98 "%s.\n", str_error(rc));
99 return rc;
100 }
101
102 if (sess_rc != EOK) {
103 usb_log_warning("Error closing session: %s.\n",
104 str_error(sess_rc));
105 return sess_rc;
106 }
107
108 return EOK;
109}
110
111/*----------------------------------------------------------------------------*/
112/**
113 * Send Set Protocol request to the HID device.
114 *
115 * @param hid_dev HID device to send the request to.
116 * @param protocol Protocol to set.
117 *
118 * @retval EOK if successful.
119 * @retval EINVAL if no HID device is given.
120 * @return Other value inherited from one of functions
121 * usb_pipe_start_session(), usb_pipe_end_session(),
122 * usb_control_request_set().
123 */
124int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
125{
126 if (hid_dev == NULL) {
127 usb_log_error("usbhid_req_set_protocol(): no HID device "
128 "structure given.\n");
129 return EINVAL;
130 }
131
132 /*
133 * No need for checking other parameters, as they are checked in
134 * the called function (usb_control_request_set()).
135 */
136
137 int rc, sess_rc;
138
139 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
140 if (sess_rc != EOK) {
141 usb_log_warning("Failed to start a session: %s.\n",
142 str_error(sess_rc));
143 return sess_rc;
144 }
145
146 usb_log_debug("Sending Set_Protocol request to the device ("
147 "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);
148
149 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
150 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
151 USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);
152
153 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
154
155 if (rc != EOK) {
156 usb_log_warning("Error sending output report to the keyboard: "
157 "%s.\n", str_error(rc));
158 return rc;
159 }
160
161 if (sess_rc != EOK) {
162 usb_log_warning("Error closing session: %s.\n",
163 str_error(sess_rc));
164 return sess_rc;
165 }
166
167 return EOK;
168}
169
170/*----------------------------------------------------------------------------*/
171/**
172 * Send Set Idle request to the HID device.
173 *
174 * @param hid_dev HID device to send the request to.
175 * @param duration Duration value (is multiplicated by 4 by the device to
176 * get real duration in miliseconds).
177 *
178 * @retval EOK if successful.
179 * @retval EINVAL if no HID device is given.
180 * @return Other value inherited from one of functions
181 * usb_pipe_start_session(), usb_pipe_end_session(),
182 * usb_control_request_set().
183 */
184int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
185{
186 if (hid_dev == NULL) {
187 usb_log_error("usbhid_req_set_idle(): no HID device "
188 "structure given.\n");
189 return EINVAL;
190 }
191
192 /*
193 * No need for checking other parameters, as they are checked in
194 * the called function (usb_control_request_set()).
195 */
196
197 int rc, sess_rc;
198
199 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
200 if (sess_rc != EOK) {
201 usb_log_warning("Failed to start a session: %s.\n",
202 str_error(sess_rc));
203 return sess_rc;
204 }
205
206 usb_log_debug("Sending Set_Idle request to the device ("
207 "duration: %u, iface: %d).\n", duration, hid_dev->iface);
208
209 uint16_t value = duration << 8;
210
211 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
212 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
213 USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
214
215 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
216
217 if (rc != EOK) {
218 usb_log_warning("Error sending output report to the keyboard: "
219 "%s.\n", str_error(rc));
220 return rc;
221 }
222
223 if (sess_rc != EOK) {
224 usb_log_warning("Error closing session: %s.\n",
225 str_error(sess_rc));
226 return sess_rc;
227 }
228
229 return EOK;
230}
231
232/*----------------------------------------------------------------------------*/
233/**
234 * Send Get Report request to the HID device.
235 *
236 * @param[in] hid_dev HID device to send the request to.
237 * @param[in] type Type of the report.
238 * @param[in][out] buffer Buffer for the report data.
239 * @param[in] buf_size Size of the buffer (in bytes).
240 * @param[out] actual_size Actual size of report received from the device
241 * (in bytes).
242 *
243 * @retval EOK if successful.
244 * @retval EINVAL if no HID device is given.
245 * @return Other value inherited from one of functions
246 * usb_pipe_start_session(), usb_pipe_end_session(),
247 * usb_control_request_set().
248 */
249int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
250 uint8_t *buffer, size_t buf_size, size_t *actual_size)
251{
252 if (hid_dev == NULL) {
253 usb_log_error("usbhid_req_set_report(): no HID device structure"
254 " given.\n");
255 return EINVAL;
256 }
257
258 /*
259 * No need for checking other parameters, as they are checked in
260 * the called function (usb_control_request_set()).
261 */
262
263 int rc, sess_rc;
264
265 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
266 if (sess_rc != EOK) {
267 usb_log_warning("Failed to start a session: %s.\n",
268 str_error(sess_rc));
269 return sess_rc;
270 }
271
272 uint16_t value = 0;
273 value |= (type << 8);
274
275 usb_log_debug("Sending Get_Report request to the device.\n");
276
277 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
278 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
279 USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
280 actual_size);
281
282 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
283
284 if (rc != EOK) {
285 usb_log_warning("Error sending output report to the keyboard: "
286 "%s.\n", str_error(rc));
287 return rc;
288 }
289
290 if (sess_rc != EOK) {
291 usb_log_warning("Error closing session: %s.\n",
292 str_error(sess_rc));
293 return sess_rc;
294 }
295
296 return EOK;
297}
298
299/*----------------------------------------------------------------------------*/
300/**
301 * Send Get Protocol request to the HID device.
302 *
303 * @param[in] hid_dev HID device to send the request to.
304 * @param[out] protocol Current protocol of the device.
305 *
306 * @retval EOK if successful.
307 * @retval EINVAL if no HID device is given.
308 * @return Other value inherited from one of functions
309 * usb_pipe_start_session(), usb_pipe_end_session(),
310 * usb_control_request_set().
311 */
312int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
313{
314 if (hid_dev == NULL) {
315 usb_log_error("usbhid_req_set_protocol(): no HID device "
316 "structure given.\n");
317 return EINVAL;
318 }
319
320 /*
321 * No need for checking other parameters, as they are checked in
322 * the called function (usb_control_request_set()).
323 */
324
325 int rc, sess_rc;
326
327 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
328 if (sess_rc != EOK) {
329 usb_log_warning("Failed to start a session: %s.\n",
330 str_error(sess_rc));
331 return sess_rc;
332 }
333
334 usb_log_debug("Sending Get_Protocol request to the device ("
335 "iface: %d).\n", hid_dev->iface);
336
337 uint8_t buffer[1];
338 size_t actual_size = 0;
339
340 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
341 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
342 USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
343
344 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
345
346 if (rc != EOK) {
347 usb_log_warning("Error sending output report to the keyboard: "
348 "%s.\n", str_error(rc));
349 return rc;
350 }
351
352 if (sess_rc != EOK) {
353 usb_log_warning("Error closing session: %s.\n",
354 str_error(sess_rc));
355 return sess_rc;
356 }
357
358 if (actual_size != 1) {
359 usb_log_warning("Wrong data size: %zu, expected: 1.\n",
360 actual_size);
361 return ELIMIT;
362 }
363
364 *protocol = buffer[0];
365
366 return EOK;
367}
368
369/*----------------------------------------------------------------------------*/
370/**
371 * Send Get Idle request to the HID device.
372 *
373 * @param[in] hid_dev HID device to send the request to.
374 * @param[out] duration Duration value (multiplicate by 4 to get real duration
375 * in miliseconds).
376 *
377 * @retval EOK if successful.
378 * @retval EINVAL if no HID device is given.
379 * @return Other value inherited from one of functions
380 * usb_pipe_start_session(), usb_pipe_end_session(),
381 * usb_control_request_set().
382 */
383int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
384{
385 if (hid_dev == NULL) {
386 usb_log_error("usbhid_req_set_idle(): no HID device "
387 "structure given.\n");
388 return EINVAL;
389 }
390
391 /*
392 * No need for checking other parameters, as they are checked in
393 * the called function (usb_control_request_set()).
394 */
395
396 int rc, sess_rc;
397
398 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
399 if (sess_rc != EOK) {
400 usb_log_warning("Failed to start a session: %s.\n",
401 str_error(sess_rc));
402 return sess_rc;
403 }
404
405 usb_log_debug("Sending Get_Idle request to the device ("
406 "iface: %d).\n", hid_dev->iface);
407
408 uint16_t value = 0;
409 uint8_t buffer[1];
410 size_t actual_size = 0;
411
412 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
413 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
414 USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
415 &actual_size);
416
417 sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
418
419 if (rc != EOK) {
420 usb_log_warning("Error sending output report to the keyboard: "
421 "%s.\n", str_error(rc));
422 return rc;
423 }
424
425 if (sess_rc != EOK) {
426 usb_log_warning("Error closing session: %s.\n",
427 str_error(sess_rc));
428 return sess_rc;
429 }
430
431 if (actual_size != 1) {
432 usb_log_warning("Wrong data size: %zu, expected: 1.\n",
433 actual_size);
434 return ELIMIT;
435 }
436
437 *duration = buffer[0];
438
439 return EOK;
440}
441
442/*----------------------------------------------------------------------------*/
443
444/**
445 * @}
446 */
Note: See TracBrowser for help on using the repository browser.