1 /* This is an AUTO-GENERATED file! Update it with the output of `ctrl-gen.py def`. */
2 #include "libuvc/libuvc.h"
3 #include "libuvc/libuvc_internal.h"
4 
5 static const int REQ_TYPE_SET = 0x21;
6 static const int REQ_TYPE_GET = 0xa1;
7 
8 /** @ingroup ctrl
9  * @brief Reads the SCANNING_MODE control.
10  * @param devh UVC device handle
11  * @param[out] mode 0: interlaced, 1: progressive
12  * @param req_code UVC_GET_* request to execute
13  */
uvc_get_scanning_mode(uvc_device_handle_t * devh,uint8_t * mode,enum uvc_req_code req_code)14 uvc_error_t uvc_get_scanning_mode(uvc_device_handle_t *devh, uint8_t* mode, enum uvc_req_code req_code) {
15   uint8_t data[1];
16   uvc_error_t ret;
17 
18   ret = libusb_control_transfer(
19     devh->usb_devh,
20     REQ_TYPE_GET, req_code,
21     UVC_CT_SCANNING_MODE_CONTROL << 8,
22     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
23     data,
24     sizeof(data),
25     0);
26 
27   if (ret == sizeof(data)) {
28     *mode = data[0];
29     return UVC_SUCCESS;
30   } else {
31     return ret;
32   }
33 }
34 
35 
36 /** @ingroup ctrl
37  * @brief Sets the SCANNING_MODE control.
38  * @param devh UVC device handle
39  * @param mode 0: interlaced, 1: progressive
40  */
uvc_set_scanning_mode(uvc_device_handle_t * devh,uint8_t mode)41 uvc_error_t uvc_set_scanning_mode(uvc_device_handle_t *devh, uint8_t mode) {
42   uint8_t data[1];
43   uvc_error_t ret;
44 
45   data[0] = mode;
46 
47   ret = libusb_control_transfer(
48     devh->usb_devh,
49     REQ_TYPE_SET, UVC_SET_CUR,
50     UVC_CT_SCANNING_MODE_CONTROL << 8,
51     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
52     data,
53     sizeof(data),
54     0);
55 
56   if (ret == sizeof(data))
57     return UVC_SUCCESS;
58   else
59     return ret;
60 }
61 
62 /** @ingroup ctrl
63  * @brief Reads camera's auto-exposure mode.
64  *
65  * See uvc_set_ae_mode() for a description of the available modes.
66  * @param devh UVC device handle
67  * @param[out] mode 1: manual mode; 2: auto mode; 4: shutter priority mode; 8: aperture priority mode
68  * @param req_code UVC_GET_* request to execute
69  */
uvc_get_ae_mode(uvc_device_handle_t * devh,uint8_t * mode,enum uvc_req_code req_code)70 uvc_error_t uvc_get_ae_mode(uvc_device_handle_t *devh, uint8_t* mode, enum uvc_req_code req_code) {
71   uint8_t data[1];
72   uvc_error_t ret;
73 
74   ret = libusb_control_transfer(
75     devh->usb_devh,
76     REQ_TYPE_GET, req_code,
77     UVC_CT_AE_MODE_CONTROL << 8,
78     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
79     data,
80     sizeof(data),
81     0);
82 
83   if (ret == sizeof(data)) {
84     *mode = data[0];
85     return UVC_SUCCESS;
86   } else {
87     return ret;
88   }
89 }
90 
91 
92 /** @ingroup ctrl
93  * @brief Sets camera's auto-exposure mode.
94  *
95  * Cameras may support any of the following AE modes:
96  *  * UVC_AUTO_EXPOSURE_MODE_MANUAL (1) - manual exposure time, manual iris
97  *  * UVC_AUTO_EXPOSURE_MODE_AUTO (2) - auto exposure time, auto iris
98  *  * UVC_AUTO_EXPOSURE_MODE_SHUTTER_PRIORITY (4) - manual exposure time, auto iris
99  *  * UVC_AUTO_EXPOSURE_MODE_APERTURE_PRIORITY (8) - auto exposure time, manual iris
100  *
101  * Most cameras provide manual mode and aperture priority mode.
102  * @param devh UVC device handle
103  * @param mode 1: manual mode; 2: auto mode; 4: shutter priority mode; 8: aperture priority mode
104  */
uvc_set_ae_mode(uvc_device_handle_t * devh,uint8_t mode)105 uvc_error_t uvc_set_ae_mode(uvc_device_handle_t *devh, uint8_t mode) {
106   uint8_t data[1];
107   uvc_error_t ret;
108 
109   data[0] = mode;
110 
111   ret = libusb_control_transfer(
112     devh->usb_devh,
113     REQ_TYPE_SET, UVC_SET_CUR,
114     UVC_CT_AE_MODE_CONTROL << 8,
115     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
116     data,
117     sizeof(data),
118     0);
119 
120   if (ret == sizeof(data))
121     return UVC_SUCCESS;
122   else
123     return ret;
124 }
125 
126 /** @ingroup ctrl
127  * @brief Checks whether the camera may vary the frame rate for exposure control reasons.
128  * See uvc_set_ae_priority() for a description of the `priority` field.
129  * @param devh UVC device handle
130  * @param[out] priority 0: frame rate must remain constant; 1: frame rate may be varied for AE purposes
131  * @param req_code UVC_GET_* request to execute
132  */
uvc_get_ae_priority(uvc_device_handle_t * devh,uint8_t * priority,enum uvc_req_code req_code)133 uvc_error_t uvc_get_ae_priority(uvc_device_handle_t *devh, uint8_t* priority, enum uvc_req_code req_code) {
134   uint8_t data[1];
135   uvc_error_t ret;
136 
137   ret = libusb_control_transfer(
138     devh->usb_devh,
139     REQ_TYPE_GET, req_code,
140     UVC_CT_AE_PRIORITY_CONTROL << 8,
141     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
142     data,
143     sizeof(data),
144     0);
145 
146   if (ret == sizeof(data)) {
147     *priority = data[0];
148     return UVC_SUCCESS;
149   } else {
150     return ret;
151   }
152 }
153 
154 
155 /** @ingroup ctrl
156  * @brief Chooses whether the camera may vary the frame rate for exposure control reasons.
157  * A `priority` value of zero means the camera may not vary its frame rate. A value of 1
158  * means the frame rate is variable. This setting has no effect outside of the `auto` and
159  * `shutter_priority` auto-exposure modes.
160  * @param devh UVC device handle
161  * @param priority 0: frame rate must remain constant; 1: frame rate may be varied for AE purposes
162  */
uvc_set_ae_priority(uvc_device_handle_t * devh,uint8_t priority)163 uvc_error_t uvc_set_ae_priority(uvc_device_handle_t *devh, uint8_t priority) {
164   uint8_t data[1];
165   uvc_error_t ret;
166 
167   data[0] = priority;
168 
169   ret = libusb_control_transfer(
170     devh->usb_devh,
171     REQ_TYPE_SET, UVC_SET_CUR,
172     UVC_CT_AE_PRIORITY_CONTROL << 8,
173     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
174     data,
175     sizeof(data),
176     0);
177 
178   if (ret == sizeof(data))
179     return UVC_SUCCESS;
180   else
181     return ret;
182 }
183 
184 /** @ingroup ctrl
185  * @brief Gets the absolute exposure time.
186  *
187  * See uvc_set_exposure_abs() for a description of the `time` field.
188  * @param devh UVC device handle
189  * @param[out] time
190  * @param req_code UVC_GET_* request to execute
191  */
uvc_get_exposure_abs(uvc_device_handle_t * devh,uint32_t * time,enum uvc_req_code req_code)192 uvc_error_t uvc_get_exposure_abs(uvc_device_handle_t *devh, uint32_t* time, enum uvc_req_code req_code) {
193   uint8_t data[4];
194   uvc_error_t ret;
195 
196   ret = libusb_control_transfer(
197     devh->usb_devh,
198     REQ_TYPE_GET, req_code,
199     UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
200     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
201     data,
202     sizeof(data),
203     0);
204 
205   if (ret == sizeof(data)) {
206     *time = DW_TO_INT(data + 0);
207     return UVC_SUCCESS;
208   } else {
209     return ret;
210   }
211 }
212 
213 
214 /** @ingroup ctrl
215  * @brief Sets the absolute exposure time.
216  *
217  * The `time` parameter should be provided in units of 0.0001 seconds (e.g., use the value 100
218  * for a 10ms exposure period). Auto exposure should be set to `manual` or `shutter_priority`
219  * before attempting to change this setting.
220  * @param devh UVC device handle
221  * @param time
222  */
uvc_set_exposure_abs(uvc_device_handle_t * devh,uint32_t time)223 uvc_error_t uvc_set_exposure_abs(uvc_device_handle_t *devh, uint32_t time) {
224   uint8_t data[4];
225   uvc_error_t ret;
226 
227   INT_TO_DW(time, data + 0);
228 
229   ret = libusb_control_transfer(
230     devh->usb_devh,
231     REQ_TYPE_SET, UVC_SET_CUR,
232     UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
233     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
234     data,
235     sizeof(data),
236     0);
237 
238   if (ret == sizeof(data))
239     return UVC_SUCCESS;
240   else
241     return ret;
242 }
243 
244 /** @ingroup ctrl
245  * @brief Reads the exposure time relative to the current setting.
246  * @param devh UVC device handle
247  * @param[out] step number of steps by which to change the exposure time, or zero to set the default exposure time
248  * @param req_code UVC_GET_* request to execute
249  */
uvc_get_exposure_rel(uvc_device_handle_t * devh,int8_t * step,enum uvc_req_code req_code)250 uvc_error_t uvc_get_exposure_rel(uvc_device_handle_t *devh, int8_t* step, enum uvc_req_code req_code) {
251   uint8_t data[1];
252   uvc_error_t ret;
253 
254   ret = libusb_control_transfer(
255     devh->usb_devh,
256     REQ_TYPE_GET, req_code,
257     UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
258     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
259     data,
260     sizeof(data),
261     0);
262 
263   if (ret == sizeof(data)) {
264     *step = data[0];
265     return UVC_SUCCESS;
266   } else {
267     return ret;
268   }
269 }
270 
271 
272 /** @ingroup ctrl
273  * @brief Sets the exposure time relative to the current setting.
274  * @param devh UVC device handle
275  * @param step number of steps by which to change the exposure time, or zero to set the default exposure time
276  */
uvc_set_exposure_rel(uvc_device_handle_t * devh,int8_t step)277 uvc_error_t uvc_set_exposure_rel(uvc_device_handle_t *devh, int8_t step) {
278   uint8_t data[1];
279   uvc_error_t ret;
280 
281   data[0] = step;
282 
283   ret = libusb_control_transfer(
284     devh->usb_devh,
285     REQ_TYPE_SET, UVC_SET_CUR,
286     UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
287     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
288     data,
289     sizeof(data),
290     0);
291 
292   if (ret == sizeof(data))
293     return UVC_SUCCESS;
294   else
295     return ret;
296 }
297 
298 /** @ingroup ctrl
299  * @brief Reads the distance at which an object is optimally focused.
300  * @param devh UVC device handle
301  * @param[out] focus focal target distance in millimeters
302  * @param req_code UVC_GET_* request to execute
303  */
uvc_get_focus_abs(uvc_device_handle_t * devh,uint16_t * focus,enum uvc_req_code req_code)304 uvc_error_t uvc_get_focus_abs(uvc_device_handle_t *devh, uint16_t* focus, enum uvc_req_code req_code) {
305   uint8_t data[2];
306   uvc_error_t ret;
307 
308   ret = libusb_control_transfer(
309     devh->usb_devh,
310     REQ_TYPE_GET, req_code,
311     UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
312     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
313     data,
314     sizeof(data),
315     0);
316 
317   if (ret == sizeof(data)) {
318     *focus = SW_TO_SHORT(data + 0);
319     return UVC_SUCCESS;
320   } else {
321     return ret;
322   }
323 }
324 
325 
326 /** @ingroup ctrl
327  * @brief Sets the distance at which an object is optimally focused.
328  * @param devh UVC device handle
329  * @param focus focal target distance in millimeters
330  */
uvc_set_focus_abs(uvc_device_handle_t * devh,uint16_t focus)331 uvc_error_t uvc_set_focus_abs(uvc_device_handle_t *devh, uint16_t focus) {
332   uint8_t data[2];
333   uvc_error_t ret;
334 
335   SHORT_TO_SW(focus, data + 0);
336 
337   ret = libusb_control_transfer(
338     devh->usb_devh,
339     REQ_TYPE_SET, UVC_SET_CUR,
340     UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
341     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
342     data,
343     sizeof(data),
344     0);
345 
346   if (ret == sizeof(data))
347     return UVC_SUCCESS;
348   else
349     return ret;
350 }
351 
352 /** @ingroup ctrl
353  * @brief Reads the FOCUS_RELATIVE control.
354  * @param devh UVC device handle
355  * @param[out] focus_rel TODO
356  * @param[out] speed TODO
357  * @param req_code UVC_GET_* request to execute
358  */
uvc_get_focus_rel(uvc_device_handle_t * devh,int8_t * focus_rel,uint8_t * speed,enum uvc_req_code req_code)359 uvc_error_t uvc_get_focus_rel(uvc_device_handle_t *devh, int8_t* focus_rel, uint8_t* speed, enum uvc_req_code req_code) {
360   uint8_t data[2];
361   uvc_error_t ret;
362 
363   ret = libusb_control_transfer(
364     devh->usb_devh,
365     REQ_TYPE_GET, req_code,
366     UVC_CT_FOCUS_RELATIVE_CONTROL << 8,
367     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
368     data,
369     sizeof(data),
370     0);
371 
372   if (ret == sizeof(data)) {
373     *focus_rel = data[0];
374     *speed = data[1];
375     return UVC_SUCCESS;
376   } else {
377     return ret;
378   }
379 }
380 
381 
382 /** @ingroup ctrl
383  * @brief Sets the FOCUS_RELATIVE control.
384  * @param devh UVC device handle
385  * @param focus_rel TODO
386  * @param speed TODO
387  */
uvc_set_focus_rel(uvc_device_handle_t * devh,int8_t focus_rel,uint8_t speed)388 uvc_error_t uvc_set_focus_rel(uvc_device_handle_t *devh, int8_t focus_rel, uint8_t speed) {
389   uint8_t data[2];
390   uvc_error_t ret;
391 
392   data[0] = focus_rel;
393   data[1] = speed;
394 
395   ret = libusb_control_transfer(
396     devh->usb_devh,
397     REQ_TYPE_SET, UVC_SET_CUR,
398     UVC_CT_FOCUS_RELATIVE_CONTROL << 8,
399     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
400     data,
401     sizeof(data),
402     0);
403 
404   if (ret == sizeof(data))
405     return UVC_SUCCESS;
406   else
407     return ret;
408 }
409 
410 /** @ingroup ctrl
411  * @brief Reads the FOCUS_SIMPLE control.
412  * @param devh UVC device handle
413  * @param[out] focus TODO
414  * @param req_code UVC_GET_* request to execute
415  */
uvc_get_focus_simple_range(uvc_device_handle_t * devh,uint8_t * focus,enum uvc_req_code req_code)416 uvc_error_t uvc_get_focus_simple_range(uvc_device_handle_t *devh, uint8_t* focus, enum uvc_req_code req_code) {
417   uint8_t data[1];
418   uvc_error_t ret;
419 
420   ret = libusb_control_transfer(
421     devh->usb_devh,
422     REQ_TYPE_GET, req_code,
423     UVC_CT_FOCUS_SIMPLE_CONTROL << 8,
424     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
425     data,
426     sizeof(data),
427     0);
428 
429   if (ret == sizeof(data)) {
430     *focus = data[0];
431     return UVC_SUCCESS;
432   } else {
433     return ret;
434   }
435 }
436 
437 
438 /** @ingroup ctrl
439  * @brief Sets the FOCUS_SIMPLE control.
440  * @param devh UVC device handle
441  * @param focus TODO
442  */
uvc_set_focus_simple_range(uvc_device_handle_t * devh,uint8_t focus)443 uvc_error_t uvc_set_focus_simple_range(uvc_device_handle_t *devh, uint8_t focus) {
444   uint8_t data[1];
445   uvc_error_t ret;
446 
447   data[0] = focus;
448 
449   ret = libusb_control_transfer(
450     devh->usb_devh,
451     REQ_TYPE_SET, UVC_SET_CUR,
452     UVC_CT_FOCUS_SIMPLE_CONTROL << 8,
453     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
454     data,
455     sizeof(data),
456     0);
457 
458   if (ret == sizeof(data))
459     return UVC_SUCCESS;
460   else
461     return ret;
462 }
463 
464 /** @ingroup ctrl
465  * @brief Reads the FOCUS_AUTO control.
466  * @param devh UVC device handle
467  * @param[out] state TODO
468  * @param req_code UVC_GET_* request to execute
469  */
uvc_get_focus_auto(uvc_device_handle_t * devh,uint8_t * state,enum uvc_req_code req_code)470 uvc_error_t uvc_get_focus_auto(uvc_device_handle_t *devh, uint8_t* state, enum uvc_req_code req_code) {
471   uint8_t data[1];
472   uvc_error_t ret;
473 
474   ret = libusb_control_transfer(
475     devh->usb_devh,
476     REQ_TYPE_GET, req_code,
477     UVC_CT_FOCUS_AUTO_CONTROL << 8,
478     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
479     data,
480     sizeof(data),
481     0);
482 
483   if (ret == sizeof(data)) {
484     *state = data[0];
485     return UVC_SUCCESS;
486   } else {
487     return ret;
488   }
489 }
490 
491 
492 /** @ingroup ctrl
493  * @brief Sets the FOCUS_AUTO control.
494  * @param devh UVC device handle
495  * @param state TODO
496  */
uvc_set_focus_auto(uvc_device_handle_t * devh,uint8_t state)497 uvc_error_t uvc_set_focus_auto(uvc_device_handle_t *devh, uint8_t state) {
498   uint8_t data[1];
499   uvc_error_t ret;
500 
501   data[0] = state;
502 
503   ret = libusb_control_transfer(
504     devh->usb_devh,
505     REQ_TYPE_SET, UVC_SET_CUR,
506     UVC_CT_FOCUS_AUTO_CONTROL << 8,
507     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
508     data,
509     sizeof(data),
510     0);
511 
512   if (ret == sizeof(data))
513     return UVC_SUCCESS;
514   else
515     return ret;
516 }
517 
518 /** @ingroup ctrl
519  * @brief Reads the IRIS_ABSOLUTE control.
520  * @param devh UVC device handle
521  * @param[out] iris TODO
522  * @param req_code UVC_GET_* request to execute
523  */
uvc_get_iris_abs(uvc_device_handle_t * devh,uint16_t * iris,enum uvc_req_code req_code)524 uvc_error_t uvc_get_iris_abs(uvc_device_handle_t *devh, uint16_t* iris, enum uvc_req_code req_code) {
525   uint8_t data[2];
526   uvc_error_t ret;
527 
528   ret = libusb_control_transfer(
529     devh->usb_devh,
530     REQ_TYPE_GET, req_code,
531     UVC_CT_IRIS_ABSOLUTE_CONTROL << 8,
532     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
533     data,
534     sizeof(data),
535     0);
536 
537   if (ret == sizeof(data)) {
538     *iris = SW_TO_SHORT(data + 0);
539     return UVC_SUCCESS;
540   } else {
541     return ret;
542   }
543 }
544 
545 
546 /** @ingroup ctrl
547  * @brief Sets the IRIS_ABSOLUTE control.
548  * @param devh UVC device handle
549  * @param iris TODO
550  */
uvc_set_iris_abs(uvc_device_handle_t * devh,uint16_t iris)551 uvc_error_t uvc_set_iris_abs(uvc_device_handle_t *devh, uint16_t iris) {
552   uint8_t data[2];
553   uvc_error_t ret;
554 
555   SHORT_TO_SW(iris, data + 0);
556 
557   ret = libusb_control_transfer(
558     devh->usb_devh,
559     REQ_TYPE_SET, UVC_SET_CUR,
560     UVC_CT_IRIS_ABSOLUTE_CONTROL << 8,
561     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
562     data,
563     sizeof(data),
564     0);
565 
566   if (ret == sizeof(data))
567     return UVC_SUCCESS;
568   else
569     return ret;
570 }
571 
572 /** @ingroup ctrl
573  * @brief Reads the IRIS_RELATIVE control.
574  * @param devh UVC device handle
575  * @param[out] iris_rel TODO
576  * @param req_code UVC_GET_* request to execute
577  */
uvc_get_iris_rel(uvc_device_handle_t * devh,uint8_t * iris_rel,enum uvc_req_code req_code)578 uvc_error_t uvc_get_iris_rel(uvc_device_handle_t *devh, uint8_t* iris_rel, enum uvc_req_code req_code) {
579   uint8_t data[1];
580   uvc_error_t ret;
581 
582   ret = libusb_control_transfer(
583     devh->usb_devh,
584     REQ_TYPE_GET, req_code,
585     UVC_CT_IRIS_RELATIVE_CONTROL << 8,
586     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
587     data,
588     sizeof(data),
589     0);
590 
591   if (ret == sizeof(data)) {
592     *iris_rel = data[0];
593     return UVC_SUCCESS;
594   } else {
595     return ret;
596   }
597 }
598 
599 
600 /** @ingroup ctrl
601  * @brief Sets the IRIS_RELATIVE control.
602  * @param devh UVC device handle
603  * @param iris_rel TODO
604  */
uvc_set_iris_rel(uvc_device_handle_t * devh,uint8_t iris_rel)605 uvc_error_t uvc_set_iris_rel(uvc_device_handle_t *devh, uint8_t iris_rel) {
606   uint8_t data[1];
607   uvc_error_t ret;
608 
609   data[0] = iris_rel;
610 
611   ret = libusb_control_transfer(
612     devh->usb_devh,
613     REQ_TYPE_SET, UVC_SET_CUR,
614     UVC_CT_IRIS_RELATIVE_CONTROL << 8,
615     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
616     data,
617     sizeof(data),
618     0);
619 
620   if (ret == sizeof(data))
621     return UVC_SUCCESS;
622   else
623     return ret;
624 }
625 
626 /** @ingroup ctrl
627  * @brief Reads the ZOOM_ABSOLUTE control.
628  * @param devh UVC device handle
629  * @param[out] focal_length TODO
630  * @param req_code UVC_GET_* request to execute
631  */
uvc_get_zoom_abs(uvc_device_handle_t * devh,uint16_t * focal_length,enum uvc_req_code req_code)632 uvc_error_t uvc_get_zoom_abs(uvc_device_handle_t *devh, uint16_t* focal_length, enum uvc_req_code req_code) {
633   uint8_t data[2];
634   uvc_error_t ret;
635 
636   ret = libusb_control_transfer(
637     devh->usb_devh,
638     REQ_TYPE_GET, req_code,
639     UVC_CT_ZOOM_ABSOLUTE_CONTROL << 8,
640     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
641     data,
642     sizeof(data),
643     0);
644 
645   if (ret == sizeof(data)) {
646     *focal_length = SW_TO_SHORT(data + 0);
647     return UVC_SUCCESS;
648   } else {
649     return ret;
650   }
651 }
652 
653 
654 /** @ingroup ctrl
655  * @brief Sets the ZOOM_ABSOLUTE control.
656  * @param devh UVC device handle
657  * @param focal_length TODO
658  */
uvc_set_zoom_abs(uvc_device_handle_t * devh,uint16_t focal_length)659 uvc_error_t uvc_set_zoom_abs(uvc_device_handle_t *devh, uint16_t focal_length) {
660   uint8_t data[2];
661   uvc_error_t ret;
662 
663   SHORT_TO_SW(focal_length, data + 0);
664 
665   ret = libusb_control_transfer(
666     devh->usb_devh,
667     REQ_TYPE_SET, UVC_SET_CUR,
668     UVC_CT_ZOOM_ABSOLUTE_CONTROL << 8,
669     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
670     data,
671     sizeof(data),
672     0);
673 
674   if (ret == sizeof(data))
675     return UVC_SUCCESS;
676   else
677     return ret;
678 }
679 
680 /** @ingroup ctrl
681  * @brief Reads the ZOOM_RELATIVE control.
682  * @param devh UVC device handle
683  * @param[out] zoom_rel TODO
684  * @param[out] digital_zoom TODO
685  * @param[out] speed TODO
686  * @param req_code UVC_GET_* request to execute
687  */
uvc_get_zoom_rel(uvc_device_handle_t * devh,int8_t * zoom_rel,uint8_t * digital_zoom,uint8_t * speed,enum uvc_req_code req_code)688 uvc_error_t uvc_get_zoom_rel(uvc_device_handle_t *devh, int8_t* zoom_rel, uint8_t* digital_zoom, uint8_t* speed, enum uvc_req_code req_code) {
689   uint8_t data[3];
690   uvc_error_t ret;
691 
692   ret = libusb_control_transfer(
693     devh->usb_devh,
694     REQ_TYPE_GET, req_code,
695     UVC_CT_ZOOM_RELATIVE_CONTROL << 8,
696     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
697     data,
698     sizeof(data),
699     0);
700 
701   if (ret == sizeof(data)) {
702     *zoom_rel = data[0];
703     *digital_zoom = data[1];
704     *speed = data[2];
705     return UVC_SUCCESS;
706   } else {
707     return ret;
708   }
709 }
710 
711 
712 /** @ingroup ctrl
713  * @brief Sets the ZOOM_RELATIVE control.
714  * @param devh UVC device handle
715  * @param zoom_rel TODO
716  * @param digital_zoom TODO
717  * @param speed TODO
718  */
uvc_set_zoom_rel(uvc_device_handle_t * devh,int8_t zoom_rel,uint8_t digital_zoom,uint8_t speed)719 uvc_error_t uvc_set_zoom_rel(uvc_device_handle_t *devh, int8_t zoom_rel, uint8_t digital_zoom, uint8_t speed) {
720   uint8_t data[3];
721   uvc_error_t ret;
722 
723   data[0] = zoom_rel;
724   data[1] = digital_zoom;
725   data[2] = speed;
726 
727   ret = libusb_control_transfer(
728     devh->usb_devh,
729     REQ_TYPE_SET, UVC_SET_CUR,
730     UVC_CT_ZOOM_RELATIVE_CONTROL << 8,
731     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
732     data,
733     sizeof(data),
734     0);
735 
736   if (ret == sizeof(data))
737     return UVC_SUCCESS;
738   else
739     return ret;
740 }
741 
742 /** @ingroup ctrl
743  * @brief Reads the PANTILT_ABSOLUTE control.
744  * @param devh UVC device handle
745  * @param[out] pan TODO
746  * @param[out] tilt TODO
747  * @param req_code UVC_GET_* request to execute
748  */
uvc_get_pantilt_abs(uvc_device_handle_t * devh,int32_t * pan,int32_t * tilt,enum uvc_req_code req_code)749 uvc_error_t uvc_get_pantilt_abs(uvc_device_handle_t *devh, int32_t* pan, int32_t* tilt, enum uvc_req_code req_code) {
750   uint8_t data[8];
751   uvc_error_t ret;
752 
753   ret = libusb_control_transfer(
754     devh->usb_devh,
755     REQ_TYPE_GET, req_code,
756     UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
757     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
758     data,
759     sizeof(data),
760     0);
761 
762   if (ret == sizeof(data)) {
763     *pan = DW_TO_INT(data + 0);
764     *tilt = DW_TO_INT(data + 4);
765     return UVC_SUCCESS;
766   } else {
767     return ret;
768   }
769 }
770 
771 
772 /** @ingroup ctrl
773  * @brief Sets the PANTILT_ABSOLUTE control.
774  * @param devh UVC device handle
775  * @param pan TODO
776  * @param tilt TODO
777  */
uvc_set_pantilt_abs(uvc_device_handle_t * devh,int32_t pan,int32_t tilt)778 uvc_error_t uvc_set_pantilt_abs(uvc_device_handle_t *devh, int32_t pan, int32_t tilt) {
779   uint8_t data[8];
780   uvc_error_t ret;
781 
782   INT_TO_DW(pan, data + 0);
783   INT_TO_DW(tilt, data + 4);
784 
785   ret = libusb_control_transfer(
786     devh->usb_devh,
787     REQ_TYPE_SET, UVC_SET_CUR,
788     UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
789     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
790     data,
791     sizeof(data),
792     0);
793 
794   if (ret == sizeof(data))
795     return UVC_SUCCESS;
796   else
797     return ret;
798 }
799 
800 /** @ingroup ctrl
801  * @brief Reads the PANTILT_RELATIVE control.
802  * @param devh UVC device handle
803  * @param[out] pan_rel TODO
804  * @param[out] pan_speed TODO
805  * @param[out] tilt_rel TODO
806  * @param[out] tilt_speed TODO
807  * @param req_code UVC_GET_* request to execute
808  */
uvc_get_pantilt_rel(uvc_device_handle_t * devh,int8_t * pan_rel,uint8_t * pan_speed,int8_t * tilt_rel,uint8_t * tilt_speed,enum uvc_req_code req_code)809 uvc_error_t uvc_get_pantilt_rel(uvc_device_handle_t *devh, int8_t* pan_rel, uint8_t* pan_speed, int8_t* tilt_rel, uint8_t* tilt_speed, enum uvc_req_code req_code) {
810   uint8_t data[4];
811   uvc_error_t ret;
812 
813   ret = libusb_control_transfer(
814     devh->usb_devh,
815     REQ_TYPE_GET, req_code,
816     UVC_CT_PANTILT_RELATIVE_CONTROL << 8,
817     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
818     data,
819     sizeof(data),
820     0);
821 
822   if (ret == sizeof(data)) {
823     *pan_rel = data[0];
824     *pan_speed = data[1];
825     *tilt_rel = data[2];
826     *tilt_speed = data[3];
827     return UVC_SUCCESS;
828   } else {
829     return ret;
830   }
831 }
832 
833 
834 /** @ingroup ctrl
835  * @brief Sets the PANTILT_RELATIVE control.
836  * @param devh UVC device handle
837  * @param pan_rel TODO
838  * @param pan_speed TODO
839  * @param tilt_rel TODO
840  * @param tilt_speed TODO
841  */
uvc_set_pantilt_rel(uvc_device_handle_t * devh,int8_t pan_rel,uint8_t pan_speed,int8_t tilt_rel,uint8_t tilt_speed)842 uvc_error_t uvc_set_pantilt_rel(uvc_device_handle_t *devh, int8_t pan_rel, uint8_t pan_speed, int8_t tilt_rel, uint8_t tilt_speed) {
843   uint8_t data[4];
844   uvc_error_t ret;
845 
846   data[0] = pan_rel;
847   data[1] = pan_speed;
848   data[2] = tilt_rel;
849   data[3] = tilt_speed;
850 
851   ret = libusb_control_transfer(
852     devh->usb_devh,
853     REQ_TYPE_SET, UVC_SET_CUR,
854     UVC_CT_PANTILT_RELATIVE_CONTROL << 8,
855     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
856     data,
857     sizeof(data),
858     0);
859 
860   if (ret == sizeof(data))
861     return UVC_SUCCESS;
862   else
863     return ret;
864 }
865 
866 /** @ingroup ctrl
867  * @brief Reads the ROLL_ABSOLUTE control.
868  * @param devh UVC device handle
869  * @param[out] roll TODO
870  * @param req_code UVC_GET_* request to execute
871  */
uvc_get_roll_abs(uvc_device_handle_t * devh,int16_t * roll,enum uvc_req_code req_code)872 uvc_error_t uvc_get_roll_abs(uvc_device_handle_t *devh, int16_t* roll, enum uvc_req_code req_code) {
873   uint8_t data[2];
874   uvc_error_t ret;
875 
876   ret = libusb_control_transfer(
877     devh->usb_devh,
878     REQ_TYPE_GET, req_code,
879     UVC_CT_ROLL_ABSOLUTE_CONTROL << 8,
880     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
881     data,
882     sizeof(data),
883     0);
884 
885   if (ret == sizeof(data)) {
886     *roll = SW_TO_SHORT(data + 0);
887     return UVC_SUCCESS;
888   } else {
889     return ret;
890   }
891 }
892 
893 
894 /** @ingroup ctrl
895  * @brief Sets the ROLL_ABSOLUTE control.
896  * @param devh UVC device handle
897  * @param roll TODO
898  */
uvc_set_roll_abs(uvc_device_handle_t * devh,int16_t roll)899 uvc_error_t uvc_set_roll_abs(uvc_device_handle_t *devh, int16_t roll) {
900   uint8_t data[2];
901   uvc_error_t ret;
902 
903   SHORT_TO_SW(roll, data + 0);
904 
905   ret = libusb_control_transfer(
906     devh->usb_devh,
907     REQ_TYPE_SET, UVC_SET_CUR,
908     UVC_CT_ROLL_ABSOLUTE_CONTROL << 8,
909     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
910     data,
911     sizeof(data),
912     0);
913 
914   if (ret == sizeof(data))
915     return UVC_SUCCESS;
916   else
917     return ret;
918 }
919 
920 /** @ingroup ctrl
921  * @brief Reads the ROLL_RELATIVE control.
922  * @param devh UVC device handle
923  * @param[out] roll_rel TODO
924  * @param[out] speed TODO
925  * @param req_code UVC_GET_* request to execute
926  */
uvc_get_roll_rel(uvc_device_handle_t * devh,int8_t * roll_rel,uint8_t * speed,enum uvc_req_code req_code)927 uvc_error_t uvc_get_roll_rel(uvc_device_handle_t *devh, int8_t* roll_rel, uint8_t* speed, enum uvc_req_code req_code) {
928   uint8_t data[2];
929   uvc_error_t ret;
930 
931   ret = libusb_control_transfer(
932     devh->usb_devh,
933     REQ_TYPE_GET, req_code,
934     UVC_CT_ROLL_RELATIVE_CONTROL << 8,
935     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
936     data,
937     sizeof(data),
938     0);
939 
940   if (ret == sizeof(data)) {
941     *roll_rel = data[0];
942     *speed = data[1];
943     return UVC_SUCCESS;
944   } else {
945     return ret;
946   }
947 }
948 
949 
950 /** @ingroup ctrl
951  * @brief Sets the ROLL_RELATIVE control.
952  * @param devh UVC device handle
953  * @param roll_rel TODO
954  * @param speed TODO
955  */
uvc_set_roll_rel(uvc_device_handle_t * devh,int8_t roll_rel,uint8_t speed)956 uvc_error_t uvc_set_roll_rel(uvc_device_handle_t *devh, int8_t roll_rel, uint8_t speed) {
957   uint8_t data[2];
958   uvc_error_t ret;
959 
960   data[0] = roll_rel;
961   data[1] = speed;
962 
963   ret = libusb_control_transfer(
964     devh->usb_devh,
965     REQ_TYPE_SET, UVC_SET_CUR,
966     UVC_CT_ROLL_RELATIVE_CONTROL << 8,
967     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
968     data,
969     sizeof(data),
970     0);
971 
972   if (ret == sizeof(data))
973     return UVC_SUCCESS;
974   else
975     return ret;
976 }
977 
978 /** @ingroup ctrl
979  * @brief Reads the PRIVACY control.
980  * @param devh UVC device handle
981  * @param[out] privacy TODO
982  * @param req_code UVC_GET_* request to execute
983  */
uvc_get_privacy(uvc_device_handle_t * devh,uint8_t * privacy,enum uvc_req_code req_code)984 uvc_error_t uvc_get_privacy(uvc_device_handle_t *devh, uint8_t* privacy, enum uvc_req_code req_code) {
985   uint8_t data[1];
986   uvc_error_t ret;
987 
988   ret = libusb_control_transfer(
989     devh->usb_devh,
990     REQ_TYPE_GET, req_code,
991     UVC_CT_PRIVACY_CONTROL << 8,
992     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
993     data,
994     sizeof(data),
995     0);
996 
997   if (ret == sizeof(data)) {
998     *privacy = data[0];
999     return UVC_SUCCESS;
1000   } else {
1001     return ret;
1002   }
1003 }
1004 
1005 
1006 /** @ingroup ctrl
1007  * @brief Sets the PRIVACY control.
1008  * @param devh UVC device handle
1009  * @param privacy TODO
1010  */
uvc_set_privacy(uvc_device_handle_t * devh,uint8_t privacy)1011 uvc_error_t uvc_set_privacy(uvc_device_handle_t *devh, uint8_t privacy) {
1012   uint8_t data[1];
1013   uvc_error_t ret;
1014 
1015   data[0] = privacy;
1016 
1017   ret = libusb_control_transfer(
1018     devh->usb_devh,
1019     REQ_TYPE_SET, UVC_SET_CUR,
1020     UVC_CT_PRIVACY_CONTROL << 8,
1021     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1022     data,
1023     sizeof(data),
1024     0);
1025 
1026   if (ret == sizeof(data))
1027     return UVC_SUCCESS;
1028   else
1029     return ret;
1030 }
1031 
1032 /** @ingroup ctrl
1033  * @brief Reads the DIGITAL_WINDOW control.
1034  * @param devh UVC device handle
1035  * @param[out] window_top TODO
1036  * @param[out] window_left TODO
1037  * @param[out] window_bottom TODO
1038  * @param[out] window_right TODO
1039  * @param[out] num_steps TODO
1040  * @param[out] num_steps_units TODO
1041  * @param req_code UVC_GET_* request to execute
1042  */
uvc_get_digital_window(uvc_device_handle_t * devh,uint16_t * window_top,uint16_t * window_left,uint16_t * window_bottom,uint16_t * window_right,uint16_t * num_steps,uint16_t * num_steps_units,enum uvc_req_code req_code)1043 uvc_error_t uvc_get_digital_window(uvc_device_handle_t *devh, uint16_t* window_top, uint16_t* window_left, uint16_t* window_bottom, uint16_t* window_right, uint16_t* num_steps, uint16_t* num_steps_units, enum uvc_req_code req_code) {
1044   uint8_t data[12];
1045   uvc_error_t ret;
1046 
1047   ret = libusb_control_transfer(
1048     devh->usb_devh,
1049     REQ_TYPE_GET, req_code,
1050     UVC_CT_DIGITAL_WINDOW_CONTROL << 8,
1051     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1052     data,
1053     sizeof(data),
1054     0);
1055 
1056   if (ret == sizeof(data)) {
1057     *window_top = SW_TO_SHORT(data + 0);
1058     *window_left = SW_TO_SHORT(data + 2);
1059     *window_bottom = SW_TO_SHORT(data + 4);
1060     *window_right = SW_TO_SHORT(data + 6);
1061     *num_steps = SW_TO_SHORT(data + 8);
1062     *num_steps_units = SW_TO_SHORT(data + 10);
1063     return UVC_SUCCESS;
1064   } else {
1065     return ret;
1066   }
1067 }
1068 
1069 
1070 /** @ingroup ctrl
1071  * @brief Sets the DIGITAL_WINDOW control.
1072  * @param devh UVC device handle
1073  * @param window_top TODO
1074  * @param window_left TODO
1075  * @param window_bottom TODO
1076  * @param window_right TODO
1077  * @param num_steps TODO
1078  * @param num_steps_units TODO
1079  */
uvc_set_digital_window(uvc_device_handle_t * devh,uint16_t window_top,uint16_t window_left,uint16_t window_bottom,uint16_t window_right,uint16_t num_steps,uint16_t num_steps_units)1080 uvc_error_t uvc_set_digital_window(uvc_device_handle_t *devh, uint16_t window_top, uint16_t window_left, uint16_t window_bottom, uint16_t window_right, uint16_t num_steps, uint16_t num_steps_units) {
1081   uint8_t data[12];
1082   uvc_error_t ret;
1083 
1084   SHORT_TO_SW(window_top, data + 0);
1085   SHORT_TO_SW(window_left, data + 2);
1086   SHORT_TO_SW(window_bottom, data + 4);
1087   SHORT_TO_SW(window_right, data + 6);
1088   SHORT_TO_SW(num_steps, data + 8);
1089   SHORT_TO_SW(num_steps_units, data + 10);
1090 
1091   ret = libusb_control_transfer(
1092     devh->usb_devh,
1093     REQ_TYPE_SET, UVC_SET_CUR,
1094     UVC_CT_DIGITAL_WINDOW_CONTROL << 8,
1095     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1096     data,
1097     sizeof(data),
1098     0);
1099 
1100   if (ret == sizeof(data))
1101     return UVC_SUCCESS;
1102   else
1103     return ret;
1104 }
1105 
1106 /** @ingroup ctrl
1107  * @brief Reads the REGION_OF_INTEREST control.
1108  * @param devh UVC device handle
1109  * @param[out] roi_top TODO
1110  * @param[out] roi_left TODO
1111  * @param[out] roi_bottom TODO
1112  * @param[out] roi_right TODO
1113  * @param[out] auto_controls TODO
1114  * @param req_code UVC_GET_* request to execute
1115  */
uvc_get_digital_roi(uvc_device_handle_t * devh,uint16_t * roi_top,uint16_t * roi_left,uint16_t * roi_bottom,uint16_t * roi_right,uint16_t * auto_controls,enum uvc_req_code req_code)1116 uvc_error_t uvc_get_digital_roi(uvc_device_handle_t *devh, uint16_t* roi_top, uint16_t* roi_left, uint16_t* roi_bottom, uint16_t* roi_right, uint16_t* auto_controls, enum uvc_req_code req_code) {
1117   uint8_t data[10];
1118   uvc_error_t ret;
1119 
1120   ret = libusb_control_transfer(
1121     devh->usb_devh,
1122     REQ_TYPE_GET, req_code,
1123     UVC_CT_REGION_OF_INTEREST_CONTROL << 8,
1124     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1125     data,
1126     sizeof(data),
1127     0);
1128 
1129   if (ret == sizeof(data)) {
1130     *roi_top = SW_TO_SHORT(data + 0);
1131     *roi_left = SW_TO_SHORT(data + 2);
1132     *roi_bottom = SW_TO_SHORT(data + 4);
1133     *roi_right = SW_TO_SHORT(data + 6);
1134     *auto_controls = SW_TO_SHORT(data + 8);
1135     return UVC_SUCCESS;
1136   } else {
1137     return ret;
1138   }
1139 }
1140 
1141 
1142 /** @ingroup ctrl
1143  * @brief Sets the REGION_OF_INTEREST control.
1144  * @param devh UVC device handle
1145  * @param roi_top TODO
1146  * @param roi_left TODO
1147  * @param roi_bottom TODO
1148  * @param roi_right TODO
1149  * @param auto_controls TODO
1150  */
uvc_set_digital_roi(uvc_device_handle_t * devh,uint16_t roi_top,uint16_t roi_left,uint16_t roi_bottom,uint16_t roi_right,uint16_t auto_controls)1151 uvc_error_t uvc_set_digital_roi(uvc_device_handle_t *devh, uint16_t roi_top, uint16_t roi_left, uint16_t roi_bottom, uint16_t roi_right, uint16_t auto_controls) {
1152   uint8_t data[10];
1153   uvc_error_t ret;
1154 
1155   SHORT_TO_SW(roi_top, data + 0);
1156   SHORT_TO_SW(roi_left, data + 2);
1157   SHORT_TO_SW(roi_bottom, data + 4);
1158   SHORT_TO_SW(roi_right, data + 6);
1159   SHORT_TO_SW(auto_controls, data + 8);
1160 
1161   ret = libusb_control_transfer(
1162     devh->usb_devh,
1163     REQ_TYPE_SET, UVC_SET_CUR,
1164     UVC_CT_REGION_OF_INTEREST_CONTROL << 8,
1165     uvc_get_camera_terminal(devh)->bTerminalID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1166     data,
1167     sizeof(data),
1168     0);
1169 
1170   if (ret == sizeof(data))
1171     return UVC_SUCCESS;
1172   else
1173     return ret;
1174 }
1175 
1176 /** @ingroup ctrl
1177  * @brief Reads the BACKLIGHT_COMPENSATION control.
1178  * @param devh UVC device handle
1179  * @param[out] backlight_compensation device-dependent backlight compensation mode; zero means backlight compensation is disabled
1180  * @param req_code UVC_GET_* request to execute
1181  */
uvc_get_backlight_compensation(uvc_device_handle_t * devh,uint16_t * backlight_compensation,enum uvc_req_code req_code)1182 uvc_error_t uvc_get_backlight_compensation(uvc_device_handle_t *devh, uint16_t* backlight_compensation, enum uvc_req_code req_code) {
1183   uint8_t data[2];
1184   uvc_error_t ret;
1185 
1186   ret = libusb_control_transfer(
1187     devh->usb_devh,
1188     REQ_TYPE_GET, req_code,
1189     UVC_PU_BACKLIGHT_COMPENSATION_CONTROL << 8,
1190     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1191     data,
1192     sizeof(data),
1193     0);
1194 
1195   if (ret == sizeof(data)) {
1196     *backlight_compensation = SW_TO_SHORT(data + 0);
1197     return UVC_SUCCESS;
1198   } else {
1199     return ret;
1200   }
1201 }
1202 
1203 
1204 /** @ingroup ctrl
1205  * @brief Sets the BACKLIGHT_COMPENSATION control.
1206  * @param devh UVC device handle
1207  * @param backlight_compensation device-dependent backlight compensation mode; zero means backlight compensation is disabled
1208  */
uvc_set_backlight_compensation(uvc_device_handle_t * devh,uint16_t backlight_compensation)1209 uvc_error_t uvc_set_backlight_compensation(uvc_device_handle_t *devh, uint16_t backlight_compensation) {
1210   uint8_t data[2];
1211   uvc_error_t ret;
1212 
1213   SHORT_TO_SW(backlight_compensation, data + 0);
1214 
1215   ret = libusb_control_transfer(
1216     devh->usb_devh,
1217     REQ_TYPE_SET, UVC_SET_CUR,
1218     UVC_PU_BACKLIGHT_COMPENSATION_CONTROL << 8,
1219     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1220     data,
1221     sizeof(data),
1222     0);
1223 
1224   if (ret == sizeof(data))
1225     return UVC_SUCCESS;
1226   else
1227     return ret;
1228 }
1229 
1230 /** @ingroup ctrl
1231  * @brief Reads the BRIGHTNESS control.
1232  * @param devh UVC device handle
1233  * @param[out] brightness TODO
1234  * @param req_code UVC_GET_* request to execute
1235  */
uvc_get_brightness(uvc_device_handle_t * devh,int16_t * brightness,enum uvc_req_code req_code)1236 uvc_error_t uvc_get_brightness(uvc_device_handle_t *devh, int16_t* brightness, enum uvc_req_code req_code) {
1237   uint8_t data[2];
1238   uvc_error_t ret;
1239 
1240   ret = libusb_control_transfer(
1241     devh->usb_devh,
1242     REQ_TYPE_GET, req_code,
1243     UVC_PU_BRIGHTNESS_CONTROL << 8,
1244     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1245     data,
1246     sizeof(data),
1247     0);
1248 
1249   if (ret == sizeof(data)) {
1250     *brightness = SW_TO_SHORT(data + 0);
1251     return UVC_SUCCESS;
1252   } else {
1253     return ret;
1254   }
1255 }
1256 
1257 
1258 /** @ingroup ctrl
1259  * @brief Sets the BRIGHTNESS control.
1260  * @param devh UVC device handle
1261  * @param brightness TODO
1262  */
uvc_set_brightness(uvc_device_handle_t * devh,int16_t brightness)1263 uvc_error_t uvc_set_brightness(uvc_device_handle_t *devh, int16_t brightness) {
1264   uint8_t data[2];
1265   uvc_error_t ret;
1266 
1267   SHORT_TO_SW(brightness, data + 0);
1268 
1269   ret = libusb_control_transfer(
1270     devh->usb_devh,
1271     REQ_TYPE_SET, UVC_SET_CUR,
1272     UVC_PU_BRIGHTNESS_CONTROL << 8,
1273     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1274     data,
1275     sizeof(data),
1276     0);
1277 
1278   if (ret == sizeof(data))
1279     return UVC_SUCCESS;
1280   else
1281     return ret;
1282 }
1283 
1284 /** @ingroup ctrl
1285  * @brief Reads the CONTRAST control.
1286  * @param devh UVC device handle
1287  * @param[out] contrast TODO
1288  * @param req_code UVC_GET_* request to execute
1289  */
uvc_get_contrast(uvc_device_handle_t * devh,uint16_t * contrast,enum uvc_req_code req_code)1290 uvc_error_t uvc_get_contrast(uvc_device_handle_t *devh, uint16_t* contrast, enum uvc_req_code req_code) {
1291   uint8_t data[2];
1292   uvc_error_t ret;
1293 
1294   ret = libusb_control_transfer(
1295     devh->usb_devh,
1296     REQ_TYPE_GET, req_code,
1297     UVC_PU_CONTRAST_CONTROL << 8,
1298     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1299     data,
1300     sizeof(data),
1301     0);
1302 
1303   if (ret == sizeof(data)) {
1304     *contrast = SW_TO_SHORT(data + 0);
1305     return UVC_SUCCESS;
1306   } else {
1307     return ret;
1308   }
1309 }
1310 
1311 
1312 /** @ingroup ctrl
1313  * @brief Sets the CONTRAST control.
1314  * @param devh UVC device handle
1315  * @param contrast TODO
1316  */
uvc_set_contrast(uvc_device_handle_t * devh,uint16_t contrast)1317 uvc_error_t uvc_set_contrast(uvc_device_handle_t *devh, uint16_t contrast) {
1318   uint8_t data[2];
1319   uvc_error_t ret;
1320 
1321   SHORT_TO_SW(contrast, data + 0);
1322 
1323   ret = libusb_control_transfer(
1324     devh->usb_devh,
1325     REQ_TYPE_SET, UVC_SET_CUR,
1326     UVC_PU_CONTRAST_CONTROL << 8,
1327     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1328     data,
1329     sizeof(data),
1330     0);
1331 
1332   if (ret == sizeof(data))
1333     return UVC_SUCCESS;
1334   else
1335     return ret;
1336 }
1337 
1338 /** @ingroup ctrl
1339  * @brief Reads the CONTRAST_AUTO control.
1340  * @param devh UVC device handle
1341  * @param[out] contrast_auto TODO
1342  * @param req_code UVC_GET_* request to execute
1343  */
uvc_get_contrast_auto(uvc_device_handle_t * devh,uint8_t * contrast_auto,enum uvc_req_code req_code)1344 uvc_error_t uvc_get_contrast_auto(uvc_device_handle_t *devh, uint8_t* contrast_auto, enum uvc_req_code req_code) {
1345   uint8_t data[1];
1346   uvc_error_t ret;
1347 
1348   ret = libusb_control_transfer(
1349     devh->usb_devh,
1350     REQ_TYPE_GET, req_code,
1351     UVC_PU_CONTRAST_AUTO_CONTROL << 8,
1352     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1353     data,
1354     sizeof(data),
1355     0);
1356 
1357   if (ret == sizeof(data)) {
1358     *contrast_auto = data[0];
1359     return UVC_SUCCESS;
1360   } else {
1361     return ret;
1362   }
1363 }
1364 
1365 
1366 /** @ingroup ctrl
1367  * @brief Sets the CONTRAST_AUTO control.
1368  * @param devh UVC device handle
1369  * @param contrast_auto TODO
1370  */
uvc_set_contrast_auto(uvc_device_handle_t * devh,uint8_t contrast_auto)1371 uvc_error_t uvc_set_contrast_auto(uvc_device_handle_t *devh, uint8_t contrast_auto) {
1372   uint8_t data[1];
1373   uvc_error_t ret;
1374 
1375   data[0] = contrast_auto;
1376 
1377   ret = libusb_control_transfer(
1378     devh->usb_devh,
1379     REQ_TYPE_SET, UVC_SET_CUR,
1380     UVC_PU_CONTRAST_AUTO_CONTROL << 8,
1381     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1382     data,
1383     sizeof(data),
1384     0);
1385 
1386   if (ret == sizeof(data))
1387     return UVC_SUCCESS;
1388   else
1389     return ret;
1390 }
1391 
1392 /** @ingroup ctrl
1393  * @brief Reads the GAIN control.
1394  * @param devh UVC device handle
1395  * @param[out] gain TODO
1396  * @param req_code UVC_GET_* request to execute
1397  */
uvc_get_gain(uvc_device_handle_t * devh,uint16_t * gain,enum uvc_req_code req_code)1398 uvc_error_t uvc_get_gain(uvc_device_handle_t *devh, uint16_t* gain, enum uvc_req_code req_code) {
1399   uint8_t data[2];
1400   uvc_error_t ret;
1401 
1402   ret = libusb_control_transfer(
1403     devh->usb_devh,
1404     REQ_TYPE_GET, req_code,
1405     UVC_PU_GAIN_CONTROL << 8,
1406     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1407     data,
1408     sizeof(data),
1409     0);
1410 
1411   if (ret == sizeof(data)) {
1412     *gain = SW_TO_SHORT(data + 0);
1413     return UVC_SUCCESS;
1414   } else {
1415     return ret;
1416   }
1417 }
1418 
1419 
1420 /** @ingroup ctrl
1421  * @brief Sets the GAIN control.
1422  * @param devh UVC device handle
1423  * @param gain TODO
1424  */
uvc_set_gain(uvc_device_handle_t * devh,uint16_t gain)1425 uvc_error_t uvc_set_gain(uvc_device_handle_t *devh, uint16_t gain) {
1426   uint8_t data[2];
1427   uvc_error_t ret;
1428 
1429   SHORT_TO_SW(gain, data + 0);
1430 
1431   ret = libusb_control_transfer(
1432     devh->usb_devh,
1433     REQ_TYPE_SET, UVC_SET_CUR,
1434     UVC_PU_GAIN_CONTROL << 8,
1435     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1436     data,
1437     sizeof(data),
1438     0);
1439 
1440   if (ret == sizeof(data))
1441     return UVC_SUCCESS;
1442   else
1443     return ret;
1444 }
1445 
1446 /** @ingroup ctrl
1447  * @brief Reads the POWER_LINE_FREQUENCY control.
1448  * @param devh UVC device handle
1449  * @param[out] power_line_frequency TODO
1450  * @param req_code UVC_GET_* request to execute
1451  */
uvc_get_power_line_frequency(uvc_device_handle_t * devh,uint8_t * power_line_frequency,enum uvc_req_code req_code)1452 uvc_error_t uvc_get_power_line_frequency(uvc_device_handle_t *devh, uint8_t* power_line_frequency, enum uvc_req_code req_code) {
1453   uint8_t data[1];
1454   uvc_error_t ret;
1455 
1456   ret = libusb_control_transfer(
1457     devh->usb_devh,
1458     REQ_TYPE_GET, req_code,
1459     UVC_PU_POWER_LINE_FREQUENCY_CONTROL << 8,
1460     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1461     data,
1462     sizeof(data),
1463     0);
1464 
1465   if (ret == sizeof(data)) {
1466     *power_line_frequency = data[0];
1467     return UVC_SUCCESS;
1468   } else {
1469     return ret;
1470   }
1471 }
1472 
1473 
1474 /** @ingroup ctrl
1475  * @brief Sets the POWER_LINE_FREQUENCY control.
1476  * @param devh UVC device handle
1477  * @param power_line_frequency TODO
1478  */
uvc_set_power_line_frequency(uvc_device_handle_t * devh,uint8_t power_line_frequency)1479 uvc_error_t uvc_set_power_line_frequency(uvc_device_handle_t *devh, uint8_t power_line_frequency) {
1480   uint8_t data[1];
1481   uvc_error_t ret;
1482 
1483   data[0] = power_line_frequency;
1484 
1485   ret = libusb_control_transfer(
1486     devh->usb_devh,
1487     REQ_TYPE_SET, UVC_SET_CUR,
1488     UVC_PU_POWER_LINE_FREQUENCY_CONTROL << 8,
1489     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1490     data,
1491     sizeof(data),
1492     0);
1493 
1494   if (ret == sizeof(data))
1495     return UVC_SUCCESS;
1496   else
1497     return ret;
1498 }
1499 
1500 /** @ingroup ctrl
1501  * @brief Reads the HUE control.
1502  * @param devh UVC device handle
1503  * @param[out] hue TODO
1504  * @param req_code UVC_GET_* request to execute
1505  */
uvc_get_hue(uvc_device_handle_t * devh,int16_t * hue,enum uvc_req_code req_code)1506 uvc_error_t uvc_get_hue(uvc_device_handle_t *devh, int16_t* hue, enum uvc_req_code req_code) {
1507   uint8_t data[2];
1508   uvc_error_t ret;
1509 
1510   ret = libusb_control_transfer(
1511     devh->usb_devh,
1512     REQ_TYPE_GET, req_code,
1513     UVC_PU_HUE_CONTROL << 8,
1514     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1515     data,
1516     sizeof(data),
1517     0);
1518 
1519   if (ret == sizeof(data)) {
1520     *hue = SW_TO_SHORT(data + 0);
1521     return UVC_SUCCESS;
1522   } else {
1523     return ret;
1524   }
1525 }
1526 
1527 
1528 /** @ingroup ctrl
1529  * @brief Sets the HUE control.
1530  * @param devh UVC device handle
1531  * @param hue TODO
1532  */
uvc_set_hue(uvc_device_handle_t * devh,int16_t hue)1533 uvc_error_t uvc_set_hue(uvc_device_handle_t *devh, int16_t hue) {
1534   uint8_t data[2];
1535   uvc_error_t ret;
1536 
1537   SHORT_TO_SW(hue, data + 0);
1538 
1539   ret = libusb_control_transfer(
1540     devh->usb_devh,
1541     REQ_TYPE_SET, UVC_SET_CUR,
1542     UVC_PU_HUE_CONTROL << 8,
1543     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1544     data,
1545     sizeof(data),
1546     0);
1547 
1548   if (ret == sizeof(data))
1549     return UVC_SUCCESS;
1550   else
1551     return ret;
1552 }
1553 
1554 /** @ingroup ctrl
1555  * @brief Reads the HUE_AUTO control.
1556  * @param devh UVC device handle
1557  * @param[out] hue_auto TODO
1558  * @param req_code UVC_GET_* request to execute
1559  */
uvc_get_hue_auto(uvc_device_handle_t * devh,uint8_t * hue_auto,enum uvc_req_code req_code)1560 uvc_error_t uvc_get_hue_auto(uvc_device_handle_t *devh, uint8_t* hue_auto, enum uvc_req_code req_code) {
1561   uint8_t data[1];
1562   uvc_error_t ret;
1563 
1564   ret = libusb_control_transfer(
1565     devh->usb_devh,
1566     REQ_TYPE_GET, req_code,
1567     UVC_PU_HUE_AUTO_CONTROL << 8,
1568     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1569     data,
1570     sizeof(data),
1571     0);
1572 
1573   if (ret == sizeof(data)) {
1574     *hue_auto = data[0];
1575     return UVC_SUCCESS;
1576   } else {
1577     return ret;
1578   }
1579 }
1580 
1581 
1582 /** @ingroup ctrl
1583  * @brief Sets the HUE_AUTO control.
1584  * @param devh UVC device handle
1585  * @param hue_auto TODO
1586  */
uvc_set_hue_auto(uvc_device_handle_t * devh,uint8_t hue_auto)1587 uvc_error_t uvc_set_hue_auto(uvc_device_handle_t *devh, uint8_t hue_auto) {
1588   uint8_t data[1];
1589   uvc_error_t ret;
1590 
1591   data[0] = hue_auto;
1592 
1593   ret = libusb_control_transfer(
1594     devh->usb_devh,
1595     REQ_TYPE_SET, UVC_SET_CUR,
1596     UVC_PU_HUE_AUTO_CONTROL << 8,
1597     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1598     data,
1599     sizeof(data),
1600     0);
1601 
1602   if (ret == sizeof(data))
1603     return UVC_SUCCESS;
1604   else
1605     return ret;
1606 }
1607 
1608 /** @ingroup ctrl
1609  * @brief Reads the SATURATION control.
1610  * @param devh UVC device handle
1611  * @param[out] saturation TODO
1612  * @param req_code UVC_GET_* request to execute
1613  */
uvc_get_saturation(uvc_device_handle_t * devh,uint16_t * saturation,enum uvc_req_code req_code)1614 uvc_error_t uvc_get_saturation(uvc_device_handle_t *devh, uint16_t* saturation, enum uvc_req_code req_code) {
1615   uint8_t data[2];
1616   uvc_error_t ret;
1617 
1618   ret = libusb_control_transfer(
1619     devh->usb_devh,
1620     REQ_TYPE_GET, req_code,
1621     UVC_PU_SATURATION_CONTROL << 8,
1622     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1623     data,
1624     sizeof(data),
1625     0);
1626 
1627   if (ret == sizeof(data)) {
1628     *saturation = SW_TO_SHORT(data + 0);
1629     return UVC_SUCCESS;
1630   } else {
1631     return ret;
1632   }
1633 }
1634 
1635 
1636 /** @ingroup ctrl
1637  * @brief Sets the SATURATION control.
1638  * @param devh UVC device handle
1639  * @param saturation TODO
1640  */
uvc_set_saturation(uvc_device_handle_t * devh,uint16_t saturation)1641 uvc_error_t uvc_set_saturation(uvc_device_handle_t *devh, uint16_t saturation) {
1642   uint8_t data[2];
1643   uvc_error_t ret;
1644 
1645   SHORT_TO_SW(saturation, data + 0);
1646 
1647   ret = libusb_control_transfer(
1648     devh->usb_devh,
1649     REQ_TYPE_SET, UVC_SET_CUR,
1650     UVC_PU_SATURATION_CONTROL << 8,
1651     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1652     data,
1653     sizeof(data),
1654     0);
1655 
1656   if (ret == sizeof(data))
1657     return UVC_SUCCESS;
1658   else
1659     return ret;
1660 }
1661 
1662 /** @ingroup ctrl
1663  * @brief Reads the SHARPNESS control.
1664  * @param devh UVC device handle
1665  * @param[out] sharpness TODO
1666  * @param req_code UVC_GET_* request to execute
1667  */
uvc_get_sharpness(uvc_device_handle_t * devh,uint16_t * sharpness,enum uvc_req_code req_code)1668 uvc_error_t uvc_get_sharpness(uvc_device_handle_t *devh, uint16_t* sharpness, enum uvc_req_code req_code) {
1669   uint8_t data[2];
1670   uvc_error_t ret;
1671 
1672   ret = libusb_control_transfer(
1673     devh->usb_devh,
1674     REQ_TYPE_GET, req_code,
1675     UVC_PU_SHARPNESS_CONTROL << 8,
1676     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1677     data,
1678     sizeof(data),
1679     0);
1680 
1681   if (ret == sizeof(data)) {
1682     *sharpness = SW_TO_SHORT(data + 0);
1683     return UVC_SUCCESS;
1684   } else {
1685     return ret;
1686   }
1687 }
1688 
1689 
1690 /** @ingroup ctrl
1691  * @brief Sets the SHARPNESS control.
1692  * @param devh UVC device handle
1693  * @param sharpness TODO
1694  */
uvc_set_sharpness(uvc_device_handle_t * devh,uint16_t sharpness)1695 uvc_error_t uvc_set_sharpness(uvc_device_handle_t *devh, uint16_t sharpness) {
1696   uint8_t data[2];
1697   uvc_error_t ret;
1698 
1699   SHORT_TO_SW(sharpness, data + 0);
1700 
1701   ret = libusb_control_transfer(
1702     devh->usb_devh,
1703     REQ_TYPE_SET, UVC_SET_CUR,
1704     UVC_PU_SHARPNESS_CONTROL << 8,
1705     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1706     data,
1707     sizeof(data),
1708     0);
1709 
1710   if (ret == sizeof(data))
1711     return UVC_SUCCESS;
1712   else
1713     return ret;
1714 }
1715 
1716 /** @ingroup ctrl
1717  * @brief Reads the GAMMA control.
1718  * @param devh UVC device handle
1719  * @param[out] gamma TODO
1720  * @param req_code UVC_GET_* request to execute
1721  */
uvc_get_gamma(uvc_device_handle_t * devh,uint16_t * gamma,enum uvc_req_code req_code)1722 uvc_error_t uvc_get_gamma(uvc_device_handle_t *devh, uint16_t* gamma, enum uvc_req_code req_code) {
1723   uint8_t data[2];
1724   uvc_error_t ret;
1725 
1726   ret = libusb_control_transfer(
1727     devh->usb_devh,
1728     REQ_TYPE_GET, req_code,
1729     UVC_PU_GAMMA_CONTROL << 8,
1730     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1731     data,
1732     sizeof(data),
1733     0);
1734 
1735   if (ret == sizeof(data)) {
1736     *gamma = SW_TO_SHORT(data + 0);
1737     return UVC_SUCCESS;
1738   } else {
1739     return ret;
1740   }
1741 }
1742 
1743 
1744 /** @ingroup ctrl
1745  * @brief Sets the GAMMA control.
1746  * @param devh UVC device handle
1747  * @param gamma TODO
1748  */
uvc_set_gamma(uvc_device_handle_t * devh,uint16_t gamma)1749 uvc_error_t uvc_set_gamma(uvc_device_handle_t *devh, uint16_t gamma) {
1750   uint8_t data[2];
1751   uvc_error_t ret;
1752 
1753   SHORT_TO_SW(gamma, data + 0);
1754 
1755   ret = libusb_control_transfer(
1756     devh->usb_devh,
1757     REQ_TYPE_SET, UVC_SET_CUR,
1758     UVC_PU_GAMMA_CONTROL << 8,
1759     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1760     data,
1761     sizeof(data),
1762     0);
1763 
1764   if (ret == sizeof(data))
1765     return UVC_SUCCESS;
1766   else
1767     return ret;
1768 }
1769 
1770 /** @ingroup ctrl
1771  * @brief Reads the WHITE_BALANCE_TEMPERATURE control.
1772  * @param devh UVC device handle
1773  * @param[out] temperature TODO
1774  * @param req_code UVC_GET_* request to execute
1775  */
uvc_get_white_balance_temperature(uvc_device_handle_t * devh,uint16_t * temperature,enum uvc_req_code req_code)1776 uvc_error_t uvc_get_white_balance_temperature(uvc_device_handle_t *devh, uint16_t* temperature, enum uvc_req_code req_code) {
1777   uint8_t data[2];
1778   uvc_error_t ret;
1779 
1780   ret = libusb_control_transfer(
1781     devh->usb_devh,
1782     REQ_TYPE_GET, req_code,
1783     UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL << 8,
1784     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1785     data,
1786     sizeof(data),
1787     0);
1788 
1789   if (ret == sizeof(data)) {
1790     *temperature = SW_TO_SHORT(data + 0);
1791     return UVC_SUCCESS;
1792   } else {
1793     return ret;
1794   }
1795 }
1796 
1797 
1798 /** @ingroup ctrl
1799  * @brief Sets the WHITE_BALANCE_TEMPERATURE control.
1800  * @param devh UVC device handle
1801  * @param temperature TODO
1802  */
uvc_set_white_balance_temperature(uvc_device_handle_t * devh,uint16_t temperature)1803 uvc_error_t uvc_set_white_balance_temperature(uvc_device_handle_t *devh, uint16_t temperature) {
1804   uint8_t data[2];
1805   uvc_error_t ret;
1806 
1807   SHORT_TO_SW(temperature, data + 0);
1808 
1809   ret = libusb_control_transfer(
1810     devh->usb_devh,
1811     REQ_TYPE_SET, UVC_SET_CUR,
1812     UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL << 8,
1813     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1814     data,
1815     sizeof(data),
1816     0);
1817 
1818   if (ret == sizeof(data))
1819     return UVC_SUCCESS;
1820   else
1821     return ret;
1822 }
1823 
1824 /** @ingroup ctrl
1825  * @brief Reads the WHITE_BALANCE_TEMPERATURE_AUTO control.
1826  * @param devh UVC device handle
1827  * @param[out] temperature_auto TODO
1828  * @param req_code UVC_GET_* request to execute
1829  */
uvc_get_white_balance_temperature_auto(uvc_device_handle_t * devh,uint8_t * temperature_auto,enum uvc_req_code req_code)1830 uvc_error_t uvc_get_white_balance_temperature_auto(uvc_device_handle_t *devh, uint8_t* temperature_auto, enum uvc_req_code req_code) {
1831   uint8_t data[1];
1832   uvc_error_t ret;
1833 
1834   ret = libusb_control_transfer(
1835     devh->usb_devh,
1836     REQ_TYPE_GET, req_code,
1837     UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL << 8,
1838     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1839     data,
1840     sizeof(data),
1841     0);
1842 
1843   if (ret == sizeof(data)) {
1844     *temperature_auto = data[0];
1845     return UVC_SUCCESS;
1846   } else {
1847     return ret;
1848   }
1849 }
1850 
1851 
1852 /** @ingroup ctrl
1853  * @brief Sets the WHITE_BALANCE_TEMPERATURE_AUTO control.
1854  * @param devh UVC device handle
1855  * @param temperature_auto TODO
1856  */
uvc_set_white_balance_temperature_auto(uvc_device_handle_t * devh,uint8_t temperature_auto)1857 uvc_error_t uvc_set_white_balance_temperature_auto(uvc_device_handle_t *devh, uint8_t temperature_auto) {
1858   uint8_t data[1];
1859   uvc_error_t ret;
1860 
1861   data[0] = temperature_auto;
1862 
1863   ret = libusb_control_transfer(
1864     devh->usb_devh,
1865     REQ_TYPE_SET, UVC_SET_CUR,
1866     UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL << 8,
1867     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1868     data,
1869     sizeof(data),
1870     0);
1871 
1872   if (ret == sizeof(data))
1873     return UVC_SUCCESS;
1874   else
1875     return ret;
1876 }
1877 
1878 /** @ingroup ctrl
1879  * @brief Reads the WHITE_BALANCE_COMPONENT control.
1880  * @param devh UVC device handle
1881  * @param[out] blue TODO
1882  * @param[out] red TODO
1883  * @param req_code UVC_GET_* request to execute
1884  */
uvc_get_white_balance_component(uvc_device_handle_t * devh,uint16_t * blue,uint16_t * red,enum uvc_req_code req_code)1885 uvc_error_t uvc_get_white_balance_component(uvc_device_handle_t *devh, uint16_t* blue, uint16_t* red, enum uvc_req_code req_code) {
1886   uint8_t data[4];
1887   uvc_error_t ret;
1888 
1889   ret = libusb_control_transfer(
1890     devh->usb_devh,
1891     REQ_TYPE_GET, req_code,
1892     UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL << 8,
1893     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1894     data,
1895     sizeof(data),
1896     0);
1897 
1898   if (ret == sizeof(data)) {
1899     *blue = SW_TO_SHORT(data + 0);
1900     *red = SW_TO_SHORT(data + 2);
1901     return UVC_SUCCESS;
1902   } else {
1903     return ret;
1904   }
1905 }
1906 
1907 
1908 /** @ingroup ctrl
1909  * @brief Sets the WHITE_BALANCE_COMPONENT control.
1910  * @param devh UVC device handle
1911  * @param blue TODO
1912  * @param red TODO
1913  */
uvc_set_white_balance_component(uvc_device_handle_t * devh,uint16_t blue,uint16_t red)1914 uvc_error_t uvc_set_white_balance_component(uvc_device_handle_t *devh, uint16_t blue, uint16_t red) {
1915   uint8_t data[4];
1916   uvc_error_t ret;
1917 
1918   SHORT_TO_SW(blue, data + 0);
1919   SHORT_TO_SW(red, data + 2);
1920 
1921   ret = libusb_control_transfer(
1922     devh->usb_devh,
1923     REQ_TYPE_SET, UVC_SET_CUR,
1924     UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL << 8,
1925     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1926     data,
1927     sizeof(data),
1928     0);
1929 
1930   if (ret == sizeof(data))
1931     return UVC_SUCCESS;
1932   else
1933     return ret;
1934 }
1935 
1936 /** @ingroup ctrl
1937  * @brief Reads the WHITE_BALANCE_COMPONENT_AUTO control.
1938  * @param devh UVC device handle
1939  * @param[out] white_balance_component_auto TODO
1940  * @param req_code UVC_GET_* request to execute
1941  */
uvc_get_white_balance_component_auto(uvc_device_handle_t * devh,uint8_t * white_balance_component_auto,enum uvc_req_code req_code)1942 uvc_error_t uvc_get_white_balance_component_auto(uvc_device_handle_t *devh, uint8_t* white_balance_component_auto, enum uvc_req_code req_code) {
1943   uint8_t data[1];
1944   uvc_error_t ret;
1945 
1946   ret = libusb_control_transfer(
1947     devh->usb_devh,
1948     REQ_TYPE_GET, req_code,
1949     UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL << 8,
1950     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1951     data,
1952     sizeof(data),
1953     0);
1954 
1955   if (ret == sizeof(data)) {
1956     *white_balance_component_auto = data[0];
1957     return UVC_SUCCESS;
1958   } else {
1959     return ret;
1960   }
1961 }
1962 
1963 
1964 /** @ingroup ctrl
1965  * @brief Sets the WHITE_BALANCE_COMPONENT_AUTO control.
1966  * @param devh UVC device handle
1967  * @param white_balance_component_auto TODO
1968  */
uvc_set_white_balance_component_auto(uvc_device_handle_t * devh,uint8_t white_balance_component_auto)1969 uvc_error_t uvc_set_white_balance_component_auto(uvc_device_handle_t *devh, uint8_t white_balance_component_auto) {
1970   uint8_t data[1];
1971   uvc_error_t ret;
1972 
1973   data[0] = white_balance_component_auto;
1974 
1975   ret = libusb_control_transfer(
1976     devh->usb_devh,
1977     REQ_TYPE_SET, UVC_SET_CUR,
1978     UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL << 8,
1979     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
1980     data,
1981     sizeof(data),
1982     0);
1983 
1984   if (ret == sizeof(data))
1985     return UVC_SUCCESS;
1986   else
1987     return ret;
1988 }
1989 
1990 /** @ingroup ctrl
1991  * @brief Reads the DIGITAL_MULTIPLIER control.
1992  * @param devh UVC device handle
1993  * @param[out] multiplier_step TODO
1994  * @param req_code UVC_GET_* request to execute
1995  */
uvc_get_digital_multiplier(uvc_device_handle_t * devh,uint16_t * multiplier_step,enum uvc_req_code req_code)1996 uvc_error_t uvc_get_digital_multiplier(uvc_device_handle_t *devh, uint16_t* multiplier_step, enum uvc_req_code req_code) {
1997   uint8_t data[2];
1998   uvc_error_t ret;
1999 
2000   ret = libusb_control_transfer(
2001     devh->usb_devh,
2002     REQ_TYPE_GET, req_code,
2003     UVC_PU_DIGITAL_MULTIPLIER_CONTROL << 8,
2004     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2005     data,
2006     sizeof(data),
2007     0);
2008 
2009   if (ret == sizeof(data)) {
2010     *multiplier_step = SW_TO_SHORT(data + 0);
2011     return UVC_SUCCESS;
2012   } else {
2013     return ret;
2014   }
2015 }
2016 
2017 
2018 /** @ingroup ctrl
2019  * @brief Sets the DIGITAL_MULTIPLIER control.
2020  * @param devh UVC device handle
2021  * @param multiplier_step TODO
2022  */
uvc_set_digital_multiplier(uvc_device_handle_t * devh,uint16_t multiplier_step)2023 uvc_error_t uvc_set_digital_multiplier(uvc_device_handle_t *devh, uint16_t multiplier_step) {
2024   uint8_t data[2];
2025   uvc_error_t ret;
2026 
2027   SHORT_TO_SW(multiplier_step, data + 0);
2028 
2029   ret = libusb_control_transfer(
2030     devh->usb_devh,
2031     REQ_TYPE_SET, UVC_SET_CUR,
2032     UVC_PU_DIGITAL_MULTIPLIER_CONTROL << 8,
2033     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2034     data,
2035     sizeof(data),
2036     0);
2037 
2038   if (ret == sizeof(data))
2039     return UVC_SUCCESS;
2040   else
2041     return ret;
2042 }
2043 
2044 /** @ingroup ctrl
2045  * @brief Reads the DIGITAL_MULTIPLIER_LIMIT control.
2046  * @param devh UVC device handle
2047  * @param[out] multiplier_step TODO
2048  * @param req_code UVC_GET_* request to execute
2049  */
uvc_get_digital_multiplier_limit(uvc_device_handle_t * devh,uint16_t * multiplier_step,enum uvc_req_code req_code)2050 uvc_error_t uvc_get_digital_multiplier_limit(uvc_device_handle_t *devh, uint16_t* multiplier_step, enum uvc_req_code req_code) {
2051   uint8_t data[2];
2052   uvc_error_t ret;
2053 
2054   ret = libusb_control_transfer(
2055     devh->usb_devh,
2056     REQ_TYPE_GET, req_code,
2057     UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL << 8,
2058     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2059     data,
2060     sizeof(data),
2061     0);
2062 
2063   if (ret == sizeof(data)) {
2064     *multiplier_step = SW_TO_SHORT(data + 0);
2065     return UVC_SUCCESS;
2066   } else {
2067     return ret;
2068   }
2069 }
2070 
2071 
2072 /** @ingroup ctrl
2073  * @brief Sets the DIGITAL_MULTIPLIER_LIMIT control.
2074  * @param devh UVC device handle
2075  * @param multiplier_step TODO
2076  */
uvc_set_digital_multiplier_limit(uvc_device_handle_t * devh,uint16_t multiplier_step)2077 uvc_error_t uvc_set_digital_multiplier_limit(uvc_device_handle_t *devh, uint16_t multiplier_step) {
2078   uint8_t data[2];
2079   uvc_error_t ret;
2080 
2081   SHORT_TO_SW(multiplier_step, data + 0);
2082 
2083   ret = libusb_control_transfer(
2084     devh->usb_devh,
2085     REQ_TYPE_SET, UVC_SET_CUR,
2086     UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL << 8,
2087     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2088     data,
2089     sizeof(data),
2090     0);
2091 
2092   if (ret == sizeof(data))
2093     return UVC_SUCCESS;
2094   else
2095     return ret;
2096 }
2097 
2098 /** @ingroup ctrl
2099  * @brief Reads the ANALOG_VIDEO_STANDARD control.
2100  * @param devh UVC device handle
2101  * @param[out] video_standard TODO
2102  * @param req_code UVC_GET_* request to execute
2103  */
uvc_get_analog_video_standard(uvc_device_handle_t * devh,uint8_t * video_standard,enum uvc_req_code req_code)2104 uvc_error_t uvc_get_analog_video_standard(uvc_device_handle_t *devh, uint8_t* video_standard, enum uvc_req_code req_code) {
2105   uint8_t data[1];
2106   uvc_error_t ret;
2107 
2108   ret = libusb_control_transfer(
2109     devh->usb_devh,
2110     REQ_TYPE_GET, req_code,
2111     UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL << 8,
2112     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2113     data,
2114     sizeof(data),
2115     0);
2116 
2117   if (ret == sizeof(data)) {
2118     *video_standard = data[0];
2119     return UVC_SUCCESS;
2120   } else {
2121     return ret;
2122   }
2123 }
2124 
2125 
2126 /** @ingroup ctrl
2127  * @brief Sets the ANALOG_VIDEO_STANDARD control.
2128  * @param devh UVC device handle
2129  * @param video_standard TODO
2130  */
uvc_set_analog_video_standard(uvc_device_handle_t * devh,uint8_t video_standard)2131 uvc_error_t uvc_set_analog_video_standard(uvc_device_handle_t *devh, uint8_t video_standard) {
2132   uint8_t data[1];
2133   uvc_error_t ret;
2134 
2135   data[0] = video_standard;
2136 
2137   ret = libusb_control_transfer(
2138     devh->usb_devh,
2139     REQ_TYPE_SET, UVC_SET_CUR,
2140     UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL << 8,
2141     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2142     data,
2143     sizeof(data),
2144     0);
2145 
2146   if (ret == sizeof(data))
2147     return UVC_SUCCESS;
2148   else
2149     return ret;
2150 }
2151 
2152 /** @ingroup ctrl
2153  * @brief Reads the ANALOG_LOCK_STATUS control.
2154  * @param devh UVC device handle
2155  * @param[out] status TODO
2156  * @param req_code UVC_GET_* request to execute
2157  */
uvc_get_analog_video_lock_status(uvc_device_handle_t * devh,uint8_t * status,enum uvc_req_code req_code)2158 uvc_error_t uvc_get_analog_video_lock_status(uvc_device_handle_t *devh, uint8_t* status, enum uvc_req_code req_code) {
2159   uint8_t data[1];
2160   uvc_error_t ret;
2161 
2162   ret = libusb_control_transfer(
2163     devh->usb_devh,
2164     REQ_TYPE_GET, req_code,
2165     UVC_PU_ANALOG_LOCK_STATUS_CONTROL << 8,
2166     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2167     data,
2168     sizeof(data),
2169     0);
2170 
2171   if (ret == sizeof(data)) {
2172     *status = data[0];
2173     return UVC_SUCCESS;
2174   } else {
2175     return ret;
2176   }
2177 }
2178 
2179 
2180 /** @ingroup ctrl
2181  * @brief Sets the ANALOG_LOCK_STATUS control.
2182  * @param devh UVC device handle
2183  * @param status TODO
2184  */
uvc_set_analog_video_lock_status(uvc_device_handle_t * devh,uint8_t status)2185 uvc_error_t uvc_set_analog_video_lock_status(uvc_device_handle_t *devh, uint8_t status) {
2186   uint8_t data[1];
2187   uvc_error_t ret;
2188 
2189   data[0] = status;
2190 
2191   ret = libusb_control_transfer(
2192     devh->usb_devh,
2193     REQ_TYPE_SET, UVC_SET_CUR,
2194     UVC_PU_ANALOG_LOCK_STATUS_CONTROL << 8,
2195     uvc_get_processing_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2196     data,
2197     sizeof(data),
2198     0);
2199 
2200   if (ret == sizeof(data))
2201     return UVC_SUCCESS;
2202   else
2203     return ret;
2204 }
2205 
2206 /** @ingroup ctrl
2207  * @brief Reads the INPUT_SELECT control.
2208  * @param devh UVC device handle
2209  * @param[out] selector TODO
2210  * @param req_code UVC_GET_* request to execute
2211  */
uvc_get_input_select(uvc_device_handle_t * devh,uint8_t * selector,enum uvc_req_code req_code)2212 uvc_error_t uvc_get_input_select(uvc_device_handle_t *devh, uint8_t* selector, enum uvc_req_code req_code) {
2213   uint8_t data[1];
2214   uvc_error_t ret;
2215 
2216   ret = libusb_control_transfer(
2217     devh->usb_devh,
2218     REQ_TYPE_GET, req_code,
2219     UVC_SU_INPUT_SELECT_CONTROL << 8,
2220     uvc_get_selector_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2221     data,
2222     sizeof(data),
2223     0);
2224 
2225   if (ret == sizeof(data)) {
2226     *selector = data[0];
2227     return UVC_SUCCESS;
2228   } else {
2229     return ret;
2230   }
2231 }
2232 
2233 
2234 /** @ingroup ctrl
2235  * @brief Sets the INPUT_SELECT control.
2236  * @param devh UVC device handle
2237  * @param selector TODO
2238  */
uvc_set_input_select(uvc_device_handle_t * devh,uint8_t selector)2239 uvc_error_t uvc_set_input_select(uvc_device_handle_t *devh, uint8_t selector) {
2240   uint8_t data[1];
2241   uvc_error_t ret;
2242 
2243   data[0] = selector;
2244 
2245   ret = libusb_control_transfer(
2246     devh->usb_devh,
2247     REQ_TYPE_SET, UVC_SET_CUR,
2248     UVC_SU_INPUT_SELECT_CONTROL << 8,
2249     uvc_get_selector_units(devh)->bUnitID << 8 | devh->info->ctrl_if.bInterfaceNumber,
2250     data,
2251     sizeof(data),
2252     0);
2253 
2254   if (ret == sizeof(data))
2255     return UVC_SUCCESS;
2256   else
2257     return ret;
2258 }
2259 
2260