Add v4l2_subdev_open() and v4l2_subdev_close() to subdev.h
[media-ctl.git] / subdev.c
1 /*
2  * Media controller test application
3  *
4  * Copyright (C) 2010 Ideas on board SPRL <laurent.pinchart@ideasonboard.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  */
19
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include <linux/v4l2-subdev.h>
31
32 #include "media.h"
33 #include "subdev.h"
34 #include "tools.h"
35
36 int v4l2_subdev_open(struct media_entity *entity)
37 {
38         if (entity->fd != -1)
39                 return 0;
40
41         entity->fd = open(entity->devname, O_RDWR);
42         if (entity->fd == -1) {
43                 printf("%s: Failed to open subdev device node %s\n", __func__,
44                         entity->devname);
45                 return -errno;
46         }
47
48         return 0;
49 }
50
51 void v4l2_subdev_close(struct media_entity *entity)
52 {
53         close(entity->fd);
54 }
55
56 int v4l2_subdev_get_format(struct media_entity *entity,
57         struct v4l2_mbus_framefmt *format, unsigned int pad,
58         enum v4l2_subdev_format_whence which)
59 {
60         struct v4l2_subdev_format fmt;
61         int ret;
62
63         ret = v4l2_subdev_open(entity);
64         if (ret < 0)
65                 return ret;
66
67         memset(&fmt, 0, sizeof(fmt));
68         fmt.pad = pad;
69         fmt.which = which;
70
71         ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FMT, &fmt);
72         if (ret < 0)
73                 return -errno;
74
75         *format = fmt.format;
76         return 0;
77 }
78
79 int v4l2_subdev_set_format(struct media_entity *entity,
80         struct v4l2_mbus_framefmt *format, unsigned int pad,
81         enum v4l2_subdev_format_whence which)
82 {
83         struct v4l2_subdev_format fmt;
84         int ret;
85
86         ret = v4l2_subdev_open(entity);
87         if (ret < 0)
88                 return ret;
89
90         memset(&fmt, 0, sizeof(fmt));
91         fmt.pad = pad;
92         fmt.which = which;
93         fmt.format = *format;
94
95         ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_FMT, &fmt);
96         if (ret < 0)
97                 return -errno;
98
99         *format = fmt.format;
100         return 0;
101 }
102
103 int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect,
104                          unsigned int pad, enum v4l2_subdev_format_whence which)
105 {
106         struct v4l2_subdev_crop crop;
107         int ret;
108
109         ret = v4l2_subdev_open(entity);
110         if (ret < 0)
111                 return ret;
112
113         memset(&crop, 0, sizeof(crop));
114         crop.pad = pad;
115         crop.which = which;
116
117         ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_CROP, &crop);
118         if (ret < 0)
119                 return -errno;
120
121         *rect = crop.rect;
122         return 0;
123 }
124
125 int v4l2_subdev_set_crop(struct media_entity *entity, struct v4l2_rect *rect,
126                          unsigned int pad, enum v4l2_subdev_format_whence which)
127 {
128         struct v4l2_subdev_crop crop;
129         int ret;
130
131         ret = v4l2_subdev_open(entity);
132         if (ret < 0)
133                 return ret;
134
135         memset(&crop, 0, sizeof(crop));
136         crop.pad = pad;
137         crop.which = which;
138         crop.rect = *rect;
139
140         ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_CROP, &crop);
141         if (ret < 0)
142                 return -errno;
143
144         *rect = crop.rect;
145         return 0;
146 }
147
148 int v4l2_subdev_set_frame_interval(struct media_entity *entity,
149                                    struct v4l2_fract *interval)
150 {
151         struct v4l2_subdev_frame_interval ival;
152         int ret;
153
154         ret = v4l2_subdev_open(entity);
155         if (ret < 0)
156                 return ret;
157
158         memset(&ival, 0, sizeof(ival));
159         ival.interval = *interval;
160
161         ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &ival);
162         if (ret < 0)
163                 return -errno;
164
165         *interval = ival.interval;
166         return 0;
167 }