blob: b686da5e432661390d3dfcc1a42c5d3726761675 [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];
138 struct ivtv_stream *s;
139 int single_step = (speed == 1 || speed == -1);
140 DEFINE_WAIT(wait);
141
142 if (speed == 0) speed = 1000;
143
144 /* No change? */
145 if (speed == itv->speed && !single_step)
146 return 0;
147
148 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
149
150 if (single_step && (speed < 0) == (itv->speed < 0)) {
151 /* Single step video and no need to change direction */
152 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
153 itv->speed = speed;
154 return 0;
155 }
156 if (single_step)
157 /* Need to change direction */
158 speed = speed < 0 ? -1000 : 1000;
159
160 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
161 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
162 data[1] = (speed < 0);
163 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300164 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300165 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
166 data[5] = 0;
167 data[6] = 0;
168
169 if (speed == 1500 || speed == -1500) data[0] |= 1;
170 else if (speed == 2000 || speed == -2000) data[0] |= 2;
171 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
172 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
173
174 /* If not decoding, just change speed setting */
175 if (atomic_read(&itv->decoding) > 0) {
176 int got_sig = 0;
177
178 /* Stop all DMA and decoding activity */
179 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
180
181 /* Wait for any DMA to finish */
182 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -0300183 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300184 got_sig = signal_pending(current);
185 if (got_sig)
186 break;
187 got_sig = 0;
188 schedule();
189 }
190 finish_wait(&itv->dma_waitq, &wait);
191 if (got_sig)
192 return -EINTR;
193
194 /* Change Speed safely */
195 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
196 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
197 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
198 }
199 if (single_step) {
200 speed = (speed < 0) ? -1 : 1;
201 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
202 }
203 itv->speed = speed;
204 return 0;
205}
206
207static int ivtv_validate_speed(int cur_speed, int new_speed)
208{
209 int fact = new_speed < 0 ? -1 : 1;
210 int s;
211
Hans Verkuil94dee762008-04-26 09:26:13 -0300212 if (cur_speed == 0)
213 cur_speed = 1000;
214 if (new_speed < 0)
215 new_speed = -new_speed;
216 if (cur_speed < 0)
217 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300218
219 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300220 if (new_speed > 1500)
221 return fact * 2000;
222 if (new_speed > 1000)
223 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300224 }
225 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300226 if (new_speed >= 2000)
227 return fact * 2000;
228 if (new_speed >= 1500)
229 return fact * 1500;
230 if (new_speed >= 1000)
231 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300232 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300233 if (new_speed == 0)
234 return 1000;
235 if (new_speed == 1 || new_speed == 1000)
236 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300237
238 s = new_speed;
239 new_speed = 1000 / new_speed;
240 if (1000 / cur_speed == new_speed)
241 new_speed += (cur_speed < s) ? -1 : 1;
242 if (new_speed > 60) return 1000 / (fact * 60);
243 return 1000 / (fact * new_speed);
244}
245
246static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
247 struct video_command *vc, int try)
248{
249 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
250
251 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
252 return -EINVAL;
253
254 switch (vc->cmd) {
255 case VIDEO_CMD_PLAY: {
Hans Verkuil25415cf2007-03-10 18:29:48 -0300256 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300257 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
258 if (vc->play.speed < 0)
259 vc->play.format = VIDEO_PLAY_FMT_GOP;
260 if (try) break;
261
262 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
263 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300264 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
265 /* forces ivtv_set_speed to be called */
266 itv->speed = 0;
267 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300268 return ivtv_start_decoding(id, vc->play.speed);
269 }
270
271 case VIDEO_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -0300272 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300273 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
274 vc->stop.pts = 0;
275 if (try) break;
276 if (atomic_read(&itv->decoding) == 0)
277 return 0;
278 if (itv->output_mode != OUT_MPG)
279 return -EBUSY;
280
281 itv->output_mode = OUT_NONE;
282 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
283
284 case VIDEO_CMD_FREEZE:
Hans Verkuil018ba852007-04-10 18:59:09 -0300285 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300286 if (try) break;
287 if (itv->output_mode != OUT_MPG)
288 return -EBUSY;
289 if (atomic_read(&itv->decoding) > 0) {
290 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
291 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300292 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300293 }
294 break;
295
296 case VIDEO_CMD_CONTINUE:
Hans Verkuil25415cf2007-03-10 18:29:48 -0300297 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300298 if (try) break;
299 if (itv->output_mode != OUT_MPG)
300 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300301 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
302 int speed = itv->speed;
303 itv->speed = 0;
304 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300305 }
306 break;
307
308 default:
309 return -EINVAL;
310 }
311 return 0;
312}
313
Hans Verkuil3f038d82008-05-29 16:43:54 -0300314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300315{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300316 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300318
Hans Verkuile88360c2008-06-21 08:00:56 -0300319 vbifmt->reserved[0] = 0;
320 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300321 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300322 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300323 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
324 if (itv->is_60hz) {
325 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
326 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
327 } else {
328 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
329 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
330 }
331 vbifmt->service_set = ivtv_get_service_set(vbifmt);
332 return 0;
333}
334
335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
336{
337 struct ivtv_open_id *id = fh;
338 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300340
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300341 pixfmt->width = itv->cxhdl.width;
342 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300343 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
344 pixfmt->field = V4L2_FIELD_INTERLACED;
345 pixfmt->priv = 0;
346 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
347 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300348 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
349 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300350 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300351 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300352 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
353 pixfmt->sizeimage = 128 * 1024;
354 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300355 }
356 return 0;
357}
358
Hans Verkuil3f038d82008-05-29 16:43:54 -0300359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300360{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300361 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300363
Hans Verkuile88360c2008-06-21 08:00:56 -0300364 vbifmt->sampling_rate = 27000000;
365 vbifmt->offset = 248;
366 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
367 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
368 vbifmt->start[0] = itv->vbi.start[0];
369 vbifmt->start[1] = itv->vbi.start[1];
370 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
371 vbifmt->flags = 0;
372 vbifmt->reserved[0] = 0;
373 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300374 return 0;
375}
376
377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
378{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300380 struct ivtv_open_id *id = fh;
381 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300382
Hans Verkuile88360c2008-06-21 08:00:56 -0300383 vbifmt->reserved[0] = 0;
384 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300385 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300386
Hans Verkuil3f038d82008-05-29 16:43:54 -0300387 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
388 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
389 V4L2_SLICED_VBI_525;
390 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300391 return 0;
392 }
393
Hans Verkuil4ff07902010-03-14 12:18:18 -0300394 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 vbifmt->service_set = ivtv_get_service_set(vbifmt);
396 return 0;
397}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300398
Hans Verkuil3f038d82008-05-29 16:43:54 -0300399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
400{
401 struct ivtv_open_id *id = fh;
402 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300404
Hans Verkuil3f038d82008-05-29 16:43:54 -0300405 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300406 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300407 pixfmt->width = itv->main_rect.width;
408 pixfmt->height = itv->main_rect.height;
409 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
410 pixfmt->field = V4L2_FIELD_INTERLACED;
411 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300412 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
413 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
414 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300415 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300416 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
417 break;
418 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300419 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300420 break;
421 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300422 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300423 break;
424 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300425 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
426 pixfmt->bytesperline = 720;
427 pixfmt->width = itv->yuv_info.v4l2_src_w;
428 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300429 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->sizeimage =
431 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300432 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
434 pixfmt->sizeimage = 128 * 1024;
435 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300436 }
437 return 0;
438}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300439
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
441{
442 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300443 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300444
445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
446 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300447 winfmt->chromakey = itv->osd_chroma_key;
448 winfmt->global_alpha = itv->osd_global_alpha;
449 winfmt->field = V4L2_FIELD_INTERLACED;
450 winfmt->clips = NULL;
451 winfmt->clipcount = 0;
452 winfmt->bitmap = NULL;
453 winfmt->w.top = winfmt->w.left = 0;
454 winfmt->w.width = itv->osd_rect.width;
455 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300456 return 0;
457}
458
459static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
460{
461 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
462}
463
464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
465{
466 struct ivtv_open_id *id = fh;
467 struct ivtv *itv = id->itv;
468 int w = fmt->fmt.pix.width;
469 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300470 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300471
472 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300473 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300474 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
475 /* YUV height must be a multiple of 32 */
476 h &= ~0x1f;
477 min_h = 32;
478 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300479 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300480 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300481 ivtv_g_fmt_vid_cap(file, fh, fmt);
482 fmt->fmt.pix.width = w;
483 fmt->fmt.pix.height = h;
484 return 0;
485}
486
487static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
488{
489 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
490}
491
492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
493{
494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
495 struct ivtv_open_id *id = fh;
496 struct ivtv *itv = id->itv;
497
498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
499 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300500
501 /* set sliced VBI capture format */
502 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300503 vbifmt->reserved[0] = 0;
504 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300505
506 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300507 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300508 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300509 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300510 return 0;
511}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300512
Hans Verkuil3f038d82008-05-29 16:43:54 -0300513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
514{
515 struct ivtv_open_id *id = fh;
Hans Verkuileffc3462008-09-06 08:24:37 -0300516 s32 w = fmt->fmt.pix.width;
517 s32 h = fmt->fmt.pix.height;
518 int field = fmt->fmt.pix.field;
519 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300520
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300521 w = min(w, 720);
522 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300523 /* Why can the height be 576 even when the output is NTSC?
524
525 Internally the buffers of the PVR350 are always set to 720x576. The
526 decoded video frame will always be placed in the top left corner of
527 this buffer. For any video which is not 720x576, the buffer will
528 then be cropped to remove the unused right and lower areas, with
529 the remaining image being scaled by the hardware to fit the display
530 area. The video can be scaled both up and down, so a 720x480 video
531 can be displayed full-screen on PAL and a 720x576 video can be
532 displayed without cropping on NTSC.
533
534 Note that the scaling only occurs on the video stream, the osd
535 resolution is locked to the broadcast standard and not scaled.
536
537 Thanks to Ian Armstrong for this explanation. */
538 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300539 h = max(h, 2);
540 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300541 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300542 fmt->fmt.pix.width = w;
543 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300544 return ret;
545}
546
547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
548{
549 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300550 u32 chromakey = fmt->fmt.win.chromakey;
551 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552
553 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
554 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300555 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
556 fmt->fmt.win.chromakey = chromakey;
557 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300558 return 0;
559}
560
561static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
562{
563 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
564}
565
566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
567{
568 struct ivtv_open_id *id = fh;
569 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300570 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300572 int w = fmt->fmt.pix.width;
573 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300574
575 if (ret)
576 return ret;
577
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300578 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300579 return 0;
580
581 if (atomic_read(&itv->capturing) > 0)
582 return -EBUSY;
583
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300584 itv->cxhdl.width = w;
585 itv->cxhdl.height = h;
586 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300587 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300588 mbus_fmt.width = fmt->fmt.pix.width;
589 mbus_fmt.height = h;
590 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
591 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300592 return ivtv_g_fmt_vid_cap(file, fh, fmt);
593}
594
595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
596{
597 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
598
Hans Verkuila8b86432008-10-04 08:05:30 -0300599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
600 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300601 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300602 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300603 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300604 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
605}
606
607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
608{
609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
610 struct ivtv_open_id *id = fh;
611 struct ivtv *itv = id->itv;
612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
613
614 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
615 return ret;
616
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300617 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300618 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300619 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300620 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300621 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300622 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
623 return 0;
624}
625
Hans Verkuil3f038d82008-05-29 16:43:54 -0300626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300627{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300628 struct ivtv_open_id *id = fh;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300629 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300630 struct yuv_playback_info *yi = &itv->yuv_info;
631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300632
Hans Verkuil3f038d82008-05-29 16:43:54 -0300633 if (ret)
634 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300635
Hans Verkuil3f038d82008-05-29 16:43:54 -0300636 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
637 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300638
Hans Verkuil3f038d82008-05-29 16:43:54 -0300639 /* Return now if we already have some frame data */
640 if (yi->stream_size)
641 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300642
Hans Verkuil3f038d82008-05-29 16:43:54 -0300643 yi->v4l2_src_w = fmt->fmt.pix.width;
644 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300645
Hans Verkuil3f038d82008-05-29 16:43:54 -0300646 switch (fmt->fmt.pix.field) {
647 case V4L2_FIELD_NONE:
648 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300649 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300650 case V4L2_FIELD_ANY:
651 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300652 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300653 case V4L2_FIELD_INTERLACED_BT:
654 yi->lace_mode =
655 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
656 break;
657 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300658 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300659 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
660 break;
661 }
662 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
663
664 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
665 itv->dma_data_req_size =
666 1080 * ((yi->v4l2_src_h + 31) & ~31);
667
Hans Verkuil3f038d82008-05-29 16:43:54 -0300668 return 0;
669}
670
671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
672{
673 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
675
676 if (ret == 0) {
677 itv->osd_chroma_key = fmt->fmt.win.chromakey;
678 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
679 ivtv_set_osd_alpha(itv);
680 }
681 return ret;
682}
683
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300685{
686 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
687
688 chip->ident = V4L2_IDENT_NONE;
689 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300690 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
691 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300692 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
693 return 0;
694 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300695 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
696 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300697 return -EINVAL;
698 /* TODO: is this correct? */
699 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300700}
701
Hans Verkuil36ecd492008-06-25 06:00:17 -0300702#ifdef CONFIG_VIDEO_ADV_DEBUG
703static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
704{
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300705 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300706 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300707
708 if (!capable(CAP_SYS_ADMIN))
709 return -EPERM;
710 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
711 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
712 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
713 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
714 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300715 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300716 reg_start = itv->enc_mem;
717 else
718 return -EINVAL;
719
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300720 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300721 if (cmd == VIDIOC_DBG_G_REGISTER)
722 regs->val = readl(regs->reg + reg_start);
723 else
724 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300725 return 0;
726}
727
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300729{
730 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
731
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300732 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300734 /* TODO: subdev errors should not be ignored, this should become a
735 subdev helper function. */
736 ivtv_call_all(itv, core, g_register, reg);
737 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300738}
739
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741{
742 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
743
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300744 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300746 /* TODO: subdev errors should not be ignored, this should become a
747 subdev helper function. */
748 ivtv_call_all(itv, core, s_register, reg);
749 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300750}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300751#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752
753static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
754{
755 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
756
757 *p = v4l2_prio_max(&itv->prio);
758
759 return 0;
760}
761
762static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
763{
764 struct ivtv_open_id *id = fh;
765 struct ivtv *itv = id->itv;
766
767 return v4l2_prio_change(&itv->prio, &id->prio, prio);
768}
769
770static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
771{
772 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
773
Hans Verkuil3f038d82008-05-29 16:43:54 -0300774 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
775 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300776 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300777 vcap->version = IVTV_DRIVER_VERSION; /* version */
778 vcap->capabilities = itv->v4l2_cap; /* capabilities */
Hans Verkuil3f038d82008-05-29 16:43:54 -0300779 return 0;
780}
781
782static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
783{
784 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
785
786 return ivtv_get_audio_input(itv, vin->index, vin);
787}
788
789static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
790{
791 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
792
793 vin->index = itv->audio_input;
794 return ivtv_get_audio_input(itv, vin->index, vin);
795}
796
797static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
798{
799 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
800
801 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300802 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300803
804 itv->audio_input = vout->index;
805 ivtv_audio_set_io(itv);
806
807 return 0;
808}
809
810static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
811{
812 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
813
814 /* set it to defaults from our table */
815 return ivtv_get_audio_output(itv, vin->index, vin);
816}
817
818static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
819{
820 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
821
822 vin->index = 0;
823 return ivtv_get_audio_output(itv, vin->index, vin);
824}
825
826static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
827{
828 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
829
830 return ivtv_get_audio_output(itv, vout->index, vout);
831}
832
833static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
834{
835 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
836
837 /* set it to defaults from our table */
838 return ivtv_get_input(itv, vin->index, vin);
839}
840
841static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
842{
843 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
844
845 return ivtv_get_output(itv, vout->index, vout);
846}
847
848static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
849{
850 struct ivtv_open_id *id = fh;
851 struct ivtv *itv = id->itv;
852 struct yuv_playback_info *yi = &itv->yuv_info;
853 int streamtype;
854
855 streamtype = id->type;
856
857 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
858 return -EINVAL;
859 cropcap->bounds.top = cropcap->bounds.left = 0;
860 cropcap->bounds.width = 720;
861 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
862 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
863 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
864 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
865 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
866 if (yi->track_osd) {
867 cropcap->bounds.width = yi->osd_full_w;
868 cropcap->bounds.height = yi->osd_full_h;
869 } else {
870 cropcap->bounds.width = 720;
871 cropcap->bounds.height =
872 itv->is_out_50hz ? 576 : 480;
873 }
874 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
875 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
876 } else {
877 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
878 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
879 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
880 }
881 cropcap->defrect = cropcap->bounds;
882 return 0;
883}
884
885static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
886{
887 struct ivtv_open_id *id = fh;
888 struct ivtv *itv = id->itv;
889 struct yuv_playback_info *yi = &itv->yuv_info;
890 int streamtype;
891
892 streamtype = id->type;
893
Hans Verkuil3f038d82008-05-29 16:43:54 -0300894 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
895 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
896 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
897 yi->main_rect = crop->c;
898 return 0;
899 } else {
900 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
901 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
902 itv->main_rect = crop->c;
903 return 0;
904 }
905 }
906 return -EINVAL;
907 }
908 return -EINVAL;
909}
910
911static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
912{
913 struct ivtv_open_id *id = fh;
914 struct ivtv *itv = id->itv;
915 struct yuv_playback_info *yi = &itv->yuv_info;
916 int streamtype;
917
918 streamtype = id->type;
919
920 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
921 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
922 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
923 crop->c = yi->main_rect;
924 else
925 crop->c = itv->main_rect;
926 return 0;
927 }
928 return -EINVAL;
929}
930
931static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
932{
933 static struct v4l2_fmtdesc formats[] = {
934 { 0, 0, 0,
935 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
936 { 0, 0, 0, 0 }
937 },
938 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
939 "MPEG", V4L2_PIX_FMT_MPEG,
940 { 0, 0, 0, 0 }
941 }
942 };
943 enum v4l2_buf_type type = fmt->type;
944
945 if (fmt->index > 1)
946 return -EINVAL;
947
948 *fmt = formats[fmt->index];
949 fmt->type = type;
950 return 0;
951}
952
953static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
954{
955 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
956
957 static struct v4l2_fmtdesc formats[] = {
958 { 0, 0, 0,
959 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
960 { 0, 0, 0, 0 }
961 },
962 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
963 "MPEG", V4L2_PIX_FMT_MPEG,
964 { 0, 0, 0, 0 }
965 }
966 };
967 enum v4l2_buf_type type = fmt->type;
968
969 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
970 return -EINVAL;
971
972 if (fmt->index > 1)
973 return -EINVAL;
974
975 *fmt = formats[fmt->index];
976 fmt->type = type;
977
978 return 0;
979}
980
981static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
982{
983 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
984
985 *i = itv->active_input;
986
987 return 0;
988}
989
990int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
991{
992 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
993
994 if (inp < 0 || inp >= itv->nof_inputs)
995 return -EINVAL;
996
997 if (inp == itv->active_input) {
998 IVTV_DEBUG_INFO("Input unchanged\n");
999 return 0;
1000 }
1001
1002 if (atomic_read(&itv->capturing) > 0) {
1003 return -EBUSY;
1004 }
1005
1006 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1007 itv->active_input, inp);
1008
1009 itv->active_input = inp;
1010 /* Set the audio input to whatever is appropriate for the
1011 input type. */
1012 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1013
1014 /* prevent others from messing with the streams until
1015 we're finished changing inputs. */
1016 ivtv_mute(itv);
1017 ivtv_video_set_io(itv);
1018 ivtv_audio_set_io(itv);
1019 ivtv_unmute(itv);
1020
1021 return 0;
1022}
1023
1024static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1025{
1026 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1027
1028 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1029 return -EINVAL;
1030
1031 *i = itv->active_output;
1032
1033 return 0;
1034}
1035
1036static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1037{
1038 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001039
1040 if (outp >= itv->card->nof_outputs)
1041 return -EINVAL;
1042
1043 if (outp == itv->active_output) {
1044 IVTV_DEBUG_INFO("Output unchanged\n");
1045 return 0;
1046 }
1047 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1048 itv->active_output, outp);
1049
1050 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001051 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1052 SAA7127_INPUT_TYPE_NORMAL,
1053 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001054
1055 return 0;
1056}
1057
1058static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1059{
1060 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1061
1062 if (vf->tuner != 0)
1063 return -EINVAL;
1064
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001065 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001066 return 0;
1067}
1068
1069int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1070{
1071 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1072
1073 if (vf->tuner != 0)
1074 return -EINVAL;
1075
1076 ivtv_mute(itv);
1077 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001078 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001079 ivtv_unmute(itv);
1080 return 0;
1081}
1082
1083static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1084{
1085 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1086
1087 *std = itv->std;
1088 return 0;
1089}
1090
1091int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1092{
Ian Armstrong2443bae2010-03-13 20:22:34 -03001093 DEFINE_WAIT(wait);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001094 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1095 struct yuv_playback_info *yi = &itv->yuv_info;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001096 int f;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001097
1098 if ((*std & V4L2_STD_ALL) == 0)
1099 return -EINVAL;
1100
1101 if (*std == itv->std)
1102 return 0;
1103
1104 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1105 atomic_read(&itv->capturing) > 0 ||
1106 atomic_read(&itv->decoding) > 0) {
1107 /* Switching standard would turn off the radio or mess
1108 with already running streams, prevent that by
1109 returning EBUSY. */
1110 return -EBUSY;
1111 }
1112
1113 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
1126 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
1127
1128 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001129 ivtv_call_all(itv, core, s_std, itv->std);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001130
1131 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1132 /* set display standard */
1133 itv->std_out = *std;
1134 itv->is_out_60hz = itv->is_60hz;
1135 itv->is_out_50hz = itv->is_50hz;
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001136 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001137
1138 /*
1139 * The next firmware call is time sensitive. Time it to
1140 * avoid risk of a hard lock, by trying to ensure the call
1141 * happens within the first 100 lines of the top field.
1142 * Make 4 attempts to sync to the decoder before giving up.
1143 */
1144 for (f = 0; f < 4; f++) {
1145 prepare_to_wait(&itv->vsync_waitq, &wait,
1146 TASK_UNINTERRUPTIBLE);
Andy Walls4e1af312010-03-13 20:37:25 -03001147 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
Ian Armstrong2443bae2010-03-13 20:22:34 -03001148 break;
1149 schedule_timeout(msecs_to_jiffies(25));
1150 }
1151 finish_wait(&itv->vsync_waitq, &wait);
1152
1153 if (f == 4)
1154 IVTV_WARN("Mode change failed to sync to decoder\n");
1155
Hans Verkuil3f038d82008-05-29 16:43:54 -03001156 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1157 itv->main_rect.left = itv->main_rect.top = 0;
1158 itv->main_rect.width = 720;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001159 itv->main_rect.height = itv->cxhdl.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001160 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1161 720, itv->main_rect.height, 0, 0);
1162 yi->main_rect = itv->main_rect;
1163 if (!itv->osd_info) {
1164 yi->osd_full_w = 720;
1165 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1166 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001167 }
1168 return 0;
1169}
1170
Hans Verkuil3f038d82008-05-29 16:43:54 -03001171static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001172{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001173 struct ivtv_open_id *id = fh;
1174 struct ivtv *itv = id->itv;
1175
1176 if (vt->index != 0)
1177 return -EINVAL;
1178
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001179 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001180
1181 return 0;
1182}
1183
1184static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1185{
1186 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1187
1188 if (vt->index != 0)
1189 return -EINVAL;
1190
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001191 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001192
1193 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1194 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1195 vt->type = V4L2_TUNER_RADIO;
1196 } else {
1197 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1198 vt->type = V4L2_TUNER_ANALOG_TV;
1199 }
1200
1201 return 0;
1202}
1203
1204static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1205{
1206 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1207 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1208 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001209
Hans Verkuil79afcb12008-06-21 09:02:36 -03001210 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001211 for (f = 0; f < 2; f++) {
1212 for (l = 0; l < 24; l++) {
1213 if (valid_service_line(f, l, itv->is_50hz))
1214 cap->service_lines[f][l] = set;
1215 }
1216 }
1217 return 0;
1218 }
Hans Verkuil79afcb12008-06-21 09:02:36 -03001219 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001220 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1221 return -EINVAL;
1222 if (itv->is_60hz) {
1223 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1224 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1225 } else {
1226 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1227 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1228 }
1229 return 0;
1230 }
1231 return -EINVAL;
1232}
1233
1234static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1235{
1236 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1237 struct v4l2_enc_idx_entry *e = idx->entry;
1238 int entries;
1239 int i;
1240
1241 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1242 IVTV_MAX_PGM_INDEX;
1243 if (entries > V4L2_ENC_IDX_ENTRIES)
1244 entries = V4L2_ENC_IDX_ENTRIES;
1245 idx->entries = 0;
1246 for (i = 0; i < entries; i++) {
1247 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1248 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1249 idx->entries++;
1250 e++;
1251 }
1252 }
1253 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1254 return 0;
1255}
1256
1257static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1258{
1259 struct ivtv_open_id *id = fh;
1260 struct ivtv *itv = id->itv;
1261
Hans Verkuil3f038d82008-05-29 16:43:54 -03001262
1263 switch (enc->cmd) {
1264 case V4L2_ENC_CMD_START:
1265 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1266 enc->flags = 0;
1267 return ivtv_start_capture(id);
1268
1269 case V4L2_ENC_CMD_STOP:
1270 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1271 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1272 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1273 return 0;
1274
1275 case V4L2_ENC_CMD_PAUSE:
1276 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1277 enc->flags = 0;
1278
1279 if (!atomic_read(&itv->capturing))
1280 return -EPERM;
1281 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1282 return 0;
1283
1284 ivtv_mute(itv);
1285 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1286 break;
1287
1288 case V4L2_ENC_CMD_RESUME:
1289 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1290 enc->flags = 0;
1291
1292 if (!atomic_read(&itv->capturing))
1293 return -EPERM;
1294
1295 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1296 return 0;
1297
1298 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1299 ivtv_unmute(itv);
1300 break;
1301 default:
1302 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1303 return -EINVAL;
1304 }
1305
1306 return 0;
1307}
1308
1309static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1310{
1311 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1312
Hans Verkuil3f038d82008-05-29 16:43:54 -03001313 switch (enc->cmd) {
1314 case V4L2_ENC_CMD_START:
1315 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1316 enc->flags = 0;
1317 return 0;
1318
1319 case V4L2_ENC_CMD_STOP:
1320 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1321 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1322 return 0;
1323
1324 case V4L2_ENC_CMD_PAUSE:
1325 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1326 enc->flags = 0;
1327 return 0;
1328
1329 case V4L2_ENC_CMD_RESUME:
1330 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1331 enc->flags = 0;
1332 return 0;
1333 default:
1334 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1335 return -EINVAL;
1336 }
1337}
1338
1339static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1340{
1341 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001342 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001343 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001344
Hans Verkuil3f038d82008-05-29 16:43:54 -03001345 int pixfmt;
1346 static u32 pixel_format[16] = {
1347 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1348 V4L2_PIX_FMT_RGB565,
1349 V4L2_PIX_FMT_RGB555,
1350 V4L2_PIX_FMT_RGB444,
1351 V4L2_PIX_FMT_RGB32,
1352 0,
1353 0,
1354 0,
1355 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1356 V4L2_PIX_FMT_YUV565,
1357 V4L2_PIX_FMT_YUV555,
1358 V4L2_PIX_FMT_YUV444,
1359 V4L2_PIX_FMT_YUV32,
1360 0,
1361 0,
1362 0,
1363 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001364
Hans Verkuil3f038d82008-05-29 16:43:54 -03001365 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1366 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001367 if (!itv->osd_video_pbase)
1368 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001369
Hans Verkuil3f038d82008-05-29 16:43:54 -03001370 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1371 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001372
Hans Verkuil3f038d82008-05-29 16:43:54 -03001373 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1374 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1375 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001376
Hans Verkuil3f038d82008-05-29 16:43:54 -03001377 fb->fmt.pixelformat = pixel_format[pixfmt];
1378 fb->fmt.width = itv->osd_rect.width;
1379 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001380 fb->fmt.field = V4L2_FIELD_INTERLACED;
1381 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001382 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1383 fb->fmt.field = V4L2_FIELD_INTERLACED;
1384 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001385 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1386 fb->fmt.bytesperline *= 2;
1387 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1388 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1389 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001390 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001391 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001392 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001393
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 if (itv->osd_chroma_key_state)
1395 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001396
Hans Verkuil3f038d82008-05-29 16:43:54 -03001397 if (itv->osd_global_alpha_state)
1398 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001399
Ian Armstrongec9faa12008-10-06 03:06:08 -03001400 if (yi->track_osd)
1401 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1402
Hans Verkuil3f038d82008-05-29 16:43:54 -03001403 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001404
Hans Verkuil3f038d82008-05-29 16:43:54 -03001405 /* no local alpha for RGB565 or unknown formats */
1406 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001407 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001408
Hans Verkuil3f038d82008-05-29 16:43:54 -03001409 /* 16-bit formats have inverted local alpha */
1410 if (pixfmt == 2 || pixfmt == 3)
1411 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1412 else
1413 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001414
Hans Verkuil3f038d82008-05-29 16:43:54 -03001415 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001416 /* 16-bit formats have inverted local alpha */
1417 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001418 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001419 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001420 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001421 }
1422
Hans Verkuil3f038d82008-05-29 16:43:54 -03001423 return 0;
1424}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001425
Hans Verkuil3f038d82008-05-29 16:43:54 -03001426static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1427{
1428 struct ivtv_open_id *id = fh;
1429 struct ivtv *itv = id->itv;
1430 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001431
Hans Verkuil3f038d82008-05-29 16:43:54 -03001432 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001433 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001434 if (!itv->osd_video_pbase)
1435 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001436
1437 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1438 itv->osd_local_alpha_state =
1439 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1440 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1441 ivtv_set_osd_alpha(itv);
1442 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001443 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001444}
1445
1446static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1447{
1448 struct ivtv_open_id *id = fh;
1449 struct ivtv *itv = id->itv;
1450
1451 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1452 return -EINVAL;
1453
1454 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1455
1456 return 0;
1457}
1458
Hans Verkuil09250192010-03-27 14:10:13 -03001459static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1460{
1461 switch (sub->type) {
1462 case V4L2_EVENT_VSYNC:
1463 case V4L2_EVENT_EOS:
1464 break;
1465 default:
1466 return -EINVAL;
1467 }
1468 return v4l2_event_subscribe(fh, sub);
1469}
1470
Hans Verkuil3f038d82008-05-29 16:43:54 -03001471static int ivtv_log_status(struct file *file, void *fh)
1472{
1473 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1474 u32 data[CX2341X_MBOX_MAX_DATA];
1475
1476 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1477 struct v4l2_input vidin;
1478 struct v4l2_audio audin;
1479 int i;
1480
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001481 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1482 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001483 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1484 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1485 struct tveeprom tv;
1486
1487 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001488 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001489 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001490 ivtv_get_input(itv, itv->active_input, &vidin);
1491 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1492 IVTV_INFO("Video Input: %s\n", vidin.name);
1493 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1494 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1495 if (has_output) {
1496 struct v4l2_output vidout;
1497 struct v4l2_audioout audout;
1498 int mode = itv->output_mode;
1499 static const char * const output_modes[5] = {
1500 "None",
1501 "MPEG Streaming",
1502 "YUV Streaming",
1503 "YUV Frames",
1504 "Passthrough",
1505 };
1506 static const char * const audio_modes[5] = {
1507 "Stereo",
1508 "Left",
1509 "Right",
1510 "Mono",
1511 "Swapped"
1512 };
1513 static const char * const alpha_mode[4] = {
1514 "None",
1515 "Global",
1516 "Local",
1517 "Global and Local"
1518 };
1519 static const char * const pixel_format[16] = {
1520 "ARGB Indexed",
1521 "RGB 5:6:5",
1522 "ARGB 1:5:5:5",
1523 "ARGB 1:4:4:4",
1524 "ARGB 8:8:8:8",
1525 "5",
1526 "6",
1527 "7",
1528 "AYUV Indexed",
1529 "YUV 5:6:5",
1530 "AYUV 1:5:5:5",
1531 "AYUV 1:4:4:4",
1532 "AYUV 8:8:8:8",
1533 "13",
1534 "14",
1535 "15",
1536 };
1537
1538 ivtv_get_output(itv, itv->active_output, &vidout);
1539 ivtv_get_audio_output(itv, 0, &audout);
1540 IVTV_INFO("Video Output: %s\n", vidout.name);
1541 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1542 audio_modes[itv->audio_stereo_mode],
1543 audio_modes[itv->audio_bilingual_mode]);
1544 if (mode < 0 || mode > OUT_PASSTHROUGH)
1545 mode = OUT_NONE;
1546 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1547 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1548 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1549 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1550 data[0] & 1 ? "On" : "Off",
1551 alpha_mode[(data[0] >> 1) & 0x3],
1552 pixel_format[(data[0] >> 3) & 0xf]);
1553 }
1554 IVTV_INFO("Tuner: %s\n",
1555 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001556 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001557 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1558 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1559 struct ivtv_stream *s = &itv->streams[i];
1560
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001561 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001562 continue;
1563 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1564 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1565 (s->buffers * s->buf_size) / 1024, s->buffers);
1566 }
1567
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001568 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1569 (long long)itv->mpg_data_received,
1570 (long long)itv->vbi_data_inserted);
1571 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1572 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001573
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001574 return 0;
1575}
1576
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001577static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001578{
Hans Verkuil09250192010-03-27 14:10:13 -03001579 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001580 struct ivtv *itv = id->itv;
1581 int nonblocking = filp->f_flags & O_NONBLOCK;
1582 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001583 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001584
1585 switch (cmd) {
1586 case IVTV_IOC_DMA_FRAME: {
1587 struct ivtv_dma_frame *args = arg;
1588
1589 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1590 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1591 return -EINVAL;
1592 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1593 return -EINVAL;
1594 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1595 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001596 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001597 return -EBUSY;
1598 }
1599 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1600 ivtv_release_stream(s);
1601 return -EBUSY;
1602 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001603 /* Mark that this file handle started the UDMA_YUV mode */
1604 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001605 if (args->y_source == NULL)
1606 return 0;
1607 return ivtv_yuv_prep_frame(itv, args);
1608 }
1609
1610 case VIDEO_GET_PTS: {
1611 u32 data[CX2341X_MBOX_MAX_DATA];
1612 u64 *pts = arg;
1613
1614 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1615 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1616 *pts = s->dma_pts;
1617 break;
1618 }
1619 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1620 return -EINVAL;
1621
1622 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1623 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1624 (u64)itv->last_dec_timing[1];
1625 break;
1626 }
1627 *pts = 0;
1628 if (atomic_read(&itv->decoding)) {
1629 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1630 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1631 return -EIO;
1632 }
1633 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1634 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1635 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1636 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1637 }
1638 break;
1639 }
1640
1641 case VIDEO_GET_FRAME_COUNT: {
1642 u32 data[CX2341X_MBOX_MAX_DATA];
1643 u64 *frame = arg;
1644
1645 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1646 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1647 *frame = 0;
1648 break;
1649 }
1650 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1651 return -EINVAL;
1652
1653 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1654 *frame = itv->last_dec_timing[0];
1655 break;
1656 }
1657 *frame = 0;
1658 if (atomic_read(&itv->decoding)) {
1659 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1660 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1661 return -EIO;
1662 }
1663 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1664 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1665 *frame = data[0];
1666 }
1667 break;
1668 }
1669
1670 case VIDEO_PLAY: {
1671 struct video_command vc;
1672
1673 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1674 memset(&vc, 0, sizeof(vc));
1675 vc.cmd = VIDEO_CMD_PLAY;
1676 return ivtv_video_command(itv, id, &vc, 0);
1677 }
1678
1679 case VIDEO_STOP: {
1680 struct video_command vc;
1681
1682 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1683 memset(&vc, 0, sizeof(vc));
1684 vc.cmd = VIDEO_CMD_STOP;
1685 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1686 return ivtv_video_command(itv, id, &vc, 0);
1687 }
1688
1689 case VIDEO_FREEZE: {
1690 struct video_command vc;
1691
1692 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1693 memset(&vc, 0, sizeof(vc));
1694 vc.cmd = VIDEO_CMD_FREEZE;
1695 return ivtv_video_command(itv, id, &vc, 0);
1696 }
1697
1698 case VIDEO_CONTINUE: {
1699 struct video_command vc;
1700
1701 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1702 memset(&vc, 0, sizeof(vc));
1703 vc.cmd = VIDEO_CMD_CONTINUE;
1704 return ivtv_video_command(itv, id, &vc, 0);
1705 }
1706
1707 case VIDEO_COMMAND:
1708 case VIDEO_TRY_COMMAND: {
1709 struct video_command *vc = arg;
1710 int try = (cmd == VIDEO_TRY_COMMAND);
1711
1712 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001713 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001714 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001715 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001716 return ivtv_video_command(itv, id, vc, try);
1717 }
1718
1719 case VIDEO_GET_EVENT: {
1720 struct video_event *ev = arg;
1721 DEFINE_WAIT(wait);
1722
1723 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1724 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1725 return -EINVAL;
1726 memset(ev, 0, sizeof(*ev));
1727 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1728
1729 while (1) {
1730 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1731 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1732 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1733 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001734 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1735 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1736 if (itv->output_mode == OUT_UDMA_YUV &&
1737 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1738 IVTV_YUV_MODE_PROGRESSIVE) {
1739 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1740 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001741 }
1742 if (ev->type)
1743 return 0;
1744 if (nonblocking)
1745 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001746 /* Wait for event. Note that serialize_lock is locked,
1747 so to allow other processes to access the driver while
1748 we are waiting unlock first and later lock again. */
1749 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001750 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001751 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1752 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001753 schedule();
1754 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001755 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001756 if (signal_pending(current)) {
1757 /* return if a signal was received */
1758 IVTV_DEBUG_INFO("User stopped wait for event\n");
1759 return -EINTR;
1760 }
1761 }
1762 break;
1763 }
1764
Hans Verkuilce680252010-04-06 15:58:53 -03001765 case VIDEO_SELECT_SOURCE:
1766 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1767 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1768 return -EINVAL;
1769 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1770
1771 case AUDIO_SET_MUTE:
1772 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1773 itv->speed_mute_audio = iarg;
1774 return 0;
1775
1776 case AUDIO_CHANNEL_SELECT:
1777 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1778 if (iarg > AUDIO_STEREO_SWAPPED)
1779 return -EINVAL;
1780 itv->audio_stereo_mode = iarg;
1781 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1782 return 0;
1783
1784 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1785 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1786 if (iarg > AUDIO_STEREO_SWAPPED)
1787 return -EINVAL;
1788 itv->audio_bilingual_mode = iarg;
1789 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1790 return 0;
1791
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001792 default:
1793 return -EINVAL;
1794 }
1795 return 0;
1796}
1797
Hans Verkuil069b7472008-12-30 07:04:34 -03001798static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001799{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001800 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001801
Hans Verkuild46c17d2007-03-10 17:59:15 -03001802 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001803 case VIDIOC_INT_RESET: {
1804 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001805
Hans Verkuil3f038d82008-05-29 16:43:54 -03001806 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1807 ivtv_reset_ir_gpio(itv);
1808 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001809 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001810 break;
1811 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001812
Hans Verkuilac9575f2009-02-14 19:58:33 -03001813 case IVTV_IOC_DMA_FRAME:
1814 case VIDEO_GET_PTS:
1815 case VIDEO_GET_FRAME_COUNT:
1816 case VIDEO_GET_EVENT:
1817 case VIDEO_PLAY:
1818 case VIDEO_STOP:
1819 case VIDEO_FREEZE:
1820 case VIDEO_CONTINUE:
1821 case VIDEO_COMMAND:
1822 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001823 case VIDEO_SELECT_SOURCE:
1824 case AUDIO_SET_MUTE:
1825 case AUDIO_CHANNEL_SELECT:
1826 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001827 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1828
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001829 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001830 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001831 }
1832 return 0;
1833}
1834
Hans Verkuil09882f02008-10-18 13:42:24 -03001835static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
Hans Verkuilbaa40722007-08-19 07:10:55 -03001836 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001837{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001838 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09250192010-03-27 14:10:13 -03001839 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil09882f02008-10-18 13:42:24 -03001840 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001841
Hans Verkuil3f038d82008-05-29 16:43:54 -03001842 /* check priority */
1843 switch (cmd) {
1844 case VIDIOC_S_CTRL:
1845 case VIDIOC_S_STD:
1846 case VIDIOC_S_INPUT:
1847 case VIDIOC_S_OUTPUT:
1848 case VIDIOC_S_TUNER:
1849 case VIDIOC_S_FREQUENCY:
1850 case VIDIOC_S_FMT:
1851 case VIDIOC_S_CROP:
1852 case VIDIOC_S_AUDIO:
1853 case VIDIOC_S_AUDOUT:
1854 case VIDIOC_S_EXT_CTRLS:
1855 case VIDIOC_S_FBUF:
Hans Verkuil3e56b0f2010-05-02 11:11:40 -03001856 case VIDIOC_S_PRIORITY:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001857 case VIDIOC_OVERLAY:
Hans Verkuilffb48772010-05-01 08:03:24 -03001858 ret = v4l2_prio_check(&itv->prio, id->prio);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001859 if (ret)
1860 return ret;
1861 }
1862
Hans Verkuil37f89f92008-06-22 11:57:31 -03001863 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1864 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001865 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001866 vfd->debug = 0;
1867 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001868}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001869
Hans Verkuil09882f02008-10-18 13:42:24 -03001870long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuilbaa40722007-08-19 07:10:55 -03001871{
Hans Verkuil09250192010-03-27 14:10:13 -03001872 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001873 struct ivtv *itv = id->itv;
Hans Verkuil09882f02008-10-18 13:42:24 -03001874 long res;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001875
Hans Verkuil09250192010-03-27 14:10:13 -03001876 /* DQEVENT can block, so this should not run with the serialize lock */
1877 if (cmd == VIDIOC_DQEVENT)
1878 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001879 mutex_lock(&itv->serialize_lock);
Hans Verkuil09882f02008-10-18 13:42:24 -03001880 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001881 mutex_unlock(&itv->serialize_lock);
1882 return res;
1883}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001884
Hans Verkuila3998102008-07-21 02:57:38 -03001885static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1886 .vidioc_querycap = ivtv_querycap,
1887 .vidioc_g_priority = ivtv_g_priority,
1888 .vidioc_s_priority = ivtv_s_priority,
1889 .vidioc_s_audio = ivtv_s_audio,
1890 .vidioc_g_audio = ivtv_g_audio,
1891 .vidioc_enumaudio = ivtv_enumaudio,
1892 .vidioc_s_audout = ivtv_s_audout,
1893 .vidioc_g_audout = ivtv_g_audout,
1894 .vidioc_enum_input = ivtv_enum_input,
1895 .vidioc_enum_output = ivtv_enum_output,
1896 .vidioc_enumaudout = ivtv_enumaudout,
1897 .vidioc_cropcap = ivtv_cropcap,
1898 .vidioc_s_crop = ivtv_s_crop,
1899 .vidioc_g_crop = ivtv_g_crop,
1900 .vidioc_g_input = ivtv_g_input,
1901 .vidioc_s_input = ivtv_s_input,
1902 .vidioc_g_output = ivtv_g_output,
1903 .vidioc_s_output = ivtv_s_output,
1904 .vidioc_g_frequency = ivtv_g_frequency,
1905 .vidioc_s_frequency = ivtv_s_frequency,
1906 .vidioc_s_tuner = ivtv_s_tuner,
1907 .vidioc_g_tuner = ivtv_g_tuner,
1908 .vidioc_g_enc_index = ivtv_g_enc_index,
1909 .vidioc_g_fbuf = ivtv_g_fbuf,
1910 .vidioc_s_fbuf = ivtv_s_fbuf,
1911 .vidioc_g_std = ivtv_g_std,
1912 .vidioc_s_std = ivtv_s_std,
1913 .vidioc_overlay = ivtv_overlay,
1914 .vidioc_log_status = ivtv_log_status,
1915 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1916 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1917 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1918 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1919 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1920 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1921 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1922 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1923 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1924 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1925 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1926 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1927 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1928 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1929 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1930 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1931 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1932 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1933 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1934 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1935 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1936 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1937 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1938 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1939#ifdef CONFIG_VIDEO_ADV_DEBUG
1940 .vidioc_g_register = ivtv_g_register,
1941 .vidioc_s_register = ivtv_s_register,
1942#endif
1943 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001944 .vidioc_subscribe_event = ivtv_subscribe_event,
1945 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001946};
1947
Hans Verkuil3f038d82008-05-29 16:43:54 -03001948void ivtv_set_funcs(struct video_device *vdev)
1949{
Hans Verkuila3998102008-07-21 02:57:38 -03001950 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001951}