blob: e95ebdeaa72f8e2e93f3d7bbcac9756ffdb71fc1 [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;
165 data[3] = itv->params.video_b_frames;
166 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 Verkuilec105a42009-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 Verkuile88360c2008-06-21 08:00:56 -0300342 pixfmt->width = itv->params.width;
343 pixfmt->height = itv->params.height;
344 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 Verkuil7bf432d2009-02-16 04:25:32 -0300395 v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt);
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;
571 struct cx2341x_mpeg_params *p = &itv->params;
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
579 if (p->width == w && p->height == h)
580 return 0;
581
582 if (atomic_read(&itv->capturing) > 0)
583 return -EBUSY;
584
585 p->width = w;
586 p->height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300587 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
588 fmt->fmt.pix.width /= 2;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300589 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300590 return ivtv_g_fmt_vid_cap(file, fh, fmt);
591}
592
593static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
594{
595 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
596
Hans Verkuila8b86432008-10-04 08:05:30 -0300597 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
598 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300599 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300600 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300601 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300602 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
603}
604
605static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
606{
607 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
608 struct ivtv_open_id *id = fh;
609 struct ivtv *itv = id->itv;
610 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
611
612 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
613 return ret;
614
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300615 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300616 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300617 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300618 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300619 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300620 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
621 return 0;
622}
623
Hans Verkuil3f038d82008-05-29 16:43:54 -0300624static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300625{
Hans Verkuil3f038d82008-05-29 16:43:54 -0300626 struct ivtv_open_id *id = fh;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300627 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300628 struct yuv_playback_info *yi = &itv->yuv_info;
629 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300630
Hans Verkuil3f038d82008-05-29 16:43:54 -0300631 if (ret)
632 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300633
Hans Verkuil3f038d82008-05-29 16:43:54 -0300634 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
635 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300636
Hans Verkuil3f038d82008-05-29 16:43:54 -0300637 /* Return now if we already have some frame data */
638 if (yi->stream_size)
639 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 yi->v4l2_src_w = fmt->fmt.pix.width;
642 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 switch (fmt->fmt.pix.field) {
645 case V4L2_FIELD_NONE:
646 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300647 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300648 case V4L2_FIELD_ANY:
649 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300650 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300651 case V4L2_FIELD_INTERLACED_BT:
652 yi->lace_mode =
653 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
654 break;
655 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300656 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300657 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
658 break;
659 }
660 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
661
662 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
663 itv->dma_data_req_size =
664 1080 * ((yi->v4l2_src_h + 31) & ~31);
665
Hans Verkuil3f038d82008-05-29 16:43:54 -0300666 return 0;
667}
668
669static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
670{
671 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
672 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
673
674 if (ret == 0) {
675 itv->osd_chroma_key = fmt->fmt.win.chromakey;
676 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
677 ivtv_set_osd_alpha(itv);
678 }
679 return ret;
680}
681
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300682static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300683{
684 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
685
686 chip->ident = V4L2_IDENT_NONE;
687 chip->revision = 0;
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300688 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
689 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300690 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
691 return 0;
692 }
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300693 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
694 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300695 return -EINVAL;
696 /* TODO: is this correct? */
697 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300698}
699
Hans Verkuil36ecd492008-06-25 06:00:17 -0300700#ifdef CONFIG_VIDEO_ADV_DEBUG
701static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
702{
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300703 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300704 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300705
706 if (!capable(CAP_SYS_ADMIN))
707 return -EPERM;
708 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
709 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
710 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
711 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
712 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300713 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300714 reg_start = itv->enc_mem;
715 else
716 return -EINVAL;
717
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300718 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300719 if (cmd == VIDIOC_DBG_G_REGISTER)
720 regs->val = readl(regs->reg + reg_start);
721 else
722 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300723 return 0;
724}
725
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300726static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300727{
728 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
729
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300730 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300731 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300732 /* TODO: subdev errors should not be ignored, this should become a
733 subdev helper function. */
734 ivtv_call_all(itv, core, g_register, reg);
735 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300736}
737
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300738static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300739{
740 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
741
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300742 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300743 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300744 /* TODO: subdev errors should not be ignored, this should become a
745 subdev helper function. */
746 ivtv_call_all(itv, core, s_register, reg);
747 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300748}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300749#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300750
751static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
752{
753 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
754
755 *p = v4l2_prio_max(&itv->prio);
756
757 return 0;
758}
759
760static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
761{
762 struct ivtv_open_id *id = fh;
763 struct ivtv *itv = id->itv;
764
765 return v4l2_prio_change(&itv->prio, &id->prio, prio);
766}
767
768static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
769{
770 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
771
Hans Verkuil3f038d82008-05-29 16:43:54 -0300772 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
773 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300774 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300775 vcap->version = IVTV_DRIVER_VERSION; /* version */
776 vcap->capabilities = itv->v4l2_cap; /* capabilities */
Hans Verkuil3f038d82008-05-29 16:43:54 -0300777 return 0;
778}
779
780static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
781{
782 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
783
784 return ivtv_get_audio_input(itv, vin->index, vin);
785}
786
787static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
788{
789 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
790
791 vin->index = itv->audio_input;
792 return ivtv_get_audio_input(itv, vin->index, vin);
793}
794
795static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
796{
797 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
798
799 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300800 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300801
802 itv->audio_input = vout->index;
803 ivtv_audio_set_io(itv);
804
805 return 0;
806}
807
808static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
809{
810 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
811
812 /* set it to defaults from our table */
813 return ivtv_get_audio_output(itv, vin->index, vin);
814}
815
816static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
817{
818 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
819
820 vin->index = 0;
821 return ivtv_get_audio_output(itv, vin->index, vin);
822}
823
824static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
825{
826 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
827
828 return ivtv_get_audio_output(itv, vout->index, vout);
829}
830
831static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
832{
833 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
834
835 /* set it to defaults from our table */
836 return ivtv_get_input(itv, vin->index, vin);
837}
838
839static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
840{
841 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
842
843 return ivtv_get_output(itv, vout->index, vout);
844}
845
846static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
847{
848 struct ivtv_open_id *id = fh;
849 struct ivtv *itv = id->itv;
850 struct yuv_playback_info *yi = &itv->yuv_info;
851 int streamtype;
852
853 streamtype = id->type;
854
855 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
856 return -EINVAL;
857 cropcap->bounds.top = cropcap->bounds.left = 0;
858 cropcap->bounds.width = 720;
859 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
860 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
861 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
862 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
863 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
864 if (yi->track_osd) {
865 cropcap->bounds.width = yi->osd_full_w;
866 cropcap->bounds.height = yi->osd_full_h;
867 } else {
868 cropcap->bounds.width = 720;
869 cropcap->bounds.height =
870 itv->is_out_50hz ? 576 : 480;
871 }
872 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
873 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
874 } else {
875 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
876 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
877 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
878 }
879 cropcap->defrect = cropcap->bounds;
880 return 0;
881}
882
883static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
884{
885 struct ivtv_open_id *id = fh;
886 struct ivtv *itv = id->itv;
887 struct yuv_playback_info *yi = &itv->yuv_info;
888 int streamtype;
889
890 streamtype = id->type;
891
Hans Verkuil3f038d82008-05-29 16:43:54 -0300892 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
893 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
894 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
895 yi->main_rect = crop->c;
896 return 0;
897 } else {
898 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
899 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
900 itv->main_rect = crop->c;
901 return 0;
902 }
903 }
904 return -EINVAL;
905 }
906 return -EINVAL;
907}
908
909static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
910{
911 struct ivtv_open_id *id = fh;
912 struct ivtv *itv = id->itv;
913 struct yuv_playback_info *yi = &itv->yuv_info;
914 int streamtype;
915
916 streamtype = id->type;
917
918 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
919 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
920 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
921 crop->c = yi->main_rect;
922 else
923 crop->c = itv->main_rect;
924 return 0;
925 }
926 return -EINVAL;
927}
928
929static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
930{
931 static struct v4l2_fmtdesc formats[] = {
932 { 0, 0, 0,
933 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
934 { 0, 0, 0, 0 }
935 },
936 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
937 "MPEG", V4L2_PIX_FMT_MPEG,
938 { 0, 0, 0, 0 }
939 }
940 };
941 enum v4l2_buf_type type = fmt->type;
942
943 if (fmt->index > 1)
944 return -EINVAL;
945
946 *fmt = formats[fmt->index];
947 fmt->type = type;
948 return 0;
949}
950
951static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
952{
953 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
954
955 static struct v4l2_fmtdesc formats[] = {
956 { 0, 0, 0,
957 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
958 { 0, 0, 0, 0 }
959 },
960 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
961 "MPEG", V4L2_PIX_FMT_MPEG,
962 { 0, 0, 0, 0 }
963 }
964 };
965 enum v4l2_buf_type type = fmt->type;
966
967 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
968 return -EINVAL;
969
970 if (fmt->index > 1)
971 return -EINVAL;
972
973 *fmt = formats[fmt->index];
974 fmt->type = type;
975
976 return 0;
977}
978
979static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
980{
981 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
982
983 *i = itv->active_input;
984
985 return 0;
986}
987
988int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
989{
990 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
991
992 if (inp < 0 || inp >= itv->nof_inputs)
993 return -EINVAL;
994
995 if (inp == itv->active_input) {
996 IVTV_DEBUG_INFO("Input unchanged\n");
997 return 0;
998 }
999
1000 if (atomic_read(&itv->capturing) > 0) {
1001 return -EBUSY;
1002 }
1003
1004 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1005 itv->active_input, inp);
1006
1007 itv->active_input = inp;
1008 /* Set the audio input to whatever is appropriate for the
1009 input type. */
1010 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1011
1012 /* prevent others from messing with the streams until
1013 we're finished changing inputs. */
1014 ivtv_mute(itv);
1015 ivtv_video_set_io(itv);
1016 ivtv_audio_set_io(itv);
1017 ivtv_unmute(itv);
1018
1019 return 0;
1020}
1021
1022static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1023{
1024 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1025
1026 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1027 return -EINVAL;
1028
1029 *i = itv->active_output;
1030
1031 return 0;
1032}
1033
1034static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1035{
1036 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001037
1038 if (outp >= itv->card->nof_outputs)
1039 return -EINVAL;
1040
1041 if (outp == itv->active_output) {
1042 IVTV_DEBUG_INFO("Output unchanged\n");
1043 return 0;
1044 }
1045 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1046 itv->active_output, outp);
1047
1048 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001049 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1050 SAA7127_INPUT_TYPE_NORMAL,
1051 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001052
1053 return 0;
1054}
1055
1056static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1057{
1058 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1059
1060 if (vf->tuner != 0)
1061 return -EINVAL;
1062
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001063 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001064 return 0;
1065}
1066
1067int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1068{
1069 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1070
1071 if (vf->tuner != 0)
1072 return -EINVAL;
1073
1074 ivtv_mute(itv);
1075 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001076 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001077 ivtv_unmute(itv);
1078 return 0;
1079}
1080
1081static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1082{
1083 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1084
1085 *std = itv->std;
1086 return 0;
1087}
1088
1089int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1090{
Ian Armstrong2443bae2010-03-13 20:22:34 -03001091 DEFINE_WAIT(wait);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001092 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1093 struct yuv_playback_info *yi = &itv->yuv_info;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001094 int f;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001095
1096 if ((*std & V4L2_STD_ALL) == 0)
1097 return -EINVAL;
1098
1099 if (*std == itv->std)
1100 return 0;
1101
1102 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1103 atomic_read(&itv->capturing) > 0 ||
1104 atomic_read(&itv->decoding) > 0) {
1105 /* Switching standard would turn off the radio or mess
1106 with already running streams, prevent that by
1107 returning EBUSY. */
1108 return -EBUSY;
1109 }
1110
1111 itv->std = *std;
1112 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1113 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1114 itv->params.width = 720;
1115 itv->params.height = itv->is_50hz ? 576 : 480;
1116 itv->vbi.count = itv->is_50hz ? 18 : 12;
1117 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1118 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1119
1120 if (itv->hw_flags & IVTV_HW_CX25840)
1121 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1122
1123 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
1124
1125 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001126 ivtv_call_all(itv, core, s_std, itv->std);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001127
1128 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1129 /* set display standard */
1130 itv->std_out = *std;
1131 itv->is_out_60hz = itv->is_60hz;
1132 itv->is_out_50hz = itv->is_50hz;
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001133 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001134
1135 /*
1136 * The next firmware call is time sensitive. Time it to
1137 * avoid risk of a hard lock, by trying to ensure the call
1138 * happens within the first 100 lines of the top field.
1139 * Make 4 attempts to sync to the decoder before giving up.
1140 */
1141 for (f = 0; f < 4; f++) {
1142 prepare_to_wait(&itv->vsync_waitq, &wait,
1143 TASK_UNINTERRUPTIBLE);
Andy Walls4e1af312010-03-13 20:37:25 -03001144 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
Ian Armstrong2443bae2010-03-13 20:22:34 -03001145 break;
1146 schedule_timeout(msecs_to_jiffies(25));
1147 }
1148 finish_wait(&itv->vsync_waitq, &wait);
1149
1150 if (f == 4)
1151 IVTV_WARN("Mode change failed to sync to decoder\n");
1152
Hans Verkuil3f038d82008-05-29 16:43:54 -03001153 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1154 itv->main_rect.left = itv->main_rect.top = 0;
1155 itv->main_rect.width = 720;
1156 itv->main_rect.height = itv->params.height;
1157 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1158 720, itv->main_rect.height, 0, 0);
1159 yi->main_rect = itv->main_rect;
1160 if (!itv->osd_info) {
1161 yi->osd_full_w = 720;
1162 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1163 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001164 }
1165 return 0;
1166}
1167
Hans Verkuil3f038d82008-05-29 16:43:54 -03001168static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001169{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001170 struct ivtv_open_id *id = fh;
1171 struct ivtv *itv = id->itv;
1172
1173 if (vt->index != 0)
1174 return -EINVAL;
1175
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001176 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001177
1178 return 0;
1179}
1180
1181static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1182{
1183 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1184
1185 if (vt->index != 0)
1186 return -EINVAL;
1187
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001188 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001189
1190 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1191 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1192 vt->type = V4L2_TUNER_RADIO;
1193 } else {
1194 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1195 vt->type = V4L2_TUNER_ANALOG_TV;
1196 }
1197
1198 return 0;
1199}
1200
1201static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1202{
1203 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1204 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1205 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001206
Hans Verkuil79afcb12008-06-21 09:02:36 -03001207 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001208 for (f = 0; f < 2; f++) {
1209 for (l = 0; l < 24; l++) {
1210 if (valid_service_line(f, l, itv->is_50hz))
1211 cap->service_lines[f][l] = set;
1212 }
1213 }
1214 return 0;
1215 }
Hans Verkuil79afcb12008-06-21 09:02:36 -03001216 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001217 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1218 return -EINVAL;
1219 if (itv->is_60hz) {
1220 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1221 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1222 } else {
1223 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1224 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1225 }
1226 return 0;
1227 }
1228 return -EINVAL;
1229}
1230
1231static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1232{
1233 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1234 struct v4l2_enc_idx_entry *e = idx->entry;
1235 int entries;
1236 int i;
1237
1238 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1239 IVTV_MAX_PGM_INDEX;
1240 if (entries > V4L2_ENC_IDX_ENTRIES)
1241 entries = V4L2_ENC_IDX_ENTRIES;
1242 idx->entries = 0;
1243 for (i = 0; i < entries; i++) {
1244 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1245 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1246 idx->entries++;
1247 e++;
1248 }
1249 }
1250 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1251 return 0;
1252}
1253
1254static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1255{
1256 struct ivtv_open_id *id = fh;
1257 struct ivtv *itv = id->itv;
1258
Hans Verkuil3f038d82008-05-29 16:43:54 -03001259
1260 switch (enc->cmd) {
1261 case V4L2_ENC_CMD_START:
1262 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1263 enc->flags = 0;
1264 return ivtv_start_capture(id);
1265
1266 case V4L2_ENC_CMD_STOP:
1267 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1268 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1269 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1270 return 0;
1271
1272 case V4L2_ENC_CMD_PAUSE:
1273 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1274 enc->flags = 0;
1275
1276 if (!atomic_read(&itv->capturing))
1277 return -EPERM;
1278 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1279 return 0;
1280
1281 ivtv_mute(itv);
1282 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1283 break;
1284
1285 case V4L2_ENC_CMD_RESUME:
1286 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1287 enc->flags = 0;
1288
1289 if (!atomic_read(&itv->capturing))
1290 return -EPERM;
1291
1292 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1293 return 0;
1294
1295 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1296 ivtv_unmute(itv);
1297 break;
1298 default:
1299 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1300 return -EINVAL;
1301 }
1302
1303 return 0;
1304}
1305
1306static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1307{
1308 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1309
Hans Verkuil3f038d82008-05-29 16:43:54 -03001310 switch (enc->cmd) {
1311 case V4L2_ENC_CMD_START:
1312 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1313 enc->flags = 0;
1314 return 0;
1315
1316 case V4L2_ENC_CMD_STOP:
1317 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1318 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1319 return 0;
1320
1321 case V4L2_ENC_CMD_PAUSE:
1322 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1323 enc->flags = 0;
1324 return 0;
1325
1326 case V4L2_ENC_CMD_RESUME:
1327 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1328 enc->flags = 0;
1329 return 0;
1330 default:
1331 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1332 return -EINVAL;
1333 }
1334}
1335
1336static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1337{
1338 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001339 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001340 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001341
Hans Verkuil3f038d82008-05-29 16:43:54 -03001342 int pixfmt;
1343 static u32 pixel_format[16] = {
1344 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1345 V4L2_PIX_FMT_RGB565,
1346 V4L2_PIX_FMT_RGB555,
1347 V4L2_PIX_FMT_RGB444,
1348 V4L2_PIX_FMT_RGB32,
1349 0,
1350 0,
1351 0,
1352 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1353 V4L2_PIX_FMT_YUV565,
1354 V4L2_PIX_FMT_YUV555,
1355 V4L2_PIX_FMT_YUV444,
1356 V4L2_PIX_FMT_YUV32,
1357 0,
1358 0,
1359 0,
1360 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001361
Hans Verkuil3f038d82008-05-29 16:43:54 -03001362 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1363 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001364 if (!itv->osd_video_pbase)
1365 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001366
Hans Verkuil3f038d82008-05-29 16:43:54 -03001367 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1368 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001369
Hans Verkuil3f038d82008-05-29 16:43:54 -03001370 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1371 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1372 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001373
Hans Verkuil3f038d82008-05-29 16:43:54 -03001374 fb->fmt.pixelformat = pixel_format[pixfmt];
1375 fb->fmt.width = itv->osd_rect.width;
1376 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001377 fb->fmt.field = V4L2_FIELD_INTERLACED;
1378 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001379 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1380 fb->fmt.field = V4L2_FIELD_INTERLACED;
1381 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001382 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1383 fb->fmt.bytesperline *= 2;
1384 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1385 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1386 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001387 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001388 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001389 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001390
Hans Verkuil3f038d82008-05-29 16:43:54 -03001391 if (itv->osd_chroma_key_state)
1392 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001393
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 if (itv->osd_global_alpha_state)
1395 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001396
Ian Armstrongec9faa12008-10-06 03:06:08 -03001397 if (yi->track_osd)
1398 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1399
Hans Verkuil3f038d82008-05-29 16:43:54 -03001400 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001401
Hans Verkuil3f038d82008-05-29 16:43:54 -03001402 /* no local alpha for RGB565 or unknown formats */
1403 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001404 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001405
Hans Verkuil3f038d82008-05-29 16:43:54 -03001406 /* 16-bit formats have inverted local alpha */
1407 if (pixfmt == 2 || pixfmt == 3)
1408 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1409 else
1410 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001411
Hans Verkuil3f038d82008-05-29 16:43:54 -03001412 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001413 /* 16-bit formats have inverted local alpha */
1414 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001415 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001416 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001417 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001418 }
1419
Hans Verkuil3f038d82008-05-29 16:43:54 -03001420 return 0;
1421}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001422
Hans Verkuil3f038d82008-05-29 16:43:54 -03001423static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1424{
1425 struct ivtv_open_id *id = fh;
1426 struct ivtv *itv = id->itv;
1427 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001428
Hans Verkuil3f038d82008-05-29 16:43:54 -03001429 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001430 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001431 if (!itv->osd_video_pbase)
1432 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433
1434 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1435 itv->osd_local_alpha_state =
1436 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1437 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1438 ivtv_set_osd_alpha(itv);
1439 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001440 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001441}
1442
1443static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1444{
1445 struct ivtv_open_id *id = fh;
1446 struct ivtv *itv = id->itv;
1447
1448 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1449 return -EINVAL;
1450
1451 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1452
1453 return 0;
1454}
1455
Hans Verkuil09250192010-03-27 14:10:13 -03001456static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1457{
1458 switch (sub->type) {
1459 case V4L2_EVENT_VSYNC:
1460 case V4L2_EVENT_EOS:
1461 break;
1462 default:
1463 return -EINVAL;
1464 }
1465 return v4l2_event_subscribe(fh, sub);
1466}
1467
Hans Verkuil3f038d82008-05-29 16:43:54 -03001468static int ivtv_log_status(struct file *file, void *fh)
1469{
1470 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1471 u32 data[CX2341X_MBOX_MAX_DATA];
1472
1473 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1474 struct v4l2_input vidin;
1475 struct v4l2_audio audin;
1476 int i;
1477
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001478 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1479 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001480 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1481 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1482 struct tveeprom tv;
1483
1484 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001485 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001486 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001487 ivtv_get_input(itv, itv->active_input, &vidin);
1488 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1489 IVTV_INFO("Video Input: %s\n", vidin.name);
1490 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1491 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1492 if (has_output) {
1493 struct v4l2_output vidout;
1494 struct v4l2_audioout audout;
1495 int mode = itv->output_mode;
1496 static const char * const output_modes[5] = {
1497 "None",
1498 "MPEG Streaming",
1499 "YUV Streaming",
1500 "YUV Frames",
1501 "Passthrough",
1502 };
1503 static const char * const audio_modes[5] = {
1504 "Stereo",
1505 "Left",
1506 "Right",
1507 "Mono",
1508 "Swapped"
1509 };
1510 static const char * const alpha_mode[4] = {
1511 "None",
1512 "Global",
1513 "Local",
1514 "Global and Local"
1515 };
1516 static const char * const pixel_format[16] = {
1517 "ARGB Indexed",
1518 "RGB 5:6:5",
1519 "ARGB 1:5:5:5",
1520 "ARGB 1:4:4:4",
1521 "ARGB 8:8:8:8",
1522 "5",
1523 "6",
1524 "7",
1525 "AYUV Indexed",
1526 "YUV 5:6:5",
1527 "AYUV 1:5:5:5",
1528 "AYUV 1:4:4:4",
1529 "AYUV 8:8:8:8",
1530 "13",
1531 "14",
1532 "15",
1533 };
1534
1535 ivtv_get_output(itv, itv->active_output, &vidout);
1536 ivtv_get_audio_output(itv, 0, &audout);
1537 IVTV_INFO("Video Output: %s\n", vidout.name);
1538 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1539 audio_modes[itv->audio_stereo_mode],
1540 audio_modes[itv->audio_bilingual_mode]);
1541 if (mode < 0 || mode > OUT_PASSTHROUGH)
1542 mode = OUT_NONE;
1543 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1544 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1545 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1546 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1547 data[0] & 1 ? "On" : "Off",
1548 alpha_mode[(data[0] >> 1) & 0x3],
1549 pixel_format[(data[0] >> 3) & 0xf]);
1550 }
1551 IVTV_INFO("Tuner: %s\n",
1552 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001553 cx2341x_log_status(&itv->params, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001554 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1555 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1556 struct ivtv_stream *s = &itv->streams[i];
1557
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001558 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001559 continue;
1560 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1561 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1562 (s->buffers * s->buf_size) / 1024, s->buffers);
1563 }
1564
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001565 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1566 (long long)itv->mpg_data_received,
1567 (long long)itv->vbi_data_inserted);
1568 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1569 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001570
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001571 return 0;
1572}
1573
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001574static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001575{
Hans Verkuil09250192010-03-27 14:10:13 -03001576 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001577 struct ivtv *itv = id->itv;
1578 int nonblocking = filp->f_flags & O_NONBLOCK;
1579 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001580 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001581
1582 switch (cmd) {
1583 case IVTV_IOC_DMA_FRAME: {
1584 struct ivtv_dma_frame *args = arg;
1585
1586 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1587 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1588 return -EINVAL;
1589 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1590 return -EINVAL;
1591 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1592 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001593 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001594 return -EBUSY;
1595 }
1596 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1597 ivtv_release_stream(s);
1598 return -EBUSY;
1599 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001600 /* Mark that this file handle started the UDMA_YUV mode */
1601 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001602 if (args->y_source == NULL)
1603 return 0;
1604 return ivtv_yuv_prep_frame(itv, args);
1605 }
1606
1607 case VIDEO_GET_PTS: {
1608 u32 data[CX2341X_MBOX_MAX_DATA];
1609 u64 *pts = arg;
1610
1611 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1612 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1613 *pts = s->dma_pts;
1614 break;
1615 }
1616 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1617 return -EINVAL;
1618
1619 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1620 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1621 (u64)itv->last_dec_timing[1];
1622 break;
1623 }
1624 *pts = 0;
1625 if (atomic_read(&itv->decoding)) {
1626 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1627 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1628 return -EIO;
1629 }
1630 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1631 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1632 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1633 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1634 }
1635 break;
1636 }
1637
1638 case VIDEO_GET_FRAME_COUNT: {
1639 u32 data[CX2341X_MBOX_MAX_DATA];
1640 u64 *frame = arg;
1641
1642 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1643 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1644 *frame = 0;
1645 break;
1646 }
1647 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1648 return -EINVAL;
1649
1650 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1651 *frame = itv->last_dec_timing[0];
1652 break;
1653 }
1654 *frame = 0;
1655 if (atomic_read(&itv->decoding)) {
1656 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1657 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1658 return -EIO;
1659 }
1660 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1661 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1662 *frame = data[0];
1663 }
1664 break;
1665 }
1666
1667 case VIDEO_PLAY: {
1668 struct video_command vc;
1669
1670 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1671 memset(&vc, 0, sizeof(vc));
1672 vc.cmd = VIDEO_CMD_PLAY;
1673 return ivtv_video_command(itv, id, &vc, 0);
1674 }
1675
1676 case VIDEO_STOP: {
1677 struct video_command vc;
1678
1679 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1680 memset(&vc, 0, sizeof(vc));
1681 vc.cmd = VIDEO_CMD_STOP;
1682 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1683 return ivtv_video_command(itv, id, &vc, 0);
1684 }
1685
1686 case VIDEO_FREEZE: {
1687 struct video_command vc;
1688
1689 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1690 memset(&vc, 0, sizeof(vc));
1691 vc.cmd = VIDEO_CMD_FREEZE;
1692 return ivtv_video_command(itv, id, &vc, 0);
1693 }
1694
1695 case VIDEO_CONTINUE: {
1696 struct video_command vc;
1697
1698 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1699 memset(&vc, 0, sizeof(vc));
1700 vc.cmd = VIDEO_CMD_CONTINUE;
1701 return ivtv_video_command(itv, id, &vc, 0);
1702 }
1703
1704 case VIDEO_COMMAND:
1705 case VIDEO_TRY_COMMAND: {
1706 struct video_command *vc = arg;
1707 int try = (cmd == VIDEO_TRY_COMMAND);
1708
1709 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001710 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001711 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001712 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001713 return ivtv_video_command(itv, id, vc, try);
1714 }
1715
1716 case VIDEO_GET_EVENT: {
1717 struct video_event *ev = arg;
1718 DEFINE_WAIT(wait);
1719
1720 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1721 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1722 return -EINVAL;
1723 memset(ev, 0, sizeof(*ev));
1724 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1725
1726 while (1) {
1727 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1728 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1729 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1730 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001731 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1732 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1733 if (itv->output_mode == OUT_UDMA_YUV &&
1734 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1735 IVTV_YUV_MODE_PROGRESSIVE) {
1736 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1737 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001738 }
1739 if (ev->type)
1740 return 0;
1741 if (nonblocking)
1742 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001743 /* Wait for event. Note that serialize_lock is locked,
1744 so to allow other processes to access the driver while
1745 we are waiting unlock first and later lock again. */
1746 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001747 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001748 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1749 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001750 schedule();
1751 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001752 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001753 if (signal_pending(current)) {
1754 /* return if a signal was received */
1755 IVTV_DEBUG_INFO("User stopped wait for event\n");
1756 return -EINTR;
1757 }
1758 }
1759 break;
1760 }
1761
Hans Verkuilce680252010-04-06 15:58:53 -03001762 case VIDEO_SELECT_SOURCE:
1763 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1764 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1765 return -EINVAL;
1766 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1767
1768 case AUDIO_SET_MUTE:
1769 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1770 itv->speed_mute_audio = iarg;
1771 return 0;
1772
1773 case AUDIO_CHANNEL_SELECT:
1774 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1775 if (iarg > AUDIO_STEREO_SWAPPED)
1776 return -EINVAL;
1777 itv->audio_stereo_mode = iarg;
1778 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1779 return 0;
1780
1781 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1782 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1783 if (iarg > AUDIO_STEREO_SWAPPED)
1784 return -EINVAL;
1785 itv->audio_bilingual_mode = iarg;
1786 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1787 return 0;
1788
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001789 default:
1790 return -EINVAL;
1791 }
1792 return 0;
1793}
1794
Hans Verkuil069b7472008-12-30 07:04:34 -03001795static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001796{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001797 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001798
Hans Verkuild46c17d2007-03-10 17:59:15 -03001799 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001800 case VIDIOC_INT_RESET: {
1801 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001802
Hans Verkuil3f038d82008-05-29 16:43:54 -03001803 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1804 ivtv_reset_ir_gpio(itv);
1805 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001806 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001807 break;
1808 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001809
Hans Verkuilac9575f2009-02-14 19:58:33 -03001810 case IVTV_IOC_DMA_FRAME:
1811 case VIDEO_GET_PTS:
1812 case VIDEO_GET_FRAME_COUNT:
1813 case VIDEO_GET_EVENT:
1814 case VIDEO_PLAY:
1815 case VIDEO_STOP:
1816 case VIDEO_FREEZE:
1817 case VIDEO_CONTINUE:
1818 case VIDEO_COMMAND:
1819 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001820 case VIDEO_SELECT_SOURCE:
1821 case AUDIO_SET_MUTE:
1822 case AUDIO_CHANNEL_SELECT:
1823 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001824 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1825
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001826 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001827 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001828 }
1829 return 0;
1830}
1831
Hans Verkuil09882f02008-10-18 13:42:24 -03001832static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
Hans Verkuilbaa40722007-08-19 07:10:55 -03001833 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001834{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001835 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09250192010-03-27 14:10:13 -03001836 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil09882f02008-10-18 13:42:24 -03001837 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001838
Hans Verkuil3f038d82008-05-29 16:43:54 -03001839 /* check priority */
1840 switch (cmd) {
1841 case VIDIOC_S_CTRL:
1842 case VIDIOC_S_STD:
1843 case VIDIOC_S_INPUT:
1844 case VIDIOC_S_OUTPUT:
1845 case VIDIOC_S_TUNER:
1846 case VIDIOC_S_FREQUENCY:
1847 case VIDIOC_S_FMT:
1848 case VIDIOC_S_CROP:
1849 case VIDIOC_S_AUDIO:
1850 case VIDIOC_S_AUDOUT:
1851 case VIDIOC_S_EXT_CTRLS:
1852 case VIDIOC_S_FBUF:
1853 case VIDIOC_OVERLAY:
1854 ret = v4l2_prio_check(&itv->prio, &id->prio);
1855 if (ret)
1856 return ret;
1857 }
1858
Hans Verkuil37f89f92008-06-22 11:57:31 -03001859 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1860 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001861 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001862 vfd->debug = 0;
1863 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001864}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001865
Hans Verkuil09882f02008-10-18 13:42:24 -03001866long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuilbaa40722007-08-19 07:10:55 -03001867{
Hans Verkuil09250192010-03-27 14:10:13 -03001868 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001869 struct ivtv *itv = id->itv;
Hans Verkuil09882f02008-10-18 13:42:24 -03001870 long res;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001871
Hans Verkuil09250192010-03-27 14:10:13 -03001872 /* DQEVENT can block, so this should not run with the serialize lock */
1873 if (cmd == VIDIOC_DQEVENT)
1874 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001875 mutex_lock(&itv->serialize_lock);
Hans Verkuil09882f02008-10-18 13:42:24 -03001876 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001877 mutex_unlock(&itv->serialize_lock);
1878 return res;
1879}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001880
Hans Verkuila3998102008-07-21 02:57:38 -03001881static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1882 .vidioc_querycap = ivtv_querycap,
1883 .vidioc_g_priority = ivtv_g_priority,
1884 .vidioc_s_priority = ivtv_s_priority,
1885 .vidioc_s_audio = ivtv_s_audio,
1886 .vidioc_g_audio = ivtv_g_audio,
1887 .vidioc_enumaudio = ivtv_enumaudio,
1888 .vidioc_s_audout = ivtv_s_audout,
1889 .vidioc_g_audout = ivtv_g_audout,
1890 .vidioc_enum_input = ivtv_enum_input,
1891 .vidioc_enum_output = ivtv_enum_output,
1892 .vidioc_enumaudout = ivtv_enumaudout,
1893 .vidioc_cropcap = ivtv_cropcap,
1894 .vidioc_s_crop = ivtv_s_crop,
1895 .vidioc_g_crop = ivtv_g_crop,
1896 .vidioc_g_input = ivtv_g_input,
1897 .vidioc_s_input = ivtv_s_input,
1898 .vidioc_g_output = ivtv_g_output,
1899 .vidioc_s_output = ivtv_s_output,
1900 .vidioc_g_frequency = ivtv_g_frequency,
1901 .vidioc_s_frequency = ivtv_s_frequency,
1902 .vidioc_s_tuner = ivtv_s_tuner,
1903 .vidioc_g_tuner = ivtv_g_tuner,
1904 .vidioc_g_enc_index = ivtv_g_enc_index,
1905 .vidioc_g_fbuf = ivtv_g_fbuf,
1906 .vidioc_s_fbuf = ivtv_s_fbuf,
1907 .vidioc_g_std = ivtv_g_std,
1908 .vidioc_s_std = ivtv_s_std,
1909 .vidioc_overlay = ivtv_overlay,
1910 .vidioc_log_status = ivtv_log_status,
1911 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1912 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1913 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1914 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1915 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1916 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1917 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1918 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1919 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1920 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1921 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1922 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1923 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1924 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1925 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1926 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1927 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1928 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1929 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1930 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1931 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1932 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1933 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1934 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1935#ifdef CONFIG_VIDEO_ADV_DEBUG
1936 .vidioc_g_register = ivtv_g_register,
1937 .vidioc_s_register = ivtv_s_register,
1938#endif
1939 .vidioc_default = ivtv_default,
1940 .vidioc_queryctrl = ivtv_queryctrl,
1941 .vidioc_querymenu = ivtv_querymenu,
1942 .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls,
1943 .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls,
1944 .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls,
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}