blob: c4bc481430985c6405580a461e2cc8e518ae2d73 [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,
249 struct video_command *vc, int try)
250{
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
256 switch (vc->cmd) {
257 case VIDEO_CMD_PLAY: {
Hans Verkuil25415cf2007-03-10 18:29:48 -0300258 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300259 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
260 if (vc->play.speed < 0)
261 vc->play.format = VIDEO_PLAY_FMT_GOP;
262 if (try) break;
263
264 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
265 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300266 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
267 /* forces ivtv_set_speed to be called */
268 itv->speed = 0;
269 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300270 return ivtv_start_decoding(id, vc->play.speed);
271 }
272
273 case VIDEO_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -0300274 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300275 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
276 vc->stop.pts = 0;
277 if (try) break;
278 if (atomic_read(&itv->decoding) == 0)
279 return 0;
280 if (itv->output_mode != OUT_MPG)
281 return -EBUSY;
282
283 itv->output_mode = OUT_NONE;
284 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
285
286 case VIDEO_CMD_FREEZE:
Hans Verkuil018ba852007-04-10 18:59:09 -0300287 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300288 if (try) break;
289 if (itv->output_mode != OUT_MPG)
290 return -EBUSY;
291 if (atomic_read(&itv->decoding) > 0) {
292 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
293 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300294 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300295 }
296 break;
297
298 case VIDEO_CMD_CONTINUE:
Hans Verkuil25415cf2007-03-10 18:29:48 -0300299 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300300 if (try) break;
301 if (itv->output_mode != OUT_MPG)
302 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300303 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
304 int speed = itv->speed;
305 itv->speed = 0;
306 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300307 }
308 break;
309
310 default:
311 return -EINVAL;
312 }
313 return 0;
314}
315
Hans Verkuil3f038d82008-05-29 16:43:54 -0300316static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300317{
Hans Verkuil2f824412011-03-12 06:43:28 -0300318 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300319 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300320
Hans Verkuile88360c2008-06-21 08:00:56 -0300321 vbifmt->reserved[0] = 0;
322 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300323 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300324 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300325 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
326 if (itv->is_60hz) {
327 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
328 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
329 } else {
330 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
331 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
332 }
333 vbifmt->service_set = ivtv_get_service_set(vbifmt);
334 return 0;
335}
336
337static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
338{
Hans Verkuil2f824412011-03-12 06:43:28 -0300339 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300340 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300341 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300342
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300343 pixfmt->width = itv->cxhdl.width;
344 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300345 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
346 pixfmt->field = V4L2_FIELD_INTERLACED;
347 pixfmt->priv = 0;
348 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
349 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300350 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
351 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300352 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300353 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300354 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
355 pixfmt->sizeimage = 128 * 1024;
356 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300357 }
358 return 0;
359}
360
Hans Verkuil3f038d82008-05-29 16:43:54 -0300361static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300362{
Hans Verkuil2f824412011-03-12 06:43:28 -0300363 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300364 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300365
Hans Verkuile88360c2008-06-21 08:00:56 -0300366 vbifmt->sampling_rate = 27000000;
367 vbifmt->offset = 248;
368 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
369 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
370 vbifmt->start[0] = itv->vbi.start[0];
371 vbifmt->start[1] = itv->vbi.start[1];
372 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
373 vbifmt->flags = 0;
374 vbifmt->reserved[0] = 0;
375 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300376 return 0;
377}
378
379static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
380{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300381 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300382 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300383 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300384
Hans Verkuile88360c2008-06-21 08:00:56 -0300385 vbifmt->reserved[0] = 0;
386 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300387 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300388
Hans Verkuil3f038d82008-05-29 16:43:54 -0300389 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
390 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
391 V4L2_SLICED_VBI_525;
392 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300393 return 0;
394 }
395
Hans Verkuil4ff07902010-03-14 12:18:18 -0300396 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300397 vbifmt->service_set = ivtv_get_service_set(vbifmt);
398 return 0;
399}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300400
Hans Verkuil3f038d82008-05-29 16:43:54 -0300401static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
402{
Hans Verkuil2f824412011-03-12 06:43:28 -0300403 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300404 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300405 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300406
Hans Verkuil3f038d82008-05-29 16:43:54 -0300407 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300408 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300409 pixfmt->width = itv->main_rect.width;
410 pixfmt->height = itv->main_rect.height;
411 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
412 pixfmt->field = V4L2_FIELD_INTERLACED;
413 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300414 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
415 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
416 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300417 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300418 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
419 break;
420 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300421 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300422 break;
423 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300424 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300425 break;
426 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300427 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
428 pixfmt->bytesperline = 720;
429 pixfmt->width = itv->yuv_info.v4l2_src_w;
430 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300432 pixfmt->sizeimage =
433 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300434 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300435 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
436 pixfmt->sizeimage = 128 * 1024;
437 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300438 }
439 return 0;
440}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300441
Hans Verkuil3f038d82008-05-29 16:43:54 -0300442static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
443{
Hans Verkuil2f824412011-03-12 06:43:28 -0300444 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300445 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300446
447 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
448 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300449 winfmt->chromakey = itv->osd_chroma_key;
450 winfmt->global_alpha = itv->osd_global_alpha;
451 winfmt->field = V4L2_FIELD_INTERLACED;
452 winfmt->clips = NULL;
453 winfmt->clipcount = 0;
454 winfmt->bitmap = NULL;
455 winfmt->w.top = winfmt->w.left = 0;
456 winfmt->w.width = itv->osd_rect.width;
457 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300458 return 0;
459}
460
461static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
462{
463 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
464}
465
466static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
467{
Hans Verkuil2f824412011-03-12 06:43:28 -0300468 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300469 struct ivtv *itv = id->itv;
470 int w = fmt->fmt.pix.width;
471 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300472 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300473
474 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300475 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300476 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
477 /* YUV height must be a multiple of 32 */
478 h &= ~0x1f;
479 min_h = 32;
480 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300481 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300482 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300483 ivtv_g_fmt_vid_cap(file, fh, fmt);
484 fmt->fmt.pix.width = w;
485 fmt->fmt.pix.height = h;
486 return 0;
487}
488
489static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
490{
491 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
492}
493
494static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
495{
496 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300497 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300498 struct ivtv *itv = id->itv;
499
500 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
501 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300502
503 /* set sliced VBI capture format */
504 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300505 vbifmt->reserved[0] = 0;
506 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300507
508 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300509 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300510 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300511 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300512 return 0;
513}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300514
Hans Verkuil3f038d82008-05-29 16:43:54 -0300515static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
516{
Hans Verkuil2f824412011-03-12 06:43:28 -0300517 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300518 s32 w = fmt->fmt.pix.width;
519 s32 h = fmt->fmt.pix.height;
520 int field = fmt->fmt.pix.field;
521 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300522
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300523 w = min(w, 720);
524 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300525 /* Why can the height be 576 even when the output is NTSC?
526
527 Internally the buffers of the PVR350 are always set to 720x576. The
528 decoded video frame will always be placed in the top left corner of
529 this buffer. For any video which is not 720x576, the buffer will
530 then be cropped to remove the unused right and lower areas, with
531 the remaining image being scaled by the hardware to fit the display
532 area. The video can be scaled both up and down, so a 720x480 video
533 can be displayed full-screen on PAL and a 720x576 video can be
534 displayed without cropping on NTSC.
535
536 Note that the scaling only occurs on the video stream, the osd
537 resolution is locked to the broadcast standard and not scaled.
538
539 Thanks to Ian Armstrong for this explanation. */
540 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300541 h = max(h, 2);
542 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300543 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300544 fmt->fmt.pix.width = w;
545 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300546 return ret;
547}
548
549static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
550{
Hans Verkuil2f824412011-03-12 06:43:28 -0300551 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300552 u32 chromakey = fmt->fmt.win.chromakey;
553 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300554
555 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
556 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300557 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
558 fmt->fmt.win.chromakey = chromakey;
559 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300560 return 0;
561}
562
563static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
564{
565 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
566}
567
568static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
569{
Hans Verkuil2f824412011-03-12 06:43:28 -0300570 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300571 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300572 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300573 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300574 int w = fmt->fmt.pix.width;
575 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300576
577 if (ret)
578 return ret;
579
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300580 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300581 return 0;
582
583 if (atomic_read(&itv->capturing) > 0)
584 return -EBUSY;
585
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300586 itv->cxhdl.width = w;
587 itv->cxhdl.height = h;
588 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300589 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300590 mbus_fmt.width = fmt->fmt.pix.width;
591 mbus_fmt.height = h;
592 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
593 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300594 return ivtv_g_fmt_vid_cap(file, fh, fmt);
595}
596
597static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
598{
Hans Verkuil2f824412011-03-12 06:43:28 -0300599 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300600
Hans Verkuila8b86432008-10-04 08:05:30 -0300601 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
602 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300603 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300604 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300605 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300606 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
607}
608
609static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
610{
611 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300612 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300613 struct ivtv *itv = id->itv;
614 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
615
616 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
617 return ret;
618
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300619 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300620 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300621 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300622 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300623 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300624 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
625 return 0;
626}
627
Hans Verkuil3f038d82008-05-29 16:43:54 -0300628static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300629{
Hans Verkuil2f824412011-03-12 06:43:28 -0300630 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300631 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300632 struct yuv_playback_info *yi = &itv->yuv_info;
633 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300634
Hans Verkuil3f038d82008-05-29 16:43:54 -0300635 if (ret)
636 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300637
Hans Verkuil3f038d82008-05-29 16:43:54 -0300638 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
639 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 /* Return now if we already have some frame data */
642 if (yi->stream_size)
643 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300644
Hans Verkuil3f038d82008-05-29 16:43:54 -0300645 yi->v4l2_src_w = fmt->fmt.pix.width;
646 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300647
Hans Verkuil3f038d82008-05-29 16:43:54 -0300648 switch (fmt->fmt.pix.field) {
649 case V4L2_FIELD_NONE:
650 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300651 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300652 case V4L2_FIELD_ANY:
653 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300654 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300655 case V4L2_FIELD_INTERLACED_BT:
656 yi->lace_mode =
657 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
658 break;
659 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300661 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
662 break;
663 }
664 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
665
666 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
667 itv->dma_data_req_size =
668 1080 * ((yi->v4l2_src_h + 31) & ~31);
669
Hans Verkuil3f038d82008-05-29 16:43:54 -0300670 return 0;
671}
672
673static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
674{
Hans Verkuil2f824412011-03-12 06:43:28 -0300675 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300676 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
677
678 if (ret == 0) {
679 itv->osd_chroma_key = fmt->fmt.win.chromakey;
680 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
681 ivtv_set_osd_alpha(itv);
682 }
683 return ret;
684}
685
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300686static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300687{
Hans Verkuil2f824412011-03-12 06:43:28 -0300688 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300689
690 chip->ident = V4L2_IDENT_NONE;
691 chip->revision = 0;
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300692 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
693 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300694 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
695 return 0;
696 }
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300697 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
698 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300699 return -EINVAL;
700 /* TODO: is this correct? */
701 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300702}
703
Hans Verkuil36ecd492008-06-25 06:00:17 -0300704#ifdef CONFIG_VIDEO_ADV_DEBUG
705static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
706{
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300707 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300708 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300709
710 if (!capable(CAP_SYS_ADMIN))
711 return -EPERM;
712 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
713 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
714 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
715 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
716 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300717 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300718 reg_start = itv->enc_mem;
719 else
720 return -EINVAL;
721
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300722 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300723 if (cmd == VIDIOC_DBG_G_REGISTER)
724 regs->val = readl(regs->reg + reg_start);
725 else
726 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300727 return 0;
728}
729
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300730static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300731{
Hans Verkuil2f824412011-03-12 06:43:28 -0300732 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300733
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300734 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300735 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300736 /* TODO: subdev errors should not be ignored, this should become a
737 subdev helper function. */
738 ivtv_call_all(itv, core, g_register, reg);
739 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300740}
741
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300742static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300743{
Hans Verkuil2f824412011-03-12 06:43:28 -0300744 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300745
Hans Verkuilaecde8b52008-12-30 07:14:19 -0300746 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300747 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300748 /* TODO: subdev errors should not be ignored, this should become a
749 subdev helper function. */
750 ivtv_call_all(itv, core, s_register, reg);
751 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300753#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300754
Hans Verkuil3f038d82008-05-29 16:43:54 -0300755static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
756{
Hans Verkuil2f824412011-03-12 06:43:28 -0300757 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300758
Hans Verkuil3f038d82008-05-29 16:43:54 -0300759 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
760 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300761 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300762 vcap->capabilities = itv->v4l2_cap; /* capabilities */
Hans Verkuil3f038d82008-05-29 16:43:54 -0300763 return 0;
764}
765
766static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
767{
Hans Verkuil2f824412011-03-12 06:43:28 -0300768 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300769
770 return ivtv_get_audio_input(itv, vin->index, vin);
771}
772
773static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
774{
Hans Verkuil2f824412011-03-12 06:43:28 -0300775 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300776
777 vin->index = itv->audio_input;
778 return ivtv_get_audio_input(itv, vin->index, vin);
779}
780
781static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
782{
Hans Verkuil2f824412011-03-12 06:43:28 -0300783 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300784
785 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300786 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300787
788 itv->audio_input = vout->index;
789 ivtv_audio_set_io(itv);
790
791 return 0;
792}
793
794static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
795{
Hans Verkuil2f824412011-03-12 06:43:28 -0300796 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300797
798 /* set it to defaults from our table */
799 return ivtv_get_audio_output(itv, vin->index, vin);
800}
801
802static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
803{
Hans Verkuil2f824412011-03-12 06:43:28 -0300804 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300805
806 vin->index = 0;
807 return ivtv_get_audio_output(itv, vin->index, vin);
808}
809
810static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
811{
Hans Verkuil2f824412011-03-12 06:43:28 -0300812 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300813
814 return ivtv_get_audio_output(itv, vout->index, vout);
815}
816
817static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
818{
Hans Verkuil2f824412011-03-12 06:43:28 -0300819 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300820
821 /* set it to defaults from our table */
822 return ivtv_get_input(itv, vin->index, vin);
823}
824
825static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
826{
Hans Verkuil2f824412011-03-12 06:43:28 -0300827 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300828
829 return ivtv_get_output(itv, vout->index, vout);
830}
831
832static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
833{
Hans Verkuil2f824412011-03-12 06:43:28 -0300834 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300835 struct ivtv *itv = id->itv;
836 struct yuv_playback_info *yi = &itv->yuv_info;
837 int streamtype;
838
839 streamtype = id->type;
840
841 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
842 return -EINVAL;
843 cropcap->bounds.top = cropcap->bounds.left = 0;
844 cropcap->bounds.width = 720;
845 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
846 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
847 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
848 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
849 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
850 if (yi->track_osd) {
851 cropcap->bounds.width = yi->osd_full_w;
852 cropcap->bounds.height = yi->osd_full_h;
853 } else {
854 cropcap->bounds.width = 720;
855 cropcap->bounds.height =
856 itv->is_out_50hz ? 576 : 480;
857 }
858 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
859 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
860 } else {
861 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
862 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
863 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
864 }
865 cropcap->defrect = cropcap->bounds;
866 return 0;
867}
868
869static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
870{
Hans Verkuil2f824412011-03-12 06:43:28 -0300871 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300872 struct ivtv *itv = id->itv;
873 struct yuv_playback_info *yi = &itv->yuv_info;
874 int streamtype;
875
876 streamtype = id->type;
877
Hans Verkuil3f038d82008-05-29 16:43:54 -0300878 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
879 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
880 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
881 yi->main_rect = crop->c;
882 return 0;
883 } else {
884 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
885 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
886 itv->main_rect = crop->c;
887 return 0;
888 }
889 }
890 return -EINVAL;
891 }
892 return -EINVAL;
893}
894
895static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
896{
Hans Verkuil2f824412011-03-12 06:43:28 -0300897 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300898 struct ivtv *itv = id->itv;
899 struct yuv_playback_info *yi = &itv->yuv_info;
900 int streamtype;
901
902 streamtype = id->type;
903
904 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
905 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
906 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
907 crop->c = yi->main_rect;
908 else
909 crop->c = itv->main_rect;
910 return 0;
911 }
912 return -EINVAL;
913}
914
915static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
916{
917 static struct v4l2_fmtdesc formats[] = {
918 { 0, 0, 0,
919 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
920 { 0, 0, 0, 0 }
921 },
922 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
923 "MPEG", V4L2_PIX_FMT_MPEG,
924 { 0, 0, 0, 0 }
925 }
926 };
927 enum v4l2_buf_type type = fmt->type;
928
929 if (fmt->index > 1)
930 return -EINVAL;
931
932 *fmt = formats[fmt->index];
933 fmt->type = type;
934 return 0;
935}
936
937static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
938{
Hans Verkuil2f824412011-03-12 06:43:28 -0300939 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300940
941 static struct v4l2_fmtdesc formats[] = {
942 { 0, 0, 0,
943 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
944 { 0, 0, 0, 0 }
945 },
946 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
947 "MPEG", V4L2_PIX_FMT_MPEG,
948 { 0, 0, 0, 0 }
949 }
950 };
951 enum v4l2_buf_type type = fmt->type;
952
953 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
954 return -EINVAL;
955
956 if (fmt->index > 1)
957 return -EINVAL;
958
959 *fmt = formats[fmt->index];
960 fmt->type = type;
961
962 return 0;
963}
964
965static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
966{
Hans Verkuil2f824412011-03-12 06:43:28 -0300967 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300968
969 *i = itv->active_input;
970
971 return 0;
972}
973
974int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
975{
Hans Verkuil2f824412011-03-12 06:43:28 -0300976 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300977
978 if (inp < 0 || inp >= itv->nof_inputs)
979 return -EINVAL;
980
981 if (inp == itv->active_input) {
982 IVTV_DEBUG_INFO("Input unchanged\n");
983 return 0;
984 }
985
986 if (atomic_read(&itv->capturing) > 0) {
987 return -EBUSY;
988 }
989
990 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
991 itv->active_input, inp);
992
993 itv->active_input = inp;
994 /* Set the audio input to whatever is appropriate for the
995 input type. */
996 itv->audio_input = itv->card->video_inputs[inp].audio_index;
997
998 /* prevent others from messing with the streams until
999 we're finished changing inputs. */
1000 ivtv_mute(itv);
1001 ivtv_video_set_io(itv);
1002 ivtv_audio_set_io(itv);
1003 ivtv_unmute(itv);
1004
1005 return 0;
1006}
1007
1008static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1009{
Hans Verkuil2f824412011-03-12 06:43:28 -03001010 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001011
1012 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1013 return -EINVAL;
1014
1015 *i = itv->active_output;
1016
1017 return 0;
1018}
1019
1020static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1021{
Hans Verkuil2f824412011-03-12 06:43:28 -03001022 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001023
1024 if (outp >= itv->card->nof_outputs)
1025 return -EINVAL;
1026
1027 if (outp == itv->active_output) {
1028 IVTV_DEBUG_INFO("Output unchanged\n");
1029 return 0;
1030 }
1031 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1032 itv->active_output, outp);
1033
1034 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001035 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1036 SAA7127_INPUT_TYPE_NORMAL,
1037 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001038
1039 return 0;
1040}
1041
1042static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1043{
Hans Verkuil2f824412011-03-12 06:43:28 -03001044 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001045
1046 if (vf->tuner != 0)
1047 return -EINVAL;
1048
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001049 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001050 return 0;
1051}
1052
1053int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1054{
Hans Verkuil2f824412011-03-12 06:43:28 -03001055 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001056
1057 if (vf->tuner != 0)
1058 return -EINVAL;
1059
1060 ivtv_mute(itv);
1061 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001062 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001063 ivtv_unmute(itv);
1064 return 0;
1065}
1066
1067static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1068{
Hans Verkuil2f824412011-03-12 06:43:28 -03001069 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001070
1071 *std = itv->std;
1072 return 0;
1073}
1074
Ian Armstrongc5874c92011-05-29 21:33:17 -03001075void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001076{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001077 itv->std = *std;
1078 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001079 itv->is_50hz = !itv->is_60hz;
1080 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1081 itv->cxhdl.width = 720;
1082 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001083 itv->vbi.count = itv->is_50hz ? 18 : 12;
1084 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1085 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1086
1087 if (itv->hw_flags & IVTV_HW_CX25840)
1088 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1089
Hans Verkuil3f038d82008-05-29 16:43:54 -03001090 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001091 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001092}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001093
Ian Armstrongc5874c92011-05-29 21:33:17 -03001094void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1095{
1096 struct yuv_playback_info *yi = &itv->yuv_info;
1097 DEFINE_WAIT(wait);
1098 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001099
Ian Armstrongc5874c92011-05-29 21:33:17 -03001100 /* set display standard */
1101 itv->std_out = *std;
1102 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1103 itv->is_out_50hz = !itv->is_out_60hz;
1104 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001105
Ian Armstrongc5874c92011-05-29 21:33:17 -03001106 /*
1107 * The next firmware call is time sensitive. Time it to
1108 * avoid risk of a hard lock, by trying to ensure the call
1109 * happens within the first 100 lines of the top field.
1110 * Make 4 attempts to sync to the decoder before giving up.
1111 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001112 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001113 for (f = 0; f < 4; f++) {
1114 prepare_to_wait(&itv->vsync_waitq, &wait,
1115 TASK_UNINTERRUPTIBLE);
1116 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1117 break;
1118 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001119 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001120 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001121 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001122
1123 if (f == 4)
1124 IVTV_WARN("Mode change failed to sync to decoder\n");
1125
1126 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1127 itv->main_rect.left = 0;
1128 itv->main_rect.top = 0;
1129 itv->main_rect.width = 720;
1130 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1131 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1132 720, itv->main_rect.height, 0, 0);
1133 yi->main_rect = itv->main_rect;
1134 if (!itv->osd_info) {
1135 yi->osd_full_w = 720;
1136 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1137 }
1138}
1139
1140int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1141{
1142 struct ivtv *itv = fh2id(fh)->itv;
1143
1144 if ((*std & V4L2_STD_ALL) == 0)
1145 return -EINVAL;
1146
1147 if (*std == itv->std)
1148 return 0;
1149
1150 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1151 atomic_read(&itv->capturing) > 0 ||
1152 atomic_read(&itv->decoding) > 0) {
1153 /* Switching standard would mess with already running
1154 streams, prevent that by returning EBUSY. */
1155 return -EBUSY;
1156 }
1157
1158 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1159 (unsigned long long)itv->std);
1160
1161 ivtv_s_std_enc(itv, std);
1162 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1163 ivtv_s_std_dec(itv, std);
1164
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001165 return 0;
1166}
1167
Hans Verkuil3f038d82008-05-29 16:43:54 -03001168static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001169{
Hans Verkuil2f824412011-03-12 06:43:28 -03001170 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001171 struct ivtv *itv = id->itv;
1172
1173 if (vt->index != 0)
1174 return -EINVAL;
1175
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001176 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001177
1178 return 0;
1179}
1180
1181static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1182{
Hans Verkuil2f824412011-03-12 06:43:28 -03001183 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001184
1185 if (vt->index != 0)
1186 return -EINVAL;
1187
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001188 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001189
Hans Verkuild118e292011-06-25 10:28:21 -03001190 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001191 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001192 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001193 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001194 return 0;
1195}
1196
1197static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1198{
Hans Verkuil2f824412011-03-12 06:43:28 -03001199 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001200 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1201 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001202
Hans Verkuil79afcb12008-06-21 09:02:36 -03001203 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001204 for (f = 0; f < 2; f++) {
1205 for (l = 0; l < 24; l++) {
1206 if (valid_service_line(f, l, itv->is_50hz))
1207 cap->service_lines[f][l] = set;
1208 }
1209 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001210 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001211 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1212 return -EINVAL;
1213 if (itv->is_60hz) {
1214 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1215 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1216 } else {
1217 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1218 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1219 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001220 } else {
1221 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001222 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001223
1224 set = 0;
1225 for (f = 0; f < 2; f++)
1226 for (l = 0; l < 24; l++)
1227 set |= cap->service_lines[f][l];
1228 cap->service_set = set;
1229 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001230}
1231
1232static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1233{
Hans Verkuil2f824412011-03-12 06:43:28 -03001234 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001235 struct v4l2_enc_idx_entry *e = idx->entry;
1236 int entries;
1237 int i;
1238
1239 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1240 IVTV_MAX_PGM_INDEX;
1241 if (entries > V4L2_ENC_IDX_ENTRIES)
1242 entries = V4L2_ENC_IDX_ENTRIES;
1243 idx->entries = 0;
1244 for (i = 0; i < entries; i++) {
1245 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1246 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1247 idx->entries++;
1248 e++;
1249 }
1250 }
1251 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1252 return 0;
1253}
1254
1255static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1256{
Hans Verkuil2f824412011-03-12 06:43:28 -03001257 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001258 struct ivtv *itv = id->itv;
1259
Hans Verkuil3f038d82008-05-29 16:43:54 -03001260
1261 switch (enc->cmd) {
1262 case V4L2_ENC_CMD_START:
1263 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1264 enc->flags = 0;
1265 return ivtv_start_capture(id);
1266
1267 case V4L2_ENC_CMD_STOP:
1268 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1269 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1270 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1271 return 0;
1272
1273 case V4L2_ENC_CMD_PAUSE:
1274 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1275 enc->flags = 0;
1276
1277 if (!atomic_read(&itv->capturing))
1278 return -EPERM;
1279 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1280 return 0;
1281
1282 ivtv_mute(itv);
1283 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1284 break;
1285
1286 case V4L2_ENC_CMD_RESUME:
1287 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1288 enc->flags = 0;
1289
1290 if (!atomic_read(&itv->capturing))
1291 return -EPERM;
1292
1293 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1294 return 0;
1295
1296 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1297 ivtv_unmute(itv);
1298 break;
1299 default:
1300 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1301 return -EINVAL;
1302 }
1303
1304 return 0;
1305}
1306
1307static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1308{
Hans Verkuil2f824412011-03-12 06:43:28 -03001309 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001310
Hans Verkuil3f038d82008-05-29 16:43:54 -03001311 switch (enc->cmd) {
1312 case V4L2_ENC_CMD_START:
1313 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1314 enc->flags = 0;
1315 return 0;
1316
1317 case V4L2_ENC_CMD_STOP:
1318 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1319 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1320 return 0;
1321
1322 case V4L2_ENC_CMD_PAUSE:
1323 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1324 enc->flags = 0;
1325 return 0;
1326
1327 case V4L2_ENC_CMD_RESUME:
1328 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1329 enc->flags = 0;
1330 return 0;
1331 default:
1332 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1333 return -EINVAL;
1334 }
1335}
1336
1337static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1338{
Hans Verkuil2f824412011-03-12 06:43:28 -03001339 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001340 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001341 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001342
Hans Verkuil3f038d82008-05-29 16:43:54 -03001343 int pixfmt;
1344 static u32 pixel_format[16] = {
1345 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1346 V4L2_PIX_FMT_RGB565,
1347 V4L2_PIX_FMT_RGB555,
1348 V4L2_PIX_FMT_RGB444,
1349 V4L2_PIX_FMT_RGB32,
1350 0,
1351 0,
1352 0,
1353 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1354 V4L2_PIX_FMT_YUV565,
1355 V4L2_PIX_FMT_YUV555,
1356 V4L2_PIX_FMT_YUV444,
1357 V4L2_PIX_FMT_YUV32,
1358 0,
1359 0,
1360 0,
1361 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001362
Hans Verkuil3f038d82008-05-29 16:43:54 -03001363 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1364 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001365 if (!itv->osd_video_pbase)
1366 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001367
Hans Verkuil3f038d82008-05-29 16:43:54 -03001368 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1369 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001370
Hans Verkuil3f038d82008-05-29 16:43:54 -03001371 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1372 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1373 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001374
Hans Verkuil3f038d82008-05-29 16:43:54 -03001375 fb->fmt.pixelformat = pixel_format[pixfmt];
1376 fb->fmt.width = itv->osd_rect.width;
1377 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001378 fb->fmt.field = V4L2_FIELD_INTERLACED;
1379 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001380 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1381 fb->fmt.field = V4L2_FIELD_INTERLACED;
1382 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001383 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1384 fb->fmt.bytesperline *= 2;
1385 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1386 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1387 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001388 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001389 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001390 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001391
Hans Verkuil3f038d82008-05-29 16:43:54 -03001392 if (itv->osd_chroma_key_state)
1393 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001394
Hans Verkuil3f038d82008-05-29 16:43:54 -03001395 if (itv->osd_global_alpha_state)
1396 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001397
Ian Armstrongec9faa12008-10-06 03:06:08 -03001398 if (yi->track_osd)
1399 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1400
Hans Verkuil3f038d82008-05-29 16:43:54 -03001401 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001402
Hans Verkuil3f038d82008-05-29 16:43:54 -03001403 /* no local alpha for RGB565 or unknown formats */
1404 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001405 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001406
Hans Verkuil3f038d82008-05-29 16:43:54 -03001407 /* 16-bit formats have inverted local alpha */
1408 if (pixfmt == 2 || pixfmt == 3)
1409 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1410 else
1411 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001412
Hans Verkuil3f038d82008-05-29 16:43:54 -03001413 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001414 /* 16-bit formats have inverted local alpha */
1415 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001416 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001417 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001418 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001419 }
1420
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 return 0;
1422}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001423
Hans Verkuil3f038d82008-05-29 16:43:54 -03001424static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1425{
Hans Verkuil2f824412011-03-12 06:43:28 -03001426 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427 struct ivtv *itv = id->itv;
1428 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001429
Hans Verkuil3f038d82008-05-29 16:43:54 -03001430 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001431 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001432 if (!itv->osd_video_pbase)
1433 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001434
1435 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1436 itv->osd_local_alpha_state =
1437 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1438 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1439 ivtv_set_osd_alpha(itv);
1440 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001441 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001442}
1443
1444static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1445{
Hans Verkuil2f824412011-03-12 06:43:28 -03001446 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001447 struct ivtv *itv = id->itv;
1448
1449 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1450 return -EINVAL;
1451
1452 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1453
1454 return 0;
1455}
1456
Hans Verkuil09250192010-03-27 14:10:13 -03001457static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1458{
1459 switch (sub->type) {
1460 case V4L2_EVENT_VSYNC:
1461 case V4L2_EVENT_EOS:
Hans Verkuil51388702011-06-28 10:40:42 -03001462 case V4L2_EVENT_CTRL:
Hans Verkuilf1e393d2011-06-13 19:24:17 -03001463 return v4l2_event_subscribe(fh, sub, 0);
Hans Verkuil09250192010-03-27 14:10:13 -03001464 default:
1465 return -EINVAL;
1466 }
Hans Verkuil09250192010-03-27 14:10:13 -03001467}
1468
Hans Verkuil3f038d82008-05-29 16:43:54 -03001469static int ivtv_log_status(struct file *file, void *fh)
1470{
Hans Verkuil2f824412011-03-12 06:43:28 -03001471 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001472 u32 data[CX2341X_MBOX_MAX_DATA];
1473
1474 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1475 struct v4l2_input vidin;
1476 struct v4l2_audio audin;
1477 int i;
1478
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001479 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1480 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001481 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1482 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1483 struct tveeprom tv;
1484
1485 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001486 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001487 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001488 ivtv_get_input(itv, itv->active_input, &vidin);
1489 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1490 IVTV_INFO("Video Input: %s\n", vidin.name);
1491 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1492 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1493 if (has_output) {
1494 struct v4l2_output vidout;
1495 struct v4l2_audioout audout;
1496 int mode = itv->output_mode;
1497 static const char * const output_modes[5] = {
1498 "None",
1499 "MPEG Streaming",
1500 "YUV Streaming",
1501 "YUV Frames",
1502 "Passthrough",
1503 };
1504 static const char * const audio_modes[5] = {
1505 "Stereo",
1506 "Left",
1507 "Right",
1508 "Mono",
1509 "Swapped"
1510 };
1511 static const char * const alpha_mode[4] = {
1512 "None",
1513 "Global",
1514 "Local",
1515 "Global and Local"
1516 };
1517 static const char * const pixel_format[16] = {
1518 "ARGB Indexed",
1519 "RGB 5:6:5",
1520 "ARGB 1:5:5:5",
1521 "ARGB 1:4:4:4",
1522 "ARGB 8:8:8:8",
1523 "5",
1524 "6",
1525 "7",
1526 "AYUV Indexed",
1527 "YUV 5:6:5",
1528 "AYUV 1:5:5:5",
1529 "AYUV 1:4:4:4",
1530 "AYUV 8:8:8:8",
1531 "13",
1532 "14",
1533 "15",
1534 };
1535
1536 ivtv_get_output(itv, itv->active_output, &vidout);
1537 ivtv_get_audio_output(itv, 0, &audout);
1538 IVTV_INFO("Video Output: %s\n", vidout.name);
1539 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1540 audio_modes[itv->audio_stereo_mode],
1541 audio_modes[itv->audio_bilingual_mode]);
1542 if (mode < 0 || mode > OUT_PASSTHROUGH)
1543 mode = OUT_NONE;
1544 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1545 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1546 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1547 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1548 data[0] & 1 ? "On" : "Off",
1549 alpha_mode[(data[0] >> 1) & 0x3],
1550 pixel_format[(data[0] >> 3) & 0xf]);
1551 }
1552 IVTV_INFO("Tuner: %s\n",
1553 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001554 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001555 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1556 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1557 struct ivtv_stream *s = &itv->streams[i];
1558
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001559 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001560 continue;
1561 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1562 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1563 (s->buffers * s->buf_size) / 1024, s->buffers);
1564 }
1565
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001566 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1567 (long long)itv->mpg_data_received,
1568 (long long)itv->vbi_data_inserted);
1569 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1570 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001571
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001572 return 0;
1573}
1574
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001575static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001576{
Hans Verkuil09250192010-03-27 14:10:13 -03001577 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001578 struct ivtv *itv = id->itv;
1579 int nonblocking = filp->f_flags & O_NONBLOCK;
1580 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001581 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001582
1583 switch (cmd) {
1584 case IVTV_IOC_DMA_FRAME: {
1585 struct ivtv_dma_frame *args = arg;
1586
1587 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1588 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1589 return -EINVAL;
1590 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1591 return -EINVAL;
1592 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1593 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001594 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001595 return -EBUSY;
1596 }
1597 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1598 ivtv_release_stream(s);
1599 return -EBUSY;
1600 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001601 /* Mark that this file handle started the UDMA_YUV mode */
1602 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001603 if (args->y_source == NULL)
1604 return 0;
1605 return ivtv_yuv_prep_frame(itv, args);
1606 }
1607
1608 case VIDEO_GET_PTS: {
1609 u32 data[CX2341X_MBOX_MAX_DATA];
1610 u64 *pts = arg;
1611
1612 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1613 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1614 *pts = s->dma_pts;
1615 break;
1616 }
1617 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1618 return -EINVAL;
1619
1620 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1621 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1622 (u64)itv->last_dec_timing[1];
1623 break;
1624 }
1625 *pts = 0;
1626 if (atomic_read(&itv->decoding)) {
1627 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1628 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1629 return -EIO;
1630 }
1631 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1632 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1633 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1634 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1635 }
1636 break;
1637 }
1638
1639 case VIDEO_GET_FRAME_COUNT: {
1640 u32 data[CX2341X_MBOX_MAX_DATA];
1641 u64 *frame = arg;
1642
1643 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1644 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1645 *frame = 0;
1646 break;
1647 }
1648 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1649 return -EINVAL;
1650
1651 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1652 *frame = itv->last_dec_timing[0];
1653 break;
1654 }
1655 *frame = 0;
1656 if (atomic_read(&itv->decoding)) {
1657 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1658 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1659 return -EIO;
1660 }
1661 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1662 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1663 *frame = data[0];
1664 }
1665 break;
1666 }
1667
1668 case VIDEO_PLAY: {
1669 struct video_command vc;
1670
1671 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1672 memset(&vc, 0, sizeof(vc));
1673 vc.cmd = VIDEO_CMD_PLAY;
1674 return ivtv_video_command(itv, id, &vc, 0);
1675 }
1676
1677 case VIDEO_STOP: {
1678 struct video_command vc;
1679
1680 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1681 memset(&vc, 0, sizeof(vc));
1682 vc.cmd = VIDEO_CMD_STOP;
1683 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1684 return ivtv_video_command(itv, id, &vc, 0);
1685 }
1686
1687 case VIDEO_FREEZE: {
1688 struct video_command vc;
1689
1690 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1691 memset(&vc, 0, sizeof(vc));
1692 vc.cmd = VIDEO_CMD_FREEZE;
1693 return ivtv_video_command(itv, id, &vc, 0);
1694 }
1695
1696 case VIDEO_CONTINUE: {
1697 struct video_command vc;
1698
1699 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1700 memset(&vc, 0, sizeof(vc));
1701 vc.cmd = VIDEO_CMD_CONTINUE;
1702 return ivtv_video_command(itv, id, &vc, 0);
1703 }
1704
1705 case VIDEO_COMMAND:
1706 case VIDEO_TRY_COMMAND: {
1707 struct video_command *vc = arg;
1708 int try = (cmd == VIDEO_TRY_COMMAND);
1709
1710 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001711 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001712 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001713 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001714 return ivtv_video_command(itv, id, vc, try);
1715 }
1716
1717 case VIDEO_GET_EVENT: {
1718 struct video_event *ev = arg;
1719 DEFINE_WAIT(wait);
1720
1721 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1722 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1723 return -EINVAL;
1724 memset(ev, 0, sizeof(*ev));
1725 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1726
1727 while (1) {
1728 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1729 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1730 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1731 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001732 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1733 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1734 if (itv->output_mode == OUT_UDMA_YUV &&
1735 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1736 IVTV_YUV_MODE_PROGRESSIVE) {
1737 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1738 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001739 }
1740 if (ev->type)
1741 return 0;
1742 if (nonblocking)
1743 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001744 /* Wait for event. Note that serialize_lock is locked,
1745 so to allow other processes to access the driver while
1746 we are waiting unlock first and later lock again. */
1747 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001748 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001749 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1750 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001751 schedule();
1752 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001753 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001754 if (signal_pending(current)) {
1755 /* return if a signal was received */
1756 IVTV_DEBUG_INFO("User stopped wait for event\n");
1757 return -EINTR;
1758 }
1759 }
1760 break;
1761 }
1762
Hans Verkuilce680252010-04-06 15:58:53 -03001763 case VIDEO_SELECT_SOURCE:
1764 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1765 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1766 return -EINVAL;
1767 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1768
1769 case AUDIO_SET_MUTE:
1770 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1771 itv->speed_mute_audio = iarg;
1772 return 0;
1773
1774 case AUDIO_CHANNEL_SELECT:
1775 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1776 if (iarg > AUDIO_STEREO_SWAPPED)
1777 return -EINVAL;
1778 itv->audio_stereo_mode = iarg;
1779 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1780 return 0;
1781
1782 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1783 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1784 if (iarg > AUDIO_STEREO_SWAPPED)
1785 return -EINVAL;
1786 itv->audio_bilingual_mode = iarg;
1787 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1788 return 0;
1789
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001790 default:
1791 return -EINVAL;
1792 }
1793 return 0;
1794}
1795
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001796static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1797 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001798{
Hans Verkuil2f824412011-03-12 06:43:28 -03001799 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001800
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001801 if (!valid_prio) {
1802 switch (cmd) {
1803 case VIDEO_PLAY:
1804 case VIDEO_STOP:
1805 case VIDEO_FREEZE:
1806 case VIDEO_CONTINUE:
1807 case VIDEO_COMMAND:
1808 case VIDEO_SELECT_SOURCE:
1809 case AUDIO_SET_MUTE:
1810 case AUDIO_CHANNEL_SELECT:
1811 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1812 return -EBUSY;
1813 }
1814 }
1815
Hans Verkuild46c17d2007-03-10 17:59:15 -03001816 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001817 case VIDIOC_INT_RESET: {
1818 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001819
Hans Verkuil3f038d82008-05-29 16:43:54 -03001820 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1821 ivtv_reset_ir_gpio(itv);
1822 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001823 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001824 break;
1825 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001826
Hans Verkuilac9575f2009-02-14 19:58:33 -03001827 case IVTV_IOC_DMA_FRAME:
1828 case VIDEO_GET_PTS:
1829 case VIDEO_GET_FRAME_COUNT:
1830 case VIDEO_GET_EVENT:
1831 case VIDEO_PLAY:
1832 case VIDEO_STOP:
1833 case VIDEO_FREEZE:
1834 case VIDEO_CONTINUE:
1835 case VIDEO_COMMAND:
1836 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001837 case VIDEO_SELECT_SOURCE:
1838 case AUDIO_SET_MUTE:
1839 case AUDIO_CHANNEL_SELECT:
1840 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001841 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1842
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001843 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001844 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001845 }
1846 return 0;
1847}
1848
Hans Verkuilcdc03782011-10-11 06:06:58 -03001849long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001850{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001851 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09882f02008-10-18 13:42:24 -03001852 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001853
Hans Verkuil37f89f92008-06-22 11:57:31 -03001854 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1855 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001856 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001857 vfd->debug = 0;
1858 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001859}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001860
Hans Verkuila3998102008-07-21 02:57:38 -03001861static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1862 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001863 .vidioc_s_audio = ivtv_s_audio,
1864 .vidioc_g_audio = ivtv_g_audio,
1865 .vidioc_enumaudio = ivtv_enumaudio,
1866 .vidioc_s_audout = ivtv_s_audout,
1867 .vidioc_g_audout = ivtv_g_audout,
1868 .vidioc_enum_input = ivtv_enum_input,
1869 .vidioc_enum_output = ivtv_enum_output,
1870 .vidioc_enumaudout = ivtv_enumaudout,
1871 .vidioc_cropcap = ivtv_cropcap,
1872 .vidioc_s_crop = ivtv_s_crop,
1873 .vidioc_g_crop = ivtv_g_crop,
1874 .vidioc_g_input = ivtv_g_input,
1875 .vidioc_s_input = ivtv_s_input,
1876 .vidioc_g_output = ivtv_g_output,
1877 .vidioc_s_output = ivtv_s_output,
1878 .vidioc_g_frequency = ivtv_g_frequency,
1879 .vidioc_s_frequency = ivtv_s_frequency,
1880 .vidioc_s_tuner = ivtv_s_tuner,
1881 .vidioc_g_tuner = ivtv_g_tuner,
1882 .vidioc_g_enc_index = ivtv_g_enc_index,
1883 .vidioc_g_fbuf = ivtv_g_fbuf,
1884 .vidioc_s_fbuf = ivtv_s_fbuf,
1885 .vidioc_g_std = ivtv_g_std,
1886 .vidioc_s_std = ivtv_s_std,
1887 .vidioc_overlay = ivtv_overlay,
1888 .vidioc_log_status = ivtv_log_status,
1889 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1890 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1891 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1892 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1893 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1894 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1895 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1896 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1897 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1898 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1899 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1900 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1901 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1902 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1903 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1904 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1905 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1906 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1907 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1908 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1909 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1910 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1911 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1912 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1913#ifdef CONFIG_VIDEO_ADV_DEBUG
1914 .vidioc_g_register = ivtv_g_register,
1915 .vidioc_s_register = ivtv_s_register,
1916#endif
1917 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001918 .vidioc_subscribe_event = ivtv_subscribe_event,
1919 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001920};
1921
Hans Verkuil3f038d82008-05-29 16:43:54 -03001922void ivtv_set_funcs(struct video_device *vdev)
1923{
Hans Verkuila3998102008-07-21 02:57:38 -03001924 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001925}