1 /*********************************************************************
2 * Software License Agreement (BSD License)
4 * Copyright (C) 2010-2012 Ken Tossell
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the author nor other contributors may be
18 * used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
35 * @defgroup ctrl Video capture and processing control
38 #include "libuvc/libuvc.h"
39 #include "libuvc/libuvc_internal.h"
41 static const int REQ_TYPE_SET = 0x21;
42 static const int REQ_TYPE_GET = 0xa1;
44 uvc_error_t uvc_get_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode *mode, enum uvc_req_code req_code) {
48 ret = libusb_control_transfer(
50 REQ_TYPE_GET, req_code,
51 UVC_VC_VIDEO_POWER_MODE_CONTROL << 8,
65 uvc_error_t uvc_set_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode mode) {
66 uint8_t mode_char = mode;
69 ret = libusb_control_transfer(
71 REQ_TYPE_SET, UVC_SET_CUR,
72 UVC_VC_VIDEO_POWER_MODE_CONTROL << 8,
84 /***** CAMERA TERMINAL CONTROLS *****/
86 uvc_error_t uvc_get_ae_mode(uvc_device_handle_t *devh, int *mode, enum uvc_req_code req_code) {
90 ret = libusb_control_transfer(
92 REQ_TYPE_GET, req_code,
93 UVC_CT_AE_MODE_CONTROL << 8,
99 if (ret == sizeof(data)) {
107 uvc_error_t uvc_set_ae_mode(uvc_device_handle_t *devh, int mode) {
113 ret = libusb_control_transfer(
115 REQ_TYPE_SET, UVC_SET_CUR,
116 UVC_CT_AE_MODE_CONTROL << 8,
122 if (ret == sizeof(data))
128 uvc_error_t uvc_get_ae_priority(uvc_device_handle_t *devh, uint8_t *priority, enum uvc_req_code req_code) {
132 ret = libusb_control_transfer(
134 REQ_TYPE_GET, req_code,
135 UVC_CT_AE_PRIORITY_CONTROL << 8,
141 if (ret == sizeof(data)) {
149 uvc_error_t uvc_set_ae_priority(uvc_device_handle_t *devh, uint8_t priority) {
155 ret = libusb_control_transfer(
157 REQ_TYPE_SET, UVC_SET_CUR,
158 UVC_CT_AE_PRIORITY_CONTROL << 8,
164 if (ret == sizeof(data))
170 uvc_error_t uvc_get_exposure_abs(uvc_device_handle_t *devh, int *time, enum uvc_req_code req_code) {
174 ret = libusb_control_transfer(
176 REQ_TYPE_GET, req_code,
177 UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
183 if (ret == sizeof(data)) {
184 *time = DW_TO_INT(data);
191 uvc_error_t uvc_set_exposure_abs(uvc_device_handle_t *devh, int time) {
195 INT_TO_DW(time, data);
197 ret = libusb_control_transfer(
199 REQ_TYPE_SET, UVC_SET_CUR,
200 UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
206 if (ret == sizeof(data))
212 uvc_error_t uvc_get_exposure_rel(uvc_device_handle_t *devh, int *step, enum uvc_req_code req_code) {
216 ret = libusb_control_transfer(
218 REQ_TYPE_GET, req_code,
219 UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
225 if (ret == sizeof(data)) {
233 uvc_error_t uvc_set_exposure_rel(uvc_device_handle_t *devh, int step) {
239 ret = libusb_control_transfer(
241 REQ_TYPE_SET, UVC_SET_CUR,
242 UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
248 if (ret == sizeof(data))
254 uvc_error_t uvc_get_scanning_mode(uvc_device_handle_t *devh, int *step, enum uvc_req_code req_code) {
258 ret = libusb_control_transfer(
260 REQ_TYPE_GET, req_code,
261 UVC_CT_SCANNING_MODE_CONTROL << 8,
267 if (ret == sizeof(data)) {
275 uvc_error_t uvc_set_scanning_mode(uvc_device_handle_t *devh, int mode) {
281 ret = libusb_control_transfer(
283 REQ_TYPE_SET, UVC_SET_CUR,
284 UVC_CT_SCANNING_MODE_CONTROL << 8,
290 if (ret == sizeof(data))
296 uvc_error_t uvc_get_focus_abs(uvc_device_handle_t *devh, short *focus, enum uvc_req_code req_code) {
300 ret = libusb_control_transfer(
302 REQ_TYPE_GET, req_code,
303 UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
309 if (ret == sizeof(data)) {
310 *focus = SW_TO_SHORT(data);
317 uvc_error_t uvc_set_focus_abs(uvc_device_handle_t *devh, short focus) {
321 SHORT_TO_SW(focus, data);
323 ret = libusb_control_transfer(
325 REQ_TYPE_SET, UVC_SET_CUR,
326 UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
332 if (ret == sizeof(data))
338 /** @todo focus_rel, focus_auto_control */
339 /** @todo iris_abs_ctrl, iris_rel_ctrl */
340 /** @todo zoom_abs, zoom_rel */
342 uvc_error_t uvc_get_pantilt_abs(uvc_device_handle_t *devh, int *pan, int *tilt, enum uvc_req_code req_code) {
346 ret = libusb_control_transfer(
348 REQ_TYPE_GET, req_code,
349 UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
355 if (ret == sizeof(data)) {
356 *pan = DW_TO_INT(data);
357 *tilt = DW_TO_INT(data + 4);
364 uvc_error_t uvc_set_pantilt_abs(uvc_device_handle_t *devh, int pan, int tilt) {
368 INT_TO_DW(pan, data);
369 INT_TO_DW(tilt, data + 4);
371 ret = libusb_control_transfer(
373 REQ_TYPE_SET, UVC_SET_CUR,
374 UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
380 if (ret == sizeof(data))
386 /** @todo pantilt_rel */
388 /** @todo roll_abs, roll_rel */
392 /***** SELECTOR UNIT CONTROLS *****/
394 /** @todo input_select */
396 /***** PROCESSING UNIT CONTROLS *****/
398 /***** GENERIC CONTROLS *****/
400 * @brief Get the length of a control on a terminal or unit.
402 * @param devh UVC device handle
403 * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit
404 * @param ctrl Vendor-specific control number to query
405 * @return On success, the length of the control as reported by the device. Otherwise,
406 * a uvc_error_t error describing the error encountered.
408 int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) {
409 unsigned char buf[2];
411 int ret = libusb_control_transfer(
413 REQ_TYPE_GET, UVC_GET_LEN,
423 return (unsigned short)SW_TO_SHORT(buf);
427 * @brief Perform a GET_* request from an extension unit.
429 * @param devh UVC device handle
430 * @param unit Unit ID; obtain this from the uvc_extension_unit_t describing the extension unit
431 * @param ctrl Control number to query
432 * @param data Data buffer to be filled by the device
433 * @param len Size of data buffer
434 * @param req_code GET_* request to execute
435 * @return On success, the number of bytes actually transferred. Otherwise,
436 * a uvc_error_t error describing the error encountered.
438 int uvc_get_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len, enum uvc_req_code req_code) {
439 return libusb_control_transfer(
441 REQ_TYPE_GET, req_code,
450 * @brief Perform a SET_CUR request to a terminal or unit.
452 * @param devh UVC device handle
453 * @param unit Unit or Terminal ID
454 * @param ctrl Control number to set
455 * @param data Data buffer to be sent to the device
456 * @param len Size of data buffer
457 * @return On success, the number of bytes actually transferred. Otherwise,
458 * a uvc_error_t error describing the error encountered.
460 int uvc_set_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len) {
461 return libusb_control_transfer(
463 REQ_TYPE_SET, UVC_SET_CUR,