blob: ff75d07097b2bc8126acea9160f0b110f18028db [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-version.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030028#include "ivtv-routing.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030029#include "ivtv-streams.h"
30#include "ivtv-yuv.h"
31#include "ivtv-ioctl.h"
32#include "ivtv-gpio.h"
33#include "ivtv-controls.h"
34#include "ivtv-cards.h"
35#include <media/saa7127.h>
36#include <media/tveeprom.h>
37#include <media/v4l2-chip-ident.h>
Hans Verkuil09250192010-03-27 14:10:13 -030038#include <media/v4l2-event.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030039#include <linux/dvb/audio.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030040
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030041u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030042{
43 switch (type) {
44 case V4L2_SLICED_TELETEXT_B:
45 return IVTV_SLICED_TYPE_TELETEXT_B;
46 case V4L2_SLICED_CAPTION_525:
47 return IVTV_SLICED_TYPE_CAPTION_525;
48 case V4L2_SLICED_WSS_625:
49 return IVTV_SLICED_TYPE_WSS_625;
50 case V4L2_SLICED_VPS:
51 return IVTV_SLICED_TYPE_VPS;
52 default:
53 return 0;
54 }
55}
56
57static int valid_service_line(int field, int line, int is_pal)
58{
59 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
60 (!is_pal && line >= 10 && line < 22);
61}
62
63static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
64{
65 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
66 int i;
67
68 set = set & valid_set;
69 if (set == 0 || !valid_service_line(field, line, is_pal)) {
70 return 0;
71 }
72 if (!is_pal) {
73 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
74 return V4L2_SLICED_CAPTION_525;
75 }
76 else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625;
81 if (line == 23)
82 return 0;
83 }
84 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set)
86 return 1 << i;
87 }
88 return 0;
89}
90
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030091void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030092{
93 u16 set = fmt->service_set;
94 int f, l;
95
96 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++) {
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 }
101 }
102}
103
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300104static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300105{
106 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300107
108 for (f = 0; f < 2; f++) {
109 for (l = 0; l < 24; l++) {
110 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300111 }
112 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300113}
114
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300115u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300116{
117 int f, l;
118 u16 set = 0;
119
120 for (f = 0; f < 2; f++) {
121 for (l = 0; l < 24; l++) {
122 set |= fmt->service_lines[f][l];
123 }
124 }
125 return set;
126}
127
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300128void ivtv_set_osd_alpha(struct ivtv *itv)
129{
130 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
131 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300132 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300133}
134
135int ivtv_set_speed(struct ivtv *itv, int speed)
136{
137 u32 data[CX2341X_MBOX_MAX_DATA];
138 struct ivtv_stream *s;
139 int single_step = (speed == 1 || speed == -1);
140 DEFINE_WAIT(wait);
141
142 if (speed == 0) speed = 1000;
143
144 /* No change? */
145 if (speed == itv->speed && !single_step)
146 return 0;
147
148 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
149
150 if (single_step && (speed < 0) == (itv->speed < 0)) {
151 /* Single step video and no need to change direction */
152 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
153 itv->speed = speed;
154 return 0;
155 }
156 if (single_step)
157 /* Need to change direction */
158 speed = speed < 0 ? -1000 : 1000;
159
160 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
161 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
162 data[1] = (speed < 0);
163 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300164 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300165 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
166 data[5] = 0;
167 data[6] = 0;
168
169 if (speed == 1500 || speed == -1500) data[0] |= 1;
170 else if (speed == 2000 || speed == -2000) data[0] |= 2;
171 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
172 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
173
174 /* If not decoding, just change speed setting */
175 if (atomic_read(&itv->decoding) > 0) {
176 int got_sig = 0;
177
178 /* Stop all DMA and decoding activity */
179 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
180
181 /* Wait for any DMA to finish */
182 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -0300183 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300184 got_sig = signal_pending(current);
185 if (got_sig)
186 break;
187 got_sig = 0;
188 schedule();
189 }
190 finish_wait(&itv->dma_waitq, &wait);
191 if (got_sig)
192 return -EINTR;
193
194 /* Change Speed safely */
195 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
196 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
197 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
198 }
199 if (single_step) {
200 speed = (speed < 0) ? -1 : 1;
201 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
202 }
203 itv->speed = speed;
204 return 0;
205}
206
207static int ivtv_validate_speed(int cur_speed, int new_speed)
208{
209 int fact = new_speed < 0 ? -1 : 1;
210 int s;
211
Hans Verkuil94dee762008-04-26 09:26:13 -0300212 if (cur_speed == 0)
213 cur_speed = 1000;
214 if (new_speed < 0)
215 new_speed = -new_speed;
216 if (cur_speed < 0)
217 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300218
219 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300220 if (new_speed > 1500)
221 return fact * 2000;
222 if (new_speed > 1000)
223 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300224 }
225 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300226 if (new_speed >= 2000)
227 return fact * 2000;
228 if (new_speed >= 1500)
229 return fact * 1500;
230 if (new_speed >= 1000)
231 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300232 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300233 if (new_speed == 0)
234 return 1000;
235 if (new_speed == 1 || new_speed == 1000)
236 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300237
238 s = new_speed;
239 new_speed = 1000 / new_speed;
240 if (1000 / cur_speed == new_speed)
241 new_speed += (cur_speed < s) ? -1 : 1;
242 if (new_speed > 60) return 1000 / (fact * 60);
243 return 1000 / (fact * new_speed);
244}
245
246static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
247 struct video_command *vc, int try)
248{
249 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
250
251 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
252 return -EINVAL;
253
254 switch (vc->cmd) {
255 case VIDEO_CMD_PLAY: {
Hans Verkuil25415cf2007-03-10 18:29:48 -0300256 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300257 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
258 if (vc->play.speed < 0)
259 vc->play.format = VIDEO_PLAY_FMT_GOP;
260 if (try) break;
261
262 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
263 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300264 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
265 /* forces ivtv_set_speed to be called */
266 itv->speed = 0;
267 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300268 return ivtv_start_decoding(id, vc->play.speed);
269 }
270
271 case VIDEO_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -0300272 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300273 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
274 vc->stop.pts = 0;
275 if (try) break;
276 if (atomic_read(&itv->decoding) == 0)
277 return 0;
278 if (itv->output_mode != OUT_MPG)
279 return -EBUSY;
280
281 itv->output_mode = OUT_NONE;
282 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
283
284 case VIDEO_CMD_FREEZE:
Hans Verkuil018ba852007-04-10 18:59:09 -0300285 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300286 if (try) break;
287 if (itv->output_mode != OUT_MPG)
288 return -EBUSY;
289 if (atomic_read(&itv->decoding) > 0) {
290 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
291 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300292 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300293 }
294 break;
295
296 case VIDEO_CMD_CONTINUE:
Hans Verkuil25415cf2007-03-10 18:29:48 -0300297 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300298 if (try) break;
299 if (itv->output_mode != OUT_MPG)
300 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300301 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
302 int speed = itv->speed;
303 itv->speed = 0;
304 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300305 }
306 break;
307
308 default:
309 return -EINVAL;
310 }
311 return 0;
312}
313
Hans Verkuil3f038d82008-05-29 16:43:54 -0300314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300315{
Hans Verkuil2f824412011-03-12 06:43:28 -0300316 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300318
Hans Verkuile88360c2008-06-21 08:00:56 -0300319 vbifmt->reserved[0] = 0;
320 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300321 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300322 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300323 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
324 if (itv->is_60hz) {
325 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
326 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
327 } else {
328 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
329 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
330 }
331 vbifmt->service_set = ivtv_get_service_set(vbifmt);
332 return 0;
333}
334
335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
336{
Hans Verkuil2f824412011-03-12 06:43:28 -0300337 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300338 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300340
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300341 pixfmt->width = itv->cxhdl.width;
342 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300343 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
344 pixfmt->field = V4L2_FIELD_INTERLACED;
345 pixfmt->priv = 0;
346 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
347 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300348 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
349 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300350 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300351 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300352 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
353 pixfmt->sizeimage = 128 * 1024;
354 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300355 }
356 return 0;
357}
358
Hans Verkuil3f038d82008-05-29 16:43:54 -0300359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300360{
Hans Verkuil2f824412011-03-12 06:43:28 -0300361 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300363
Hans Verkuile88360c2008-06-21 08:00:56 -0300364 vbifmt->sampling_rate = 27000000;
365 vbifmt->offset = 248;
366 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
367 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
368 vbifmt->start[0] = itv->vbi.start[0];
369 vbifmt->start[1] = itv->vbi.start[1];
370 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
371 vbifmt->flags = 0;
372 vbifmt->reserved[0] = 0;
373 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300374 return 0;
375}
376
377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
378{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300380 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300381 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300382
Hans Verkuile88360c2008-06-21 08:00:56 -0300383 vbifmt->reserved[0] = 0;
384 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300385 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300386
Hans Verkuil3f038d82008-05-29 16:43:54 -0300387 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
388 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
389 V4L2_SLICED_VBI_525;
390 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300391 return 0;
392 }
393
Hans Verkuil4ff07902010-03-14 12:18:18 -0300394 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 vbifmt->service_set = ivtv_get_service_set(vbifmt);
396 return 0;
397}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300398
Hans Verkuil3f038d82008-05-29 16:43:54 -0300399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
400{
Hans Verkuil2f824412011-03-12 06:43:28 -0300401 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300402 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300404
Hans Verkuil3f038d82008-05-29 16:43:54 -0300405 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300406 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300407 pixfmt->width = itv->main_rect.width;
408 pixfmt->height = itv->main_rect.height;
409 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
410 pixfmt->field = V4L2_FIELD_INTERLACED;
411 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300412 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
413 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
414 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300415 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300416 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
417 break;
418 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300419 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300420 break;
421 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300422 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300423 break;
424 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300425 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
426 pixfmt->bytesperline = 720;
427 pixfmt->width = itv->yuv_info.v4l2_src_w;
428 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300429 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->sizeimage =
431 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300432 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
434 pixfmt->sizeimage = 128 * 1024;
435 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300436 }
437 return 0;
438}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300439
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
441{
Hans Verkuil2f824412011-03-12 06:43:28 -0300442 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300443 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300444
445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
446 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300447 winfmt->chromakey = itv->osd_chroma_key;
448 winfmt->global_alpha = itv->osd_global_alpha;
449 winfmt->field = V4L2_FIELD_INTERLACED;
450 winfmt->clips = NULL;
451 winfmt->clipcount = 0;
452 winfmt->bitmap = NULL;
453 winfmt->w.top = winfmt->w.left = 0;
454 winfmt->w.width = itv->osd_rect.width;
455 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300456 return 0;
457}
458
459static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
460{
461 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
462}
463
464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
465{
Hans Verkuil2f824412011-03-12 06:43:28 -0300466 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300467 struct ivtv *itv = id->itv;
468 int w = fmt->fmt.pix.width;
469 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300470 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300471
472 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300473 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300474 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
475 /* YUV height must be a multiple of 32 */
476 h &= ~0x1f;
477 min_h = 32;
478 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300479 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300480 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300481 ivtv_g_fmt_vid_cap(file, fh, fmt);
482 fmt->fmt.pix.width = w;
483 fmt->fmt.pix.height = h;
484 return 0;
485}
486
487static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
488{
489 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
490}
491
492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
493{
494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300495 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300496 struct ivtv *itv = id->itv;
497
498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
499 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300500
501 /* set sliced VBI capture format */
502 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300503 vbifmt->reserved[0] = 0;
504 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300505
506 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300507 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300508 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300509 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300510 return 0;
511}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300512
Hans Verkuil3f038d82008-05-29 16:43:54 -0300513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
514{
Hans Verkuil2f824412011-03-12 06:43:28 -0300515 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300516 s32 w = fmt->fmt.pix.width;
517 s32 h = fmt->fmt.pix.height;
518 int field = fmt->fmt.pix.field;
519 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300520
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300521 w = min(w, 720);
522 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300523 /* Why can the height be 576 even when the output is NTSC?
524
525 Internally the buffers of the PVR350 are always set to 720x576. The
526 decoded video frame will always be placed in the top left corner of
527 this buffer. For any video which is not 720x576, the buffer will
528 then be cropped to remove the unused right and lower areas, with
529 the remaining image being scaled by the hardware to fit the display
530 area. The video can be scaled both up and down, so a 720x480 video
531 can be displayed full-screen on PAL and a 720x576 video can be
532 displayed without cropping on NTSC.
533
534 Note that the scaling only occurs on the video stream, the osd
535 resolution is locked to the broadcast standard and not scaled.
536
537 Thanks to Ian Armstrong for this explanation. */
538 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300539 h = max(h, 2);
540 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300541 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300542 fmt->fmt.pix.width = w;
543 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300544 return ret;
545}
546
547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
548{
Hans Verkuil2f824412011-03-12 06:43:28 -0300549 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300550 u32 chromakey = fmt->fmt.win.chromakey;
551 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552
553 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
554 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300555 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
556 fmt->fmt.win.chromakey = chromakey;
557 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300558 return 0;
559}
560
561static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
562{
563 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
564}
565
566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
567{
Hans Verkuil2f824412011-03-12 06:43:28 -0300568 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300569 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300570 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300572 int w = fmt->fmt.pix.width;
573 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300574
575 if (ret)
576 return ret;
577
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300578 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300579 return 0;
580
581 if (atomic_read(&itv->capturing) > 0)
582 return -EBUSY;
583
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300584 itv->cxhdl.width = w;
585 itv->cxhdl.height = h;
586 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300587 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300588 mbus_fmt.width = fmt->fmt.pix.width;
589 mbus_fmt.height = h;
590 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
591 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300592 return ivtv_g_fmt_vid_cap(file, fh, fmt);
593}
594
595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
596{
Hans Verkuil2f824412011-03-12 06:43:28 -0300597 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300598
Hans Verkuila8b86432008-10-04 08:05:30 -0300599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
600 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300601 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300602 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300603 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300604 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
605}
606
607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
608{
609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300610 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300611 struct ivtv *itv = id->itv;
612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
613
614 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
615 return ret;
616
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300617 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300618 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300619 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300620 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300621 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300622 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
623 return 0;
624}
625
Hans Verkuil3f038d82008-05-29 16:43:54 -0300626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300627{
Hans Verkuil2f824412011-03-12 06:43:28 -0300628 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300629 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300630 struct yuv_playback_info *yi = &itv->yuv_info;
631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300632
Hans Verkuil3f038d82008-05-29 16:43:54 -0300633 if (ret)
634 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300635
Hans Verkuil3f038d82008-05-29 16:43:54 -0300636 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
637 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300638
Hans Verkuil3f038d82008-05-29 16:43:54 -0300639 /* Return now if we already have some frame data */
640 if (yi->stream_size)
641 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300642
Hans Verkuil3f038d82008-05-29 16:43:54 -0300643 yi->v4l2_src_w = fmt->fmt.pix.width;
644 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300645
Hans Verkuil3f038d82008-05-29 16:43:54 -0300646 switch (fmt->fmt.pix.field) {
647 case V4L2_FIELD_NONE:
648 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300649 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300650 case V4L2_FIELD_ANY:
651 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300652 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300653 case V4L2_FIELD_INTERLACED_BT:
654 yi->lace_mode =
655 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
656 break;
657 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300658 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300659 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
660 break;
661 }
662 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
663
664 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
665 itv->dma_data_req_size =
666 1080 * ((yi->v4l2_src_h + 31) & ~31);
667
Hans Verkuil3f038d82008-05-29 16:43:54 -0300668 return 0;
669}
670
671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
672{
Hans Verkuil2f824412011-03-12 06:43:28 -0300673 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
675
676 if (ret == 0) {
677 itv->osd_chroma_key = fmt->fmt.win.chromakey;
678 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
679 ivtv_set_osd_alpha(itv);
680 }
681 return ret;
682}
683
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300685{
Hans Verkuil2f824412011-03-12 06:43:28 -0300686 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300687
688 chip->ident = V4L2_IDENT_NONE;
689 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300690 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
691 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300692 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
693 return 0;
694 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300695 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
696 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300697 return -EINVAL;
698 /* TODO: is this correct? */
699 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300700}
701
Hans Verkuil36ecd492008-06-25 06:00:17 -0300702#ifdef CONFIG_VIDEO_ADV_DEBUG
703static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
704{
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300705 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300706 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300707
708 if (!capable(CAP_SYS_ADMIN))
709 return -EPERM;
710 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
711 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
712 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
713 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
714 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300715 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300716 reg_start = itv->enc_mem;
717 else
718 return -EINVAL;
719
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300720 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300721 if (cmd == VIDIOC_DBG_G_REGISTER)
722 regs->val = readl(regs->reg + reg_start);
723 else
724 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300725 return 0;
726}
727
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300729{
Hans Verkuil2f824412011-03-12 06:43:28 -0300730 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300731
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300732 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300734 /* TODO: subdev errors should not be ignored, this should become a
735 subdev helper function. */
736 ivtv_call_all(itv, core, g_register, reg);
737 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300738}
739
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741{
Hans Verkuil2f824412011-03-12 06:43:28 -0300742 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300743
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300744 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300746 /* TODO: subdev errors should not be ignored, this should become a
747 subdev helper function. */
748 ivtv_call_all(itv, core, s_register, reg);
749 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300750}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300751#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752
Hans Verkuil3f038d82008-05-29 16:43:54 -0300753static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
754{
Hans Verkuil2f824412011-03-12 06:43:28 -0300755 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300756
Hans Verkuil3f038d82008-05-29 16:43:54 -0300757 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
758 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300759 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300760 vcap->capabilities = itv->v4l2_cap; /* capabilities */
Hans Verkuil3f038d82008-05-29 16:43:54 -0300761 return 0;
762}
763
764static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
765{
Hans Verkuil2f824412011-03-12 06:43:28 -0300766 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300767
768 return ivtv_get_audio_input(itv, vin->index, vin);
769}
770
771static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
772{
Hans Verkuil2f824412011-03-12 06:43:28 -0300773 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300774
775 vin->index = itv->audio_input;
776 return ivtv_get_audio_input(itv, vin->index, vin);
777}
778
779static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
780{
Hans Verkuil2f824412011-03-12 06:43:28 -0300781 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300782
783 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300784 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300785
786 itv->audio_input = vout->index;
787 ivtv_audio_set_io(itv);
788
789 return 0;
790}
791
792static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
793{
Hans Verkuil2f824412011-03-12 06:43:28 -0300794 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300795
796 /* set it to defaults from our table */
797 return ivtv_get_audio_output(itv, vin->index, vin);
798}
799
800static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
801{
Hans Verkuil2f824412011-03-12 06:43:28 -0300802 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300803
804 vin->index = 0;
805 return ivtv_get_audio_output(itv, vin->index, vin);
806}
807
808static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
809{
Hans Verkuil2f824412011-03-12 06:43:28 -0300810 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300811
812 return ivtv_get_audio_output(itv, vout->index, vout);
813}
814
815static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
816{
Hans Verkuil2f824412011-03-12 06:43:28 -0300817 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300818
819 /* set it to defaults from our table */
820 return ivtv_get_input(itv, vin->index, vin);
821}
822
823static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
824{
Hans Verkuil2f824412011-03-12 06:43:28 -0300825 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300826
827 return ivtv_get_output(itv, vout->index, vout);
828}
829
830static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
831{
Hans Verkuil2f824412011-03-12 06:43:28 -0300832 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300833 struct ivtv *itv = id->itv;
834 struct yuv_playback_info *yi = &itv->yuv_info;
835 int streamtype;
836
837 streamtype = id->type;
838
839 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
840 return -EINVAL;
841 cropcap->bounds.top = cropcap->bounds.left = 0;
842 cropcap->bounds.width = 720;
843 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
844 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
845 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
846 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
847 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
848 if (yi->track_osd) {
849 cropcap->bounds.width = yi->osd_full_w;
850 cropcap->bounds.height = yi->osd_full_h;
851 } else {
852 cropcap->bounds.width = 720;
853 cropcap->bounds.height =
854 itv->is_out_50hz ? 576 : 480;
855 }
856 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
857 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
858 } else {
859 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
860 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
861 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
862 }
863 cropcap->defrect = cropcap->bounds;
864 return 0;
865}
866
867static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
868{
Hans Verkuil2f824412011-03-12 06:43:28 -0300869 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300870 struct ivtv *itv = id->itv;
871 struct yuv_playback_info *yi = &itv->yuv_info;
872 int streamtype;
873
874 streamtype = id->type;
875
Hans Verkuil3f038d82008-05-29 16:43:54 -0300876 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
877 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
878 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
879 yi->main_rect = crop->c;
880 return 0;
881 } else {
882 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
883 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
884 itv->main_rect = crop->c;
885 return 0;
886 }
887 }
888 return -EINVAL;
889 }
890 return -EINVAL;
891}
892
893static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
894{
Hans Verkuil2f824412011-03-12 06:43:28 -0300895 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300896 struct ivtv *itv = id->itv;
897 struct yuv_playback_info *yi = &itv->yuv_info;
898 int streamtype;
899
900 streamtype = id->type;
901
902 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
903 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
904 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
905 crop->c = yi->main_rect;
906 else
907 crop->c = itv->main_rect;
908 return 0;
909 }
910 return -EINVAL;
911}
912
913static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
914{
915 static struct v4l2_fmtdesc formats[] = {
916 { 0, 0, 0,
917 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
918 { 0, 0, 0, 0 }
919 },
920 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
921 "MPEG", V4L2_PIX_FMT_MPEG,
922 { 0, 0, 0, 0 }
923 }
924 };
925 enum v4l2_buf_type type = fmt->type;
926
927 if (fmt->index > 1)
928 return -EINVAL;
929
930 *fmt = formats[fmt->index];
931 fmt->type = type;
932 return 0;
933}
934
935static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
936{
Hans Verkuil2f824412011-03-12 06:43:28 -0300937 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300938
939 static struct v4l2_fmtdesc formats[] = {
940 { 0, 0, 0,
941 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
942 { 0, 0, 0, 0 }
943 },
944 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
945 "MPEG", V4L2_PIX_FMT_MPEG,
946 { 0, 0, 0, 0 }
947 }
948 };
949 enum v4l2_buf_type type = fmt->type;
950
951 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
952 return -EINVAL;
953
954 if (fmt->index > 1)
955 return -EINVAL;
956
957 *fmt = formats[fmt->index];
958 fmt->type = type;
959
960 return 0;
961}
962
963static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
964{
Hans Verkuil2f824412011-03-12 06:43:28 -0300965 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300966
967 *i = itv->active_input;
968
969 return 0;
970}
971
972int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
973{
Hans Verkuil2f824412011-03-12 06:43:28 -0300974 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300975
976 if (inp < 0 || inp >= itv->nof_inputs)
977 return -EINVAL;
978
979 if (inp == itv->active_input) {
980 IVTV_DEBUG_INFO("Input unchanged\n");
981 return 0;
982 }
983
984 if (atomic_read(&itv->capturing) > 0) {
985 return -EBUSY;
986 }
987
988 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
989 itv->active_input, inp);
990
991 itv->active_input = inp;
992 /* Set the audio input to whatever is appropriate for the
993 input type. */
994 itv->audio_input = itv->card->video_inputs[inp].audio_index;
995
996 /* prevent others from messing with the streams until
997 we're finished changing inputs. */
998 ivtv_mute(itv);
999 ivtv_video_set_io(itv);
1000 ivtv_audio_set_io(itv);
1001 ivtv_unmute(itv);
1002
1003 return 0;
1004}
1005
1006static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1007{
Hans Verkuil2f824412011-03-12 06:43:28 -03001008 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001009
1010 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1011 return -EINVAL;
1012
1013 *i = itv->active_output;
1014
1015 return 0;
1016}
1017
1018static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1019{
Hans Verkuil2f824412011-03-12 06:43:28 -03001020 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001021
1022 if (outp >= itv->card->nof_outputs)
1023 return -EINVAL;
1024
1025 if (outp == itv->active_output) {
1026 IVTV_DEBUG_INFO("Output unchanged\n");
1027 return 0;
1028 }
1029 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1030 itv->active_output, outp);
1031
1032 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001033 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1034 SAA7127_INPUT_TYPE_NORMAL,
1035 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001036
1037 return 0;
1038}
1039
1040static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1041{
Hans Verkuil2f824412011-03-12 06:43:28 -03001042 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001043
1044 if (vf->tuner != 0)
1045 return -EINVAL;
1046
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001047 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001048 return 0;
1049}
1050
1051int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1052{
Hans Verkuil2f824412011-03-12 06:43:28 -03001053 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001054
1055 if (vf->tuner != 0)
1056 return -EINVAL;
1057
1058 ivtv_mute(itv);
1059 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001060 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001061 ivtv_unmute(itv);
1062 return 0;
1063}
1064
1065static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1066{
Hans Verkuil2f824412011-03-12 06:43:28 -03001067 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001068
1069 *std = itv->std;
1070 return 0;
1071}
1072
Ian Armstrongc5874c92011-05-29 21:33:17 -03001073void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001074{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001075 itv->std = *std;
1076 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001077 itv->is_50hz = !itv->is_60hz;
1078 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1079 itv->cxhdl.width = 720;
1080 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001081 itv->vbi.count = itv->is_50hz ? 18 : 12;
1082 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1083 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1084
1085 if (itv->hw_flags & IVTV_HW_CX25840)
1086 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1087
Hans Verkuil3f038d82008-05-29 16:43:54 -03001088 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001089 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001090}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001091
Ian Armstrongc5874c92011-05-29 21:33:17 -03001092void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1093{
1094 struct yuv_playback_info *yi = &itv->yuv_info;
1095 DEFINE_WAIT(wait);
1096 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001097
Ian Armstrongc5874c92011-05-29 21:33:17 -03001098 /* set display standard */
1099 itv->std_out = *std;
1100 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1101 itv->is_out_50hz = !itv->is_out_60hz;
1102 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001103
Ian Armstrongc5874c92011-05-29 21:33:17 -03001104 /*
1105 * The next firmware call is time sensitive. Time it to
1106 * avoid risk of a hard lock, by trying to ensure the call
1107 * happens within the first 100 lines of the top field.
1108 * Make 4 attempts to sync to the decoder before giving up.
1109 */
1110 for (f = 0; f < 4; f++) {
1111 prepare_to_wait(&itv->vsync_waitq, &wait,
1112 TASK_UNINTERRUPTIBLE);
1113 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1114 break;
1115 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001116 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001117 finish_wait(&itv->vsync_waitq, &wait);
1118
1119 if (f == 4)
1120 IVTV_WARN("Mode change failed to sync to decoder\n");
1121
1122 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1123 itv->main_rect.left = 0;
1124 itv->main_rect.top = 0;
1125 itv->main_rect.width = 720;
1126 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1127 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1128 720, itv->main_rect.height, 0, 0);
1129 yi->main_rect = itv->main_rect;
1130 if (!itv->osd_info) {
1131 yi->osd_full_w = 720;
1132 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1133 }
1134}
1135
1136int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1137{
1138 struct ivtv *itv = fh2id(fh)->itv;
1139
1140 if ((*std & V4L2_STD_ALL) == 0)
1141 return -EINVAL;
1142
1143 if (*std == itv->std)
1144 return 0;
1145
1146 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1147 atomic_read(&itv->capturing) > 0 ||
1148 atomic_read(&itv->decoding) > 0) {
1149 /* Switching standard would mess with already running
1150 streams, prevent that by returning EBUSY. */
1151 return -EBUSY;
1152 }
1153
1154 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1155 (unsigned long long)itv->std);
1156
1157 ivtv_s_std_enc(itv, std);
1158 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1159 ivtv_s_std_dec(itv, std);
1160
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001161 return 0;
1162}
1163
Hans Verkuil3f038d82008-05-29 16:43:54 -03001164static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001165{
Hans Verkuil2f824412011-03-12 06:43:28 -03001166 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001167 struct ivtv *itv = id->itv;
1168
1169 if (vt->index != 0)
1170 return -EINVAL;
1171
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001172 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001173
1174 return 0;
1175}
1176
1177static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1178{
Hans Verkuil2f824412011-03-12 06:43:28 -03001179 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001180
1181 if (vt->index != 0)
1182 return -EINVAL;
1183
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001184 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001185
Hans Verkuild118e292011-06-25 10:28:21 -03001186 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001187 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001188 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001189 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001190 return 0;
1191}
1192
1193static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1194{
Hans Verkuil2f824412011-03-12 06:43:28 -03001195 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001196 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1197 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001198
Hans Verkuil79afcb12008-06-21 09:02:36 -03001199 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001200 for (f = 0; f < 2; f++) {
1201 for (l = 0; l < 24; l++) {
1202 if (valid_service_line(f, l, itv->is_50hz))
1203 cap->service_lines[f][l] = set;
1204 }
1205 }
1206 return 0;
1207 }
Hans Verkuil79afcb12008-06-21 09:02:36 -03001208 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001209 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1210 return -EINVAL;
1211 if (itv->is_60hz) {
1212 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1213 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1214 } else {
1215 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1216 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1217 }
1218 return 0;
1219 }
1220 return -EINVAL;
1221}
1222
1223static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1224{
Hans Verkuil2f824412011-03-12 06:43:28 -03001225 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001226 struct v4l2_enc_idx_entry *e = idx->entry;
1227 int entries;
1228 int i;
1229
1230 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1231 IVTV_MAX_PGM_INDEX;
1232 if (entries > V4L2_ENC_IDX_ENTRIES)
1233 entries = V4L2_ENC_IDX_ENTRIES;
1234 idx->entries = 0;
1235 for (i = 0; i < entries; i++) {
1236 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1237 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1238 idx->entries++;
1239 e++;
1240 }
1241 }
1242 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1243 return 0;
1244}
1245
1246static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1247{
Hans Verkuil2f824412011-03-12 06:43:28 -03001248 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001249 struct ivtv *itv = id->itv;
1250
Hans Verkuil3f038d82008-05-29 16:43:54 -03001251
1252 switch (enc->cmd) {
1253 case V4L2_ENC_CMD_START:
1254 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1255 enc->flags = 0;
1256 return ivtv_start_capture(id);
1257
1258 case V4L2_ENC_CMD_STOP:
1259 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1260 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1261 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1262 return 0;
1263
1264 case V4L2_ENC_CMD_PAUSE:
1265 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1266 enc->flags = 0;
1267
1268 if (!atomic_read(&itv->capturing))
1269 return -EPERM;
1270 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1271 return 0;
1272
1273 ivtv_mute(itv);
1274 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1275 break;
1276
1277 case V4L2_ENC_CMD_RESUME:
1278 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1279 enc->flags = 0;
1280
1281 if (!atomic_read(&itv->capturing))
1282 return -EPERM;
1283
1284 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1285 return 0;
1286
1287 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1288 ivtv_unmute(itv);
1289 break;
1290 default:
1291 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1292 return -EINVAL;
1293 }
1294
1295 return 0;
1296}
1297
1298static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1299{
Hans Verkuil2f824412011-03-12 06:43:28 -03001300 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001301
Hans Verkuil3f038d82008-05-29 16:43:54 -03001302 switch (enc->cmd) {
1303 case V4L2_ENC_CMD_START:
1304 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1305 enc->flags = 0;
1306 return 0;
1307
1308 case V4L2_ENC_CMD_STOP:
1309 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1310 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1311 return 0;
1312
1313 case V4L2_ENC_CMD_PAUSE:
1314 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1315 enc->flags = 0;
1316 return 0;
1317
1318 case V4L2_ENC_CMD_RESUME:
1319 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1320 enc->flags = 0;
1321 return 0;
1322 default:
1323 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1324 return -EINVAL;
1325 }
1326}
1327
1328static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1329{
Hans Verkuil2f824412011-03-12 06:43:28 -03001330 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001331 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001332 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001333
Hans Verkuil3f038d82008-05-29 16:43:54 -03001334 int pixfmt;
1335 static u32 pixel_format[16] = {
1336 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1337 V4L2_PIX_FMT_RGB565,
1338 V4L2_PIX_FMT_RGB555,
1339 V4L2_PIX_FMT_RGB444,
1340 V4L2_PIX_FMT_RGB32,
1341 0,
1342 0,
1343 0,
1344 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1345 V4L2_PIX_FMT_YUV565,
1346 V4L2_PIX_FMT_YUV555,
1347 V4L2_PIX_FMT_YUV444,
1348 V4L2_PIX_FMT_YUV32,
1349 0,
1350 0,
1351 0,
1352 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001353
Hans Verkuil3f038d82008-05-29 16:43:54 -03001354 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1355 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001356 if (!itv->osd_video_pbase)
1357 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001358
Hans Verkuil3f038d82008-05-29 16:43:54 -03001359 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1360 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001361
Hans Verkuil3f038d82008-05-29 16:43:54 -03001362 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1363 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1364 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001365
Hans Verkuil3f038d82008-05-29 16:43:54 -03001366 fb->fmt.pixelformat = pixel_format[pixfmt];
1367 fb->fmt.width = itv->osd_rect.width;
1368 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001369 fb->fmt.field = V4L2_FIELD_INTERLACED;
1370 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001371 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1372 fb->fmt.field = V4L2_FIELD_INTERLACED;
1373 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001374 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1375 fb->fmt.bytesperline *= 2;
1376 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1377 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1378 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001379 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001380 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001381 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001382
Hans Verkuil3f038d82008-05-29 16:43:54 -03001383 if (itv->osd_chroma_key_state)
1384 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001385
Hans Verkuil3f038d82008-05-29 16:43:54 -03001386 if (itv->osd_global_alpha_state)
1387 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001388
Ian Armstrongec9faa12008-10-06 03:06:08 -03001389 if (yi->track_osd)
1390 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1391
Hans Verkuil3f038d82008-05-29 16:43:54 -03001392 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001393
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 /* no local alpha for RGB565 or unknown formats */
1395 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001396 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001397
Hans Verkuil3f038d82008-05-29 16:43:54 -03001398 /* 16-bit formats have inverted local alpha */
1399 if (pixfmt == 2 || pixfmt == 3)
1400 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1401 else
1402 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001403
Hans Verkuil3f038d82008-05-29 16:43:54 -03001404 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001405 /* 16-bit formats have inverted local alpha */
1406 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001407 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001408 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001409 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001410 }
1411
Hans Verkuil3f038d82008-05-29 16:43:54 -03001412 return 0;
1413}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001414
Hans Verkuil3f038d82008-05-29 16:43:54 -03001415static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1416{
Hans Verkuil2f824412011-03-12 06:43:28 -03001417 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001418 struct ivtv *itv = id->itv;
1419 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001420
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001422 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001423 if (!itv->osd_video_pbase)
1424 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001425
1426 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1427 itv->osd_local_alpha_state =
1428 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1429 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1430 ivtv_set_osd_alpha(itv);
1431 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001432 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433}
1434
1435static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1436{
Hans Verkuil2f824412011-03-12 06:43:28 -03001437 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001438 struct ivtv *itv = id->itv;
1439
1440 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1441 return -EINVAL;
1442
1443 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1444
1445 return 0;
1446}
1447
Hans Verkuil09250192010-03-27 14:10:13 -03001448static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1449{
1450 switch (sub->type) {
1451 case V4L2_EVENT_VSYNC:
1452 case V4L2_EVENT_EOS:
1453 break;
Hans Verkuil51388702011-06-28 10:40:42 -03001454 case V4L2_EVENT_CTRL:
1455 return v4l2_ctrl_subscribe_fh(fh, sub, 0);
Hans Verkuil09250192010-03-27 14:10:13 -03001456 default:
1457 return -EINVAL;
1458 }
1459 return v4l2_event_subscribe(fh, sub);
1460}
1461
Hans Verkuil3f038d82008-05-29 16:43:54 -03001462static int ivtv_log_status(struct file *file, void *fh)
1463{
Hans Verkuil2f824412011-03-12 06:43:28 -03001464 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001465 u32 data[CX2341X_MBOX_MAX_DATA];
1466
1467 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1468 struct v4l2_input vidin;
1469 struct v4l2_audio audin;
1470 int i;
1471
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001472 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1473 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001474 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1475 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1476 struct tveeprom tv;
1477
1478 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001479 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001480 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001481 ivtv_get_input(itv, itv->active_input, &vidin);
1482 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1483 IVTV_INFO("Video Input: %s\n", vidin.name);
1484 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1485 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1486 if (has_output) {
1487 struct v4l2_output vidout;
1488 struct v4l2_audioout audout;
1489 int mode = itv->output_mode;
1490 static const char * const output_modes[5] = {
1491 "None",
1492 "MPEG Streaming",
1493 "YUV Streaming",
1494 "YUV Frames",
1495 "Passthrough",
1496 };
1497 static const char * const audio_modes[5] = {
1498 "Stereo",
1499 "Left",
1500 "Right",
1501 "Mono",
1502 "Swapped"
1503 };
1504 static const char * const alpha_mode[4] = {
1505 "None",
1506 "Global",
1507 "Local",
1508 "Global and Local"
1509 };
1510 static const char * const pixel_format[16] = {
1511 "ARGB Indexed",
1512 "RGB 5:6:5",
1513 "ARGB 1:5:5:5",
1514 "ARGB 1:4:4:4",
1515 "ARGB 8:8:8:8",
1516 "5",
1517 "6",
1518 "7",
1519 "AYUV Indexed",
1520 "YUV 5:6:5",
1521 "AYUV 1:5:5:5",
1522 "AYUV 1:4:4:4",
1523 "AYUV 8:8:8:8",
1524 "13",
1525 "14",
1526 "15",
1527 };
1528
1529 ivtv_get_output(itv, itv->active_output, &vidout);
1530 ivtv_get_audio_output(itv, 0, &audout);
1531 IVTV_INFO("Video Output: %s\n", vidout.name);
1532 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1533 audio_modes[itv->audio_stereo_mode],
1534 audio_modes[itv->audio_bilingual_mode]);
1535 if (mode < 0 || mode > OUT_PASSTHROUGH)
1536 mode = OUT_NONE;
1537 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1538 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1539 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1540 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1541 data[0] & 1 ? "On" : "Off",
1542 alpha_mode[(data[0] >> 1) & 0x3],
1543 pixel_format[(data[0] >> 3) & 0xf]);
1544 }
1545 IVTV_INFO("Tuner: %s\n",
1546 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001547 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001548 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1549 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1550 struct ivtv_stream *s = &itv->streams[i];
1551
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001552 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001553 continue;
1554 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1555 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1556 (s->buffers * s->buf_size) / 1024, s->buffers);
1557 }
1558
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001559 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1560 (long long)itv->mpg_data_received,
1561 (long long)itv->vbi_data_inserted);
1562 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1563 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001564
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001565 return 0;
1566}
1567
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001568static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001569{
Hans Verkuil09250192010-03-27 14:10:13 -03001570 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001571 struct ivtv *itv = id->itv;
1572 int nonblocking = filp->f_flags & O_NONBLOCK;
1573 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001574 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001575
1576 switch (cmd) {
1577 case IVTV_IOC_DMA_FRAME: {
1578 struct ivtv_dma_frame *args = arg;
1579
1580 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1581 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1582 return -EINVAL;
1583 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1584 return -EINVAL;
1585 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1586 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001587 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001588 return -EBUSY;
1589 }
1590 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1591 ivtv_release_stream(s);
1592 return -EBUSY;
1593 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001594 /* Mark that this file handle started the UDMA_YUV mode */
1595 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001596 if (args->y_source == NULL)
1597 return 0;
1598 return ivtv_yuv_prep_frame(itv, args);
1599 }
1600
1601 case VIDEO_GET_PTS: {
1602 u32 data[CX2341X_MBOX_MAX_DATA];
1603 u64 *pts = arg;
1604
1605 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1606 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1607 *pts = s->dma_pts;
1608 break;
1609 }
1610 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1611 return -EINVAL;
1612
1613 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1614 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1615 (u64)itv->last_dec_timing[1];
1616 break;
1617 }
1618 *pts = 0;
1619 if (atomic_read(&itv->decoding)) {
1620 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1621 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1622 return -EIO;
1623 }
1624 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1625 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1626 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1627 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1628 }
1629 break;
1630 }
1631
1632 case VIDEO_GET_FRAME_COUNT: {
1633 u32 data[CX2341X_MBOX_MAX_DATA];
1634 u64 *frame = arg;
1635
1636 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1637 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1638 *frame = 0;
1639 break;
1640 }
1641 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1642 return -EINVAL;
1643
1644 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1645 *frame = itv->last_dec_timing[0];
1646 break;
1647 }
1648 *frame = 0;
1649 if (atomic_read(&itv->decoding)) {
1650 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1651 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1652 return -EIO;
1653 }
1654 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1655 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1656 *frame = data[0];
1657 }
1658 break;
1659 }
1660
1661 case VIDEO_PLAY: {
1662 struct video_command vc;
1663
1664 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1665 memset(&vc, 0, sizeof(vc));
1666 vc.cmd = VIDEO_CMD_PLAY;
1667 return ivtv_video_command(itv, id, &vc, 0);
1668 }
1669
1670 case VIDEO_STOP: {
1671 struct video_command vc;
1672
1673 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1674 memset(&vc, 0, sizeof(vc));
1675 vc.cmd = VIDEO_CMD_STOP;
1676 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1677 return ivtv_video_command(itv, id, &vc, 0);
1678 }
1679
1680 case VIDEO_FREEZE: {
1681 struct video_command vc;
1682
1683 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1684 memset(&vc, 0, sizeof(vc));
1685 vc.cmd = VIDEO_CMD_FREEZE;
1686 return ivtv_video_command(itv, id, &vc, 0);
1687 }
1688
1689 case VIDEO_CONTINUE: {
1690 struct video_command vc;
1691
1692 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1693 memset(&vc, 0, sizeof(vc));
1694 vc.cmd = VIDEO_CMD_CONTINUE;
1695 return ivtv_video_command(itv, id, &vc, 0);
1696 }
1697
1698 case VIDEO_COMMAND:
1699 case VIDEO_TRY_COMMAND: {
1700 struct video_command *vc = arg;
1701 int try = (cmd == VIDEO_TRY_COMMAND);
1702
1703 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001704 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001705 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001706 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001707 return ivtv_video_command(itv, id, vc, try);
1708 }
1709
1710 case VIDEO_GET_EVENT: {
1711 struct video_event *ev = arg;
1712 DEFINE_WAIT(wait);
1713
1714 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1715 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1716 return -EINVAL;
1717 memset(ev, 0, sizeof(*ev));
1718 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1719
1720 while (1) {
1721 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1722 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1723 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1724 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001725 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1726 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1727 if (itv->output_mode == OUT_UDMA_YUV &&
1728 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1729 IVTV_YUV_MODE_PROGRESSIVE) {
1730 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1731 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001732 }
1733 if (ev->type)
1734 return 0;
1735 if (nonblocking)
1736 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001737 /* Wait for event. Note that serialize_lock is locked,
1738 so to allow other processes to access the driver while
1739 we are waiting unlock first and later lock again. */
1740 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001741 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001742 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1743 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001744 schedule();
1745 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001746 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001747 if (signal_pending(current)) {
1748 /* return if a signal was received */
1749 IVTV_DEBUG_INFO("User stopped wait for event\n");
1750 return -EINTR;
1751 }
1752 }
1753 break;
1754 }
1755
Hans Verkuilce680252010-04-06 15:58:53 -03001756 case VIDEO_SELECT_SOURCE:
1757 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1758 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1759 return -EINVAL;
1760 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1761
1762 case AUDIO_SET_MUTE:
1763 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1764 itv->speed_mute_audio = iarg;
1765 return 0;
1766
1767 case AUDIO_CHANNEL_SELECT:
1768 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1769 if (iarg > AUDIO_STEREO_SWAPPED)
1770 return -EINVAL;
1771 itv->audio_stereo_mode = iarg;
1772 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1773 return 0;
1774
1775 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1776 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1777 if (iarg > AUDIO_STEREO_SWAPPED)
1778 return -EINVAL;
1779 itv->audio_bilingual_mode = iarg;
1780 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1781 return 0;
1782
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001783 default:
1784 return -EINVAL;
1785 }
1786 return 0;
1787}
1788
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001789static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1790 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001791{
Hans Verkuil2f824412011-03-12 06:43:28 -03001792 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001793
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001794 if (!valid_prio) {
1795 switch (cmd) {
1796 case VIDEO_PLAY:
1797 case VIDEO_STOP:
1798 case VIDEO_FREEZE:
1799 case VIDEO_CONTINUE:
1800 case VIDEO_COMMAND:
1801 case VIDEO_SELECT_SOURCE:
1802 case AUDIO_SET_MUTE:
1803 case AUDIO_CHANNEL_SELECT:
1804 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1805 return -EBUSY;
1806 }
1807 }
1808
Hans Verkuild46c17d2007-03-10 17:59:15 -03001809 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001810 case VIDIOC_INT_RESET: {
1811 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001812
Hans Verkuil3f038d82008-05-29 16:43:54 -03001813 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1814 ivtv_reset_ir_gpio(itv);
1815 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001816 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001817 break;
1818 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001819
Hans Verkuilac9575f2009-02-14 19:58:33 -03001820 case IVTV_IOC_DMA_FRAME:
1821 case VIDEO_GET_PTS:
1822 case VIDEO_GET_FRAME_COUNT:
1823 case VIDEO_GET_EVENT:
1824 case VIDEO_PLAY:
1825 case VIDEO_STOP:
1826 case VIDEO_FREEZE:
1827 case VIDEO_CONTINUE:
1828 case VIDEO_COMMAND:
1829 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001830 case VIDEO_SELECT_SOURCE:
1831 case AUDIO_SET_MUTE:
1832 case AUDIO_CHANNEL_SELECT:
1833 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001834 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1835
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001836 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001837 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001838 }
1839 return 0;
1840}
1841
Hans Verkuil09882f02008-10-18 13:42:24 -03001842static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
Hans Verkuilbaa40722007-08-19 07:10:55 -03001843 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001844{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001845 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09882f02008-10-18 13:42:24 -03001846 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001847
Hans Verkuil37f89f92008-06-22 11:57:31 -03001848 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1849 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001850 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001851 vfd->debug = 0;
1852 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001853}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001854
Hans Verkuil09882f02008-10-18 13:42:24 -03001855long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuilbaa40722007-08-19 07:10:55 -03001856{
Hans Verkuil09250192010-03-27 14:10:13 -03001857 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001858 struct ivtv *itv = id->itv;
Hans Verkuil09882f02008-10-18 13:42:24 -03001859 long res;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001860
Hans Verkuil09250192010-03-27 14:10:13 -03001861 /* DQEVENT can block, so this should not run with the serialize lock */
1862 if (cmd == VIDIOC_DQEVENT)
1863 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001864 mutex_lock(&itv->serialize_lock);
Hans Verkuil09882f02008-10-18 13:42:24 -03001865 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001866 mutex_unlock(&itv->serialize_lock);
1867 return res;
1868}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001869
Hans Verkuila3998102008-07-21 02:57:38 -03001870static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1871 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001872 .vidioc_s_audio = ivtv_s_audio,
1873 .vidioc_g_audio = ivtv_g_audio,
1874 .vidioc_enumaudio = ivtv_enumaudio,
1875 .vidioc_s_audout = ivtv_s_audout,
1876 .vidioc_g_audout = ivtv_g_audout,
1877 .vidioc_enum_input = ivtv_enum_input,
1878 .vidioc_enum_output = ivtv_enum_output,
1879 .vidioc_enumaudout = ivtv_enumaudout,
1880 .vidioc_cropcap = ivtv_cropcap,
1881 .vidioc_s_crop = ivtv_s_crop,
1882 .vidioc_g_crop = ivtv_g_crop,
1883 .vidioc_g_input = ivtv_g_input,
1884 .vidioc_s_input = ivtv_s_input,
1885 .vidioc_g_output = ivtv_g_output,
1886 .vidioc_s_output = ivtv_s_output,
1887 .vidioc_g_frequency = ivtv_g_frequency,
1888 .vidioc_s_frequency = ivtv_s_frequency,
1889 .vidioc_s_tuner = ivtv_s_tuner,
1890 .vidioc_g_tuner = ivtv_g_tuner,
1891 .vidioc_g_enc_index = ivtv_g_enc_index,
1892 .vidioc_g_fbuf = ivtv_g_fbuf,
1893 .vidioc_s_fbuf = ivtv_s_fbuf,
1894 .vidioc_g_std = ivtv_g_std,
1895 .vidioc_s_std = ivtv_s_std,
1896 .vidioc_overlay = ivtv_overlay,
1897 .vidioc_log_status = ivtv_log_status,
1898 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1899 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1900 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1901 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1902 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1903 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1904 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1905 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1906 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1907 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1908 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1909 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1910 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1911 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1912 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1913 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1914 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1915 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1916 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1917 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1918 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1919 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1920 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1921 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1922#ifdef CONFIG_VIDEO_ADV_DEBUG
1923 .vidioc_g_register = ivtv_g_register,
1924 .vidioc_s_register = ivtv_s_register,
1925#endif
1926 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001927 .vidioc_subscribe_event = ivtv_subscribe_event,
1928 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001929};
1930
Hans Verkuil3f038d82008-05-29 16:43:54 -03001931void ivtv_set_funcs(struct video_device *vdev)
1932{
Hans Verkuila3998102008-07-21 02:57:38 -03001933 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001934}