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