libv4l2: add subdev_get_node_num function
authorHyeonmyeong Choi <hyeon.choi@samsung.com>
Thu, 20 Dec 2012 07:52:21 +0000 (16:52 +0900)
committerHyeonmyeong Choi <hyeon.choi@samsung.com>
Thu, 20 Dec 2012 07:52:21 +0000 (16:52 +0900)
Change-Id: If8d545aacb359e8911627b7694e404f686df89ef
Signed-off-by: Hyeonmyeong Choi <hyeon.choi@samsung.com>
include/exynos_v4l2.h
libv4l2/exynos_subdev.c

index 1ceafa305ea684718d1edd0d2d8ce06a948e90ef..0b550ef9629c1b6bc801a9be8b09861f7dea9ed3 100644 (file)
@@ -101,6 +101,8 @@ int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl);
 /*! \ingroup exynos_v4l2 */
 int exynos_subdev_open(const char *filename, int oflag, ...);
 /*! \ingroup exynos_v4l2 */
+int exynos_subdev_get_node_num(const char *devname, int oflag, ...);
+/*! \ingroup exynos_v4l2 */
 int exynos_subdev_open_devname(const char *devname, int oflag, ...);
 /*! \ingroup exynos_v4l2 */
 int exynos_subdev_close(int fd);
index 13f33219b73b7d3381d6f6003aeef498ec73b1ed..e03d02ff668263dcb4f466f0bd6aaaf6e3d5bf73 100644 (file)
@@ -67,6 +67,61 @@ int exynos_subdev_open(const char *filename, int oflag, ...)
     return fd;
 }
 
+int exynos_subdev_get_node_num(const char *devname, int oflag, ...)
+{
+    bool found = false;
+    int ret = -1;
+    struct stat s;
+    va_list ap;
+    FILE *stream_fd;
+    char filename[64], name[64];
+    int minor, size, i = 0;
+
+    do {
+        if (i > (SUBDEV_MINOR_MAX - 128))
+            break;
+
+        /* video device node */
+        sprintf(filename, "/dev/v4l-subdev%d", i++);
+
+        /* if the node is video device */
+        if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) &&
+                ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) {
+            minor = (int)((unsigned short)(s.st_rdev & 0x3f));
+            ALOGD("try node: %s, minor: %d", filename, minor);
+            /* open sysfs entry */
+            sprintf(filename, "/sys/class/video4linux/v4l-subdev%d/name", minor);
+            stream_fd = fopen(filename, "r");
+            if (stream_fd == NULL) {
+                ALOGE("failed to open sysfs entry for subdev");
+                continue;   /* try next */
+            }
+
+            /* read sysfs entry for device name */
+            size = (int)fgets(name, sizeof(name), stream_fd);
+            fclose(stream_fd);
+
+            /* check read size */
+            if (size == 0) {
+                ALOGE("failed to read sysfs entry for subdev");
+            } else {
+                /* matched */
+                if (strncmp(name, devname, strlen(devname)) == 0) {
+                    ALOGI("node found for device %s: /dev/v4l-subdev%d", devname, minor);
+                    found = true;
+                }
+            }
+        }
+    } while (found == false);
+
+    if (found)
+        ret = minor;
+    else
+        ALOGE("no subdev device found");
+
+    return ret;
+}
+
 int exynos_subdev_open_devname(const char *devname, int oflag, ...)
 {
     bool found = false;