1e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/* 2e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * Copyright (C) 2011 The Android Open Source Project 3e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * 4e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * you may not use this file except in compliance with the License. 6e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * You may obtain a copy of the License at 7e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * 8e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * http://www.apache.org/licenses/LICENSE-2.0 9e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * 10e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * Unless required by applicable law or agreed to in writing, software 11e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * distributed under the License is distributed on an "AS IS" BASIS, 12e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * See the License for the specific language governing permissions and 14e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * limitations under the License. 15e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 16e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 17e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/*! 18e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * \file exynos_subdev.c 19e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * \brief source file for libv4l2 20e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * \author Jinsung Yang (jsgood.yang@samsung.com) 21e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * \author Sangwoo Park (sw5771.park@samsung.com) 22e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * \date 2012/01/17 23e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * 24e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * <b>Revision History: </b> 25e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n 26e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * Initial version 27e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * 28e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 29e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 30e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <stdio.h> 31e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <stdarg.h> 32e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <fcntl.h> 33e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <sys/types.h> 34e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <sys/ioctl.h> 35e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <sys/stat.h> 36e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 37e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include "exynos_v4l2.h" 38e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 39e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang//#define LOG_NDEBUG 0 40e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#define LOG_TAG "libexynosv4l2-subdev" 41e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#include <utils/Log.h> 42e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 43e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang#define SUBDEV_MINOR_MAX 191 44e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 45e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changstatic int __subdev_open(const char *filename, int oflag, va_list ap) 46e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 47e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang mode_t mode = 0; 48e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int fd; 49e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 50e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (oflag & O_CREAT) 51e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang mode = va_arg(ap, int); 52e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 53e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang fd = open(filename, oflag, mode); 54e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 55e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return fd; 56e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 57e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 58e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_open(const char *filename, int oflag, ...) 59e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 60e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_list ap; 61e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int fd; 62e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 63e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_start(ap, oflag); 64e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang fd = __subdev_open(filename, oflag, ap); 65e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_end(ap); 66e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 67e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return fd; 68e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 69e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 70e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_open_devname(const char *devname, int oflag, ...) 71e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 72e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang bool found = false; 73e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int fd = -1; 74e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang struct stat s; 75e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_list ap; 76e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang FILE *stream_fd; 77e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang char filename[64], name[64]; 78e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int minor, size, i = 0; 79e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 80e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang do { 81e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (i > (SUBDEV_MINOR_MAX - 128)) 82e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang break; 83e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 84e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* video device node */ 85e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang sprintf(filename, "/dev/v4l-subdev%d", i++); 86e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 87e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* if the node is video device */ 88e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) && 89e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) { 90e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang minor = (int)((unsigned short)(s.st_rdev & 0x3f)); 917642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGD("try node: %s, minor: %d", filename, minor); 92e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* open sysfs entry */ 93e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang sprintf(filename, "/sys/class/video4linux/v4l-subdev%d/name", minor); 94e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang stream_fd = fopen(filename, "r"); 95d970bdc0636895887d8a5b3931d39fddd7411317Jiho Chang if (stream_fd == NULL) { 967642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to open sysfs entry for subdev"); 97e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang continue; /* try next */ 98e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 99e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 100e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* read sysfs entry for device name */ 101e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang size = (int)fgets(name, sizeof(name), stream_fd); 102e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang fclose(stream_fd); 103e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 104e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* check read size */ 105e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (size == 0) { 1067642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to read sysfs entry for subdev"); 107e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } else { 108e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang /* matched */ 109e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (strncmp(name, devname, strlen(devname)) == 0) { 1107642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGI("node found for device %s: /dev/v4l-subdev%d", devname, minor); 111e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang found = true; 112e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 113e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 114e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 115e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } while (found == false); 116e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 117e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (found) { 118e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang sprintf(filename, "/dev/v4l-subdev%d", minor); 119e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_start(ap, oflag); 120e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang fd = __subdev_open(filename, oflag, ap); 121e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang va_end(ap); 122e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 123e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd > 0) 1247642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGI("open subdev device %s", filename); 125e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang else 1267642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to open subdev device %s", filename); 127e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } else { 1287642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("no subdev device found"); 129e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 130e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 131e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return fd; 132e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 133e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 134e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 135e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief enum frame size on a pad. 136e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 137e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 138e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_enum_frame_size(int fd, struct v4l2_subdev_frame_size_enum *frame_size_enum) 139e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 140e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 141e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 142e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 1437642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 144e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 145e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 146e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 147e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!frame_size_enum) { 1487642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: frame_size_enum is NULL", __func__); 149e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 150e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 151e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 152e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, frame_size_enum); 153e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 1547642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE"); 155e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 156e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 157e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 158e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 159e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 160e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 161e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 162e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Retrieve the format on a pad. 163e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 164e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 165e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_g_fmt(int fd, struct v4l2_subdev_format *fmt) 166e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 167e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 168e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 169e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 1707642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 171e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 172e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 173e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 174e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!fmt) { 1757642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: fmt is NULL", __func__); 176e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 177e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 178e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 179e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_G_FMT, fmt); 180e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 1817642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_FMT"); 182e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 183e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 184e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 185e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 186e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 187e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 188e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 189e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Set the format on a pad. 190e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 191e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 192e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_s_fmt(int fd, struct v4l2_subdev_format *fmt) 193e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 194e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 195e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 196e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 1977642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 198e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 199e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 200e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 201e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!fmt) { 2027642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: fmt is NULL", __func__); 203e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 204e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 205e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 206e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_S_FMT, fmt); 207e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 2087642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_FMT"); 209e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 210e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 211e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 212e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 213e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 214e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 215e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 216e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Retrieve the crop rectangle on a pad. 217e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 218e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 219e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_g_crop(int fd, struct v4l2_subdev_crop *crop) 220e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 221e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 222e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 223e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 2247642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 225e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 226e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 227e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 228e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!crop) { 2297642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: crop is NULL", __func__); 230e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 231e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 232e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 233e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_G_CROP, crop); 234e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 2357642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_CROP"); 236e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 237e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 238e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 239e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 240e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 241e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 242e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 243e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Set the crop rectangle on a pad. 244e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 245e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 246e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_s_crop(int fd, struct v4l2_subdev_crop *crop) 247e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 248e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 249e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 250e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 2517642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 252e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 253e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 254e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 255e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!crop) { 2567642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: crop is NULL", __func__); 257e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 258e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 259e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 260e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_S_CROP, crop); 261e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 2627642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_CROP"); 263e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 264e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 265e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 266e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 267e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 268e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 269e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 270e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Retrieve the frame interval on a sub-device. 271e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 272e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 273e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_enum_frame_interval(int fd, struct v4l2_subdev_frame_interval_enum *frame_internval_enum) 274e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 275e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 276e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 277e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 2787642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 279e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 280e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 281e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 282e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!frame_internval_enum) { 2837642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: frame_internval_enum is NULL", __func__); 284e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 285e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 286e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 287e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, frame_internval_enum); 288e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 2897642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL"); 290e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 291e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 292e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 293e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 294e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 295e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 296e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 297e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Retrieve the frame interval on a sub-device. 298e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 299e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 300e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_g_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval) 301e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 302e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 303e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 304e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 3057642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 306e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 307e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 308e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 309e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!frame_internval) { 3107642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: frame_internval is NULL", __func__); 311e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 312e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 313e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 314e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, frame_internval); 315e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 3167642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL"); 317e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 318e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 319e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 320e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 321e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 322e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 323e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 324e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief Set the frame interval on a sub-device. 325e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 326e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 327e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_s_frame_interval(int fd, struct v4l2_subdev_frame_interval *frame_internval) 328e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 329e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 330e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 331e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 3327642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 333e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 334e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 335e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 336e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!frame_internval) { 3377642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: frame_internval is NULL", __func__); 338e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 339e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 340e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 341e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, frame_internval); 342e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 3437642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL"); 344e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 345e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 346e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 347e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 348e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 349e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 350e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang/** 351e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @brief enum mbus code 352e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang * @return 0 on success, or a negative error code on failure. 353e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang */ 354e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Changint exynos_subdev_enum_mbus_code(int fd, struct v4l2_subdev_mbus_code_enum *mbus_code_enum) 355e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang{ 356e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang int ret = -1; 357e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 358e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (fd < 0) { 3597642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: invalid fd: %d", __func__, fd); 360e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 361e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 362e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 363e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (!mbus_code_enum) { 3647642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("%s: mbus_code_enum is NULL", __func__); 365e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 366e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 367e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 368e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang ret = ioctl(fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, mbus_code_enum); 369e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang if (ret) { 3707642c64b6834edd132584e143495b048fe0cadceDima Zavin ALOGE("failed to ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE"); 371e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 372e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang } 373e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang 374e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang return ret; 375e5931c34383266bf0faa2c1a2cbc18bac7afeb5fJiho Chang} 376