| /********************************************************************* |
| * Software License Agreement (BSD License) |
| * |
| * Copyright (C) 2010-2012 Ken Tossell |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of the author nor other contributors may be |
| * used to endorse or promote products derived from this software |
| * without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| *********************************************************************/ |
| /** |
| * @defgroup ctrl Video capture and processing controls |
| * @brief Functions for manipulating device settings and stream parameters |
| * |
| * The `uvc_get_*` and `uvc_set_*` functions are used to read and write the settings associated |
| * with the device's input, processing and output units. |
| */ |
| |
| #include "libuvc/libuvc.h" |
| #include "libuvc/libuvc_internal.h" |
| |
| static const int REQ_TYPE_SET = 0x21; |
| static const int REQ_TYPE_GET = 0xa1; |
| |
| /***** GENERIC CONTROLS *****/ |
| /** |
| * @brief Get the length of a control on a terminal or unit. |
| * |
| * @param devh UVC device handle |
| * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit |
| * @param ctrl Vendor-specific control number to query |
| * @return On success, the length of the control as reported by the device. Otherwise, |
| * a uvc_error_t error describing the error encountered. |
| * @ingroup ctrl |
| */ |
| int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) { |
| unsigned char buf[2]; |
| |
| int ret = libusb_control_transfer( |
| devh->usb_devh, |
| REQ_TYPE_GET, UVC_GET_LEN, |
| ctrl << 8, |
| unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki |
| buf, |
| 2, |
| 0 /* timeout */); |
| |
| if (ret < 0) |
| return ret; |
| else |
| return (unsigned short)SW_TO_SHORT(buf); |
| } |
| |
| /** |
| * @brief Perform a GET_* request from an extension unit. |
| * |
| * @param devh UVC device handle |
| * @param unit Unit ID; obtain this from the uvc_extension_unit_t describing the extension unit |
| * @param ctrl Control number to query |
| * @param data Data buffer to be filled by the device |
| * @param len Size of data buffer |
| * @param req_code GET_* request to execute |
| * @return On success, the number of bytes actually transferred. Otherwise, |
| * a uvc_error_t error describing the error encountered. |
| * @ingroup ctrl |
| */ |
| 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) { |
| return libusb_control_transfer( |
| devh->usb_devh, |
| REQ_TYPE_GET, req_code, |
| ctrl << 8, |
| unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki |
| data, |
| len, |
| 0 /* timeout */); |
| } |
| |
| /** |
| * @brief Perform a SET_CUR request to a terminal or unit. |
| * |
| * @param devh UVC device handle |
| * @param unit Unit or Terminal ID |
| * @param ctrl Control number to set |
| * @param data Data buffer to be sent to the device |
| * @param len Size of data buffer |
| * @return On success, the number of bytes actually transferred. Otherwise, |
| * a uvc_error_t error describing the error encountered. |
| * @ingroup ctrl |
| */ |
| int uvc_set_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len) { |
| return libusb_control_transfer( |
| devh->usb_devh, |
| REQ_TYPE_SET, UVC_SET_CUR, |
| ctrl << 8, |
| unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki |
| data, |
| len, |
| 0 /* timeout */); |
| } |
| |
| /***** INTERFACE CONTROLS *****/ |
| uvc_error_t uvc_get_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode *mode, enum uvc_req_code req_code) { |
| uint8_t mode_char; |
| uvc_error_t ret; |
| |
| ret = libusb_control_transfer( |
| devh->usb_devh, |
| REQ_TYPE_GET, req_code, |
| UVC_VC_VIDEO_POWER_MODE_CONTROL << 8, |
| devh->info->ctrl_if.bInterfaceNumber, // XXX saki |
| &mode_char, |
| sizeof(mode_char), |
| 0); |
| |
| if (ret == 1) { |
| *mode = mode_char; |
| return UVC_SUCCESS; |
| } else { |
| return ret; |
| } |
| } |
| |
| uvc_error_t uvc_set_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode mode) { |
| uint8_t mode_char = mode; |
| uvc_error_t ret; |
| |
| ret = libusb_control_transfer( |
| devh->usb_devh, |
| REQ_TYPE_SET, UVC_SET_CUR, |
| UVC_VC_VIDEO_POWER_MODE_CONTROL << 8, |
| devh->info->ctrl_if.bInterfaceNumber, // XXX saki |
| &mode_char, |
| sizeof(mode_char), |
| 0); |
| |
| if (ret == 1) |
| return UVC_SUCCESS; |
| else |
| return ret; |
| } |
| |
| /** @todo Request Error Code Control (UVC 1.5, 4.2.1.2) */ |