blob: 4eed9123683e69541c6881f9a05e87897349a491 [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>
40#include <linux/i2c-id.h>
41
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030042u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030043{
44 switch (type) {
45 case V4L2_SLICED_TELETEXT_B:
46 return IVTV_SLICED_TYPE_TELETEXT_B;
47 case V4L2_SLICED_CAPTION_525:
48 return IVTV_SLICED_TYPE_CAPTION_525;
49 case V4L2_SLICED_WSS_625:
50 return IVTV_SLICED_TYPE_WSS_625;
51 case V4L2_SLICED_VPS:
52 return IVTV_SLICED_TYPE_VPS;
53 default:
54 return 0;
55 }
56}
57
58static int valid_service_line(int field, int line, int is_pal)
59{
60 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
61 (!is_pal && line >= 10 && line < 22);
62}
63
64static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
65{
66 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
67 int i;
68
69 set = set & valid_set;
70 if (set == 0 || !valid_service_line(field, line, is_pal)) {
71 return 0;
72 }
73 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525;
76 }
77 else {
78 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
79 return V4L2_SLICED_VPS;
80 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
81 return V4L2_SLICED_WSS_625;
82 if (line == 23)
83 return 0;
84 }
85 for (i = 0; i < 32; i++) {
86 if ((1 << i) & set)
87 return 1 << i;
88 }
89 return 0;
90}
91
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030092void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030093{
94 u16 set = fmt->service_set;
95 int f, l;
96
97 fmt->service_set = 0;
98 for (f = 0; f < 2; f++) {
99 for (l = 0; l < 24; l++) {
100 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
101 }
102 }
103}
104
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300105static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300106{
107 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300108
109 for (f = 0; f < 2; f++) {
110 for (l = 0; l < 24; l++) {
111 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 -0300112 }
113 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300114}
115
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300116u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300117{
118 int f, l;
119 u16 set = 0;
120
121 for (f = 0; f < 2; f++) {
122 for (l = 0; l < 24; l++) {
123 set |= fmt->service_lines[f][l];
124 }
125 }
126 return set;
127}
128
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300129void ivtv_set_osd_alpha(struct ivtv *itv)
130{
131 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
132 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300133 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 -0300134}
135
136int ivtv_set_speed(struct ivtv *itv, int speed)
137{
138 u32 data[CX2341X_MBOX_MAX_DATA];
139 struct ivtv_stream *s;
140 int single_step = (speed == 1 || speed == -1);
141 DEFINE_WAIT(wait);
142
143 if (speed == 0) speed = 1000;
144
145 /* No change? */
146 if (speed == itv->speed && !single_step)
147 return 0;
148
149 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
150
151 if (single_step && (speed < 0) == (itv->speed < 0)) {
152 /* Single step video and no need to change direction */
153 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
154 itv->speed = speed;
155 return 0;
156 }
157 if (single_step)
158 /* Need to change direction */
159 speed = speed < 0 ? -1000 : 1000;
160
161 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
162 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
163 data[1] = (speed < 0);
164 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300165 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300166 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
167 data[5] = 0;
168 data[6] = 0;
169
170 if (speed == 1500 || speed == -1500) data[0] |= 1;
171 else if (speed == 2000 || speed == -2000) data[0] |= 2;
172 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
173 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
174
175 /* If not decoding, just change speed setting */
176 if (atomic_read(&itv->decoding) > 0) {
177 int got_sig = 0;
178
179 /* Stop all DMA and decoding activity */
180 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
181
182 /* Wait for any DMA to finish */
183 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -0300184 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300185 got_sig = signal_pending(current);
186 if (got_sig)
187 break;
188 got_sig = 0;
189 schedule();
190 }
191 finish_wait(&itv->dma_waitq, &wait);
192 if (got_sig)
193 return -EINTR;
194
195 /* Change Speed safely */
196 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
197 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
198 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
199 }
200 if (single_step) {
201 speed = (speed < 0) ? -1 : 1;
202 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
203 }
204 itv->speed = speed;
205 return 0;
206}
207
208static int ivtv_validate_speed(int cur_speed, int new_speed)
209{
210 int fact = new_speed < 0 ? -1 : 1;
211 int s;
212
Hans Verkuil94dee762008-04-26 09:26:13 -0300213 if (cur_speed == 0)
214 cur_speed = 1000;
215 if (new_speed < 0)
216 new_speed = -new_speed;
217 if (cur_speed < 0)
218 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300219
220 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300221 if (new_speed > 1500)
222 return fact * 2000;
223 if (new_speed > 1000)
224 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300225 }
226 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300227 if (new_speed >= 2000)
228 return fact * 2000;
229 if (new_speed >= 1500)
230 return fact * 1500;
231 if (new_speed >= 1000)
232 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300233 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300234 if (new_speed == 0)
235 return 1000;
236 if (new_speed == 1 || new_speed == 1000)
237 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300238
239 s = new_speed;
240 new_speed = 1000 / new_speed;
241 if (1000 / cur_speed == new_speed)
242 new_speed += (cur_speed < s) ? -1 : 1;
243 if (new_speed > 60) return 1000 / (fact * 60);
244 return 1000 / (fact * new_speed);
245}
246
247static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
248 struct video_command *vc, int try)
249{
250 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
251
252 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
253 return -EINVAL;
254
255 switch (vc->cmd) {
256 case VIDEO_CMD_PLAY: {
Hans Verkuil25415cf2007-03-10 18:29:48 -0300257 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300258 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
259 if (vc->play.speed < 0)
260 vc->play.format = VIDEO_PLAY_FMT_GOP;
261 if (try) break;
262
263 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
264 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300265 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
266 /* forces ivtv_set_speed to be called */
267 itv->speed = 0;
268 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300269 return ivtv_start_decoding(id, vc->play.speed);
270 }
271
272 case VIDEO_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -0300273 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300274 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
275 vc->stop.pts = 0;
276 if (try) break;
277 if (atomic_read(&itv->decoding) == 0)
278 return 0;
279 if (itv->output_mode != OUT_MPG)
280 return -EBUSY;
281
282 itv->output_mode = OUT_NONE;
283 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
284
285 case VIDEO_CMD_FREEZE:
Hans Verkuil018ba852007-04-10 18:59:09 -0300286 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300287 if (try) break;
288 if (itv->output_mode != OUT_MPG)
289 return -EBUSY;
290 if (atomic_read(&itv->decoding) > 0) {
291 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
292 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300293 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300294 }
295 break;
296
297 case VIDEO_CMD_CONTINUE:
Hans Verkuil25415cf2007-03-10 18:29:48 -0300298 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300299 if (try) break;
300 if (itv->output_mode != OUT_MPG)
301 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300302 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
303 int speed = itv->speed;
304 itv->speed = 0;
305 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300306 }
307 break;
308
309 default:
310 return -EINVAL;
311 }
312 return 0;
313}
314
Hans Verkuil3f038d82008-05-29 16:43:54 -0300315static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300316{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300317 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
318 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300319
Hans Verkuile88360c2008-06-21 08:00:56 -0300320 vbifmt->reserved[0] = 0;
321 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300322 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300323 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300324 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
325 if (itv->is_60hz) {
326 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
327 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
328 } else {
329 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
330 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
331 }
332 vbifmt->service_set = ivtv_get_service_set(vbifmt);
333 return 0;
334}
335
336static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
337{
338 struct ivtv_open_id *id = fh;
339 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300340 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300341
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300342 pixfmt->width = itv->cxhdl.width;
343 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300344 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
345 pixfmt->field = V4L2_FIELD_INTERLACED;
346 pixfmt->priv = 0;
347 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
348 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300349 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
350 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300351 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300352 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300353 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
354 pixfmt->sizeimage = 128 * 1024;
355 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300356 }
357 return 0;
358}
359
Hans Verkuil3f038d82008-05-29 16:43:54 -0300360static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300361{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300362 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300363 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300364
Hans Verkuile88360c2008-06-21 08:00:56 -0300365 vbifmt->sampling_rate = 27000000;
366 vbifmt->offset = 248;
367 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
368 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
369 vbifmt->start[0] = itv->vbi.start[0];
370 vbifmt->start[1] = itv->vbi.start[1];
371 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
372 vbifmt->flags = 0;
373 vbifmt->reserved[0] = 0;
374 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300375 return 0;
376}
377
378static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
379{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300380 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300381 struct ivtv_open_id *id = fh;
382 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300383
Hans Verkuile88360c2008-06-21 08:00:56 -0300384 vbifmt->reserved[0] = 0;
385 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300386 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300387
Hans Verkuil3f038d82008-05-29 16:43:54 -0300388 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
389 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
390 V4L2_SLICED_VBI_525;
391 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300392 return 0;
393 }
394
Hans Verkuil4ff07902010-03-14 12:18:18 -0300395 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300396 vbifmt->service_set = ivtv_get_service_set(vbifmt);
397 return 0;
398}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300399
Hans Verkuil3f038d82008-05-29 16:43:54 -0300400static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
401{
402 struct ivtv_open_id *id = fh;
403 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300404 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300405
Hans Verkuil3f038d82008-05-29 16:43:54 -0300406 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300407 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300408 pixfmt->width = itv->main_rect.width;
409 pixfmt->height = itv->main_rect.height;
410 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
411 pixfmt->field = V4L2_FIELD_INTERLACED;
412 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300413 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
414 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
415 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300416 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300417 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
418 break;
419 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300420 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300421 break;
422 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300423 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300424 break;
425 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300426 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
427 pixfmt->bytesperline = 720;
428 pixfmt->width = itv->yuv_info.v4l2_src_w;
429 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300430 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300431 pixfmt->sizeimage =
432 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300433 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300434 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
435 pixfmt->sizeimage = 128 * 1024;
436 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300437 }
438 return 0;
439}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300440
Hans Verkuil3f038d82008-05-29 16:43:54 -0300441static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
442{
443 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300444 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300445
446 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
447 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300448 winfmt->chromakey = itv->osd_chroma_key;
449 winfmt->global_alpha = itv->osd_global_alpha;
450 winfmt->field = V4L2_FIELD_INTERLACED;
451 winfmt->clips = NULL;
452 winfmt->clipcount = 0;
453 winfmt->bitmap = NULL;
454 winfmt->w.top = winfmt->w.left = 0;
455 winfmt->w.width = itv->osd_rect.width;
456 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300457 return 0;
458}
459
460static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
461{
462 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
463}
464
465static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
466{
467 struct ivtv_open_id *id = fh;
468 struct ivtv *itv = id->itv;
469 int w = fmt->fmt.pix.width;
470 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300471 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300472
473 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300474 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300475 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
476 /* YUV height must be a multiple of 32 */
477 h &= ~0x1f;
478 min_h = 32;
479 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300480 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300481 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300482 ivtv_g_fmt_vid_cap(file, fh, fmt);
483 fmt->fmt.pix.width = w;
484 fmt->fmt.pix.height = h;
485 return 0;
486}
487
488static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
489{
490 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
491}
492
493static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
494{
495 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
496 struct ivtv_open_id *id = fh;
497 struct ivtv *itv = id->itv;
498
499 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
500 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300501
502 /* set sliced VBI capture format */
503 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300504 vbifmt->reserved[0] = 0;
505 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300506
507 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300508 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300509 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300510 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300511 return 0;
512}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300513
Hans Verkuil3f038d82008-05-29 16:43:54 -0300514static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
515{
516 struct ivtv_open_id *id = fh;
Hans Verkuileffc3462008-09-06 08:24:37 -0300517 s32 w = fmt->fmt.pix.width;
518 s32 h = fmt->fmt.pix.height;
519 int field = fmt->fmt.pix.field;
520 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300521
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300522 w = min(w, 720);
523 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300524 /* Why can the height be 576 even when the output is NTSC?
525
526 Internally the buffers of the PVR350 are always set to 720x576. The
527 decoded video frame will always be placed in the top left corner of
528 this buffer. For any video which is not 720x576, the buffer will
529 then be cropped to remove the unused right and lower areas, with
530 the remaining image being scaled by the hardware to fit the display
531 area. The video can be scaled both up and down, so a 720x480 video
532 can be displayed full-screen on PAL and a 720x576 video can be
533 displayed without cropping on NTSC.
534
535 Note that the scaling only occurs on the video stream, the osd
536 resolution is locked to the broadcast standard and not scaled.
537
538 Thanks to Ian Armstrong for this explanation. */
539 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300540 h = max(h, 2);
541 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300542 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300543 fmt->fmt.pix.width = w;
544 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300545 return ret;
546}
547
548static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
549{
550 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300551 u32 chromakey = fmt->fmt.win.chromakey;
552 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300553
554 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
555 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300556 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
557 fmt->fmt.win.chromakey = chromakey;
558 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300559 return 0;
560}
561
562static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
563{
564 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
565}
566
567static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
568{
569 struct ivtv_open_id *id = fh;
570 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300571 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300572 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300573 int w = fmt->fmt.pix.width;
574 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300575
576 if (ret)
577 return ret;
578
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300579 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300580 return 0;
581
582 if (atomic_read(&itv->capturing) > 0)
583 return -EBUSY;
584
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300585 itv->cxhdl.width = w;
586 itv->cxhdl.height = h;
587 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300588 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300589 mbus_fmt.width = fmt->fmt.pix.width;
590 mbus_fmt.height = h;
591 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
592 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300593 return ivtv_g_fmt_vid_cap(file, fh, fmt);
594}
595
596static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
597{
598 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
599
Hans Verkuila8b86432008-10-04 08:05:30 -0300600 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
601 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300602 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300603 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300604 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300605 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
606}
607
608static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
609{
610 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
611 struct ivtv_open_id *id = fh;
612 struct ivtv *itv = id->itv;
613 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
614
615 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
616 return ret;
617
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300618 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300619 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300620 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300621 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300622 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300623 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
624 return 0;
625}
626
Hans Verkuil3f038d82008-05-29 16:43:54 -0300627static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300628{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300629 struct ivtv_open_id *id = fh;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300630 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300631 struct yuv_playback_info *yi = &itv->yuv_info;
632 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300633
Hans Verkuil3f038d82008-05-29 16:43:54 -0300634 if (ret)
635 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300636
Hans Verkuil3f038d82008-05-29 16:43:54 -0300637 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
638 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300639
Hans Verkuil3f038d82008-05-29 16:43:54 -0300640 /* Return now if we already have some frame data */
641 if (yi->stream_size)
642 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 yi->v4l2_src_w = fmt->fmt.pix.width;
645 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300646
Hans Verkuil3f038d82008-05-29 16:43:54 -0300647 switch (fmt->fmt.pix.field) {
648 case V4L2_FIELD_NONE:
649 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300650 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300651 case V4L2_FIELD_ANY:
652 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300653 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300654 case V4L2_FIELD_INTERLACED_BT:
655 yi->lace_mode =
656 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
657 break;
658 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300659 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300660 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
661 break;
662 }
663 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
664
665 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
666 itv->dma_data_req_size =
667 1080 * ((yi->v4l2_src_h + 31) & ~31);
668
Hans Verkuil3f038d82008-05-29 16:43:54 -0300669 return 0;
670}
671
672static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
673{
674 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
675 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
676
677 if (ret == 0) {
678 itv->osd_chroma_key = fmt->fmt.win.chromakey;
679 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
680 ivtv_set_osd_alpha(itv);
681 }
682 return ret;
683}
684
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300685static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300686{
687 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
688
689 chip->ident = V4L2_IDENT_NONE;
690 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300691 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
692 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300693 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
694 return 0;
695 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300696 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
697 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300698 return -EINVAL;
699 /* TODO: is this correct? */
700 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300701}
702
Hans Verkuil36ecd492008-06-25 06:00:17 -0300703#ifdef CONFIG_VIDEO_ADV_DEBUG
704static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
705{
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300706 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300707 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300708
709 if (!capable(CAP_SYS_ADMIN))
710 return -EPERM;
711 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
712 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
713 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
714 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
715 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300716 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300717 reg_start = itv->enc_mem;
718 else
719 return -EINVAL;
720
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300721 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300722 if (cmd == VIDIOC_DBG_G_REGISTER)
723 regs->val = readl(regs->reg + reg_start);
724 else
725 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300726 return 0;
727}
728
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300729static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300730{
731 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
732
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300733 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300734 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300735 /* TODO: subdev errors should not be ignored, this should become a
736 subdev helper function. */
737 ivtv_call_all(itv, core, g_register, reg);
738 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300739}
740
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300741static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300742{
743 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
744
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300745 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300746 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300747 /* TODO: subdev errors should not be ignored, this should become a
748 subdev helper function. */
749 ivtv_call_all(itv, core, s_register, reg);
750 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300751}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300752#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300753
754static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
755{
756 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
757
758 *p = v4l2_prio_max(&itv->prio);
759
760 return 0;
761}
762
763static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
764{
765 struct ivtv_open_id *id = fh;
766 struct ivtv *itv = id->itv;
767
768 return v4l2_prio_change(&itv->prio, &id->prio, prio);
769}
770
771static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
772{
773 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
774
Hans Verkuil3f038d82008-05-29 16:43:54 -0300775 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
776 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300777 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300778 vcap->version = IVTV_DRIVER_VERSION; /* version */
779 vcap->capabilities = itv->v4l2_cap; /* capabilities */
Hans Verkuil3f038d82008-05-29 16:43:54 -0300780 return 0;
781}
782
783static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
784{
785 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
786
787 return ivtv_get_audio_input(itv, vin->index, vin);
788}
789
790static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
791{
792 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
793
794 vin->index = itv->audio_input;
795 return ivtv_get_audio_input(itv, vin->index, vin);
796}
797
798static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
799{
800 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
801
802 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300803 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300804
805 itv->audio_input = vout->index;
806 ivtv_audio_set_io(itv);
807
808 return 0;
809}
810
811static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
812{
813 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
814
815 /* set it to defaults from our table */
816 return ivtv_get_audio_output(itv, vin->index, vin);
817}
818
819static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
820{
821 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
822
823 vin->index = 0;
824 return ivtv_get_audio_output(itv, vin->index, vin);
825}
826
827static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
828{
829 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
830
831 return ivtv_get_audio_output(itv, vout->index, vout);
832}
833
834static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
835{
836 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
837
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{
844 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
845
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{
851 struct ivtv_open_id *id = fh;
852 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
886static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
887{
888 struct ivtv_open_id *id = fh;
889 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{
914 struct ivtv_open_id *id = fh;
915 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{
934 static struct v4l2_fmtdesc formats[] = {
935 { 0, 0, 0,
936 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
937 { 0, 0, 0, 0 }
938 },
939 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
940 "MPEG", V4L2_PIX_FMT_MPEG,
941 { 0, 0, 0, 0 }
942 }
943 };
944 enum v4l2_buf_type type = fmt->type;
945
946 if (fmt->index > 1)
947 return -EINVAL;
948
949 *fmt = formats[fmt->index];
950 fmt->type = type;
951 return 0;
952}
953
954static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
955{
956 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
957
958 static struct v4l2_fmtdesc formats[] = {
959 { 0, 0, 0,
960 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
961 { 0, 0, 0, 0 }
962 },
963 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
964 "MPEG", V4L2_PIX_FMT_MPEG,
965 { 0, 0, 0, 0 }
966 }
967 };
968 enum v4l2_buf_type type = fmt->type;
969
970 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
971 return -EINVAL;
972
973 if (fmt->index > 1)
974 return -EINVAL;
975
976 *fmt = formats[fmt->index];
977 fmt->type = type;
978
979 return 0;
980}
981
982static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
983{
984 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
985
986 *i = itv->active_input;
987
988 return 0;
989}
990
991int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
992{
993 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
994
995 if (inp < 0 || inp >= itv->nof_inputs)
996 return -EINVAL;
997
998 if (inp == itv->active_input) {
999 IVTV_DEBUG_INFO("Input unchanged\n");
1000 return 0;
1001 }
1002
1003 if (atomic_read(&itv->capturing) > 0) {
1004 return -EBUSY;
1005 }
1006
1007 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1008 itv->active_input, inp);
1009
1010 itv->active_input = inp;
1011 /* Set the audio input to whatever is appropriate for the
1012 input type. */
1013 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1014
1015 /* prevent others from messing with the streams until
1016 we're finished changing inputs. */
1017 ivtv_mute(itv);
1018 ivtv_video_set_io(itv);
1019 ivtv_audio_set_io(itv);
1020 ivtv_unmute(itv);
1021
1022 return 0;
1023}
1024
1025static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1026{
1027 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1028
1029 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1030 return -EINVAL;
1031
1032 *i = itv->active_output;
1033
1034 return 0;
1035}
1036
1037static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1038{
1039 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001040
1041 if (outp >= itv->card->nof_outputs)
1042 return -EINVAL;
1043
1044 if (outp == itv->active_output) {
1045 IVTV_DEBUG_INFO("Output unchanged\n");
1046 return 0;
1047 }
1048 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1049 itv->active_output, outp);
1050
1051 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001052 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1053 SAA7127_INPUT_TYPE_NORMAL,
1054 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001055
1056 return 0;
1057}
1058
1059static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1060{
1061 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1062
1063 if (vf->tuner != 0)
1064 return -EINVAL;
1065
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001066 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001067 return 0;
1068}
1069
1070int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1071{
1072 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1073
1074 if (vf->tuner != 0)
1075 return -EINVAL;
1076
1077 ivtv_mute(itv);
1078 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001079 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001080 ivtv_unmute(itv);
1081 return 0;
1082}
1083
1084static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1085{
1086 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1087
1088 *std = itv->std;
1089 return 0;
1090}
1091
1092int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1093{
Ian Armstrong2443bae2010-03-13 20:22:34 -03001094 DEFINE_WAIT(wait);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001095 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1096 struct yuv_playback_info *yi = &itv->yuv_info;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001097 int f;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001098
1099 if ((*std & V4L2_STD_ALL) == 0)
1100 return -EINVAL;
1101
1102 if (*std == itv->std)
1103 return 0;
1104
1105 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1106 atomic_read(&itv->capturing) > 0 ||
1107 atomic_read(&itv->decoding) > 0) {
1108 /* Switching standard would turn off the radio or mess
1109 with already running streams, prevent that by
1110 returning EBUSY. */
1111 return -EBUSY;
1112 }
1113
1114 itv->std = *std;
1115 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001116 itv->is_50hz = !itv->is_60hz;
1117 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1118 itv->cxhdl.width = 720;
1119 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001120 itv->vbi.count = itv->is_50hz ? 18 : 12;
1121 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1122 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1123
1124 if (itv->hw_flags & IVTV_HW_CX25840)
1125 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1126
1127 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
1128
1129 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001130 ivtv_call_all(itv, core, s_std, itv->std);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001131
1132 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1133 /* set display standard */
1134 itv->std_out = *std;
1135 itv->is_out_60hz = itv->is_60hz;
1136 itv->is_out_50hz = itv->is_50hz;
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001137 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001138
1139 /*
1140 * The next firmware call is time sensitive. Time it to
1141 * avoid risk of a hard lock, by trying to ensure the call
1142 * happens within the first 100 lines of the top field.
1143 * Make 4 attempts to sync to the decoder before giving up.
1144 */
1145 for (f = 0; f < 4; f++) {
1146 prepare_to_wait(&itv->vsync_waitq, &wait,
1147 TASK_UNINTERRUPTIBLE);
Andy Walls4e1af312010-03-13 20:37:25 -03001148 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
Ian Armstrong2443bae2010-03-13 20:22:34 -03001149 break;
1150 schedule_timeout(msecs_to_jiffies(25));
1151 }
1152 finish_wait(&itv->vsync_waitq, &wait);
1153
1154 if (f == 4)
1155 IVTV_WARN("Mode change failed to sync to decoder\n");
1156
Hans Verkuil3f038d82008-05-29 16:43:54 -03001157 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1158 itv->main_rect.left = itv->main_rect.top = 0;
1159 itv->main_rect.width = 720;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001160 itv->main_rect.height = itv->cxhdl.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001161 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1162 720, itv->main_rect.height, 0, 0);
1163 yi->main_rect = itv->main_rect;
1164 if (!itv->osd_info) {
1165 yi->osd_full_w = 720;
1166 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1167 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001168 }
1169 return 0;
1170}
1171
Hans Verkuil3f038d82008-05-29 16:43:54 -03001172static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001173{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001174 struct ivtv_open_id *id = fh;
1175 struct ivtv *itv = id->itv;
1176
1177 if (vt->index != 0)
1178 return -EINVAL;
1179
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001180 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001181
1182 return 0;
1183}
1184
1185static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1186{
1187 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1188
1189 if (vt->index != 0)
1190 return -EINVAL;
1191
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001192 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001193
1194 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1195 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1196 vt->type = V4L2_TUNER_RADIO;
1197 } else {
1198 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1199 vt->type = V4L2_TUNER_ANALOG_TV;
1200 }
1201
1202 return 0;
1203}
1204
1205static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1206{
1207 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1208 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1209 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001210
Hans Verkuil79afcb12008-06-21 09:02:36 -03001211 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001212 for (f = 0; f < 2; f++) {
1213 for (l = 0; l < 24; l++) {
1214 if (valid_service_line(f, l, itv->is_50hz))
1215 cap->service_lines[f][l] = set;
1216 }
1217 }
1218 return 0;
1219 }
Hans Verkuil79afcb12008-06-21 09:02:36 -03001220 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001221 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1222 return -EINVAL;
1223 if (itv->is_60hz) {
1224 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1225 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1226 } else {
1227 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1228 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1229 }
1230 return 0;
1231 }
1232 return -EINVAL;
1233}
1234
1235static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1236{
1237 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1238 struct v4l2_enc_idx_entry *e = idx->entry;
1239 int entries;
1240 int i;
1241
1242 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1243 IVTV_MAX_PGM_INDEX;
1244 if (entries > V4L2_ENC_IDX_ENTRIES)
1245 entries = V4L2_ENC_IDX_ENTRIES;
1246 idx->entries = 0;
1247 for (i = 0; i < entries; i++) {
1248 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1249 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1250 idx->entries++;
1251 e++;
1252 }
1253 }
1254 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1255 return 0;
1256}
1257
1258static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1259{
1260 struct ivtv_open_id *id = fh;
1261 struct ivtv *itv = id->itv;
1262
Hans Verkuil3f038d82008-05-29 16:43:54 -03001263
1264 switch (enc->cmd) {
1265 case V4L2_ENC_CMD_START:
1266 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1267 enc->flags = 0;
1268 return ivtv_start_capture(id);
1269
1270 case V4L2_ENC_CMD_STOP:
1271 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1272 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1273 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1274 return 0;
1275
1276 case V4L2_ENC_CMD_PAUSE:
1277 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1278 enc->flags = 0;
1279
1280 if (!atomic_read(&itv->capturing))
1281 return -EPERM;
1282 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1283 return 0;
1284
1285 ivtv_mute(itv);
1286 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1287 break;
1288
1289 case V4L2_ENC_CMD_RESUME:
1290 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1291 enc->flags = 0;
1292
1293 if (!atomic_read(&itv->capturing))
1294 return -EPERM;
1295
1296 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1297 return 0;
1298
1299 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1300 ivtv_unmute(itv);
1301 break;
1302 default:
1303 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1304 return -EINVAL;
1305 }
1306
1307 return 0;
1308}
1309
1310static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1311{
1312 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1313
Hans Verkuil3f038d82008-05-29 16:43:54 -03001314 switch (enc->cmd) {
1315 case V4L2_ENC_CMD_START:
1316 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1317 enc->flags = 0;
1318 return 0;
1319
1320 case V4L2_ENC_CMD_STOP:
1321 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1322 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1323 return 0;
1324
1325 case V4L2_ENC_CMD_PAUSE:
1326 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1327 enc->flags = 0;
1328 return 0;
1329
1330 case V4L2_ENC_CMD_RESUME:
1331 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1332 enc->flags = 0;
1333 return 0;
1334 default:
1335 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1336 return -EINVAL;
1337 }
1338}
1339
1340static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1341{
1342 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001343 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001344 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001345
Hans Verkuil3f038d82008-05-29 16:43:54 -03001346 int pixfmt;
1347 static u32 pixel_format[16] = {
1348 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1349 V4L2_PIX_FMT_RGB565,
1350 V4L2_PIX_FMT_RGB555,
1351 V4L2_PIX_FMT_RGB444,
1352 V4L2_PIX_FMT_RGB32,
1353 0,
1354 0,
1355 0,
1356 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1357 V4L2_PIX_FMT_YUV565,
1358 V4L2_PIX_FMT_YUV555,
1359 V4L2_PIX_FMT_YUV444,
1360 V4L2_PIX_FMT_YUV32,
1361 0,
1362 0,
1363 0,
1364 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001365
Hans Verkuil3f038d82008-05-29 16:43:54 -03001366 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1367 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001368 if (!itv->osd_video_pbase)
1369 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001370
Hans Verkuil3f038d82008-05-29 16:43:54 -03001371 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1372 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001373
Hans Verkuil3f038d82008-05-29 16:43:54 -03001374 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1375 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1376 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001377
Hans Verkuil3f038d82008-05-29 16:43:54 -03001378 fb->fmt.pixelformat = pixel_format[pixfmt];
1379 fb->fmt.width = itv->osd_rect.width;
1380 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001381 fb->fmt.field = V4L2_FIELD_INTERLACED;
1382 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001383 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1384 fb->fmt.field = V4L2_FIELD_INTERLACED;
1385 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001386 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1387 fb->fmt.bytesperline *= 2;
1388 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1389 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1390 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001391 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001392 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001393 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001394
Hans Verkuil3f038d82008-05-29 16:43:54 -03001395 if (itv->osd_chroma_key_state)
1396 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001397
Hans Verkuil3f038d82008-05-29 16:43:54 -03001398 if (itv->osd_global_alpha_state)
1399 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001400
Ian Armstrongec9faa12008-10-06 03:06:08 -03001401 if (yi->track_osd)
1402 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1403
Hans Verkuil3f038d82008-05-29 16:43:54 -03001404 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001405
Hans Verkuil3f038d82008-05-29 16:43:54 -03001406 /* no local alpha for RGB565 or unknown formats */
1407 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001408 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001409
Hans Verkuil3f038d82008-05-29 16:43:54 -03001410 /* 16-bit formats have inverted local alpha */
1411 if (pixfmt == 2 || pixfmt == 3)
1412 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1413 else
1414 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001415
Hans Verkuil3f038d82008-05-29 16:43:54 -03001416 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001417 /* 16-bit formats have inverted local alpha */
1418 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001419 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001420 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001422 }
1423
Hans Verkuil3f038d82008-05-29 16:43:54 -03001424 return 0;
1425}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001426
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1428{
1429 struct ivtv_open_id *id = fh;
1430 struct ivtv *itv = id->itv;
1431 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001432
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001434 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001435 if (!itv->osd_video_pbase)
1436 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001437
1438 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1439 itv->osd_local_alpha_state =
1440 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1441 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1442 ivtv_set_osd_alpha(itv);
1443 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001444 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001445}
1446
1447static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1448{
1449 struct ivtv_open_id *id = fh;
1450 struct ivtv *itv = id->itv;
1451
1452 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1453 return -EINVAL;
1454
1455 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1456
1457 return 0;
1458}
1459
Hans Verkuil09250192010-03-27 14:10:13 -03001460static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1461{
1462 switch (sub->type) {
1463 case V4L2_EVENT_VSYNC:
1464 case V4L2_EVENT_EOS:
1465 break;
1466 default:
1467 return -EINVAL;
1468 }
1469 return v4l2_event_subscribe(fh, sub);
1470}
1471
Hans Verkuil3f038d82008-05-29 16:43:54 -03001472static int ivtv_log_status(struct file *file, void *fh)
1473{
1474 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1475 u32 data[CX2341X_MBOX_MAX_DATA];
1476
1477 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1478 struct v4l2_input vidin;
1479 struct v4l2_audio audin;
1480 int i;
1481
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001482 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1483 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001484 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1485 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1486 struct tveeprom tv;
1487
1488 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001489 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001490 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001491 ivtv_get_input(itv, itv->active_input, &vidin);
1492 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1493 IVTV_INFO("Video Input: %s\n", vidin.name);
1494 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1495 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1496 if (has_output) {
1497 struct v4l2_output vidout;
1498 struct v4l2_audioout audout;
1499 int mode = itv->output_mode;
1500 static const char * const output_modes[5] = {
1501 "None",
1502 "MPEG Streaming",
1503 "YUV Streaming",
1504 "YUV Frames",
1505 "Passthrough",
1506 };
1507 static const char * const audio_modes[5] = {
1508 "Stereo",
1509 "Left",
1510 "Right",
1511 "Mono",
1512 "Swapped"
1513 };
1514 static const char * const alpha_mode[4] = {
1515 "None",
1516 "Global",
1517 "Local",
1518 "Global and Local"
1519 };
1520 static const char * const pixel_format[16] = {
1521 "ARGB Indexed",
1522 "RGB 5:6:5",
1523 "ARGB 1:5:5:5",
1524 "ARGB 1:4:4:4",
1525 "ARGB 8:8:8:8",
1526 "5",
1527 "6",
1528 "7",
1529 "AYUV Indexed",
1530 "YUV 5:6:5",
1531 "AYUV 1:5:5:5",
1532 "AYUV 1:4:4:4",
1533 "AYUV 8:8:8:8",
1534 "13",
1535 "14",
1536 "15",
1537 };
1538
1539 ivtv_get_output(itv, itv->active_output, &vidout);
1540 ivtv_get_audio_output(itv, 0, &audout);
1541 IVTV_INFO("Video Output: %s\n", vidout.name);
1542 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1543 audio_modes[itv->audio_stereo_mode],
1544 audio_modes[itv->audio_bilingual_mode]);
1545 if (mode < 0 || mode > OUT_PASSTHROUGH)
1546 mode = OUT_NONE;
1547 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1548 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1549 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1550 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1551 data[0] & 1 ? "On" : "Off",
1552 alpha_mode[(data[0] >> 1) & 0x3],
1553 pixel_format[(data[0] >> 3) & 0xf]);
1554 }
1555 IVTV_INFO("Tuner: %s\n",
1556 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001557 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001558 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1559 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1560 struct ivtv_stream *s = &itv->streams[i];
1561
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001562 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001563 continue;
1564 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1565 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1566 (s->buffers * s->buf_size) / 1024, s->buffers);
1567 }
1568
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001569 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1570 (long long)itv->mpg_data_received,
1571 (long long)itv->vbi_data_inserted);
1572 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1573 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001574
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001575 return 0;
1576}
1577
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001578static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001579{
Hans Verkuil09250192010-03-27 14:10:13 -03001580 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001581 struct ivtv *itv = id->itv;
1582 int nonblocking = filp->f_flags & O_NONBLOCK;
1583 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001584 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001585
1586 switch (cmd) {
1587 case IVTV_IOC_DMA_FRAME: {
1588 struct ivtv_dma_frame *args = arg;
1589
1590 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1591 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1592 return -EINVAL;
1593 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1594 return -EINVAL;
1595 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1596 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001597 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001598 return -EBUSY;
1599 }
1600 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1601 ivtv_release_stream(s);
1602 return -EBUSY;
1603 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001604 /* Mark that this file handle started the UDMA_YUV mode */
1605 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001606 if (args->y_source == NULL)
1607 return 0;
1608 return ivtv_yuv_prep_frame(itv, args);
1609 }
1610
1611 case VIDEO_GET_PTS: {
1612 u32 data[CX2341X_MBOX_MAX_DATA];
1613 u64 *pts = arg;
1614
1615 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1616 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1617 *pts = s->dma_pts;
1618 break;
1619 }
1620 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1621 return -EINVAL;
1622
1623 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1624 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1625 (u64)itv->last_dec_timing[1];
1626 break;
1627 }
1628 *pts = 0;
1629 if (atomic_read(&itv->decoding)) {
1630 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1631 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1632 return -EIO;
1633 }
1634 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1635 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1636 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1637 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1638 }
1639 break;
1640 }
1641
1642 case VIDEO_GET_FRAME_COUNT: {
1643 u32 data[CX2341X_MBOX_MAX_DATA];
1644 u64 *frame = arg;
1645
1646 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1647 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1648 *frame = 0;
1649 break;
1650 }
1651 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1652 return -EINVAL;
1653
1654 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1655 *frame = itv->last_dec_timing[0];
1656 break;
1657 }
1658 *frame = 0;
1659 if (atomic_read(&itv->decoding)) {
1660 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1661 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1662 return -EIO;
1663 }
1664 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1665 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1666 *frame = data[0];
1667 }
1668 break;
1669 }
1670
1671 case VIDEO_PLAY: {
1672 struct video_command vc;
1673
1674 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1675 memset(&vc, 0, sizeof(vc));
1676 vc.cmd = VIDEO_CMD_PLAY;
1677 return ivtv_video_command(itv, id, &vc, 0);
1678 }
1679
1680 case VIDEO_STOP: {
1681 struct video_command vc;
1682
1683 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1684 memset(&vc, 0, sizeof(vc));
1685 vc.cmd = VIDEO_CMD_STOP;
1686 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1687 return ivtv_video_command(itv, id, &vc, 0);
1688 }
1689
1690 case VIDEO_FREEZE: {
1691 struct video_command vc;
1692
1693 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1694 memset(&vc, 0, sizeof(vc));
1695 vc.cmd = VIDEO_CMD_FREEZE;
1696 return ivtv_video_command(itv, id, &vc, 0);
1697 }
1698
1699 case VIDEO_CONTINUE: {
1700 struct video_command vc;
1701
1702 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1703 memset(&vc, 0, sizeof(vc));
1704 vc.cmd = VIDEO_CMD_CONTINUE;
1705 return ivtv_video_command(itv, id, &vc, 0);
1706 }
1707
1708 case VIDEO_COMMAND:
1709 case VIDEO_TRY_COMMAND: {
1710 struct video_command *vc = arg;
1711 int try = (cmd == VIDEO_TRY_COMMAND);
1712
1713 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001714 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001715 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001716 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001717 return ivtv_video_command(itv, id, vc, try);
1718 }
1719
1720 case VIDEO_GET_EVENT: {
1721 struct video_event *ev = arg;
1722 DEFINE_WAIT(wait);
1723
1724 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1725 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1726 return -EINVAL;
1727 memset(ev, 0, sizeof(*ev));
1728 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1729
1730 while (1) {
1731 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1732 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1733 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1734 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001735 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1736 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1737 if (itv->output_mode == OUT_UDMA_YUV &&
1738 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1739 IVTV_YUV_MODE_PROGRESSIVE) {
1740 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1741 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001742 }
1743 if (ev->type)
1744 return 0;
1745 if (nonblocking)
1746 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001747 /* Wait for event. Note that serialize_lock is locked,
1748 so to allow other processes to access the driver while
1749 we are waiting unlock first and later lock again. */
1750 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001751 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001752 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1753 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001754 schedule();
1755 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001756 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001757 if (signal_pending(current)) {
1758 /* return if a signal was received */
1759 IVTV_DEBUG_INFO("User stopped wait for event\n");
1760 return -EINTR;
1761 }
1762 }
1763 break;
1764 }
1765
Hans Verkuilce680252010-04-06 15:58:53 -03001766 case VIDEO_SELECT_SOURCE:
1767 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1768 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1769 return -EINVAL;
1770 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1771
1772 case AUDIO_SET_MUTE:
1773 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1774 itv->speed_mute_audio = iarg;
1775 return 0;
1776
1777 case AUDIO_CHANNEL_SELECT:
1778 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1779 if (iarg > AUDIO_STEREO_SWAPPED)
1780 return -EINVAL;
1781 itv->audio_stereo_mode = iarg;
1782 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1783 return 0;
1784
1785 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1786 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1787 if (iarg > AUDIO_STEREO_SWAPPED)
1788 return -EINVAL;
1789 itv->audio_bilingual_mode = iarg;
1790 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1791 return 0;
1792
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001793 default:
1794 return -EINVAL;
1795 }
1796 return 0;
1797}
1798
Hans Verkuil069b7472008-12-30 07:04:34 -03001799static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001800{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001801 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001802
Hans Verkuild46c17d2007-03-10 17:59:15 -03001803 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001804 case VIDIOC_INT_RESET: {
1805 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001806
Hans Verkuil3f038d82008-05-29 16:43:54 -03001807 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1808 ivtv_reset_ir_gpio(itv);
1809 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001810 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001811 break;
1812 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001813
Hans Verkuilac9575f2009-02-14 19:58:33 -03001814 case IVTV_IOC_DMA_FRAME:
1815 case VIDEO_GET_PTS:
1816 case VIDEO_GET_FRAME_COUNT:
1817 case VIDEO_GET_EVENT:
1818 case VIDEO_PLAY:
1819 case VIDEO_STOP:
1820 case VIDEO_FREEZE:
1821 case VIDEO_CONTINUE:
1822 case VIDEO_COMMAND:
1823 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001824 case VIDEO_SELECT_SOURCE:
1825 case AUDIO_SET_MUTE:
1826 case AUDIO_CHANNEL_SELECT:
1827 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001828 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1829
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001830 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001831 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001832 }
1833 return 0;
1834}
1835
Hans Verkuil09882f02008-10-18 13:42:24 -03001836static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
Hans Verkuilbaa40722007-08-19 07:10:55 -03001837 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001838{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001839 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09250192010-03-27 14:10:13 -03001840 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil09882f02008-10-18 13:42:24 -03001841 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001842
Hans Verkuil3f038d82008-05-29 16:43:54 -03001843 /* check priority */
1844 switch (cmd) {
1845 case VIDIOC_S_CTRL:
1846 case VIDIOC_S_STD:
1847 case VIDIOC_S_INPUT:
1848 case VIDIOC_S_OUTPUT:
1849 case VIDIOC_S_TUNER:
1850 case VIDIOC_S_FREQUENCY:
1851 case VIDIOC_S_FMT:
1852 case VIDIOC_S_CROP:
1853 case VIDIOC_S_AUDIO:
1854 case VIDIOC_S_AUDOUT:
1855 case VIDIOC_S_EXT_CTRLS:
1856 case VIDIOC_S_FBUF:
Hans Verkuil3e56b0f2010-05-02 11:11:40 -03001857 case VIDIOC_S_PRIORITY:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001858 case VIDIOC_OVERLAY:
Hans Verkuilffb48772010-05-01 08:03:24 -03001859 ret = v4l2_prio_check(&itv->prio, id->prio);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001860 if (ret)
1861 return ret;
1862 }
1863
Hans Verkuil37f89f92008-06-22 11:57:31 -03001864 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1865 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001866 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001867 vfd->debug = 0;
1868 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001869}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001870
Hans Verkuil09882f02008-10-18 13:42:24 -03001871long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuilbaa40722007-08-19 07:10:55 -03001872{
Hans Verkuil09250192010-03-27 14:10:13 -03001873 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001874 struct ivtv *itv = id->itv;
Hans Verkuil09882f02008-10-18 13:42:24 -03001875 long res;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001876
Hans Verkuil09250192010-03-27 14:10:13 -03001877 /* DQEVENT can block, so this should not run with the serialize lock */
1878 if (cmd == VIDIOC_DQEVENT)
1879 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001880 mutex_lock(&itv->serialize_lock);
Hans Verkuil09882f02008-10-18 13:42:24 -03001881 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001882 mutex_unlock(&itv->serialize_lock);
1883 return res;
1884}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001885
Hans Verkuila3998102008-07-21 02:57:38 -03001886static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1887 .vidioc_querycap = ivtv_querycap,
1888 .vidioc_g_priority = ivtv_g_priority,
1889 .vidioc_s_priority = ivtv_s_priority,
1890 .vidioc_s_audio = ivtv_s_audio,
1891 .vidioc_g_audio = ivtv_g_audio,
1892 .vidioc_enumaudio = ivtv_enumaudio,
1893 .vidioc_s_audout = ivtv_s_audout,
1894 .vidioc_g_audout = ivtv_g_audout,
1895 .vidioc_enum_input = ivtv_enum_input,
1896 .vidioc_enum_output = ivtv_enum_output,
1897 .vidioc_enumaudout = ivtv_enumaudout,
1898 .vidioc_cropcap = ivtv_cropcap,
1899 .vidioc_s_crop = ivtv_s_crop,
1900 .vidioc_g_crop = ivtv_g_crop,
1901 .vidioc_g_input = ivtv_g_input,
1902 .vidioc_s_input = ivtv_s_input,
1903 .vidioc_g_output = ivtv_g_output,
1904 .vidioc_s_output = ivtv_s_output,
1905 .vidioc_g_frequency = ivtv_g_frequency,
1906 .vidioc_s_frequency = ivtv_s_frequency,
1907 .vidioc_s_tuner = ivtv_s_tuner,
1908 .vidioc_g_tuner = ivtv_g_tuner,
1909 .vidioc_g_enc_index = ivtv_g_enc_index,
1910 .vidioc_g_fbuf = ivtv_g_fbuf,
1911 .vidioc_s_fbuf = ivtv_s_fbuf,
1912 .vidioc_g_std = ivtv_g_std,
1913 .vidioc_s_std = ivtv_s_std,
1914 .vidioc_overlay = ivtv_overlay,
1915 .vidioc_log_status = ivtv_log_status,
1916 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1917 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1918 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1919 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1920 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1921 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1922 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1923 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1924 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1925 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1926 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1927 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1928 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1929 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1930 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1931 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1932 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1933 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1934 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1935 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1936 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1937 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1938 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1939 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1940#ifdef CONFIG_VIDEO_ADV_DEBUG
1941 .vidioc_g_register = ivtv_g_register,
1942 .vidioc_s_register = ivtv_s_register,
1943#endif
1944 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001945 .vidioc_subscribe_event = ivtv_subscribe_event,
1946 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001947};
1948
Hans Verkuil3f038d82008-05-29 16:43:54 -03001949void ivtv_set_funcs(struct video_device *vdev)
1950{
Hans Verkuila3998102008-07-21 02:57:38 -03001951 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001952}