blob: 2dc4b20f3ac0a80773167a6a8ef52d5a042581c5 [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-version.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h"
Hans Verkuil33c0fcad2007-08-23 06:32:46 -030028#include "ivtv-routing.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030029#include "ivtv-streams.h"
30#include "ivtv-yuv.h"
31#include "ivtv-ioctl.h"
32#include "ivtv-gpio.h"
33#include "ivtv-controls.h"
34#include "ivtv-cards.h"
Mauro Carvalho Chehabb5dcee222015-11-10 12:01:44 -020035#include <media/i2c/saa7127.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030036#include <media/tveeprom.h>
Hans Verkuil09250192010-03-27 14:10:13 -030037#include <media/v4l2-event.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030038#include <linux/dvb/audio.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030039
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030040u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030041{
42 switch (type) {
43 case V4L2_SLICED_TELETEXT_B:
44 return IVTV_SLICED_TYPE_TELETEXT_B;
45 case V4L2_SLICED_CAPTION_525:
46 return IVTV_SLICED_TYPE_CAPTION_525;
47 case V4L2_SLICED_WSS_625:
48 return IVTV_SLICED_TYPE_WSS_625;
49 case V4L2_SLICED_VPS:
50 return IVTV_SLICED_TYPE_VPS;
51 default:
52 return 0;
53 }
54}
55
56static int valid_service_line(int field, int line, int is_pal)
57{
58 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
59 (!is_pal && line >= 10 && line < 22);
60}
61
62static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
63{
64 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
65 int i;
66
67 set = set & valid_set;
68 if (set == 0 || !valid_service_line(field, line, is_pal)) {
69 return 0;
70 }
71 if (!is_pal) {
72 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
73 return V4L2_SLICED_CAPTION_525;
74 }
75 else {
76 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
77 return V4L2_SLICED_VPS;
78 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
79 return V4L2_SLICED_WSS_625;
80 if (line == 23)
81 return 0;
82 }
83 for (i = 0; i < 32; i++) {
84 if ((1 << i) & set)
85 return 1 << i;
86 }
87 return 0;
88}
89
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030090void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030091{
92 u16 set = fmt->service_set;
93 int f, l;
94
95 fmt->service_set = 0;
96 for (f = 0; f < 2; f++) {
97 for (l = 0; l < 24; l++) {
98 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
99 }
100 }
101}
102
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300103static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300104{
105 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300106
107 for (f = 0; f < 2; f++) {
108 for (l = 0; l < 24; l++) {
109 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300110 }
111 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300112}
113
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300114u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300115{
116 int f, l;
117 u16 set = 0;
118
119 for (f = 0; f < 2; f++) {
120 for (l = 0; l < 24; l++) {
121 set |= fmt->service_lines[f][l];
122 }
123 }
124 return set;
125}
126
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300127void ivtv_set_osd_alpha(struct ivtv *itv)
128{
129 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
130 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300131 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300132}
133
134int ivtv_set_speed(struct ivtv *itv, int speed)
135{
136 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300137 int single_step = (speed == 1 || speed == -1);
138 DEFINE_WAIT(wait);
139
140 if (speed == 0) speed = 1000;
141
142 /* No change? */
143 if (speed == itv->speed && !single_step)
144 return 0;
145
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300146 if (single_step && (speed < 0) == (itv->speed < 0)) {
147 /* Single step video and no need to change direction */
148 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
149 itv->speed = speed;
150 return 0;
151 }
152 if (single_step)
153 /* Need to change direction */
154 speed = speed < 0 ? -1000 : 1000;
155
156 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
157 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
158 data[1] = (speed < 0);
159 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300160 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300161 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
162 data[5] = 0;
163 data[6] = 0;
164
165 if (speed == 1500 || speed == -1500) data[0] |= 1;
166 else if (speed == 2000 || speed == -2000) data[0] |= 2;
167 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
168 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
169
170 /* If not decoding, just change speed setting */
171 if (atomic_read(&itv->decoding) > 0) {
172 int got_sig = 0;
173
174 /* Stop all DMA and decoding activity */
175 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
176
177 /* Wait for any DMA to finish */
Hans Verkuilcdc03782011-10-11 06:06:58 -0300178 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300179 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -0300180 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300181 got_sig = signal_pending(current);
182 if (got_sig)
183 break;
184 got_sig = 0;
185 schedule();
186 }
187 finish_wait(&itv->dma_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -0300188 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300189 if (got_sig)
190 return -EINTR;
191
192 /* Change Speed safely */
193 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
194 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
195 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
196 }
197 if (single_step) {
198 speed = (speed < 0) ? -1 : 1;
199 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
200 }
201 itv->speed = speed;
202 return 0;
203}
204
205static int ivtv_validate_speed(int cur_speed, int new_speed)
206{
207 int fact = new_speed < 0 ? -1 : 1;
208 int s;
209
Hans Verkuil94dee762008-04-26 09:26:13 -0300210 if (cur_speed == 0)
211 cur_speed = 1000;
212 if (new_speed < 0)
213 new_speed = -new_speed;
214 if (cur_speed < 0)
215 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300216
217 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300218 if (new_speed > 1500)
219 return fact * 2000;
220 if (new_speed > 1000)
221 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300222 }
223 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300224 if (new_speed >= 2000)
225 return fact * 2000;
226 if (new_speed >= 1500)
227 return fact * 1500;
228 if (new_speed >= 1000)
229 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300230 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300231 if (new_speed == 0)
232 return 1000;
233 if (new_speed == 1 || new_speed == 1000)
234 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300235
236 s = new_speed;
237 new_speed = 1000 / new_speed;
238 if (1000 / cur_speed == new_speed)
239 new_speed += (cur_speed < s) ? -1 : 1;
240 if (new_speed > 60) return 1000 / (fact * 60);
241 return 1000 / (fact * new_speed);
242}
243
244static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300245 struct v4l2_decoder_cmd *dc, int try)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300246{
247 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
248
249 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
250 return -EINVAL;
251
Hans Verkuilda8ec562011-11-24 09:58:53 -0300252 switch (dc->cmd) {
253 case V4L2_DEC_CMD_START: {
254 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
255 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
256 if (dc->start.speed < 0)
257 dc->start.format = V4L2_DEC_START_FMT_GOP;
258 else
259 dc->start.format = V4L2_DEC_START_FMT_NONE;
260 if (dc->start.speed != 500 && dc->start.speed != 1500)
261 dc->flags = dc->start.speed == 1000 ? 0 :
262 V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300263 if (try) break;
264
Hans Verkuilda8ec562011-11-24 09:58:53 -0300265 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300266 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
267 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300268 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
269 /* forces ivtv_set_speed to be called */
270 itv->speed = 0;
271 }
Hans Verkuilda8ec562011-11-24 09:58:53 -0300272 return ivtv_start_decoding(id, dc->start.speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300273 }
274
Hans Verkuilda8ec562011-11-24 09:58:53 -0300275 case V4L2_DEC_CMD_STOP:
276 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
277 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
278 dc->stop.pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300279 if (try) break;
280 if (atomic_read(&itv->decoding) == 0)
281 return 0;
282 if (itv->output_mode != OUT_MPG)
283 return -EBUSY;
284
285 itv->output_mode = OUT_NONE;
Hans Verkuilda8ec562011-11-24 09:58:53 -0300286 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300287
Hans Verkuilda8ec562011-11-24 09:58:53 -0300288 case V4L2_DEC_CMD_PAUSE:
289 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300290 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300291 if (!atomic_read(&itv->decoding))
292 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300293 if (itv->output_mode != OUT_MPG)
294 return -EBUSY;
295 if (atomic_read(&itv->decoding) > 0) {
296 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300297 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300298 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300299 }
300 break;
301
Hans Verkuilda8ec562011-11-24 09:58:53 -0300302 case V4L2_DEC_CMD_RESUME:
303 dc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300304 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300305 if (!atomic_read(&itv->decoding))
306 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300307 if (itv->output_mode != OUT_MPG)
308 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300309 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
310 int speed = itv->speed;
311 itv->speed = 0;
312 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300313 }
314 break;
315
316 default:
317 return -EINVAL;
318 }
319 return 0;
320}
321
Hans Verkuil3f038d82008-05-29 16:43:54 -0300322static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300323{
Hans Verkuil2f824412011-03-12 06:43:28 -0300324 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300325 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300326
Hans Verkuile88360c2008-06-21 08:00:56 -0300327 vbifmt->reserved[0] = 0;
328 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300329 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300330 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300331 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil30634e82012-09-05 10:38:10 -0300332 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300333 if (itv->is_60hz) {
334 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
335 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
336 } else {
337 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
338 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
339 }
340 vbifmt->service_set = ivtv_get_service_set(vbifmt);
341 return 0;
342}
343
344static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
345{
Hans Verkuil2f824412011-03-12 06:43:28 -0300346 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300347 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300348 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300349
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300350 pixfmt->width = itv->cxhdl.width;
351 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300352 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
353 pixfmt->field = V4L2_FIELD_INTERLACED;
Hans Verkuile88360c2008-06-21 08:00:56 -0300354 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
355 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300356 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
357 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300358 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300359 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300360 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
361 pixfmt->sizeimage = 128 * 1024;
362 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300363 }
364 return 0;
365}
366
Hans Verkuil3f038d82008-05-29 16:43:54 -0300367static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300368{
Hans Verkuil2f824412011-03-12 06:43:28 -0300369 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300370 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300371
Hans Verkuile88360c2008-06-21 08:00:56 -0300372 vbifmt->sampling_rate = 27000000;
373 vbifmt->offset = 248;
374 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
375 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
376 vbifmt->start[0] = itv->vbi.start[0];
377 vbifmt->start[1] = itv->vbi.start[1];
378 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
379 vbifmt->flags = 0;
380 vbifmt->reserved[0] = 0;
381 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300382 return 0;
383}
384
385static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
386{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300387 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300388 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300389 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300390
Hans Verkuile88360c2008-06-21 08:00:56 -0300391 vbifmt->reserved[0] = 0;
392 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300393 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300394
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
396 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
397 V4L2_SLICED_VBI_525;
398 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuilc5c46f22012-09-05 12:27:19 -0300399 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300400 return 0;
401 }
402
Hans Verkuil4ff07902010-03-14 12:18:18 -0300403 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300404 vbifmt->service_set = ivtv_get_service_set(vbifmt);
405 return 0;
406}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300407
Hans Verkuil3f038d82008-05-29 16:43:54 -0300408static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
409{
Hans Verkuil2f824412011-03-12 06:43:28 -0300410 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300411 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300412 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300413
Hans Verkuil3f038d82008-05-29 16:43:54 -0300414 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300415 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300416 pixfmt->width = itv->main_rect.width;
417 pixfmt->height = itv->main_rect.height;
418 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
419 pixfmt->field = V4L2_FIELD_INTERLACED;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300420 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
421 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
422 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300423 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300424 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
425 break;
426 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300427 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300428 break;
429 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 break;
432 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
434 pixfmt->bytesperline = 720;
435 pixfmt->width = itv->yuv_info.v4l2_src_w;
436 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300437 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300438 pixfmt->sizeimage =
439 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300441 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
442 pixfmt->sizeimage = 128 * 1024;
443 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300444 }
445 return 0;
446}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447
Hans Verkuil3f038d82008-05-29 16:43:54 -0300448static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
449{
Hans Verkuil2f824412011-03-12 06:43:28 -0300450 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil38a14212015-03-30 04:53:11 -0300451 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuile88360c2008-06-21 08:00:56 -0300452 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300453
Hans Verkuil38a14212015-03-30 04:53:11 -0300454 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
455 return -EINVAL;
456 if (!itv->osd_video_pbase)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300457 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300458 winfmt->chromakey = itv->osd_chroma_key;
459 winfmt->global_alpha = itv->osd_global_alpha;
460 winfmt->field = V4L2_FIELD_INTERLACED;
461 winfmt->clips = NULL;
462 winfmt->clipcount = 0;
463 winfmt->bitmap = NULL;
464 winfmt->w.top = winfmt->w.left = 0;
465 winfmt->w.width = itv->osd_rect.width;
466 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300467 return 0;
468}
469
470static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
471{
472 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
473}
474
475static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
476{
Hans Verkuil2f824412011-03-12 06:43:28 -0300477 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300478 struct ivtv *itv = id->itv;
479 int w = fmt->fmt.pix.width;
480 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300481 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300482
483 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300484 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300485 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
486 /* YUV height must be a multiple of 32 */
487 h &= ~0x1f;
488 min_h = 32;
489 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300490 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300491 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300492 ivtv_g_fmt_vid_cap(file, fh, fmt);
493 fmt->fmt.pix.width = w;
494 fmt->fmt.pix.height = h;
495 return 0;
496}
497
498static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
499{
500 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
501}
502
503static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
504{
505 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300506 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300507 struct ivtv *itv = id->itv;
508
509 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
510 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300511
512 /* set sliced VBI capture format */
513 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300514 vbifmt->reserved[0] = 0;
515 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300516
517 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300518 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300519 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300520 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300521 return 0;
522}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300523
Hans Verkuil3f038d82008-05-29 16:43:54 -0300524static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
525{
Hans Verkuil2f824412011-03-12 06:43:28 -0300526 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300527 s32 w = fmt->fmt.pix.width;
528 s32 h = fmt->fmt.pix.height;
529 int field = fmt->fmt.pix.field;
530 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300531
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300532 w = min(w, 720);
533 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300534 /* Why can the height be 576 even when the output is NTSC?
535
536 Internally the buffers of the PVR350 are always set to 720x576. The
537 decoded video frame will always be placed in the top left corner of
538 this buffer. For any video which is not 720x576, the buffer will
539 then be cropped to remove the unused right and lower areas, with
540 the remaining image being scaled by the hardware to fit the display
541 area. The video can be scaled both up and down, so a 720x480 video
542 can be displayed full-screen on PAL and a 720x576 video can be
543 displayed without cropping on NTSC.
544
545 Note that the scaling only occurs on the video stream, the osd
546 resolution is locked to the broadcast standard and not scaled.
547
548 Thanks to Ian Armstrong for this explanation. */
549 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300550 h = max(h, 2);
551 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300553 fmt->fmt.pix.width = w;
554 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300555 return ret;
556}
557
558static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
559{
Hans Verkuil2f824412011-03-12 06:43:28 -0300560 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil38a14212015-03-30 04:53:11 -0300561 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuile88360c2008-06-21 08:00:56 -0300562 u32 chromakey = fmt->fmt.win.chromakey;
563 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300564
Hans Verkuil38a14212015-03-30 04:53:11 -0300565 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
566 return -EINVAL;
567 if (!itv->osd_video_pbase)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300568 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300569 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
570 fmt->fmt.win.chromakey = chromakey;
571 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300572 return 0;
573}
574
575static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
576{
577 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
578}
579
580static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
581{
Hans Verkuil2f824412011-03-12 06:43:28 -0300582 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300583 struct ivtv *itv = id->itv;
Hans Verkuilebf984b2015-04-09 04:05:59 -0300584 struct v4l2_subdev_format format = {
585 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
586 };
Hans Verkuileffc3462008-09-06 08:24:37 -0300587 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300588 int w = fmt->fmt.pix.width;
589 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300590
591 if (ret)
592 return ret;
593
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300594 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300595 return 0;
596
597 if (atomic_read(&itv->capturing) > 0)
598 return -EBUSY;
599
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300600 itv->cxhdl.width = w;
601 itv->cxhdl.height = h;
602 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300603 fmt->fmt.pix.width /= 2;
Hans Verkuilebf984b2015-04-09 04:05:59 -0300604 format.format.width = fmt->fmt.pix.width;
605 format.format.height = h;
606 format.format.code = MEDIA_BUS_FMT_FIXED;
607 v4l2_subdev_call(itv->sd_video, pad, set_fmt, NULL, &format);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300608 return ivtv_g_fmt_vid_cap(file, fh, fmt);
609}
610
611static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
612{
Hans Verkuil2f824412011-03-12 06:43:28 -0300613 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300614
Hans Verkuila8b86432008-10-04 08:05:30 -0300615 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
616 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300617 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300618 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300619 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300620 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
621}
622
623static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
624{
625 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300626 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300627 struct ivtv *itv = id->itv;
628 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
629
630 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
631 return ret;
632
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300633 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300634 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300635 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300636 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300637 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300638 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
639 return 0;
640}
641
Hans Verkuil3f038d82008-05-29 16:43:54 -0300642static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643{
Hans Verkuil2f824412011-03-12 06:43:28 -0300644 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300645 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300646 struct yuv_playback_info *yi = &itv->yuv_info;
647 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300648
Hans Verkuil3f038d82008-05-29 16:43:54 -0300649 if (ret)
650 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300651
Hans Verkuil3f038d82008-05-29 16:43:54 -0300652 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
653 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300654
Hans Verkuil3f038d82008-05-29 16:43:54 -0300655 /* Return now if we already have some frame data */
656 if (yi->stream_size)
657 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300658
Hans Verkuil3f038d82008-05-29 16:43:54 -0300659 yi->v4l2_src_w = fmt->fmt.pix.width;
660 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300661
Hans Verkuil3f038d82008-05-29 16:43:54 -0300662 switch (fmt->fmt.pix.field) {
663 case V4L2_FIELD_NONE:
664 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300665 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300666 case V4L2_FIELD_ANY:
667 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300668 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300669 case V4L2_FIELD_INTERLACED_BT:
670 yi->lace_mode =
671 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
672 break;
673 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300674 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300675 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
676 break;
677 }
678 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
679
680 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
681 itv->dma_data_req_size =
682 1080 * ((yi->v4l2_src_h + 31) & ~31);
683
Hans Verkuil3f038d82008-05-29 16:43:54 -0300684 return 0;
685}
686
687static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
688{
Hans Verkuil2f824412011-03-12 06:43:28 -0300689 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300690 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
691
692 if (ret == 0) {
693 itv->osd_chroma_key = fmt->fmt.win.chromakey;
694 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
695 ivtv_set_osd_alpha(itv);
696 }
697 return ret;
698}
699
Hans Verkuil36ecd492008-06-25 06:00:17 -0300700#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilb5656e82013-03-24 08:24:19 -0300701static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300702{
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300703 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300704
Hans Verkuile9dab582013-05-29 07:00:10 -0300705 if (reg & 0x3)
706 return -EINVAL;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300707 if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300708 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300709 else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
710 reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300711 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300712 else if (reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300713 reg_start = itv->enc_mem;
714 else
715 return -EINVAL;
716
Hans Verkuilb5656e82013-03-24 08:24:19 -0300717 if (get)
718 *val = readl(reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300719 else
Hans Verkuilb5656e82013-03-24 08:24:19 -0300720 writel(*val, reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300721 return 0;
722}
723
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300724static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300725{
Hans Verkuil2f824412011-03-12 06:43:28 -0300726 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300727
Hans Verkuil4bd81932013-05-29 06:59:38 -0300728 reg->size = 4;
729 return ivtv_itvc(itv, true, reg->reg, &reg->val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300730}
731
Hans Verkuil977ba3b12013-03-24 08:28:46 -0300732static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300733{
Hans Verkuil2f824412011-03-12 06:43:28 -0300734 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil4bd81932013-05-29 06:59:38 -0300735 u64 val = reg->val;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300736
Hans Verkuil4bd81932013-05-29 06:59:38 -0300737 return ivtv_itvc(itv, false, reg->reg, &val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300738}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300739#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300740
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
742{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300743 struct ivtv_open_id *id = fh2id(file->private_data);
744 struct ivtv *itv = id->itv;
745 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300746
Hans Verkuil3f038d82008-05-29 16:43:54 -0300747 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
748 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300749 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300750 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
751 vcap->device_caps = s->caps;
Hans Verkuil38a14212015-03-30 04:53:11 -0300752 if ((s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) &&
753 !itv->osd_video_pbase) {
754 vcap->capabilities &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
755 vcap->device_caps &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
756 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300757 return 0;
758}
759
760static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
761{
Hans Verkuil2f824412011-03-12 06:43:28 -0300762 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300763
764 return ivtv_get_audio_input(itv, vin->index, vin);
765}
766
767static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
768{
Hans Verkuil2f824412011-03-12 06:43:28 -0300769 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300770
771 vin->index = itv->audio_input;
772 return ivtv_get_audio_input(itv, vin->index, vin);
773}
774
Hans Verkuil0e8025b92012-09-04 11:59:31 -0300775static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300776{
Hans Verkuil2f824412011-03-12 06:43:28 -0300777 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300778
779 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300780 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300781
782 itv->audio_input = vout->index;
783 ivtv_audio_set_io(itv);
784
785 return 0;
786}
787
788static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
789{
Hans Verkuil2f824412011-03-12 06:43:28 -0300790 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300791
792 /* set it to defaults from our table */
793 return ivtv_get_audio_output(itv, vin->index, vin);
794}
795
796static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
797{
Hans Verkuil2f824412011-03-12 06:43:28 -0300798 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300799
800 vin->index = 0;
801 return ivtv_get_audio_output(itv, vin->index, vin);
802}
803
Hans Verkuilba9425b2012-09-04 12:03:49 -0300804static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300805{
Hans Verkuil2f824412011-03-12 06:43:28 -0300806 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300807
Hans Verkuilba9425b2012-09-04 12:03:49 -0300808 if (itv->card->video_outputs == NULL || vout->index != 0)
809 return -EINVAL;
810 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300811}
812
813static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
814{
Hans Verkuil2f824412011-03-12 06:43:28 -0300815 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300816
817 /* set it to defaults from our table */
818 return ivtv_get_input(itv, vin->index, vin);
819}
820
821static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
822{
Hans Verkuil2f824412011-03-12 06:43:28 -0300823 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300824
825 return ivtv_get_output(itv, vout->index, vout);
826}
827
828static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
829{
Hans Verkuil2f824412011-03-12 06:43:28 -0300830 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300831 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300832
Hans Verkuil3f038d82008-05-29 16:43:54 -0300833 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Hans Verkuil80954cb2015-11-30 10:05:53 -0200834 cropcap->pixelaspect.numerator = itv->is_50hz ? 54 : 11;
835 cropcap->pixelaspect.denominator = itv->is_50hz ? 59 : 10;
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300836 } else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
Hans Verkuil80954cb2015-11-30 10:05:53 -0200837 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 54 : 11;
838 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 59 : 10;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300839 } else {
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300840 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300841 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300842 return 0;
843}
844
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300845static int ivtv_s_selection(struct file *file, void *fh,
846 struct v4l2_selection *sel)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300847{
Hans Verkuil2f824412011-03-12 06:43:28 -0300848 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300849 struct ivtv *itv = id->itv;
850 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300851 struct v4l2_rect r = { 0, 0, 720, 0 };
852 int streamtype = id->type;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300853
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300854 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
855 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300856 return -EINVAL;
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300857
858 if (sel->target != V4L2_SEL_TGT_COMPOSE)
859 return -EINVAL;
860
861
862 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
863 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
864 return -EINVAL;
865
866 r.height = itv->is_out_50hz ? 576 : 480;
867 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) {
868 r.width = yi->osd_full_w;
869 r.height = yi->osd_full_h;
870 }
871 sel->r.width = clamp(sel->r.width, 16U, r.width);
872 sel->r.height = clamp(sel->r.height, 16U, r.height);
873 sel->r.left = clamp_t(unsigned, sel->r.left, 0, r.width - sel->r.width);
874 sel->r.top = clamp_t(unsigned, sel->r.top, 0, r.height - sel->r.height);
875
876 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
877 yi->main_rect = sel->r;
878 return 0;
879 }
880 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
881 sel->r.width, sel->r.height, sel->r.left, sel->r.top)) {
882 itv->main_rect = sel->r;
883 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300884 }
885 return -EINVAL;
886}
887
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300888static int ivtv_g_selection(struct file *file, void *fh,
889 struct v4l2_selection *sel)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300890{
Hans Verkuil2f824412011-03-12 06:43:28 -0300891 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300892 struct ivtv *itv = id->itv;
893 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300894 struct v4l2_rect r = { 0, 0, 720, 0 };
895 int streamtype = id->type;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300896
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300897 if (sel->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
898 switch (sel->target) {
899 case V4L2_SEL_TGT_CROP_DEFAULT:
900 case V4L2_SEL_TGT_CROP_BOUNDS:
901 sel->r.top = sel->r.left = 0;
902 sel->r.width = 720;
903 sel->r.height = itv->is_50hz ? 576 : 480;
904 return 0;
905 default:
906 return -EINVAL;
907 }
908 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300909
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300910 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
911 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
912 return -EINVAL;
913
914 switch (sel->target) {
915 case V4L2_SEL_TGT_COMPOSE:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300916 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300917 sel->r = yi->main_rect;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300918 else
Hans Verkuilbbc9fa22015-03-30 13:54:13 -0300919 sel->r = itv->main_rect;
920 return 0;
921 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
922 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
923 r.height = itv->is_out_50hz ? 576 : 480;
924 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) {
925 r.width = yi->osd_full_w;
926 r.height = yi->osd_full_h;
927 }
928 sel->r = r;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300929 return 0;
930 }
931 return -EINVAL;
932}
933
934static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
935{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300936 static const struct v4l2_fmtdesc hm12 = {
937 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
938 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
939 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300940 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300941 static const struct v4l2_fmtdesc mpeg = {
942 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
943 "MPEG", V4L2_PIX_FMT_MPEG,
944 { 0, 0, 0, 0 }
945 };
946 struct ivtv *itv = fh2id(fh)->itv;
947 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300948
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300949 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300950 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300951 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
952 *fmt = mpeg;
953 else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
954 *fmt = hm12;
955 else
956 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300957 return 0;
958}
959
960static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
961{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300962 static const struct v4l2_fmtdesc hm12 = {
963 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0,
964 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
965 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300966 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300967 static const struct v4l2_fmtdesc mpeg = {
968 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_FMT_FLAG_COMPRESSED,
969 "MPEG", V4L2_PIX_FMT_MPEG,
970 { 0, 0, 0, 0 }
971 };
972 struct ivtv *itv = fh2id(fh)->itv;
973 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300974
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300975 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300976 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300977 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
978 *fmt = mpeg;
979 else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
980 *fmt = hm12;
981 else
Hans Verkuil3f038d82008-05-29 16:43:54 -0300982 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300983 return 0;
984}
985
986static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
987{
Hans Verkuil2f824412011-03-12 06:43:28 -0300988 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300989
990 *i = itv->active_input;
991
992 return 0;
993}
994
995int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
996{
Hans Verkuil2f824412011-03-12 06:43:28 -0300997 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300998 v4l2_std_id std;
999 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001000
Mauro Carvalho Chehabd6eb0b92012-10-27 12:52:19 -03001001 if (inp >= itv->nof_inputs)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001002 return -EINVAL;
1003
1004 if (inp == itv->active_input) {
1005 IVTV_DEBUG_INFO("Input unchanged\n");
1006 return 0;
1007 }
1008
1009 if (atomic_read(&itv->capturing) > 0) {
1010 return -EBUSY;
1011 }
1012
1013 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1014 itv->active_input, inp);
1015
1016 itv->active_input = inp;
1017 /* Set the audio input to whatever is appropriate for the
1018 input type. */
1019 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1020
Hans Verkuilf659f0e72012-09-05 08:56:55 -03001021 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
1022 std = itv->tuner_std;
1023 else
1024 std = V4L2_STD_ALL;
1025 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
Hans Verkuil635d62f2015-03-09 13:33:55 -03001026 itv->streams[i].vdev.tvnorms = std;
Hans Verkuilf659f0e72012-09-05 08:56:55 -03001027
Hans Verkuil3f038d82008-05-29 16:43:54 -03001028 /* prevent others from messing with the streams until
1029 we're finished changing inputs. */
1030 ivtv_mute(itv);
1031 ivtv_video_set_io(itv);
1032 ivtv_audio_set_io(itv);
1033 ivtv_unmute(itv);
1034
1035 return 0;
1036}
1037
1038static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1039{
Hans Verkuil2f824412011-03-12 06:43:28 -03001040 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001041
1042 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1043 return -EINVAL;
1044
1045 *i = itv->active_output;
1046
1047 return 0;
1048}
1049
1050static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1051{
Hans Verkuil2f824412011-03-12 06:43:28 -03001052 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001053
1054 if (outp >= itv->card->nof_outputs)
1055 return -EINVAL;
1056
1057 if (outp == itv->active_output) {
1058 IVTV_DEBUG_INFO("Output unchanged\n");
1059 return 0;
1060 }
1061 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1062 itv->active_output, outp);
1063
1064 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001065 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1066 SAA7127_INPUT_TYPE_NORMAL,
1067 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001068
1069 return 0;
1070}
1071
1072static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1073{
Hans Verkuil2f824412011-03-12 06:43:28 -03001074 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001075 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001076
Hans Verkuil635d62f2015-03-09 13:33:55 -03001077 if (s->vdev.vfl_dir)
Hans Verkuildff274f2012-10-01 06:45:36 -03001078 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001079 if (vf->tuner != 0)
1080 return -EINVAL;
1081
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001082 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001083 return 0;
1084}
1085
Hans Verkuilb530a442013-03-19 04:09:26 -03001086int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001087{
Hans Verkuil2f824412011-03-12 06:43:28 -03001088 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001089 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001090
Hans Verkuil635d62f2015-03-09 13:33:55 -03001091 if (s->vdev.vfl_dir)
Hans Verkuildff274f2012-10-01 06:45:36 -03001092 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001093 if (vf->tuner != 0)
1094 return -EINVAL;
1095
1096 ivtv_mute(itv);
1097 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001098 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001099 ivtv_unmute(itv);
1100 return 0;
1101}
1102
1103static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1104{
Hans Verkuil2f824412011-03-12 06:43:28 -03001105 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001106
1107 *std = itv->std;
1108 return 0;
1109}
1110
Hans Verkuil314527acb2013-03-15 06:10:40 -03001111void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001112{
Hans Verkuil314527acb2013-03-15 06:10:40 -03001113 itv->std = std;
1114 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001115 itv->is_50hz = !itv->is_60hz;
1116 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1117 itv->cxhdl.width = 720;
1118 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001119 itv->vbi.count = itv->is_50hz ? 18 : 12;
1120 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1121 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1122
1123 if (itv->hw_flags & IVTV_HW_CX25840)
1124 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1125
Hans Verkuil3f038d82008-05-29 16:43:54 -03001126 /* Tuner */
Laurent Pinchart8774bed2014-04-28 16:53:01 -03001127 ivtv_call_all(itv, video, s_std, itv->std);
Ian Armstrongc5874c922011-05-29 21:33:17 -03001128}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001129
Hans Verkuil314527acb2013-03-15 06:10:40 -03001130void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
Ian Armstrongc5874c922011-05-29 21:33:17 -03001131{
1132 struct yuv_playback_info *yi = &itv->yuv_info;
1133 DEFINE_WAIT(wait);
1134 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001135
Ian Armstrongc5874c922011-05-29 21:33:17 -03001136 /* set display standard */
Hans Verkuil314527acb2013-03-15 06:10:40 -03001137 itv->std_out = std;
1138 itv->is_out_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Ian Armstrongc5874c922011-05-29 21:33:17 -03001139 itv->is_out_50hz = !itv->is_out_60hz;
1140 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001141
Ian Armstrongc5874c922011-05-29 21:33:17 -03001142 /*
1143 * The next firmware call is time sensitive. Time it to
1144 * avoid risk of a hard lock, by trying to ensure the call
1145 * happens within the first 100 lines of the top field.
1146 * Make 4 attempts to sync to the decoder before giving up.
1147 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001148 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c922011-05-29 21:33:17 -03001149 for (f = 0; f < 4; f++) {
1150 prepare_to_wait(&itv->vsync_waitq, &wait,
1151 TASK_UNINTERRUPTIBLE);
1152 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1153 break;
1154 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001155 }
Ian Armstrongc5874c922011-05-29 21:33:17 -03001156 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001157 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c922011-05-29 21:33:17 -03001158
1159 if (f == 4)
1160 IVTV_WARN("Mode change failed to sync to decoder\n");
1161
1162 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1163 itv->main_rect.left = 0;
1164 itv->main_rect.top = 0;
1165 itv->main_rect.width = 720;
1166 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1167 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1168 720, itv->main_rect.height, 0, 0);
1169 yi->main_rect = itv->main_rect;
1170 if (!itv->osd_info) {
1171 yi->osd_full_w = 720;
1172 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1173 }
1174}
1175
Hans Verkuil314527acb2013-03-15 06:10:40 -03001176static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
Ian Armstrongc5874c922011-05-29 21:33:17 -03001177{
1178 struct ivtv *itv = fh2id(fh)->itv;
1179
Hans Verkuil314527acb2013-03-15 06:10:40 -03001180 if ((std & V4L2_STD_ALL) == 0)
Ian Armstrongc5874c922011-05-29 21:33:17 -03001181 return -EINVAL;
1182
Hans Verkuil314527acb2013-03-15 06:10:40 -03001183 if (std == itv->std)
Ian Armstrongc5874c922011-05-29 21:33:17 -03001184 return 0;
1185
1186 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1187 atomic_read(&itv->capturing) > 0 ||
1188 atomic_read(&itv->decoding) > 0) {
1189 /* Switching standard would mess with already running
1190 streams, prevent that by returning EBUSY. */
1191 return -EBUSY;
1192 }
1193
1194 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1195 (unsigned long long)itv->std);
1196
1197 ivtv_s_std_enc(itv, std);
1198 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1199 ivtv_s_std_dec(itv, std);
1200
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001201 return 0;
1202}
1203
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001204static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001205{
Hans Verkuil2f824412011-03-12 06:43:28 -03001206 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001207 struct ivtv *itv = id->itv;
1208
1209 if (vt->index != 0)
1210 return -EINVAL;
1211
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001212 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001213
1214 return 0;
1215}
1216
1217static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1218{
Hans Verkuil2f824412011-03-12 06:43:28 -03001219 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001220
1221 if (vt->index != 0)
1222 return -EINVAL;
1223
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001224 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001225
Hans Verkuild118e292011-06-25 10:28:21 -03001226 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001227 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001228 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001229 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001230 return 0;
1231}
1232
1233static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1234{
Hans Verkuil2f824412011-03-12 06:43:28 -03001235 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001236 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1237 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001238
Hans Verkuil79afcb12008-06-21 09:02:36 -03001239 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001240 for (f = 0; f < 2; f++) {
1241 for (l = 0; l < 24; l++) {
1242 if (valid_service_line(f, l, itv->is_50hz))
1243 cap->service_lines[f][l] = set;
1244 }
1245 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001246 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001247 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1248 return -EINVAL;
1249 if (itv->is_60hz) {
1250 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1251 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1252 } else {
1253 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1254 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1255 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001256 } else {
1257 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001258 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001259
1260 set = 0;
1261 for (f = 0; f < 2; f++)
1262 for (l = 0; l < 24; l++)
1263 set |= cap->service_lines[f][l];
1264 cap->service_set = set;
1265 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001266}
1267
1268static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1269{
Hans Verkuil2f824412011-03-12 06:43:28 -03001270 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001271 struct v4l2_enc_idx_entry *e = idx->entry;
1272 int entries;
1273 int i;
1274
1275 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1276 IVTV_MAX_PGM_INDEX;
1277 if (entries > V4L2_ENC_IDX_ENTRIES)
1278 entries = V4L2_ENC_IDX_ENTRIES;
1279 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001280 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1281 if (!atomic_read(&itv->capturing))
1282 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001283 for (i = 0; i < entries; i++) {
1284 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1285 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1286 idx->entries++;
1287 e++;
1288 }
1289 }
1290 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1291 return 0;
1292}
1293
1294static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1295{
Hans Verkuil2f824412011-03-12 06:43:28 -03001296 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001297 struct ivtv *itv = id->itv;
1298
Hans Verkuil3f038d82008-05-29 16:43:54 -03001299
1300 switch (enc->cmd) {
1301 case V4L2_ENC_CMD_START:
1302 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1303 enc->flags = 0;
1304 return ivtv_start_capture(id);
1305
1306 case V4L2_ENC_CMD_STOP:
1307 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1308 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1309 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1310 return 0;
1311
1312 case V4L2_ENC_CMD_PAUSE:
1313 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1314 enc->flags = 0;
1315
1316 if (!atomic_read(&itv->capturing))
1317 return -EPERM;
1318 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1319 return 0;
1320
1321 ivtv_mute(itv);
1322 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1323 break;
1324
1325 case V4L2_ENC_CMD_RESUME:
1326 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1327 enc->flags = 0;
1328
1329 if (!atomic_read(&itv->capturing))
1330 return -EPERM;
1331
1332 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1333 return 0;
1334
1335 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1336 ivtv_unmute(itv);
1337 break;
1338 default:
1339 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1340 return -EINVAL;
1341 }
1342
1343 return 0;
1344}
1345
1346static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1347{
Hans Verkuil2f824412011-03-12 06:43:28 -03001348 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001349
Hans Verkuil3f038d82008-05-29 16:43:54 -03001350 switch (enc->cmd) {
1351 case V4L2_ENC_CMD_START:
1352 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1353 enc->flags = 0;
1354 return 0;
1355
1356 case V4L2_ENC_CMD_STOP:
1357 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1358 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1359 return 0;
1360
1361 case V4L2_ENC_CMD_PAUSE:
1362 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1363 enc->flags = 0;
1364 return 0;
1365
1366 case V4L2_ENC_CMD_RESUME:
1367 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1368 enc->flags = 0;
1369 return 0;
1370 default:
1371 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1372 return -EINVAL;
1373 }
1374}
1375
1376static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1377{
Hans Verkuil2f824412011-03-12 06:43:28 -03001378 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil38a14212015-03-30 04:53:11 -03001379 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001380 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001381 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001382
Hans Verkuil3f038d82008-05-29 16:43:54 -03001383 int pixfmt;
1384 static u32 pixel_format[16] = {
1385 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1386 V4L2_PIX_FMT_RGB565,
1387 V4L2_PIX_FMT_RGB555,
1388 V4L2_PIX_FMT_RGB444,
1389 V4L2_PIX_FMT_RGB32,
1390 0,
1391 0,
1392 0,
1393 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1394 V4L2_PIX_FMT_YUV565,
1395 V4L2_PIX_FMT_YUV555,
1396 V4L2_PIX_FMT_YUV444,
1397 V4L2_PIX_FMT_YUV32,
1398 0,
1399 0,
1400 0,
1401 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001402
Hans Verkuil38a14212015-03-30 04:53:11 -03001403 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1404 return -ENOTTY;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001405 if (!itv->osd_video_pbase)
Hans Verkuil38a14212015-03-30 04:53:11 -03001406 return -ENOTTY;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001407
Hans Verkuil3f038d82008-05-29 16:43:54 -03001408 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1409 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001410
Hans Verkuil3f038d82008-05-29 16:43:54 -03001411 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1412 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1413 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001414
Hans Verkuil3f038d82008-05-29 16:43:54 -03001415 fb->fmt.pixelformat = pixel_format[pixfmt];
1416 fb->fmt.width = itv->osd_rect.width;
1417 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001418 fb->fmt.field = V4L2_FIELD_INTERLACED;
1419 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001420 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1421 fb->fmt.field = V4L2_FIELD_INTERLACED;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001422 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1423 fb->fmt.bytesperline *= 2;
1424 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1425 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1426 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001427 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001428 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001429 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001430
Hans Verkuil3f038d82008-05-29 16:43:54 -03001431 if (itv->osd_chroma_key_state)
1432 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001433
Hans Verkuil3f038d82008-05-29 16:43:54 -03001434 if (itv->osd_global_alpha_state)
1435 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001436
Ian Armstrongec9faa12008-10-06 03:06:08 -03001437 if (yi->track_osd)
1438 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1439
Hans Verkuil3f038d82008-05-29 16:43:54 -03001440 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001441
Hans Verkuil3f038d82008-05-29 16:43:54 -03001442 /* no local alpha for RGB565 or unknown formats */
1443 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001444 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001445
Hans Verkuil3f038d82008-05-29 16:43:54 -03001446 /* 16-bit formats have inverted local alpha */
1447 if (pixfmt == 2 || pixfmt == 3)
1448 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1449 else
1450 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001451
Hans Verkuil3f038d82008-05-29 16:43:54 -03001452 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001453 /* 16-bit formats have inverted local alpha */
1454 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001455 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001456 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001457 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001458 }
1459
Hans Verkuil3f038d82008-05-29 16:43:54 -03001460 return 0;
1461}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001462
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001463static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001464{
Hans Verkuil2f824412011-03-12 06:43:28 -03001465 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001466 struct ivtv *itv = id->itv;
Hans Verkuil38a14212015-03-30 04:53:11 -03001467 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001468 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001469
Hans Verkuil38a14212015-03-30 04:53:11 -03001470 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1471 return -ENOTTY;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001472 if (!itv->osd_video_pbase)
Hans Verkuil38a14212015-03-30 04:53:11 -03001473 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001474
1475 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1476 itv->osd_local_alpha_state =
1477 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1478 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1479 ivtv_set_osd_alpha(itv);
1480 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001481 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001482}
1483
1484static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1485{
Hans Verkuil2f824412011-03-12 06:43:28 -03001486 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001487 struct ivtv *itv = id->itv;
Hans Verkuil38a14212015-03-30 04:53:11 -03001488 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001489
Hans Verkuil38a14212015-03-30 04:53:11 -03001490 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1491 return -ENOTTY;
1492 if (!itv->osd_video_pbase)
1493 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001494
1495 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1496
1497 return 0;
1498}
1499
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001500static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001501{
1502 switch (sub->type) {
1503 case V4L2_EVENT_VSYNC:
1504 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001505 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001506 case V4L2_EVENT_CTRL:
1507 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001508 default:
1509 return -EINVAL;
1510 }
Hans Verkuil09250192010-03-27 14:10:13 -03001511}
1512
Hans Verkuil3f038d82008-05-29 16:43:54 -03001513static int ivtv_log_status(struct file *file, void *fh)
1514{
Hans Verkuil2f824412011-03-12 06:43:28 -03001515 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001516 u32 data[CX2341X_MBOX_MAX_DATA];
1517
1518 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1519 struct v4l2_input vidin;
1520 struct v4l2_audio audin;
1521 int i;
1522
Hans Verkuil3f038d82008-05-29 16:43:54 -03001523 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1524 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1525 struct tveeprom tv;
1526
1527 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001528 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001529 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001530 ivtv_get_input(itv, itv->active_input, &vidin);
1531 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1532 IVTV_INFO("Video Input: %s\n", vidin.name);
1533 IVTV_INFO("Audio Input: %s%s\n", audin.name,
Hans Verkuil3725d532015-05-18 10:29:17 -03001534 itv->dualwatch_stereo_mode == V4L2_MPEG_AUDIO_MODE_DUAL ?
1535 " (Bilingual)" : "");
Hans Verkuil3f038d82008-05-29 16:43:54 -03001536 if (has_output) {
1537 struct v4l2_output vidout;
1538 struct v4l2_audioout audout;
1539 int mode = itv->output_mode;
1540 static const char * const output_modes[5] = {
1541 "None",
1542 "MPEG Streaming",
1543 "YUV Streaming",
1544 "YUV Frames",
1545 "Passthrough",
1546 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001547 static const char * const alpha_mode[4] = {
1548 "None",
1549 "Global",
1550 "Local",
1551 "Global and Local"
1552 };
1553 static const char * const pixel_format[16] = {
1554 "ARGB Indexed",
1555 "RGB 5:6:5",
1556 "ARGB 1:5:5:5",
1557 "ARGB 1:4:4:4",
1558 "ARGB 8:8:8:8",
1559 "5",
1560 "6",
1561 "7",
1562 "AYUV Indexed",
1563 "YUV 5:6:5",
1564 "AYUV 1:5:5:5",
1565 "AYUV 1:4:4:4",
1566 "AYUV 8:8:8:8",
1567 "13",
1568 "14",
1569 "15",
1570 };
1571
1572 ivtv_get_output(itv, itv->active_output, &vidout);
1573 ivtv_get_audio_output(itv, 0, &audout);
1574 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001575 if (mode < 0 || mode > OUT_PASSTHROUGH)
1576 mode = OUT_NONE;
1577 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1578 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1579 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1580 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1581 data[0] & 1 ? "On" : "Off",
1582 alpha_mode[(data[0] >> 1) & 0x3],
1583 pixel_format[(data[0] >> 3) & 0xf]);
1584 }
1585 IVTV_INFO("Tuner: %s\n",
1586 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001587 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001588 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1589 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1590 struct ivtv_stream *s = &itv->streams[i];
1591
Hans Verkuil635d62f2015-03-09 13:33:55 -03001592 if (s->vdev.v4l2_dev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001593 continue;
1594 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1595 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1596 (s->buffers * s->buf_size) / 1024, s->buffers);
1597 }
1598
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001599 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1600 (long long)itv->mpg_data_received,
1601 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001602 return 0;
1603}
1604
Hans Verkuilda8ec562011-11-24 09:58:53 -03001605static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1606{
1607 struct ivtv_open_id *id = fh2id(file->private_data);
1608 struct ivtv *itv = id->itv;
1609
1610 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1611 return ivtv_video_command(itv, id, dec, false);
1612}
1613
1614static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1615{
1616 struct ivtv_open_id *id = fh2id(file->private_data);
1617 struct ivtv *itv = id->itv;
1618
1619 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1620 return ivtv_video_command(itv, id, dec, true);
1621}
1622
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001623static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001624{
Hans Verkuil09250192010-03-27 14:10:13 -03001625 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001626 struct ivtv *itv = id->itv;
1627 int nonblocking = filp->f_flags & O_NONBLOCK;
1628 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001629 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001630
1631 switch (cmd) {
1632 case IVTV_IOC_DMA_FRAME: {
1633 struct ivtv_dma_frame *args = arg;
1634
1635 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1636 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1637 return -EINVAL;
1638 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1639 return -EINVAL;
1640 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1641 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001642 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001643 return -EBUSY;
1644 }
1645 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1646 ivtv_release_stream(s);
1647 return -EBUSY;
1648 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001649 /* Mark that this file handle started the UDMA_YUV mode */
1650 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001651 if (args->y_source == NULL)
1652 return 0;
1653 return ivtv_yuv_prep_frame(itv, args);
1654 }
1655
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001656 case IVTV_IOC_PASSTHROUGH_MODE:
1657 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1658 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1659 return -EINVAL;
1660 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1661
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001662 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001663 s64 *pts = arg;
1664 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001665
1666 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1667 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1668 *pts = s->dma_pts;
1669 break;
1670 }
1671 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1672 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001673 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001674 }
1675
1676 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001677 s64 *frame = arg;
1678 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001679
1680 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1681 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1682 *frame = 0;
1683 break;
1684 }
1685 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1686 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001687 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001688 }
1689
1690 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001691 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001692
1693 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001694 memset(&dc, 0, sizeof(dc));
1695 dc.cmd = V4L2_DEC_CMD_START;
1696 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001697 }
1698
1699 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001700 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001701
1702 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001703 memset(&dc, 0, sizeof(dc));
1704 dc.cmd = V4L2_DEC_CMD_STOP;
1705 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1706 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001707 }
1708
1709 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001710 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001711
1712 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001713 memset(&dc, 0, sizeof(dc));
1714 dc.cmd = V4L2_DEC_CMD_PAUSE;
1715 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001716 }
1717
1718 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001719 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001720
1721 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001722 memset(&dc, 0, sizeof(dc));
1723 dc.cmd = V4L2_DEC_CMD_RESUME;
1724 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001725 }
1726
1727 case VIDEO_COMMAND:
1728 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001729 /* Note: struct v4l2_decoder_cmd has the same layout as
1730 struct video_command */
1731 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001732 int try = (cmd == VIDEO_TRY_COMMAND);
1733
1734 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001735 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001736 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001737 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1738 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001739 }
1740
1741 case VIDEO_GET_EVENT: {
1742 struct video_event *ev = arg;
1743 DEFINE_WAIT(wait);
1744
1745 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1746 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1747 return -EINVAL;
1748 memset(ev, 0, sizeof(*ev));
1749 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1750
1751 while (1) {
1752 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1753 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1754 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1755 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001756 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1757 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1758 if (itv->output_mode == OUT_UDMA_YUV &&
1759 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1760 IVTV_YUV_MODE_PROGRESSIVE) {
1761 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1762 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001763 }
1764 if (ev->type)
1765 return 0;
1766 if (nonblocking)
1767 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001768 /* Wait for event. Note that serialize_lock is locked,
1769 so to allow other processes to access the driver while
1770 we are waiting unlock first and later lock again. */
1771 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001772 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001773 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1774 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001775 schedule();
1776 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001777 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001778 if (signal_pending(current)) {
1779 /* return if a signal was received */
1780 IVTV_DEBUG_INFO("User stopped wait for event\n");
1781 return -EINTR;
1782 }
1783 }
1784 break;
1785 }
1786
Hans Verkuilce680252010-04-06 15:58:53 -03001787 case VIDEO_SELECT_SOURCE:
1788 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1789 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1790 return -EINVAL;
1791 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1792
1793 case AUDIO_SET_MUTE:
1794 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1795 itv->speed_mute_audio = iarg;
1796 return 0;
1797
1798 case AUDIO_CHANNEL_SELECT:
1799 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1800 if (iarg > AUDIO_STEREO_SWAPPED)
1801 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001802 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001803
1804 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1805 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1806 if (iarg > AUDIO_STEREO_SWAPPED)
1807 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001808 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001809
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001810 default:
1811 return -EINVAL;
1812 }
1813 return 0;
1814}
1815
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001816static long ivtv_default(struct file *file, void *fh, bool valid_prio,
Mauro Carvalho Chehab6d43be72013-03-26 08:04:52 -03001817 unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001818{
Hans Verkuil2f824412011-03-12 06:43:28 -03001819 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001820
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001821 if (!valid_prio) {
1822 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001823 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001824 case VIDEO_PLAY:
1825 case VIDEO_STOP:
1826 case VIDEO_FREEZE:
1827 case VIDEO_CONTINUE:
1828 case VIDEO_COMMAND:
1829 case VIDEO_SELECT_SOURCE:
1830 case AUDIO_SET_MUTE:
1831 case AUDIO_CHANNEL_SELECT:
1832 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1833 return -EBUSY;
1834 }
1835 }
1836
Hans Verkuild46c17d2007-03-10 17:59:15 -03001837 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001838 case VIDIOC_INT_RESET: {
1839 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001840
Hans Verkuil3f038d82008-05-29 16:43:54 -03001841 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1842 ivtv_reset_ir_gpio(itv);
1843 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001844 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001845 break;
1846 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001847
Hans Verkuilac9575f2009-02-14 19:58:33 -03001848 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001849 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001850 case VIDEO_GET_PTS:
1851 case VIDEO_GET_FRAME_COUNT:
1852 case VIDEO_GET_EVENT:
1853 case VIDEO_PLAY:
1854 case VIDEO_STOP:
1855 case VIDEO_FREEZE:
1856 case VIDEO_CONTINUE:
1857 case VIDEO_COMMAND:
1858 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001859 case VIDEO_SELECT_SOURCE:
1860 case AUDIO_SET_MUTE:
1861 case AUDIO_CHANNEL_SELECT:
1862 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001863 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1864
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001865 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001866 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001867 }
1868 return 0;
1869}
1870
Hans Verkuila3998102008-07-21 02:57:38 -03001871static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1872 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001873 .vidioc_s_audio = ivtv_s_audio,
1874 .vidioc_g_audio = ivtv_g_audio,
1875 .vidioc_enumaudio = ivtv_enumaudio,
1876 .vidioc_s_audout = ivtv_s_audout,
1877 .vidioc_g_audout = ivtv_g_audout,
1878 .vidioc_enum_input = ivtv_enum_input,
1879 .vidioc_enum_output = ivtv_enum_output,
1880 .vidioc_enumaudout = ivtv_enumaudout,
1881 .vidioc_cropcap = ivtv_cropcap,
Hans Verkuilbbc9fa22015-03-30 13:54:13 -03001882 .vidioc_s_selection = ivtv_s_selection,
1883 .vidioc_g_selection = ivtv_g_selection,
Hans Verkuila3998102008-07-21 02:57:38 -03001884 .vidioc_g_input = ivtv_g_input,
1885 .vidioc_s_input = ivtv_s_input,
1886 .vidioc_g_output = ivtv_g_output,
1887 .vidioc_s_output = ivtv_s_output,
1888 .vidioc_g_frequency = ivtv_g_frequency,
1889 .vidioc_s_frequency = ivtv_s_frequency,
1890 .vidioc_s_tuner = ivtv_s_tuner,
1891 .vidioc_g_tuner = ivtv_g_tuner,
1892 .vidioc_g_enc_index = ivtv_g_enc_index,
1893 .vidioc_g_fbuf = ivtv_g_fbuf,
1894 .vidioc_s_fbuf = ivtv_s_fbuf,
1895 .vidioc_g_std = ivtv_g_std,
1896 .vidioc_s_std = ivtv_s_std,
1897 .vidioc_overlay = ivtv_overlay,
1898 .vidioc_log_status = ivtv_log_status,
1899 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1900 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1901 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001902 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1903 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001904 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1905 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1906 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1907 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1908 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1909 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1910 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1911 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1912 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1913 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1914 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1915 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1916 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1917 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1918 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1919 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1920 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1921 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1922 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1923 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
Hans Verkuila3998102008-07-21 02:57:38 -03001924#ifdef CONFIG_VIDEO_ADV_DEBUG
1925 .vidioc_g_register = ivtv_g_register,
1926 .vidioc_s_register = ivtv_s_register,
1927#endif
1928 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001929 .vidioc_subscribe_event = ivtv_subscribe_event,
1930 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001931};
1932
Hans Verkuil3f038d82008-05-29 16:43:54 -03001933void ivtv_set_funcs(struct video_device *vdev)
1934{
Hans Verkuila3998102008-07-21 02:57:38 -03001935 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001936}