blob: 70cd802c9ca855c9653ab9c5b06333743c40bbf9 [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 */
Hans Verkuilcdc03782011-10-11 06:06:58 -0300182 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300183 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);
Hans Verkuilcdc03782011-10-11 06:06:58 -0300192 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300193 if (got_sig)
194 return -EINTR;
195
196 /* Change Speed safely */
197 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
198 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
199 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
200 }
201 if (single_step) {
202 speed = (speed < 0) ? -1 : 1;
203 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
204 }
205 itv->speed = speed;
206 return 0;
207}
208
209static int ivtv_validate_speed(int cur_speed, int new_speed)
210{
211 int fact = new_speed < 0 ? -1 : 1;
212 int s;
213
Hans Verkuil94dee762008-04-26 09:26:13 -0300214 if (cur_speed == 0)
215 cur_speed = 1000;
216 if (new_speed < 0)
217 new_speed = -new_speed;
218 if (cur_speed < 0)
219 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300220
221 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300222 if (new_speed > 1500)
223 return fact * 2000;
224 if (new_speed > 1000)
225 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300226 }
227 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300228 if (new_speed >= 2000)
229 return fact * 2000;
230 if (new_speed >= 1500)
231 return fact * 1500;
232 if (new_speed >= 1000)
233 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300234 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300235 if (new_speed == 0)
236 return 1000;
237 if (new_speed == 1 || new_speed == 1000)
238 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300239
240 s = new_speed;
241 new_speed = 1000 / new_speed;
242 if (1000 / cur_speed == new_speed)
243 new_speed += (cur_speed < s) ? -1 : 1;
244 if (new_speed > 60) return 1000 / (fact * 60);
245 return 1000 / (fact * new_speed);
246}
247
248static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300249 struct v4l2_decoder_cmd *dc, int try)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300250{
251 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
252
253 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
254 return -EINVAL;
255
Hans Verkuilda8ec562011-11-24 09:58:53 -0300256 switch (dc->cmd) {
257 case V4L2_DEC_CMD_START: {
258 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
259 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
260 if (dc->start.speed < 0)
261 dc->start.format = V4L2_DEC_START_FMT_GOP;
262 else
263 dc->start.format = V4L2_DEC_START_FMT_NONE;
264 if (dc->start.speed != 500 && dc->start.speed != 1500)
265 dc->flags = dc->start.speed == 1000 ? 0 :
266 V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300267 if (try) break;
268
Hans Verkuilda8ec562011-11-24 09:58:53 -0300269 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300270 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
271 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300272 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
273 /* forces ivtv_set_speed to be called */
274 itv->speed = 0;
275 }
Hans Verkuilda8ec562011-11-24 09:58:53 -0300276 return ivtv_start_decoding(id, dc->start.speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300277 }
278
Hans Verkuilda8ec562011-11-24 09:58:53 -0300279 case V4L2_DEC_CMD_STOP:
280 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
281 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
282 dc->stop.pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300283 if (try) break;
284 if (atomic_read(&itv->decoding) == 0)
285 return 0;
286 if (itv->output_mode != OUT_MPG)
287 return -EBUSY;
288
289 itv->output_mode = OUT_NONE;
Hans Verkuilda8ec562011-11-24 09:58:53 -0300290 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300291
Hans Verkuilda8ec562011-11-24 09:58:53 -0300292 case V4L2_DEC_CMD_PAUSE:
293 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300294 if (try) break;
295 if (itv->output_mode != OUT_MPG)
296 return -EBUSY;
297 if (atomic_read(&itv->decoding) > 0) {
298 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300299 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300300 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300301 }
302 break;
303
Hans Verkuilda8ec562011-11-24 09:58:53 -0300304 case V4L2_DEC_CMD_RESUME:
305 dc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300306 if (try) break;
307 if (itv->output_mode != OUT_MPG)
308 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300309 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
310 int speed = itv->speed;
311 itv->speed = 0;
312 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300313 }
314 break;
315
316 default:
317 return -EINVAL;
318 }
319 return 0;
320}
321
Hans Verkuil3f038d82008-05-29 16:43:54 -0300322static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300323{
Hans Verkuil2f824412011-03-12 06:43:28 -0300324 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300325 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300326
Hans Verkuile88360c2008-06-21 08:00:56 -0300327 vbifmt->reserved[0] = 0;
328 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300329 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300330 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300331 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
332 if (itv->is_60hz) {
333 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
334 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
335 } else {
336 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
337 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
338 }
339 vbifmt->service_set = ivtv_get_service_set(vbifmt);
340 return 0;
341}
342
343static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
344{
Hans Verkuil2f824412011-03-12 06:43:28 -0300345 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300346 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300347 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300348
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300349 pixfmt->width = itv->cxhdl.width;
350 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300351 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
352 pixfmt->field = V4L2_FIELD_INTERLACED;
353 pixfmt->priv = 0;
354 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
355 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300356 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
357 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300358 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300359 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300360 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
361 pixfmt->sizeimage = 128 * 1024;
362 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300363 }
364 return 0;
365}
366
Hans Verkuil3f038d82008-05-29 16:43:54 -0300367static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300368{
Hans Verkuil2f824412011-03-12 06:43:28 -0300369 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300370 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300371
Hans Verkuile88360c2008-06-21 08:00:56 -0300372 vbifmt->sampling_rate = 27000000;
373 vbifmt->offset = 248;
374 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
375 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
376 vbifmt->start[0] = itv->vbi.start[0];
377 vbifmt->start[1] = itv->vbi.start[1];
378 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
379 vbifmt->flags = 0;
380 vbifmt->reserved[0] = 0;
381 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300382 return 0;
383}
384
385static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
386{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300387 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300388 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300389 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300390
Hans Verkuile88360c2008-06-21 08:00:56 -0300391 vbifmt->reserved[0] = 0;
392 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300393 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300394
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
396 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
397 V4L2_SLICED_VBI_525;
398 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300399 return 0;
400 }
401
Hans Verkuil4ff07902010-03-14 12:18:18 -0300402 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300403 vbifmt->service_set = ivtv_get_service_set(vbifmt);
404 return 0;
405}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300406
Hans Verkuil3f038d82008-05-29 16:43:54 -0300407static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
408{
Hans Verkuil2f824412011-03-12 06:43:28 -0300409 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300410 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300411 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300412
Hans Verkuil3f038d82008-05-29 16:43:54 -0300413 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300414 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300415 pixfmt->width = itv->main_rect.width;
416 pixfmt->height = itv->main_rect.height;
417 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
418 pixfmt->field = V4L2_FIELD_INTERLACED;
419 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300420 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
421 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
422 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300423 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300424 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
425 break;
426 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300427 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300428 break;
429 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 break;
432 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
434 pixfmt->bytesperline = 720;
435 pixfmt->width = itv->yuv_info.v4l2_src_w;
436 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300437 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300438 pixfmt->sizeimage =
439 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300441 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
442 pixfmt->sizeimage = 128 * 1024;
443 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300444 }
445 return 0;
446}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447
Hans Verkuil3f038d82008-05-29 16:43:54 -0300448static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
449{
Hans Verkuil2f824412011-03-12 06:43:28 -0300450 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300451 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300452
453 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
454 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300455 winfmt->chromakey = itv->osd_chroma_key;
456 winfmt->global_alpha = itv->osd_global_alpha;
457 winfmt->field = V4L2_FIELD_INTERLACED;
458 winfmt->clips = NULL;
459 winfmt->clipcount = 0;
460 winfmt->bitmap = NULL;
461 winfmt->w.top = winfmt->w.left = 0;
462 winfmt->w.width = itv->osd_rect.width;
463 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300464 return 0;
465}
466
467static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
468{
469 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
470}
471
472static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
473{
Hans Verkuil2f824412011-03-12 06:43:28 -0300474 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300475 struct ivtv *itv = id->itv;
476 int w = fmt->fmt.pix.width;
477 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300478 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300479
480 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300481 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300482 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
483 /* YUV height must be a multiple of 32 */
484 h &= ~0x1f;
485 min_h = 32;
486 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300487 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300488 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300489 ivtv_g_fmt_vid_cap(file, fh, fmt);
490 fmt->fmt.pix.width = w;
491 fmt->fmt.pix.height = h;
492 return 0;
493}
494
495static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
496{
497 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
498}
499
500static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
501{
502 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300503 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300504 struct ivtv *itv = id->itv;
505
506 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
507 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300508
509 /* set sliced VBI capture format */
510 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300511 vbifmt->reserved[0] = 0;
512 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300513
514 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300515 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300516 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300517 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300518 return 0;
519}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300520
Hans Verkuil3f038d82008-05-29 16:43:54 -0300521static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
522{
Hans Verkuil2f824412011-03-12 06:43:28 -0300523 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300524 s32 w = fmt->fmt.pix.width;
525 s32 h = fmt->fmt.pix.height;
526 int field = fmt->fmt.pix.field;
527 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300528
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300529 w = min(w, 720);
530 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300531 /* Why can the height be 576 even when the output is NTSC?
532
533 Internally the buffers of the PVR350 are always set to 720x576. The
534 decoded video frame will always be placed in the top left corner of
535 this buffer. For any video which is not 720x576, the buffer will
536 then be cropped to remove the unused right and lower areas, with
537 the remaining image being scaled by the hardware to fit the display
538 area. The video can be scaled both up and down, so a 720x480 video
539 can be displayed full-screen on PAL and a 720x576 video can be
540 displayed without cropping on NTSC.
541
542 Note that the scaling only occurs on the video stream, the osd
543 resolution is locked to the broadcast standard and not scaled.
544
545 Thanks to Ian Armstrong for this explanation. */
546 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300547 h = max(h, 2);
548 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300549 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300550 fmt->fmt.pix.width = w;
551 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552 return ret;
553}
554
555static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
556{
Hans Verkuil2f824412011-03-12 06:43:28 -0300557 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300558 u32 chromakey = fmt->fmt.win.chromakey;
559 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300560
561 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
562 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300563 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
564 fmt->fmt.win.chromakey = chromakey;
565 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300566 return 0;
567}
568
569static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
570{
571 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
572}
573
574static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
575{
Hans Verkuil2f824412011-03-12 06:43:28 -0300576 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300577 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300578 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300579 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300580 int w = fmt->fmt.pix.width;
581 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300582
583 if (ret)
584 return ret;
585
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300586 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300587 return 0;
588
589 if (atomic_read(&itv->capturing) > 0)
590 return -EBUSY;
591
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300592 itv->cxhdl.width = w;
593 itv->cxhdl.height = h;
594 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300595 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300596 mbus_fmt.width = fmt->fmt.pix.width;
597 mbus_fmt.height = h;
598 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
599 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300600 return ivtv_g_fmt_vid_cap(file, fh, fmt);
601}
602
603static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
604{
Hans Verkuil2f824412011-03-12 06:43:28 -0300605 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300606
Hans Verkuila8b86432008-10-04 08:05:30 -0300607 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
608 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300609 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300610 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300611 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300612 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
613}
614
615static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
616{
617 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300618 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300619 struct ivtv *itv = id->itv;
620 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
621
622 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
623 return ret;
624
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300625 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300626 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300627 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300628 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300629 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300630 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
631 return 0;
632}
633
Hans Verkuil3f038d82008-05-29 16:43:54 -0300634static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300635{
Hans Verkuil2f824412011-03-12 06:43:28 -0300636 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300637 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300638 struct yuv_playback_info *yi = &itv->yuv_info;
639 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 if (ret)
642 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
645 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300646
Hans Verkuil3f038d82008-05-29 16:43:54 -0300647 /* Return now if we already have some frame data */
648 if (yi->stream_size)
649 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300650
Hans Verkuil3f038d82008-05-29 16:43:54 -0300651 yi->v4l2_src_w = fmt->fmt.pix.width;
652 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300653
Hans Verkuil3f038d82008-05-29 16:43:54 -0300654 switch (fmt->fmt.pix.field) {
655 case V4L2_FIELD_NONE:
656 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300657 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300658 case V4L2_FIELD_ANY:
659 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300661 case V4L2_FIELD_INTERLACED_BT:
662 yi->lace_mode =
663 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
664 break;
665 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300666 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300667 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
668 break;
669 }
670 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
671
672 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
673 itv->dma_data_req_size =
674 1080 * ((yi->v4l2_src_h + 31) & ~31);
675
Hans Verkuil3f038d82008-05-29 16:43:54 -0300676 return 0;
677}
678
679static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
680{
Hans Verkuil2f824412011-03-12 06:43:28 -0300681 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300682 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
683
684 if (ret == 0) {
685 itv->osd_chroma_key = fmt->fmt.win.chromakey;
686 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
687 ivtv_set_osd_alpha(itv);
688 }
689 return ret;
690}
691
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300692static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300693{
Hans Verkuil2f824412011-03-12 06:43:28 -0300694 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300695
696 chip->ident = V4L2_IDENT_NONE;
697 chip->revision = 0;
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300698 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
699 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300700 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
701 return 0;
702 }
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300703 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
704 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300705 return -EINVAL;
706 /* TODO: is this correct? */
707 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300708}
709
Hans Verkuil36ecd492008-06-25 06:00:17 -0300710#ifdef CONFIG_VIDEO_ADV_DEBUG
711static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
712{
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300713 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300714 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300715
716 if (!capable(CAP_SYS_ADMIN))
717 return -EPERM;
718 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
719 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
720 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
721 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
722 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300723 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300724 reg_start = itv->enc_mem;
725 else
726 return -EINVAL;
727
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300728 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300729 if (cmd == VIDIOC_DBG_G_REGISTER)
730 regs->val = readl(regs->reg + reg_start);
731 else
732 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300733 return 0;
734}
735
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300736static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300737{
Hans Verkuil2f824412011-03-12 06:43:28 -0300738 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300739
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300740 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300742 /* TODO: subdev errors should not be ignored, this should become a
743 subdev helper function. */
744 ivtv_call_all(itv, core, g_register, reg);
745 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300746}
747
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300748static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300749{
Hans Verkuil2f824412011-03-12 06:43:28 -0300750 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300751
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300752 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300753 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300754 /* TODO: subdev errors should not be ignored, this should become a
755 subdev helper function. */
756 ivtv_call_all(itv, core, s_register, reg);
757 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300758}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300759#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300760
Hans Verkuil3f038d82008-05-29 16:43:54 -0300761static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
762{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300763 struct ivtv_open_id *id = fh2id(file->private_data);
764 struct ivtv *itv = id->itv;
765 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300766
Hans Verkuil3f038d82008-05-29 16:43:54 -0300767 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
768 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300769 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300770 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
771 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300772 return 0;
773}
774
775static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
776{
Hans Verkuil2f824412011-03-12 06:43:28 -0300777 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300778
779 return ivtv_get_audio_input(itv, vin->index, vin);
780}
781
782static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
783{
Hans Verkuil2f824412011-03-12 06:43:28 -0300784 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300785
786 vin->index = itv->audio_input;
787 return ivtv_get_audio_input(itv, vin->index, vin);
788}
789
790static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
791{
Hans Verkuil2f824412011-03-12 06:43:28 -0300792 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300793
794 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300795 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300796
797 itv->audio_input = vout->index;
798 ivtv_audio_set_io(itv);
799
800 return 0;
801}
802
803static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
804{
Hans Verkuil2f824412011-03-12 06:43:28 -0300805 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300806
807 /* set it to defaults from our table */
808 return ivtv_get_audio_output(itv, vin->index, vin);
809}
810
811static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
812{
Hans Verkuil2f824412011-03-12 06:43:28 -0300813 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300814
815 vin->index = 0;
816 return ivtv_get_audio_output(itv, vin->index, vin);
817}
818
819static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
820{
Hans Verkuil2f824412011-03-12 06:43:28 -0300821 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300822
823 return ivtv_get_audio_output(itv, vout->index, vout);
824}
825
826static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
827{
Hans Verkuil2f824412011-03-12 06:43:28 -0300828 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300829
830 /* set it to defaults from our table */
831 return ivtv_get_input(itv, vin->index, vin);
832}
833
834static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
835{
Hans Verkuil2f824412011-03-12 06:43:28 -0300836 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300837
838 return ivtv_get_output(itv, vout->index, vout);
839}
840
841static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
842{
Hans Verkuil2f824412011-03-12 06:43:28 -0300843 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300844 struct ivtv *itv = id->itv;
845 struct yuv_playback_info *yi = &itv->yuv_info;
846 int streamtype;
847
848 streamtype = id->type;
849
850 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
851 return -EINVAL;
852 cropcap->bounds.top = cropcap->bounds.left = 0;
853 cropcap->bounds.width = 720;
854 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
855 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
856 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
857 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
858 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
859 if (yi->track_osd) {
860 cropcap->bounds.width = yi->osd_full_w;
861 cropcap->bounds.height = yi->osd_full_h;
862 } else {
863 cropcap->bounds.width = 720;
864 cropcap->bounds.height =
865 itv->is_out_50hz ? 576 : 480;
866 }
867 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
868 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
869 } else {
870 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
871 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
872 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
873 }
874 cropcap->defrect = cropcap->bounds;
875 return 0;
876}
877
878static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
879{
Hans Verkuil2f824412011-03-12 06:43:28 -0300880 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300881 struct ivtv *itv = id->itv;
882 struct yuv_playback_info *yi = &itv->yuv_info;
883 int streamtype;
884
885 streamtype = id->type;
886
Hans Verkuil3f038d82008-05-29 16:43:54 -0300887 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
888 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
889 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
890 yi->main_rect = crop->c;
891 return 0;
892 } else {
893 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
894 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
895 itv->main_rect = crop->c;
896 return 0;
897 }
898 }
899 return -EINVAL;
900 }
901 return -EINVAL;
902}
903
904static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
905{
Hans Verkuil2f824412011-03-12 06:43:28 -0300906 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300907 struct ivtv *itv = id->itv;
908 struct yuv_playback_info *yi = &itv->yuv_info;
909 int streamtype;
910
911 streamtype = id->type;
912
913 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
914 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
915 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
916 crop->c = yi->main_rect;
917 else
918 crop->c = itv->main_rect;
919 return 0;
920 }
921 return -EINVAL;
922}
923
924static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
925{
926 static struct v4l2_fmtdesc formats[] = {
927 { 0, 0, 0,
928 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
929 { 0, 0, 0, 0 }
930 },
931 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
932 "MPEG", V4L2_PIX_FMT_MPEG,
933 { 0, 0, 0, 0 }
934 }
935 };
936 enum v4l2_buf_type type = fmt->type;
937
938 if (fmt->index > 1)
939 return -EINVAL;
940
941 *fmt = formats[fmt->index];
942 fmt->type = type;
943 return 0;
944}
945
946static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
947{
Hans Verkuil2f824412011-03-12 06:43:28 -0300948 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300949
950 static struct v4l2_fmtdesc formats[] = {
951 { 0, 0, 0,
952 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
953 { 0, 0, 0, 0 }
954 },
955 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
956 "MPEG", V4L2_PIX_FMT_MPEG,
957 { 0, 0, 0, 0 }
958 }
959 };
960 enum v4l2_buf_type type = fmt->type;
961
962 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
963 return -EINVAL;
964
965 if (fmt->index > 1)
966 return -EINVAL;
967
968 *fmt = formats[fmt->index];
969 fmt->type = type;
970
971 return 0;
972}
973
974static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
975{
Hans Verkuil2f824412011-03-12 06:43:28 -0300976 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300977
978 *i = itv->active_input;
979
980 return 0;
981}
982
983int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
984{
Hans Verkuil2f824412011-03-12 06:43:28 -0300985 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300986
987 if (inp < 0 || inp >= itv->nof_inputs)
988 return -EINVAL;
989
990 if (inp == itv->active_input) {
991 IVTV_DEBUG_INFO("Input unchanged\n");
992 return 0;
993 }
994
995 if (atomic_read(&itv->capturing) > 0) {
996 return -EBUSY;
997 }
998
999 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1000 itv->active_input, inp);
1001
1002 itv->active_input = inp;
1003 /* Set the audio input to whatever is appropriate for the
1004 input type. */
1005 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1006
1007 /* prevent others from messing with the streams until
1008 we're finished changing inputs. */
1009 ivtv_mute(itv);
1010 ivtv_video_set_io(itv);
1011 ivtv_audio_set_io(itv);
1012 ivtv_unmute(itv);
1013
1014 return 0;
1015}
1016
1017static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1018{
Hans Verkuil2f824412011-03-12 06:43:28 -03001019 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001020
1021 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1022 return -EINVAL;
1023
1024 *i = itv->active_output;
1025
1026 return 0;
1027}
1028
1029static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1030{
Hans Verkuil2f824412011-03-12 06:43:28 -03001031 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001032
1033 if (outp >= itv->card->nof_outputs)
1034 return -EINVAL;
1035
1036 if (outp == itv->active_output) {
1037 IVTV_DEBUG_INFO("Output unchanged\n");
1038 return 0;
1039 }
1040 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1041 itv->active_output, outp);
1042
1043 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001044 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1045 SAA7127_INPUT_TYPE_NORMAL,
1046 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001047
1048 return 0;
1049}
1050
1051static int ivtv_g_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
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001058 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001059 return 0;
1060}
1061
1062int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1063{
Hans Verkuil2f824412011-03-12 06:43:28 -03001064 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001065
1066 if (vf->tuner != 0)
1067 return -EINVAL;
1068
1069 ivtv_mute(itv);
1070 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001071 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001072 ivtv_unmute(itv);
1073 return 0;
1074}
1075
1076static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1077{
Hans Verkuil2f824412011-03-12 06:43:28 -03001078 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001079
1080 *std = itv->std;
1081 return 0;
1082}
1083
Ian Armstrongc5874c92011-05-29 21:33:17 -03001084void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001085{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001086 itv->std = *std;
1087 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001088 itv->is_50hz = !itv->is_60hz;
1089 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1090 itv->cxhdl.width = 720;
1091 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001092 itv->vbi.count = itv->is_50hz ? 18 : 12;
1093 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1094 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1095
1096 if (itv->hw_flags & IVTV_HW_CX25840)
1097 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1098
Hans Verkuil3f038d82008-05-29 16:43:54 -03001099 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001100 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001101}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001102
Ian Armstrongc5874c92011-05-29 21:33:17 -03001103void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1104{
1105 struct yuv_playback_info *yi = &itv->yuv_info;
1106 DEFINE_WAIT(wait);
1107 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001108
Ian Armstrongc5874c92011-05-29 21:33:17 -03001109 /* set display standard */
1110 itv->std_out = *std;
1111 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1112 itv->is_out_50hz = !itv->is_out_60hz;
1113 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001114
Ian Armstrongc5874c92011-05-29 21:33:17 -03001115 /*
1116 * The next firmware call is time sensitive. Time it to
1117 * avoid risk of a hard lock, by trying to ensure the call
1118 * happens within the first 100 lines of the top field.
1119 * Make 4 attempts to sync to the decoder before giving up.
1120 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001121 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001122 for (f = 0; f < 4; f++) {
1123 prepare_to_wait(&itv->vsync_waitq, &wait,
1124 TASK_UNINTERRUPTIBLE);
1125 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1126 break;
1127 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001128 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001129 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001130 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001131
1132 if (f == 4)
1133 IVTV_WARN("Mode change failed to sync to decoder\n");
1134
1135 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1136 itv->main_rect.left = 0;
1137 itv->main_rect.top = 0;
1138 itv->main_rect.width = 720;
1139 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1140 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1141 720, itv->main_rect.height, 0, 0);
1142 yi->main_rect = itv->main_rect;
1143 if (!itv->osd_info) {
1144 yi->osd_full_w = 720;
1145 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1146 }
1147}
1148
1149int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1150{
1151 struct ivtv *itv = fh2id(fh)->itv;
1152
1153 if ((*std & V4L2_STD_ALL) == 0)
1154 return -EINVAL;
1155
1156 if (*std == itv->std)
1157 return 0;
1158
1159 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1160 atomic_read(&itv->capturing) > 0 ||
1161 atomic_read(&itv->decoding) > 0) {
1162 /* Switching standard would mess with already running
1163 streams, prevent that by returning EBUSY. */
1164 return -EBUSY;
1165 }
1166
1167 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1168 (unsigned long long)itv->std);
1169
1170 ivtv_s_std_enc(itv, std);
1171 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1172 ivtv_s_std_dec(itv, std);
1173
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001174 return 0;
1175}
1176
Hans Verkuil3f038d82008-05-29 16:43:54 -03001177static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001178{
Hans Verkuil2f824412011-03-12 06:43:28 -03001179 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001180 struct ivtv *itv = id->itv;
1181
1182 if (vt->index != 0)
1183 return -EINVAL;
1184
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001185 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001186
1187 return 0;
1188}
1189
1190static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1191{
Hans Verkuil2f824412011-03-12 06:43:28 -03001192 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001193
1194 if (vt->index != 0)
1195 return -EINVAL;
1196
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001197 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001198
Hans Verkuild118e292011-06-25 10:28:21 -03001199 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001200 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001201 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001202 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001203 return 0;
1204}
1205
1206static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1207{
Hans Verkuil2f824412011-03-12 06:43:28 -03001208 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001209 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1210 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001211
Hans Verkuil79afcb12008-06-21 09:02:36 -03001212 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001213 for (f = 0; f < 2; f++) {
1214 for (l = 0; l < 24; l++) {
1215 if (valid_service_line(f, l, itv->is_50hz))
1216 cap->service_lines[f][l] = set;
1217 }
1218 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001219 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001220 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1221 return -EINVAL;
1222 if (itv->is_60hz) {
1223 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1224 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1225 } else {
1226 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1227 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1228 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001229 } else {
1230 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001231 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001232
1233 set = 0;
1234 for (f = 0; f < 2; f++)
1235 for (l = 0; l < 24; l++)
1236 set |= cap->service_lines[f][l];
1237 cap->service_set = set;
1238 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001239}
1240
1241static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1242{
Hans Verkuil2f824412011-03-12 06:43:28 -03001243 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001244 struct v4l2_enc_idx_entry *e = idx->entry;
1245 int entries;
1246 int i;
1247
1248 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1249 IVTV_MAX_PGM_INDEX;
1250 if (entries > V4L2_ENC_IDX_ENTRIES)
1251 entries = V4L2_ENC_IDX_ENTRIES;
1252 idx->entries = 0;
1253 for (i = 0; i < entries; i++) {
1254 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1255 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1256 idx->entries++;
1257 e++;
1258 }
1259 }
1260 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1261 return 0;
1262}
1263
1264static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1265{
Hans Verkuil2f824412011-03-12 06:43:28 -03001266 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001267 struct ivtv *itv = id->itv;
1268
Hans Verkuil3f038d82008-05-29 16:43:54 -03001269
1270 switch (enc->cmd) {
1271 case V4L2_ENC_CMD_START:
1272 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1273 enc->flags = 0;
1274 return ivtv_start_capture(id);
1275
1276 case V4L2_ENC_CMD_STOP:
1277 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1278 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1279 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1280 return 0;
1281
1282 case V4L2_ENC_CMD_PAUSE:
1283 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1284 enc->flags = 0;
1285
1286 if (!atomic_read(&itv->capturing))
1287 return -EPERM;
1288 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1289 return 0;
1290
1291 ivtv_mute(itv);
1292 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1293 break;
1294
1295 case V4L2_ENC_CMD_RESUME:
1296 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1297 enc->flags = 0;
1298
1299 if (!atomic_read(&itv->capturing))
1300 return -EPERM;
1301
1302 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1303 return 0;
1304
1305 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1306 ivtv_unmute(itv);
1307 break;
1308 default:
1309 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1310 return -EINVAL;
1311 }
1312
1313 return 0;
1314}
1315
1316static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1317{
Hans Verkuil2f824412011-03-12 06:43:28 -03001318 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001319
Hans Verkuil3f038d82008-05-29 16:43:54 -03001320 switch (enc->cmd) {
1321 case V4L2_ENC_CMD_START:
1322 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1323 enc->flags = 0;
1324 return 0;
1325
1326 case V4L2_ENC_CMD_STOP:
1327 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1328 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1329 return 0;
1330
1331 case V4L2_ENC_CMD_PAUSE:
1332 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1333 enc->flags = 0;
1334 return 0;
1335
1336 case V4L2_ENC_CMD_RESUME:
1337 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1338 enc->flags = 0;
1339 return 0;
1340 default:
1341 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1342 return -EINVAL;
1343 }
1344}
1345
1346static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1347{
Hans Verkuil2f824412011-03-12 06:43:28 -03001348 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001349 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001350 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001351
Hans Verkuil3f038d82008-05-29 16:43:54 -03001352 int pixfmt;
1353 static u32 pixel_format[16] = {
1354 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1355 V4L2_PIX_FMT_RGB565,
1356 V4L2_PIX_FMT_RGB555,
1357 V4L2_PIX_FMT_RGB444,
1358 V4L2_PIX_FMT_RGB32,
1359 0,
1360 0,
1361 0,
1362 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1363 V4L2_PIX_FMT_YUV565,
1364 V4L2_PIX_FMT_YUV555,
1365 V4L2_PIX_FMT_YUV444,
1366 V4L2_PIX_FMT_YUV32,
1367 0,
1368 0,
1369 0,
1370 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001371
Hans Verkuil3f038d82008-05-29 16:43:54 -03001372 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1373 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001374 if (!itv->osd_video_pbase)
1375 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001376
Hans Verkuil3f038d82008-05-29 16:43:54 -03001377 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1378 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001379
Hans Verkuil3f038d82008-05-29 16:43:54 -03001380 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1381 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1382 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001383
Hans Verkuil3f038d82008-05-29 16:43:54 -03001384 fb->fmt.pixelformat = pixel_format[pixfmt];
1385 fb->fmt.width = itv->osd_rect.width;
1386 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001387 fb->fmt.field = V4L2_FIELD_INTERLACED;
1388 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001389 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1390 fb->fmt.field = V4L2_FIELD_INTERLACED;
1391 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001392 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1393 fb->fmt.bytesperline *= 2;
1394 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1395 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1396 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001397 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001398 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001399 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001400
Hans Verkuil3f038d82008-05-29 16:43:54 -03001401 if (itv->osd_chroma_key_state)
1402 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001403
Hans Verkuil3f038d82008-05-29 16:43:54 -03001404 if (itv->osd_global_alpha_state)
1405 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001406
Ian Armstrongec9faa12008-10-06 03:06:08 -03001407 if (yi->track_osd)
1408 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1409
Hans Verkuil3f038d82008-05-29 16:43:54 -03001410 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001411
Hans Verkuil3f038d82008-05-29 16:43:54 -03001412 /* no local alpha for RGB565 or unknown formats */
1413 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001414 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001415
Hans Verkuil3f038d82008-05-29 16:43:54 -03001416 /* 16-bit formats have inverted local alpha */
1417 if (pixfmt == 2 || pixfmt == 3)
1418 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1419 else
1420 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001421
Hans Verkuil3f038d82008-05-29 16:43:54 -03001422 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001423 /* 16-bit formats have inverted local alpha */
1424 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001425 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001426 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001428 }
1429
Hans Verkuil3f038d82008-05-29 16:43:54 -03001430 return 0;
1431}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001432
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1434{
Hans Verkuil2f824412011-03-12 06:43:28 -03001435 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001436 struct ivtv *itv = id->itv;
1437 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001438
Hans Verkuil3f038d82008-05-29 16:43:54 -03001439 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001440 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001441 if (!itv->osd_video_pbase)
1442 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001443
1444 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1445 itv->osd_local_alpha_state =
1446 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1447 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1448 ivtv_set_osd_alpha(itv);
1449 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001450 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001451}
1452
1453static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1454{
Hans Verkuil2f824412011-03-12 06:43:28 -03001455 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001456 struct ivtv *itv = id->itv;
1457
1458 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1459 return -EINVAL;
1460
1461 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1462
1463 return 0;
1464}
1465
Hans Verkuil09250192010-03-27 14:10:13 -03001466static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1467{
1468 switch (sub->type) {
1469 case V4L2_EVENT_VSYNC:
1470 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001471 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001472 case V4L2_EVENT_CTRL:
1473 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001474 default:
1475 return -EINVAL;
1476 }
Hans Verkuil09250192010-03-27 14:10:13 -03001477}
1478
Hans Verkuil3f038d82008-05-29 16:43:54 -03001479static int ivtv_log_status(struct file *file, void *fh)
1480{
Hans Verkuil2f824412011-03-12 06:43:28 -03001481 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001482 u32 data[CX2341X_MBOX_MAX_DATA];
1483
1484 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1485 struct v4l2_input vidin;
1486 struct v4l2_audio audin;
1487 int i;
1488
Hans Verkuil3f038d82008-05-29 16:43:54 -03001489 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1490 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1491 struct tveeprom tv;
1492
1493 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001494 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001495 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001496 ivtv_get_input(itv, itv->active_input, &vidin);
1497 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1498 IVTV_INFO("Video Input: %s\n", vidin.name);
1499 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1500 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1501 if (has_output) {
1502 struct v4l2_output vidout;
1503 struct v4l2_audioout audout;
1504 int mode = itv->output_mode;
1505 static const char * const output_modes[5] = {
1506 "None",
1507 "MPEG Streaming",
1508 "YUV Streaming",
1509 "YUV Frames",
1510 "Passthrough",
1511 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001512 static const char * const alpha_mode[4] = {
1513 "None",
1514 "Global",
1515 "Local",
1516 "Global and Local"
1517 };
1518 static const char * const pixel_format[16] = {
1519 "ARGB Indexed",
1520 "RGB 5:6:5",
1521 "ARGB 1:5:5:5",
1522 "ARGB 1:4:4:4",
1523 "ARGB 8:8:8:8",
1524 "5",
1525 "6",
1526 "7",
1527 "AYUV Indexed",
1528 "YUV 5:6:5",
1529 "AYUV 1:5:5:5",
1530 "AYUV 1:4:4:4",
1531 "AYUV 8:8:8:8",
1532 "13",
1533 "14",
1534 "15",
1535 };
1536
1537 ivtv_get_output(itv, itv->active_output, &vidout);
1538 ivtv_get_audio_output(itv, 0, &audout);
1539 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001540 if (mode < 0 || mode > OUT_PASSTHROUGH)
1541 mode = OUT_NONE;
1542 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1543 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1544 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1545 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1546 data[0] & 1 ? "On" : "Off",
1547 alpha_mode[(data[0] >> 1) & 0x3],
1548 pixel_format[(data[0] >> 3) & 0xf]);
1549 }
1550 IVTV_INFO("Tuner: %s\n",
1551 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001552 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001553 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1554 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1555 struct ivtv_stream *s = &itv->streams[i];
1556
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001557 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001558 continue;
1559 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1560 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1561 (s->buffers * s->buf_size) / 1024, s->buffers);
1562 }
1563
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001564 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1565 (long long)itv->mpg_data_received,
1566 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001567 return 0;
1568}
1569
Hans Verkuilda8ec562011-11-24 09:58:53 -03001570static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1571{
1572 struct ivtv_open_id *id = fh2id(file->private_data);
1573 struct ivtv *itv = id->itv;
1574
1575 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1576 return ivtv_video_command(itv, id, dec, false);
1577}
1578
1579static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1580{
1581 struct ivtv_open_id *id = fh2id(file->private_data);
1582 struct ivtv *itv = id->itv;
1583
1584 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1585 return ivtv_video_command(itv, id, dec, true);
1586}
1587
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001588static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001589{
Hans Verkuil09250192010-03-27 14:10:13 -03001590 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001591 struct ivtv *itv = id->itv;
1592 int nonblocking = filp->f_flags & O_NONBLOCK;
1593 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001594 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001595
1596 switch (cmd) {
1597 case IVTV_IOC_DMA_FRAME: {
1598 struct ivtv_dma_frame *args = arg;
1599
1600 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1601 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1602 return -EINVAL;
1603 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1604 return -EINVAL;
1605 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1606 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001607 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001608 return -EBUSY;
1609 }
1610 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1611 ivtv_release_stream(s);
1612 return -EBUSY;
1613 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001614 /* Mark that this file handle started the UDMA_YUV mode */
1615 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001616 if (args->y_source == NULL)
1617 return 0;
1618 return ivtv_yuv_prep_frame(itv, args);
1619 }
1620
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001621 case IVTV_IOC_PASSTHROUGH_MODE:
1622 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1623 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1624 return -EINVAL;
1625 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1626
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001627 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001628 s64 *pts = arg;
1629 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001630
1631 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1632 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1633 *pts = s->dma_pts;
1634 break;
1635 }
1636 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1637 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001638 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001639 }
1640
1641 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001642 s64 *frame = arg;
1643 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001644
1645 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1646 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1647 *frame = 0;
1648 break;
1649 }
1650 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1651 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001652 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001653 }
1654
1655 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001656 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001657
1658 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001659 memset(&dc, 0, sizeof(dc));
1660 dc.cmd = V4L2_DEC_CMD_START;
1661 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001662 }
1663
1664 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001665 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001666
1667 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001668 memset(&dc, 0, sizeof(dc));
1669 dc.cmd = V4L2_DEC_CMD_STOP;
1670 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1671 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001672 }
1673
1674 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001675 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001676
1677 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001678 memset(&dc, 0, sizeof(dc));
1679 dc.cmd = V4L2_DEC_CMD_PAUSE;
1680 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001681 }
1682
1683 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001684 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001685
1686 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001687 memset(&dc, 0, sizeof(dc));
1688 dc.cmd = V4L2_DEC_CMD_RESUME;
1689 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001690 }
1691
1692 case VIDEO_COMMAND:
1693 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001694 /* Note: struct v4l2_decoder_cmd has the same layout as
1695 struct video_command */
1696 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001697 int try = (cmd == VIDEO_TRY_COMMAND);
1698
1699 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001700 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001701 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001702 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1703 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001704 }
1705
1706 case VIDEO_GET_EVENT: {
1707 struct video_event *ev = arg;
1708 DEFINE_WAIT(wait);
1709
1710 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1711 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1712 return -EINVAL;
1713 memset(ev, 0, sizeof(*ev));
1714 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1715
1716 while (1) {
1717 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1718 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1719 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1720 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001721 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1722 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1723 if (itv->output_mode == OUT_UDMA_YUV &&
1724 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1725 IVTV_YUV_MODE_PROGRESSIVE) {
1726 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1727 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001728 }
1729 if (ev->type)
1730 return 0;
1731 if (nonblocking)
1732 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001733 /* Wait for event. Note that serialize_lock is locked,
1734 so to allow other processes to access the driver while
1735 we are waiting unlock first and later lock again. */
1736 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001737 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001738 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1739 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001740 schedule();
1741 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001742 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001743 if (signal_pending(current)) {
1744 /* return if a signal was received */
1745 IVTV_DEBUG_INFO("User stopped wait for event\n");
1746 return -EINTR;
1747 }
1748 }
1749 break;
1750 }
1751
Hans Verkuilce680252010-04-06 15:58:53 -03001752 case VIDEO_SELECT_SOURCE:
1753 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1754 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1755 return -EINVAL;
1756 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1757
1758 case AUDIO_SET_MUTE:
1759 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1760 itv->speed_mute_audio = iarg;
1761 return 0;
1762
1763 case AUDIO_CHANNEL_SELECT:
1764 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1765 if (iarg > AUDIO_STEREO_SWAPPED)
1766 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001767 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001768
1769 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1770 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1771 if (iarg > AUDIO_STEREO_SWAPPED)
1772 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001773 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001774
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001775 default:
1776 return -EINVAL;
1777 }
1778 return 0;
1779}
1780
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001781static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1782 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001783{
Hans Verkuil2f824412011-03-12 06:43:28 -03001784 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001785
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001786 if (!valid_prio) {
1787 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001788 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001789 case VIDEO_PLAY:
1790 case VIDEO_STOP:
1791 case VIDEO_FREEZE:
1792 case VIDEO_CONTINUE:
1793 case VIDEO_COMMAND:
1794 case VIDEO_SELECT_SOURCE:
1795 case AUDIO_SET_MUTE:
1796 case AUDIO_CHANNEL_SELECT:
1797 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1798 return -EBUSY;
1799 }
1800 }
1801
Hans Verkuild46c17d2007-03-10 17:59:15 -03001802 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001803 case VIDIOC_INT_RESET: {
1804 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001805
Hans Verkuil3f038d82008-05-29 16:43:54 -03001806 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1807 ivtv_reset_ir_gpio(itv);
1808 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001809 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001810 break;
1811 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001812
Hans Verkuilac9575f2009-02-14 19:58:33 -03001813 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001814 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001815 case VIDEO_GET_PTS:
1816 case VIDEO_GET_FRAME_COUNT:
1817 case VIDEO_GET_EVENT:
1818 case VIDEO_PLAY:
1819 case VIDEO_STOP:
1820 case VIDEO_FREEZE:
1821 case VIDEO_CONTINUE:
1822 case VIDEO_COMMAND:
1823 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001824 case VIDEO_SELECT_SOURCE:
1825 case AUDIO_SET_MUTE:
1826 case AUDIO_CHANNEL_SELECT:
1827 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001828 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1829
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001830 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001831 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001832 }
1833 return 0;
1834}
1835
Hans Verkuilcdc03782011-10-11 06:06:58 -03001836long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001837{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001838 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09882f02008-10-18 13:42:24 -03001839 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001840
Hans Verkuil37f89f92008-06-22 11:57:31 -03001841 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1842 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001843 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001844 vfd->debug = 0;
1845 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001846}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001847
Hans Verkuila3998102008-07-21 02:57:38 -03001848static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1849 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001850 .vidioc_s_audio = ivtv_s_audio,
1851 .vidioc_g_audio = ivtv_g_audio,
1852 .vidioc_enumaudio = ivtv_enumaudio,
1853 .vidioc_s_audout = ivtv_s_audout,
1854 .vidioc_g_audout = ivtv_g_audout,
1855 .vidioc_enum_input = ivtv_enum_input,
1856 .vidioc_enum_output = ivtv_enum_output,
1857 .vidioc_enumaudout = ivtv_enumaudout,
1858 .vidioc_cropcap = ivtv_cropcap,
1859 .vidioc_s_crop = ivtv_s_crop,
1860 .vidioc_g_crop = ivtv_g_crop,
1861 .vidioc_g_input = ivtv_g_input,
1862 .vidioc_s_input = ivtv_s_input,
1863 .vidioc_g_output = ivtv_g_output,
1864 .vidioc_s_output = ivtv_s_output,
1865 .vidioc_g_frequency = ivtv_g_frequency,
1866 .vidioc_s_frequency = ivtv_s_frequency,
1867 .vidioc_s_tuner = ivtv_s_tuner,
1868 .vidioc_g_tuner = ivtv_g_tuner,
1869 .vidioc_g_enc_index = ivtv_g_enc_index,
1870 .vidioc_g_fbuf = ivtv_g_fbuf,
1871 .vidioc_s_fbuf = ivtv_s_fbuf,
1872 .vidioc_g_std = ivtv_g_std,
1873 .vidioc_s_std = ivtv_s_std,
1874 .vidioc_overlay = ivtv_overlay,
1875 .vidioc_log_status = ivtv_log_status,
1876 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1877 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1878 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001879 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1880 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001881 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1882 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1883 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1884 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1885 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1886 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1887 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1888 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1889 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1890 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1891 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1892 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1893 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1894 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1895 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1896 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1897 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1898 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1899 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1900 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1901 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1902#ifdef CONFIG_VIDEO_ADV_DEBUG
1903 .vidioc_g_register = ivtv_g_register,
1904 .vidioc_s_register = ivtv_s_register,
1905#endif
1906 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001907 .vidioc_subscribe_event = ivtv_subscribe_event,
1908 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001909};
1910
Hans Verkuil3f038d82008-05-29 16:43:54 -03001911void ivtv_set_funcs(struct video_device *vdev)
1912{
Hans Verkuila3998102008-07-21 02:57:38 -03001913 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001914}