blob: 50379b26768b87523321b4907db62198549bf460 [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 Verkuil33c0fca2007-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"
35#include <media/saa7127.h>
36#include <media/tveeprom.h>
37#include <media/v4l2-chip-ident.h>
Hans Verkuil09250192010-03-27 14:10:13 -030038#include <media/v4l2-event.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030039#include <linux/dvb/audio.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030040
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030041u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030042{
43 switch (type) {
44 case V4L2_SLICED_TELETEXT_B:
45 return IVTV_SLICED_TYPE_TELETEXT_B;
46 case V4L2_SLICED_CAPTION_525:
47 return IVTV_SLICED_TYPE_CAPTION_525;
48 case V4L2_SLICED_WSS_625:
49 return IVTV_SLICED_TYPE_WSS_625;
50 case V4L2_SLICED_VPS:
51 return IVTV_SLICED_TYPE_VPS;
52 default:
53 return 0;
54 }
55}
56
57static int valid_service_line(int field, int line, int is_pal)
58{
59 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
60 (!is_pal && line >= 10 && line < 22);
61}
62
63static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
64{
65 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
66 int i;
67
68 set = set & valid_set;
69 if (set == 0 || !valid_service_line(field, line, is_pal)) {
70 return 0;
71 }
72 if (!is_pal) {
73 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
74 return V4L2_SLICED_CAPTION_525;
75 }
76 else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625;
81 if (line == 23)
82 return 0;
83 }
84 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set)
86 return 1 << i;
87 }
88 return 0;
89}
90
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030091void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030092{
93 u16 set = fmt->service_set;
94 int f, l;
95
96 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++) {
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 }
101 }
102}
103
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300104static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300105{
106 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300107
108 for (f = 0; f < 2; f++) {
109 for (l = 0; l < 24; l++) {
110 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 -0300111 }
112 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300113}
114
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300115u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300116{
117 int f, l;
118 u16 set = 0;
119
120 for (f = 0; f < 2; f++) {
121 for (l = 0; l < 24; l++) {
122 set |= fmt->service_lines[f][l];
123 }
124 }
125 return set;
126}
127
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300128void ivtv_set_osd_alpha(struct ivtv *itv)
129{
130 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
131 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300132 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 -0300133}
134
135int ivtv_set_speed(struct ivtv *itv, int speed)
136{
137 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300138 int single_step = (speed == 1 || speed == -1);
139 DEFINE_WAIT(wait);
140
141 if (speed == 0) speed = 1000;
142
143 /* No change? */
144 if (speed == itv->speed && !single_step)
145 return 0;
146
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300147 if (single_step && (speed < 0) == (itv->speed < 0)) {
148 /* Single step video and no need to change direction */
149 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
150 itv->speed = speed;
151 return 0;
152 }
153 if (single_step)
154 /* Need to change direction */
155 speed = speed < 0 ? -1000 : 1000;
156
157 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
158 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
159 data[1] = (speed < 0);
160 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300161 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300162 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
163 data[5] = 0;
164 data[6] = 0;
165
166 if (speed == 1500 || speed == -1500) data[0] |= 1;
167 else if (speed == 2000 || speed == -2000) data[0] |= 2;
168 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
169 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
170
171 /* If not decoding, just change speed setting */
172 if (atomic_read(&itv->decoding) > 0) {
173 int got_sig = 0;
174
175 /* Stop all DMA and decoding activity */
176 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
177
178 /* Wait for any DMA to finish */
Hans Verkuilcdc03782011-10-11 06:06:58 -0300179 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300180 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -0300181 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300182 got_sig = signal_pending(current);
183 if (got_sig)
184 break;
185 got_sig = 0;
186 schedule();
187 }
188 finish_wait(&itv->dma_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -0300189 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300190 if (got_sig)
191 return -EINTR;
192
193 /* Change Speed safely */
194 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
195 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
196 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
197 }
198 if (single_step) {
199 speed = (speed < 0) ? -1 : 1;
200 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
201 }
202 itv->speed = speed;
203 return 0;
204}
205
206static int ivtv_validate_speed(int cur_speed, int new_speed)
207{
208 int fact = new_speed < 0 ? -1 : 1;
209 int s;
210
Hans Verkuil94dee762008-04-26 09:26:13 -0300211 if (cur_speed == 0)
212 cur_speed = 1000;
213 if (new_speed < 0)
214 new_speed = -new_speed;
215 if (cur_speed < 0)
216 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300217
218 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300219 if (new_speed > 1500)
220 return fact * 2000;
221 if (new_speed > 1000)
222 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300223 }
224 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300225 if (new_speed >= 2000)
226 return fact * 2000;
227 if (new_speed >= 1500)
228 return fact * 1500;
229 if (new_speed >= 1000)
230 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300231 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300232 if (new_speed == 0)
233 return 1000;
234 if (new_speed == 1 || new_speed == 1000)
235 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300236
237 s = new_speed;
238 new_speed = 1000 / new_speed;
239 if (1000 / cur_speed == new_speed)
240 new_speed += (cur_speed < s) ? -1 : 1;
241 if (new_speed > 60) return 1000 / (fact * 60);
242 return 1000 / (fact * new_speed);
243}
244
245static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300246 struct v4l2_decoder_cmd *dc, int try)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300247{
248 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
249
250 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
251 return -EINVAL;
252
Hans Verkuilda8ec562011-11-24 09:58:53 -0300253 switch (dc->cmd) {
254 case V4L2_DEC_CMD_START: {
255 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
256 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
257 if (dc->start.speed < 0)
258 dc->start.format = V4L2_DEC_START_FMT_GOP;
259 else
260 dc->start.format = V4L2_DEC_START_FMT_NONE;
261 if (dc->start.speed != 500 && dc->start.speed != 1500)
262 dc->flags = dc->start.speed == 1000 ? 0 :
263 V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300264 if (try) break;
265
Hans Verkuilda8ec562011-11-24 09:58:53 -0300266 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300267 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
268 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300269 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
270 /* forces ivtv_set_speed to be called */
271 itv->speed = 0;
272 }
Hans Verkuilda8ec562011-11-24 09:58:53 -0300273 return ivtv_start_decoding(id, dc->start.speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300274 }
275
Hans Verkuilda8ec562011-11-24 09:58:53 -0300276 case V4L2_DEC_CMD_STOP:
277 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
278 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
279 dc->stop.pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300280 if (try) break;
281 if (atomic_read(&itv->decoding) == 0)
282 return 0;
283 if (itv->output_mode != OUT_MPG)
284 return -EBUSY;
285
286 itv->output_mode = OUT_NONE;
Hans Verkuilda8ec562011-11-24 09:58:53 -0300287 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300288
Hans Verkuilda8ec562011-11-24 09:58:53 -0300289 case V4L2_DEC_CMD_PAUSE:
290 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300291 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300292 if (!atomic_read(&itv->decoding))
293 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300294 if (itv->output_mode != OUT_MPG)
295 return -EBUSY;
296 if (atomic_read(&itv->decoding) > 0) {
297 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300298 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300299 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300300 }
301 break;
302
Hans Verkuilda8ec562011-11-24 09:58:53 -0300303 case V4L2_DEC_CMD_RESUME:
304 dc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300305 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300306 if (!atomic_read(&itv->decoding))
307 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300308 if (itv->output_mode != OUT_MPG)
309 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300310 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
311 int speed = itv->speed;
312 itv->speed = 0;
313 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300314 }
315 break;
316
317 default:
318 return -EINVAL;
319 }
320 return 0;
321}
322
Hans Verkuil3f038d82008-05-29 16:43:54 -0300323static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300324{
Hans Verkuil2f824412011-03-12 06:43:28 -0300325 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300326 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300327
Hans Verkuile88360c2008-06-21 08:00:56 -0300328 vbifmt->reserved[0] = 0;
329 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300330 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300331 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300332 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil30634e82012-09-05 10:38:10 -0300333 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300334 if (itv->is_60hz) {
335 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
336 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
337 } else {
338 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
339 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
340 }
341 vbifmt->service_set = ivtv_get_service_set(vbifmt);
342 return 0;
343}
344
345static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
346{
Hans Verkuil2f824412011-03-12 06:43:28 -0300347 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300348 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300349 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300350
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300351 pixfmt->width = itv->cxhdl.width;
352 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300353 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
354 pixfmt->field = V4L2_FIELD_INTERLACED;
355 pixfmt->priv = 0;
356 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
357 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300358 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
359 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300360 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300361 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300362 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
363 pixfmt->sizeimage = 128 * 1024;
364 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300365 }
366 return 0;
367}
368
Hans Verkuil3f038d82008-05-29 16:43:54 -0300369static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300370{
Hans Verkuil2f824412011-03-12 06:43:28 -0300371 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300372 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300373
Hans Verkuile88360c2008-06-21 08:00:56 -0300374 vbifmt->sampling_rate = 27000000;
375 vbifmt->offset = 248;
376 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
377 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
378 vbifmt->start[0] = itv->vbi.start[0];
379 vbifmt->start[1] = itv->vbi.start[1];
380 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
381 vbifmt->flags = 0;
382 vbifmt->reserved[0] = 0;
383 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300384 return 0;
385}
386
387static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
388{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300389 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300390 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300391 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300392
Hans Verkuile88360c2008-06-21 08:00:56 -0300393 vbifmt->reserved[0] = 0;
394 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300396
Hans Verkuil3f038d82008-05-29 16:43:54 -0300397 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
398 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
399 V4L2_SLICED_VBI_525;
400 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuilc5c46f22012-09-05 12:27:19 -0300401 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300402 return 0;
403 }
404
Hans Verkuil4ff07902010-03-14 12:18:18 -0300405 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300406 vbifmt->service_set = ivtv_get_service_set(vbifmt);
407 return 0;
408}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300409
Hans Verkuil3f038d82008-05-29 16:43:54 -0300410static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
411{
Hans Verkuil2f824412011-03-12 06:43:28 -0300412 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300413 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300414 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300415
Hans Verkuil3f038d82008-05-29 16:43:54 -0300416 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300417 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300418 pixfmt->width = itv->main_rect.width;
419 pixfmt->height = itv->main_rect.height;
420 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
421 pixfmt->field = V4L2_FIELD_INTERLACED;
422 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300423 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
424 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
425 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300426 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300427 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
428 break;
429 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 break;
432 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300434 break;
435 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300436 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
437 pixfmt->bytesperline = 720;
438 pixfmt->width = itv->yuv_info.v4l2_src_w;
439 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300441 pixfmt->sizeimage =
442 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300443 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300444 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
445 pixfmt->sizeimage = 128 * 1024;
446 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300447 }
448 return 0;
449}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300450
Hans Verkuil3f038d82008-05-29 16:43:54 -0300451static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
452{
Hans Verkuil2f824412011-03-12 06:43:28 -0300453 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300454 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300455
456 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
457 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 Verkuile88360c2008-06-21 08:00:56 -0300561 u32 chromakey = fmt->fmt.win.chromakey;
562 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300563
564 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
565 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300566 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
567 fmt->fmt.win.chromakey = chromakey;
568 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300569 return 0;
570}
571
572static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
573{
574 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
575}
576
577static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
578{
Hans Verkuil2f824412011-03-12 06:43:28 -0300579 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300580 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300581 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300582 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300583 int w = fmt->fmt.pix.width;
584 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300585
586 if (ret)
587 return ret;
588
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300589 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300590 return 0;
591
592 if (atomic_read(&itv->capturing) > 0)
593 return -EBUSY;
594
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300595 itv->cxhdl.width = w;
596 itv->cxhdl.height = h;
597 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300598 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300599 mbus_fmt.width = fmt->fmt.pix.width;
600 mbus_fmt.height = h;
601 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
602 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300603 return ivtv_g_fmt_vid_cap(file, fh, fmt);
604}
605
606static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
607{
Hans Verkuil2f824412011-03-12 06:43:28 -0300608 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300609
Hans Verkuila8b86432008-10-04 08:05:30 -0300610 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
611 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300612 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300613 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300614 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300615 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
616}
617
618static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
619{
620 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300621 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300622 struct ivtv *itv = id->itv;
623 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
624
625 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
626 return ret;
627
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300628 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300629 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300630 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300631 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300632 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300633 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
634 return 0;
635}
636
Hans Verkuil3f038d82008-05-29 16:43:54 -0300637static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300638{
Hans Verkuil2f824412011-03-12 06:43:28 -0300639 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 struct yuv_playback_info *yi = &itv->yuv_info;
642 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 if (ret)
645 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300646
Hans Verkuil3f038d82008-05-29 16:43:54 -0300647 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
648 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300649
Hans Verkuil3f038d82008-05-29 16:43:54 -0300650 /* Return now if we already have some frame data */
651 if (yi->stream_size)
652 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300653
Hans Verkuil3f038d82008-05-29 16:43:54 -0300654 yi->v4l2_src_w = fmt->fmt.pix.width;
655 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300656
Hans Verkuil3f038d82008-05-29 16:43:54 -0300657 switch (fmt->fmt.pix.field) {
658 case V4L2_FIELD_NONE:
659 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300661 case V4L2_FIELD_ANY:
662 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300663 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300664 case V4L2_FIELD_INTERLACED_BT:
665 yi->lace_mode =
666 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
667 break;
668 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300669 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300670 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
671 break;
672 }
673 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
674
675 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
676 itv->dma_data_req_size =
677 1080 * ((yi->v4l2_src_h + 31) & ~31);
678
Hans Verkuil3f038d82008-05-29 16:43:54 -0300679 return 0;
680}
681
682static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
683{
Hans Verkuil2f824412011-03-12 06:43:28 -0300684 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300685 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
686
687 if (ret == 0) {
688 itv->osd_chroma_key = fmt->fmt.win.chromakey;
689 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
690 ivtv_set_osd_alpha(itv);
691 }
692 return ret;
693}
694
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300695static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300696{
Hans Verkuil2f824412011-03-12 06:43:28 -0300697 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300698
699 chip->ident = V4L2_IDENT_NONE;
700 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300701 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
702 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300703 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
704 return 0;
705 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300706 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
707 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300708 return -EINVAL;
709 /* TODO: is this correct? */
710 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300711}
712
Hans Verkuil36ecd492008-06-25 06:00:17 -0300713#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilb5656e82013-03-24 08:24:19 -0300714static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300715{
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300716 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300717
718 if (!capable(CAP_SYS_ADMIN))
719 return -EPERM;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300720 if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300721 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300722 else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
723 reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300724 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300725 else if (reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300726 reg_start = itv->enc_mem;
727 else
728 return -EINVAL;
729
Hans Verkuilb5656e82013-03-24 08:24:19 -0300730 if (get)
731 *val = readl(reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300732 else
Hans Verkuilb5656e82013-03-24 08:24:19 -0300733 writel(*val, reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300734 return 0;
735}
736
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300737static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300738{
Hans Verkuil2f824412011-03-12 06:43:28 -0300739 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300740
Hans Verkuilb5656e82013-03-24 08:24:19 -0300741 if (v4l2_chip_match_host(&reg->match)) {
742 reg->size = 4;
743 return ivtv_itvc(itv, true, reg->reg, &reg->val);
744 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300745 /* TODO: subdev errors should not be ignored, this should become a
746 subdev helper function. */
747 ivtv_call_all(itv, core, g_register, reg);
748 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300749}
750
Hans Verkuil977ba3b2013-03-24 08:28:46 -0300751static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752{
Hans Verkuil2f824412011-03-12 06:43:28 -0300753 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300754
Hans Verkuil977ba3b2013-03-24 08:28:46 -0300755 if (v4l2_chip_match_host(&reg->match)) {
756 u64 val = reg->val;
757
758 return ivtv_itvc(itv, false, reg->reg, &val);
759 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300760 /* TODO: subdev errors should not be ignored, this should become a
761 subdev helper function. */
762 ivtv_call_all(itv, core, s_register, reg);
763 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300764}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300765#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300766
Hans Verkuil3f038d82008-05-29 16:43:54 -0300767static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
768{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300769 struct ivtv_open_id *id = fh2id(file->private_data);
770 struct ivtv *itv = id->itv;
771 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300772
Hans Verkuil3f038d82008-05-29 16:43:54 -0300773 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
774 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300775 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300776 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
777 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300778 return 0;
779}
780
781static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
782{
Hans Verkuil2f824412011-03-12 06:43:28 -0300783 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300784
785 return ivtv_get_audio_input(itv, vin->index, vin);
786}
787
788static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *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 vin->index = itv->audio_input;
793 return ivtv_get_audio_input(itv, vin->index, vin);
794}
795
Hans Verkuil0e8025b2012-09-04 11:59:31 -0300796static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300797{
Hans Verkuil2f824412011-03-12 06:43:28 -0300798 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300799
800 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300801 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300802
803 itv->audio_input = vout->index;
804 ivtv_audio_set_io(itv);
805
806 return 0;
807}
808
809static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
810{
Hans Verkuil2f824412011-03-12 06:43:28 -0300811 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300812
813 /* set it to defaults from our table */
814 return ivtv_get_audio_output(itv, vin->index, vin);
815}
816
817static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
818{
Hans Verkuil2f824412011-03-12 06:43:28 -0300819 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300820
821 vin->index = 0;
822 return ivtv_get_audio_output(itv, vin->index, vin);
823}
824
Hans Verkuilba9425b2012-09-04 12:03:49 -0300825static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300826{
Hans Verkuil2f824412011-03-12 06:43:28 -0300827 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300828
Hans Verkuilba9425b2012-09-04 12:03:49 -0300829 if (itv->card->video_outputs == NULL || vout->index != 0)
830 return -EINVAL;
831 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300832}
833
834static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
835{
Hans Verkuil2f824412011-03-12 06:43:28 -0300836 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300837
838 /* set it to defaults from our table */
839 return ivtv_get_input(itv, vin->index, vin);
840}
841
842static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
843{
Hans Verkuil2f824412011-03-12 06:43:28 -0300844 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300845
846 return ivtv_get_output(itv, vout->index, vout);
847}
848
849static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
850{
Hans Verkuil2f824412011-03-12 06:43:28 -0300851 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300852 struct ivtv *itv = id->itv;
853 struct yuv_playback_info *yi = &itv->yuv_info;
854 int streamtype;
855
856 streamtype = id->type;
857
858 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
859 return -EINVAL;
860 cropcap->bounds.top = cropcap->bounds.left = 0;
861 cropcap->bounds.width = 720;
862 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
863 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
864 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
865 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
866 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
867 if (yi->track_osd) {
868 cropcap->bounds.width = yi->osd_full_w;
869 cropcap->bounds.height = yi->osd_full_h;
870 } else {
871 cropcap->bounds.width = 720;
872 cropcap->bounds.height =
873 itv->is_out_50hz ? 576 : 480;
874 }
875 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
876 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
877 } else {
878 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
879 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
880 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
881 }
882 cropcap->defrect = cropcap->bounds;
883 return 0;
884}
885
Hans Verkuil4f9965942012-09-05 05:10:48 -0300886static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300887{
Hans Verkuil2f824412011-03-12 06:43:28 -0300888 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300889 struct ivtv *itv = id->itv;
890 struct yuv_playback_info *yi = &itv->yuv_info;
891 int streamtype;
892
893 streamtype = id->type;
894
Hans Verkuil3f038d82008-05-29 16:43:54 -0300895 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
896 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
897 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
898 yi->main_rect = crop->c;
899 return 0;
900 } else {
901 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
902 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
903 itv->main_rect = crop->c;
904 return 0;
905 }
906 }
907 return -EINVAL;
908 }
909 return -EINVAL;
910}
911
912static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
913{
Hans Verkuil2f824412011-03-12 06:43:28 -0300914 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300915 struct ivtv *itv = id->itv;
916 struct yuv_playback_info *yi = &itv->yuv_info;
917 int streamtype;
918
919 streamtype = id->type;
920
921 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
922 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
923 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
924 crop->c = yi->main_rect;
925 else
926 crop->c = itv->main_rect;
927 return 0;
928 }
929 return -EINVAL;
930}
931
932static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
933{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300934 static const struct v4l2_fmtdesc hm12 = {
935 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
936 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
937 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300938 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300939 static const struct v4l2_fmtdesc mpeg = {
940 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
941 "MPEG", V4L2_PIX_FMT_MPEG,
942 { 0, 0, 0, 0 }
943 };
944 struct ivtv *itv = fh2id(fh)->itv;
945 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300946
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300947 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300948 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300949 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
950 *fmt = mpeg;
951 else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
952 *fmt = hm12;
953 else
954 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300955 return 0;
956}
957
958static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
959{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300960 static const struct v4l2_fmtdesc hm12 = {
961 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0,
962 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
963 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300964 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300965 static const struct v4l2_fmtdesc mpeg = {
966 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_FMT_FLAG_COMPRESSED,
967 "MPEG", V4L2_PIX_FMT_MPEG,
968 { 0, 0, 0, 0 }
969 };
970 struct ivtv *itv = fh2id(fh)->itv;
971 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300972
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300973 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300974 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300975 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
976 *fmt = mpeg;
977 else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
978 *fmt = hm12;
979 else
Hans Verkuil3f038d82008-05-29 16:43:54 -0300980 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300981 return 0;
982}
983
984static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
985{
Hans Verkuil2f824412011-03-12 06:43:28 -0300986 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300987
988 *i = itv->active_input;
989
990 return 0;
991}
992
993int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
994{
Hans Verkuil2f824412011-03-12 06:43:28 -0300995 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300996 v4l2_std_id std;
997 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300998
Mauro Carvalho Chehabd6eb0b92012-10-27 12:52:19 -0300999 if (inp >= itv->nof_inputs)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001000 return -EINVAL;
1001
1002 if (inp == itv->active_input) {
1003 IVTV_DEBUG_INFO("Input unchanged\n");
1004 return 0;
1005 }
1006
1007 if (atomic_read(&itv->capturing) > 0) {
1008 return -EBUSY;
1009 }
1010
1011 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1012 itv->active_input, inp);
1013
1014 itv->active_input = inp;
1015 /* Set the audio input to whatever is appropriate for the
1016 input type. */
1017 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1018
Hans Verkuilf659f0e72012-09-05 08:56:55 -03001019 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
1020 std = itv->tuner_std;
1021 else
1022 std = V4L2_STD_ALL;
1023 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
1024 itv->streams[i].vdev->tvnorms = std;
1025
Hans Verkuil3f038d82008-05-29 16:43:54 -03001026 /* prevent others from messing with the streams until
1027 we're finished changing inputs. */
1028 ivtv_mute(itv);
1029 ivtv_video_set_io(itv);
1030 ivtv_audio_set_io(itv);
1031 ivtv_unmute(itv);
1032
1033 return 0;
1034}
1035
1036static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1037{
Hans Verkuil2f824412011-03-12 06:43:28 -03001038 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001039
1040 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1041 return -EINVAL;
1042
1043 *i = itv->active_output;
1044
1045 return 0;
1046}
1047
1048static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1049{
Hans Verkuil2f824412011-03-12 06:43:28 -03001050 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001051
1052 if (outp >= itv->card->nof_outputs)
1053 return -EINVAL;
1054
1055 if (outp == itv->active_output) {
1056 IVTV_DEBUG_INFO("Output unchanged\n");
1057 return 0;
1058 }
1059 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1060 itv->active_output, outp);
1061
1062 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001063 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1064 SAA7127_INPUT_TYPE_NORMAL,
1065 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001066
1067 return 0;
1068}
1069
1070static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1071{
Hans Verkuil2f824412011-03-12 06:43:28 -03001072 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001073 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001074
Hans Verkuildff274f2012-10-01 06:45:36 -03001075 if (s->vdev->vfl_dir)
1076 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001077 if (vf->tuner != 0)
1078 return -EINVAL;
1079
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001080 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001081 return 0;
1082}
1083
Hans Verkuilb530a442013-03-19 04:09:26 -03001084int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001085{
Hans Verkuil2f824412011-03-12 06:43:28 -03001086 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001087 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001088
Hans Verkuildff274f2012-10-01 06:45:36 -03001089 if (s->vdev->vfl_dir)
1090 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001091 if (vf->tuner != 0)
1092 return -EINVAL;
1093
1094 ivtv_mute(itv);
1095 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001096 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001097 ivtv_unmute(itv);
1098 return 0;
1099}
1100
1101static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1102{
Hans Verkuil2f824412011-03-12 06:43:28 -03001103 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001104
1105 *std = itv->std;
1106 return 0;
1107}
1108
Hans Verkuil314527a2013-03-15 06:10:40 -03001109void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001110{
Hans Verkuil314527a2013-03-15 06:10:40 -03001111 itv->std = std;
1112 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001113 itv->is_50hz = !itv->is_60hz;
1114 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1115 itv->cxhdl.width = 720;
1116 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001117 itv->vbi.count = itv->is_50hz ? 18 : 12;
1118 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1119 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1120
1121 if (itv->hw_flags & IVTV_HW_CX25840)
1122 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1123
Hans Verkuil3f038d82008-05-29 16:43:54 -03001124 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001125 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001126}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001127
Hans Verkuil314527a2013-03-15 06:10:40 -03001128void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001129{
1130 struct yuv_playback_info *yi = &itv->yuv_info;
1131 DEFINE_WAIT(wait);
1132 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001133
Ian Armstrongc5874c92011-05-29 21:33:17 -03001134 /* set display standard */
Hans Verkuil314527a2013-03-15 06:10:40 -03001135 itv->std_out = std;
1136 itv->is_out_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Ian Armstrongc5874c92011-05-29 21:33:17 -03001137 itv->is_out_50hz = !itv->is_out_60hz;
1138 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001139
Ian Armstrongc5874c92011-05-29 21:33:17 -03001140 /*
1141 * The next firmware call is time sensitive. Time it to
1142 * avoid risk of a hard lock, by trying to ensure the call
1143 * happens within the first 100 lines of the top field.
1144 * Make 4 attempts to sync to the decoder before giving up.
1145 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001146 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001147 for (f = 0; f < 4; f++) {
1148 prepare_to_wait(&itv->vsync_waitq, &wait,
1149 TASK_UNINTERRUPTIBLE);
1150 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1151 break;
1152 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001153 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001154 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001155 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001156
1157 if (f == 4)
1158 IVTV_WARN("Mode change failed to sync to decoder\n");
1159
1160 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1161 itv->main_rect.left = 0;
1162 itv->main_rect.top = 0;
1163 itv->main_rect.width = 720;
1164 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1165 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1166 720, itv->main_rect.height, 0, 0);
1167 yi->main_rect = itv->main_rect;
1168 if (!itv->osd_info) {
1169 yi->osd_full_w = 720;
1170 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1171 }
1172}
1173
Hans Verkuil314527a2013-03-15 06:10:40 -03001174static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001175{
1176 struct ivtv *itv = fh2id(fh)->itv;
1177
Hans Verkuil314527a2013-03-15 06:10:40 -03001178 if ((std & V4L2_STD_ALL) == 0)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001179 return -EINVAL;
1180
Hans Verkuil314527a2013-03-15 06:10:40 -03001181 if (std == itv->std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001182 return 0;
1183
1184 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1185 atomic_read(&itv->capturing) > 0 ||
1186 atomic_read(&itv->decoding) > 0) {
1187 /* Switching standard would mess with already running
1188 streams, prevent that by returning EBUSY. */
1189 return -EBUSY;
1190 }
1191
1192 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1193 (unsigned long long)itv->std);
1194
1195 ivtv_s_std_enc(itv, std);
1196 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1197 ivtv_s_std_dec(itv, std);
1198
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001199 return 0;
1200}
1201
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001202static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001203{
Hans Verkuil2f824412011-03-12 06:43:28 -03001204 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001205 struct ivtv *itv = id->itv;
1206
1207 if (vt->index != 0)
1208 return -EINVAL;
1209
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001210 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001211
1212 return 0;
1213}
1214
1215static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1216{
Hans Verkuil2f824412011-03-12 06:43:28 -03001217 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001218
1219 if (vt->index != 0)
1220 return -EINVAL;
1221
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001222 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001223
Hans Verkuild118e292011-06-25 10:28:21 -03001224 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001225 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001226 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001227 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001228 return 0;
1229}
1230
1231static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1232{
Hans Verkuil2f824412011-03-12 06:43:28 -03001233 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001234 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1235 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001236
Hans Verkuil79afcb12008-06-21 09:02:36 -03001237 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001238 for (f = 0; f < 2; f++) {
1239 for (l = 0; l < 24; l++) {
1240 if (valid_service_line(f, l, itv->is_50hz))
1241 cap->service_lines[f][l] = set;
1242 }
1243 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001244 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001245 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1246 return -EINVAL;
1247 if (itv->is_60hz) {
1248 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1249 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1250 } else {
1251 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1252 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1253 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001254 } else {
1255 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001256 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001257
1258 set = 0;
1259 for (f = 0; f < 2; f++)
1260 for (l = 0; l < 24; l++)
1261 set |= cap->service_lines[f][l];
1262 cap->service_set = set;
1263 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001264}
1265
1266static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1267{
Hans Verkuil2f824412011-03-12 06:43:28 -03001268 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001269 struct v4l2_enc_idx_entry *e = idx->entry;
1270 int entries;
1271 int i;
1272
1273 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1274 IVTV_MAX_PGM_INDEX;
1275 if (entries > V4L2_ENC_IDX_ENTRIES)
1276 entries = V4L2_ENC_IDX_ENTRIES;
1277 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001278 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1279 if (!atomic_read(&itv->capturing))
1280 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001281 for (i = 0; i < entries; i++) {
1282 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1283 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1284 idx->entries++;
1285 e++;
1286 }
1287 }
1288 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1289 return 0;
1290}
1291
1292static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1293{
Hans Verkuil2f824412011-03-12 06:43:28 -03001294 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001295 struct ivtv *itv = id->itv;
1296
Hans Verkuil3f038d82008-05-29 16:43:54 -03001297
1298 switch (enc->cmd) {
1299 case V4L2_ENC_CMD_START:
1300 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1301 enc->flags = 0;
1302 return ivtv_start_capture(id);
1303
1304 case V4L2_ENC_CMD_STOP:
1305 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1306 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1307 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1308 return 0;
1309
1310 case V4L2_ENC_CMD_PAUSE:
1311 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1312 enc->flags = 0;
1313
1314 if (!atomic_read(&itv->capturing))
1315 return -EPERM;
1316 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1317 return 0;
1318
1319 ivtv_mute(itv);
1320 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1321 break;
1322
1323 case V4L2_ENC_CMD_RESUME:
1324 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1325 enc->flags = 0;
1326
1327 if (!atomic_read(&itv->capturing))
1328 return -EPERM;
1329
1330 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1331 return 0;
1332
1333 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1334 ivtv_unmute(itv);
1335 break;
1336 default:
1337 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1338 return -EINVAL;
1339 }
1340
1341 return 0;
1342}
1343
1344static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1345{
Hans Verkuil2f824412011-03-12 06:43:28 -03001346 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001347
Hans Verkuil3f038d82008-05-29 16:43:54 -03001348 switch (enc->cmd) {
1349 case V4L2_ENC_CMD_START:
1350 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1351 enc->flags = 0;
1352 return 0;
1353
1354 case V4L2_ENC_CMD_STOP:
1355 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1356 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1357 return 0;
1358
1359 case V4L2_ENC_CMD_PAUSE:
1360 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1361 enc->flags = 0;
1362 return 0;
1363
1364 case V4L2_ENC_CMD_RESUME:
1365 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1366 enc->flags = 0;
1367 return 0;
1368 default:
1369 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1370 return -EINVAL;
1371 }
1372}
1373
1374static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1375{
Hans Verkuil2f824412011-03-12 06:43:28 -03001376 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001377 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001378 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001379
Hans Verkuil3f038d82008-05-29 16:43:54 -03001380 int pixfmt;
1381 static u32 pixel_format[16] = {
1382 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1383 V4L2_PIX_FMT_RGB565,
1384 V4L2_PIX_FMT_RGB555,
1385 V4L2_PIX_FMT_RGB444,
1386 V4L2_PIX_FMT_RGB32,
1387 0,
1388 0,
1389 0,
1390 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1391 V4L2_PIX_FMT_YUV565,
1392 V4L2_PIX_FMT_YUV555,
1393 V4L2_PIX_FMT_YUV444,
1394 V4L2_PIX_FMT_YUV32,
1395 0,
1396 0,
1397 0,
1398 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001399
Hans Verkuil3f038d82008-05-29 16:43:54 -03001400 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1401 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001402 if (!itv->osd_video_pbase)
1403 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001404
Hans Verkuil3f038d82008-05-29 16:43:54 -03001405 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1406 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001407
Hans Verkuil3f038d82008-05-29 16:43:54 -03001408 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1409 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1410 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001411
Hans Verkuil3f038d82008-05-29 16:43:54 -03001412 fb->fmt.pixelformat = pixel_format[pixfmt];
1413 fb->fmt.width = itv->osd_rect.width;
1414 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001415 fb->fmt.field = V4L2_FIELD_INTERLACED;
1416 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001417 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1418 fb->fmt.field = V4L2_FIELD_INTERLACED;
1419 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001420 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1421 fb->fmt.bytesperline *= 2;
1422 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1423 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1424 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001425 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001426 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001427 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001428
Hans Verkuil3f038d82008-05-29 16:43:54 -03001429 if (itv->osd_chroma_key_state)
1430 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001431
Hans Verkuil3f038d82008-05-29 16:43:54 -03001432 if (itv->osd_global_alpha_state)
1433 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001434
Ian Armstrongec9faa12008-10-06 03:06:08 -03001435 if (yi->track_osd)
1436 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1437
Hans Verkuil3f038d82008-05-29 16:43:54 -03001438 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001439
Hans Verkuil3f038d82008-05-29 16:43:54 -03001440 /* no local alpha for RGB565 or unknown formats */
1441 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001442 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001443
Hans Verkuil3f038d82008-05-29 16:43:54 -03001444 /* 16-bit formats have inverted local alpha */
1445 if (pixfmt == 2 || pixfmt == 3)
1446 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1447 else
1448 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001449
Hans Verkuil3f038d82008-05-29 16:43:54 -03001450 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001451 /* 16-bit formats have inverted local alpha */
1452 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001453 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001454 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001455 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001456 }
1457
Hans Verkuil3f038d82008-05-29 16:43:54 -03001458 return 0;
1459}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001460
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001461static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001462{
Hans Verkuil2f824412011-03-12 06:43:28 -03001463 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001464 struct ivtv *itv = id->itv;
1465 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001466
Hans Verkuil3f038d82008-05-29 16:43:54 -03001467 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001468 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001469 if (!itv->osd_video_pbase)
1470 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001471
1472 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1473 itv->osd_local_alpha_state =
1474 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1475 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1476 ivtv_set_osd_alpha(itv);
1477 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001478 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001479}
1480
1481static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1482{
Hans Verkuil2f824412011-03-12 06:43:28 -03001483 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001484 struct ivtv *itv = id->itv;
1485
1486 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1487 return -EINVAL;
1488
1489 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1490
1491 return 0;
1492}
1493
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001494static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001495{
1496 switch (sub->type) {
1497 case V4L2_EVENT_VSYNC:
1498 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001499 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001500 case V4L2_EVENT_CTRL:
1501 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001502 default:
1503 return -EINVAL;
1504 }
Hans Verkuil09250192010-03-27 14:10:13 -03001505}
1506
Hans Verkuil3f038d82008-05-29 16:43:54 -03001507static int ivtv_log_status(struct file *file, void *fh)
1508{
Hans Verkuil2f824412011-03-12 06:43:28 -03001509 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001510 u32 data[CX2341X_MBOX_MAX_DATA];
1511
1512 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1513 struct v4l2_input vidin;
1514 struct v4l2_audio audin;
1515 int i;
1516
Hans Verkuil3f038d82008-05-29 16:43:54 -03001517 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1518 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1519 struct tveeprom tv;
1520
1521 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001522 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001523 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001524 ivtv_get_input(itv, itv->active_input, &vidin);
1525 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1526 IVTV_INFO("Video Input: %s\n", vidin.name);
1527 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1528 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1529 if (has_output) {
1530 struct v4l2_output vidout;
1531 struct v4l2_audioout audout;
1532 int mode = itv->output_mode;
1533 static const char * const output_modes[5] = {
1534 "None",
1535 "MPEG Streaming",
1536 "YUV Streaming",
1537 "YUV Frames",
1538 "Passthrough",
1539 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001540 static const char * const alpha_mode[4] = {
1541 "None",
1542 "Global",
1543 "Local",
1544 "Global and Local"
1545 };
1546 static const char * const pixel_format[16] = {
1547 "ARGB Indexed",
1548 "RGB 5:6:5",
1549 "ARGB 1:5:5:5",
1550 "ARGB 1:4:4:4",
1551 "ARGB 8:8:8:8",
1552 "5",
1553 "6",
1554 "7",
1555 "AYUV Indexed",
1556 "YUV 5:6:5",
1557 "AYUV 1:5:5:5",
1558 "AYUV 1:4:4:4",
1559 "AYUV 8:8:8:8",
1560 "13",
1561 "14",
1562 "15",
1563 };
1564
1565 ivtv_get_output(itv, itv->active_output, &vidout);
1566 ivtv_get_audio_output(itv, 0, &audout);
1567 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001568 if (mode < 0 || mode > OUT_PASSTHROUGH)
1569 mode = OUT_NONE;
1570 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1571 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1572 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1573 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1574 data[0] & 1 ? "On" : "Off",
1575 alpha_mode[(data[0] >> 1) & 0x3],
1576 pixel_format[(data[0] >> 3) & 0xf]);
1577 }
1578 IVTV_INFO("Tuner: %s\n",
1579 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001580 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001581 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1582 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1583 struct ivtv_stream *s = &itv->streams[i];
1584
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001585 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001586 continue;
1587 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1588 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1589 (s->buffers * s->buf_size) / 1024, s->buffers);
1590 }
1591
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001592 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1593 (long long)itv->mpg_data_received,
1594 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001595 return 0;
1596}
1597
Hans Verkuilda8ec562011-11-24 09:58:53 -03001598static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1599{
1600 struct ivtv_open_id *id = fh2id(file->private_data);
1601 struct ivtv *itv = id->itv;
1602
1603 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1604 return ivtv_video_command(itv, id, dec, false);
1605}
1606
1607static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1608{
1609 struct ivtv_open_id *id = fh2id(file->private_data);
1610 struct ivtv *itv = id->itv;
1611
1612 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1613 return ivtv_video_command(itv, id, dec, true);
1614}
1615
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001616static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001617{
Hans Verkuil09250192010-03-27 14:10:13 -03001618 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001619 struct ivtv *itv = id->itv;
1620 int nonblocking = filp->f_flags & O_NONBLOCK;
1621 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001622 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001623
1624 switch (cmd) {
1625 case IVTV_IOC_DMA_FRAME: {
1626 struct ivtv_dma_frame *args = arg;
1627
1628 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1629 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1630 return -EINVAL;
1631 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1632 return -EINVAL;
1633 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1634 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001635 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001636 return -EBUSY;
1637 }
1638 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1639 ivtv_release_stream(s);
1640 return -EBUSY;
1641 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001642 /* Mark that this file handle started the UDMA_YUV mode */
1643 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001644 if (args->y_source == NULL)
1645 return 0;
1646 return ivtv_yuv_prep_frame(itv, args);
1647 }
1648
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001649 case IVTV_IOC_PASSTHROUGH_MODE:
1650 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1651 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1652 return -EINVAL;
1653 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1654
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001655 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001656 s64 *pts = arg;
1657 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001658
1659 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1660 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1661 *pts = s->dma_pts;
1662 break;
1663 }
1664 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1665 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001666 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001667 }
1668
1669 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001670 s64 *frame = arg;
1671 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001672
1673 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1674 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1675 *frame = 0;
1676 break;
1677 }
1678 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1679 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001680 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001681 }
1682
1683 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001684 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001685
1686 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001687 memset(&dc, 0, sizeof(dc));
1688 dc.cmd = V4L2_DEC_CMD_START;
1689 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001690 }
1691
1692 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001693 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001694
1695 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001696 memset(&dc, 0, sizeof(dc));
1697 dc.cmd = V4L2_DEC_CMD_STOP;
1698 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1699 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001700 }
1701
1702 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001703 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001704
1705 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001706 memset(&dc, 0, sizeof(dc));
1707 dc.cmd = V4L2_DEC_CMD_PAUSE;
1708 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001709 }
1710
1711 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001712 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001713
1714 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001715 memset(&dc, 0, sizeof(dc));
1716 dc.cmd = V4L2_DEC_CMD_RESUME;
1717 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001718 }
1719
1720 case VIDEO_COMMAND:
1721 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001722 /* Note: struct v4l2_decoder_cmd has the same layout as
1723 struct video_command */
1724 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001725 int try = (cmd == VIDEO_TRY_COMMAND);
1726
1727 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001728 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001729 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001730 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1731 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001732 }
1733
1734 case VIDEO_GET_EVENT: {
1735 struct video_event *ev = arg;
1736 DEFINE_WAIT(wait);
1737
1738 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1739 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1740 return -EINVAL;
1741 memset(ev, 0, sizeof(*ev));
1742 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1743
1744 while (1) {
1745 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1746 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1747 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1748 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001749 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1750 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1751 if (itv->output_mode == OUT_UDMA_YUV &&
1752 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1753 IVTV_YUV_MODE_PROGRESSIVE) {
1754 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1755 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001756 }
1757 if (ev->type)
1758 return 0;
1759 if (nonblocking)
1760 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001761 /* Wait for event. Note that serialize_lock is locked,
1762 so to allow other processes to access the driver while
1763 we are waiting unlock first and later lock again. */
1764 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001765 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001766 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1767 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001768 schedule();
1769 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001770 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001771 if (signal_pending(current)) {
1772 /* return if a signal was received */
1773 IVTV_DEBUG_INFO("User stopped wait for event\n");
1774 return -EINTR;
1775 }
1776 }
1777 break;
1778 }
1779
Hans Verkuilce680252010-04-06 15:58:53 -03001780 case VIDEO_SELECT_SOURCE:
1781 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1782 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1783 return -EINVAL;
1784 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1785
1786 case AUDIO_SET_MUTE:
1787 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1788 itv->speed_mute_audio = iarg;
1789 return 0;
1790
1791 case AUDIO_CHANNEL_SELECT:
1792 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1793 if (iarg > AUDIO_STEREO_SWAPPED)
1794 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001795 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001796
1797 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1798 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1799 if (iarg > AUDIO_STEREO_SWAPPED)
1800 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001801 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001802
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001803 default:
1804 return -EINVAL;
1805 }
1806 return 0;
1807}
1808
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001809static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1810 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001811{
Hans Verkuil2f824412011-03-12 06:43:28 -03001812 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001813
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001814 if (!valid_prio) {
1815 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001816 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001817 case VIDEO_PLAY:
1818 case VIDEO_STOP:
1819 case VIDEO_FREEZE:
1820 case VIDEO_CONTINUE:
1821 case VIDEO_COMMAND:
1822 case VIDEO_SELECT_SOURCE:
1823 case AUDIO_SET_MUTE:
1824 case AUDIO_CHANNEL_SELECT:
1825 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1826 return -EBUSY;
1827 }
1828 }
1829
Hans Verkuild46c17d2007-03-10 17:59:15 -03001830 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001831 case VIDIOC_INT_RESET: {
1832 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001833
Hans Verkuil3f038d82008-05-29 16:43:54 -03001834 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1835 ivtv_reset_ir_gpio(itv);
1836 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001837 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001838 break;
1839 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001840
Hans Verkuilac9575f2009-02-14 19:58:33 -03001841 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001842 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001843 case VIDEO_GET_PTS:
1844 case VIDEO_GET_FRAME_COUNT:
1845 case VIDEO_GET_EVENT:
1846 case VIDEO_PLAY:
1847 case VIDEO_STOP:
1848 case VIDEO_FREEZE:
1849 case VIDEO_CONTINUE:
1850 case VIDEO_COMMAND:
1851 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001852 case VIDEO_SELECT_SOURCE:
1853 case AUDIO_SET_MUTE:
1854 case AUDIO_CHANNEL_SELECT:
1855 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001856 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1857
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001858 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001859 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001860 }
1861 return 0;
1862}
1863
Hans Verkuila3998102008-07-21 02:57:38 -03001864static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1865 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001866 .vidioc_s_audio = ivtv_s_audio,
1867 .vidioc_g_audio = ivtv_g_audio,
1868 .vidioc_enumaudio = ivtv_enumaudio,
1869 .vidioc_s_audout = ivtv_s_audout,
1870 .vidioc_g_audout = ivtv_g_audout,
1871 .vidioc_enum_input = ivtv_enum_input,
1872 .vidioc_enum_output = ivtv_enum_output,
1873 .vidioc_enumaudout = ivtv_enumaudout,
1874 .vidioc_cropcap = ivtv_cropcap,
1875 .vidioc_s_crop = ivtv_s_crop,
1876 .vidioc_g_crop = ivtv_g_crop,
1877 .vidioc_g_input = ivtv_g_input,
1878 .vidioc_s_input = ivtv_s_input,
1879 .vidioc_g_output = ivtv_g_output,
1880 .vidioc_s_output = ivtv_s_output,
1881 .vidioc_g_frequency = ivtv_g_frequency,
1882 .vidioc_s_frequency = ivtv_s_frequency,
1883 .vidioc_s_tuner = ivtv_s_tuner,
1884 .vidioc_g_tuner = ivtv_g_tuner,
1885 .vidioc_g_enc_index = ivtv_g_enc_index,
1886 .vidioc_g_fbuf = ivtv_g_fbuf,
1887 .vidioc_s_fbuf = ivtv_s_fbuf,
1888 .vidioc_g_std = ivtv_g_std,
1889 .vidioc_s_std = ivtv_s_std,
1890 .vidioc_overlay = ivtv_overlay,
1891 .vidioc_log_status = ivtv_log_status,
1892 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1893 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1894 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001895 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1896 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001897 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1898 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1899 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1900 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1901 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1902 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1903 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1904 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1905 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1906 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1907 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1908 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1909 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1910 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1911 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1912 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1913 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1914 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1915 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1916 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1917 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1918#ifdef CONFIG_VIDEO_ADV_DEBUG
1919 .vidioc_g_register = ivtv_g_register,
1920 .vidioc_s_register = ivtv_s_register,
1921#endif
1922 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001923 .vidioc_subscribe_event = ivtv_subscribe_event,
1924 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001925};
1926
Hans Verkuil3f038d82008-05-29 16:43:54 -03001927void ivtv_set_funcs(struct video_device *vdev)
1928{
Hans Verkuila3998102008-07-21 02:57:38 -03001929 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001930}