blob: b0630773e507b8aba480ac5390e19a02c482354c [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 Verkuilec105a422009-05-02 11:10:23 -0300184 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300185 got_sig = signal_pending(current);
186 if (got_sig)
187 break;
188 got_sig = 0;
189 schedule();
190 }
191 finish_wait(&itv->dma_waitq, &wait);
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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuilaecde8b2008-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 Verkuild0c8b2d2011-11-07 07:25:10 -0300757 struct ivtv_open_id *id = fh2id(file->private_data);
758 struct ivtv *itv = id->itv;
759 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300760
Hans Verkuil3f038d82008-05-29 16:43:54 -0300761 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
762 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300763 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300764 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
765 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300766 return 0;
767}
768
769static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
770{
Hans Verkuil2f824412011-03-12 06:43:28 -0300771 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300772
773 return ivtv_get_audio_input(itv, vin->index, vin);
774}
775
776static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
777{
Hans Verkuil2f824412011-03-12 06:43:28 -0300778 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300779
780 vin->index = itv->audio_input;
781 return ivtv_get_audio_input(itv, vin->index, vin);
782}
783
784static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
785{
Hans Verkuil2f824412011-03-12 06:43:28 -0300786 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300787
788 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300789 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300790
791 itv->audio_input = vout->index;
792 ivtv_audio_set_io(itv);
793
794 return 0;
795}
796
797static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
798{
Hans Verkuil2f824412011-03-12 06:43:28 -0300799 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300800
801 /* set it to defaults from our table */
802 return ivtv_get_audio_output(itv, vin->index, vin);
803}
804
805static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
806{
Hans Verkuil2f824412011-03-12 06:43:28 -0300807 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300808
809 vin->index = 0;
810 return ivtv_get_audio_output(itv, vin->index, vin);
811}
812
813static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
814{
Hans Verkuil2f824412011-03-12 06:43:28 -0300815 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300816
817 return ivtv_get_audio_output(itv, vout->index, vout);
818}
819
820static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
821{
Hans Verkuil2f824412011-03-12 06:43:28 -0300822 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300823
824 /* set it to defaults from our table */
825 return ivtv_get_input(itv, vin->index, vin);
826}
827
828static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
829{
Hans Verkuil2f824412011-03-12 06:43:28 -0300830 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300831
832 return ivtv_get_output(itv, vout->index, vout);
833}
834
835static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
836{
Hans Verkuil2f824412011-03-12 06:43:28 -0300837 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300838 struct ivtv *itv = id->itv;
839 struct yuv_playback_info *yi = &itv->yuv_info;
840 int streamtype;
841
842 streamtype = id->type;
843
844 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
845 return -EINVAL;
846 cropcap->bounds.top = cropcap->bounds.left = 0;
847 cropcap->bounds.width = 720;
848 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
849 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
850 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
851 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
852 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
853 if (yi->track_osd) {
854 cropcap->bounds.width = yi->osd_full_w;
855 cropcap->bounds.height = yi->osd_full_h;
856 } else {
857 cropcap->bounds.width = 720;
858 cropcap->bounds.height =
859 itv->is_out_50hz ? 576 : 480;
860 }
861 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
862 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
863 } else {
864 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
865 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
866 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
867 }
868 cropcap->defrect = cropcap->bounds;
869 return 0;
870}
871
872static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
873{
Hans Verkuil2f824412011-03-12 06:43:28 -0300874 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300875 struct ivtv *itv = id->itv;
876 struct yuv_playback_info *yi = &itv->yuv_info;
877 int streamtype;
878
879 streamtype = id->type;
880
Hans Verkuil3f038d82008-05-29 16:43:54 -0300881 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
882 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
883 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
884 yi->main_rect = crop->c;
885 return 0;
886 } else {
887 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
888 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
889 itv->main_rect = crop->c;
890 return 0;
891 }
892 }
893 return -EINVAL;
894 }
895 return -EINVAL;
896}
897
898static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
899{
Hans Verkuil2f824412011-03-12 06:43:28 -0300900 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300901 struct ivtv *itv = id->itv;
902 struct yuv_playback_info *yi = &itv->yuv_info;
903 int streamtype;
904
905 streamtype = id->type;
906
907 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
908 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
909 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
910 crop->c = yi->main_rect;
911 else
912 crop->c = itv->main_rect;
913 return 0;
914 }
915 return -EINVAL;
916}
917
918static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
919{
920 static struct v4l2_fmtdesc formats[] = {
921 { 0, 0, 0,
922 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
923 { 0, 0, 0, 0 }
924 },
925 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
926 "MPEG", V4L2_PIX_FMT_MPEG,
927 { 0, 0, 0, 0 }
928 }
929 };
930 enum v4l2_buf_type type = fmt->type;
931
932 if (fmt->index > 1)
933 return -EINVAL;
934
935 *fmt = formats[fmt->index];
936 fmt->type = type;
937 return 0;
938}
939
940static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
941{
Hans Verkuil2f824412011-03-12 06:43:28 -0300942 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300943
944 static struct v4l2_fmtdesc formats[] = {
945 { 0, 0, 0,
946 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
947 { 0, 0, 0, 0 }
948 },
949 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
950 "MPEG", V4L2_PIX_FMT_MPEG,
951 { 0, 0, 0, 0 }
952 }
953 };
954 enum v4l2_buf_type type = fmt->type;
955
956 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
957 return -EINVAL;
958
959 if (fmt->index > 1)
960 return -EINVAL;
961
962 *fmt = formats[fmt->index];
963 fmt->type = type;
964
965 return 0;
966}
967
968static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
969{
Hans Verkuil2f824412011-03-12 06:43:28 -0300970 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300971
972 *i = itv->active_input;
973
974 return 0;
975}
976
977int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
978{
Hans Verkuil2f824412011-03-12 06:43:28 -0300979 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300980
981 if (inp < 0 || inp >= itv->nof_inputs)
982 return -EINVAL;
983
984 if (inp == itv->active_input) {
985 IVTV_DEBUG_INFO("Input unchanged\n");
986 return 0;
987 }
988
989 if (atomic_read(&itv->capturing) > 0) {
990 return -EBUSY;
991 }
992
993 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
994 itv->active_input, inp);
995
996 itv->active_input = inp;
997 /* Set the audio input to whatever is appropriate for the
998 input type. */
999 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1000
1001 /* prevent others from messing with the streams until
1002 we're finished changing inputs. */
1003 ivtv_mute(itv);
1004 ivtv_video_set_io(itv);
1005 ivtv_audio_set_io(itv);
1006 ivtv_unmute(itv);
1007
1008 return 0;
1009}
1010
1011static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1012{
Hans Verkuil2f824412011-03-12 06:43:28 -03001013 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001014
1015 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1016 return -EINVAL;
1017
1018 *i = itv->active_output;
1019
1020 return 0;
1021}
1022
1023static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1024{
Hans Verkuil2f824412011-03-12 06:43:28 -03001025 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001026
1027 if (outp >= itv->card->nof_outputs)
1028 return -EINVAL;
1029
1030 if (outp == itv->active_output) {
1031 IVTV_DEBUG_INFO("Output unchanged\n");
1032 return 0;
1033 }
1034 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1035 itv->active_output, outp);
1036
1037 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001038 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1039 SAA7127_INPUT_TYPE_NORMAL,
1040 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001041
1042 return 0;
1043}
1044
1045static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1046{
Hans Verkuil2f824412011-03-12 06:43:28 -03001047 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001048
1049 if (vf->tuner != 0)
1050 return -EINVAL;
1051
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001052 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001053 return 0;
1054}
1055
1056int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1057{
Hans Verkuil2f824412011-03-12 06:43:28 -03001058 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001059
1060 if (vf->tuner != 0)
1061 return -EINVAL;
1062
1063 ivtv_mute(itv);
1064 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001065 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001066 ivtv_unmute(itv);
1067 return 0;
1068}
1069
1070static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1071{
Hans Verkuil2f824412011-03-12 06:43:28 -03001072 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001073
1074 *std = itv->std;
1075 return 0;
1076}
1077
Ian Armstrongc5874c92011-05-29 21:33:17 -03001078void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001079{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001080 itv->std = *std;
1081 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001082 itv->is_50hz = !itv->is_60hz;
1083 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1084 itv->cxhdl.width = 720;
1085 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001086 itv->vbi.count = itv->is_50hz ? 18 : 12;
1087 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1088 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1089
1090 if (itv->hw_flags & IVTV_HW_CX25840)
1091 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1092
Hans Verkuil3f038d82008-05-29 16:43:54 -03001093 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001094 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001095}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001096
Ian Armstrongc5874c92011-05-29 21:33:17 -03001097void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1098{
1099 struct yuv_playback_info *yi = &itv->yuv_info;
1100 DEFINE_WAIT(wait);
1101 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001102
Ian Armstrongc5874c92011-05-29 21:33:17 -03001103 /* set display standard */
1104 itv->std_out = *std;
1105 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1106 itv->is_out_50hz = !itv->is_out_60hz;
1107 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001108
Ian Armstrongc5874c92011-05-29 21:33:17 -03001109 /*
1110 * The next firmware call is time sensitive. Time it to
1111 * avoid risk of a hard lock, by trying to ensure the call
1112 * happens within the first 100 lines of the top field.
1113 * Make 4 attempts to sync to the decoder before giving up.
1114 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001115 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001116 for (f = 0; f < 4; f++) {
1117 prepare_to_wait(&itv->vsync_waitq, &wait,
1118 TASK_UNINTERRUPTIBLE);
1119 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1120 break;
1121 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001122 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001123 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001124 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001125
1126 if (f == 4)
1127 IVTV_WARN("Mode change failed to sync to decoder\n");
1128
1129 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1130 itv->main_rect.left = 0;
1131 itv->main_rect.top = 0;
1132 itv->main_rect.width = 720;
1133 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1134 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1135 720, itv->main_rect.height, 0, 0);
1136 yi->main_rect = itv->main_rect;
1137 if (!itv->osd_info) {
1138 yi->osd_full_w = 720;
1139 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1140 }
1141}
1142
1143int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1144{
1145 struct ivtv *itv = fh2id(fh)->itv;
1146
1147 if ((*std & V4L2_STD_ALL) == 0)
1148 return -EINVAL;
1149
1150 if (*std == itv->std)
1151 return 0;
1152
1153 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1154 atomic_read(&itv->capturing) > 0 ||
1155 atomic_read(&itv->decoding) > 0) {
1156 /* Switching standard would mess with already running
1157 streams, prevent that by returning EBUSY. */
1158 return -EBUSY;
1159 }
1160
1161 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1162 (unsigned long long)itv->std);
1163
1164 ivtv_s_std_enc(itv, std);
1165 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1166 ivtv_s_std_dec(itv, std);
1167
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001168 return 0;
1169}
1170
Hans Verkuil3f038d82008-05-29 16:43:54 -03001171static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001172{
Hans Verkuil2f824412011-03-12 06:43:28 -03001173 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001174 struct ivtv *itv = id->itv;
1175
1176 if (vt->index != 0)
1177 return -EINVAL;
1178
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001179 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001180
1181 return 0;
1182}
1183
1184static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1185{
Hans Verkuil2f824412011-03-12 06:43:28 -03001186 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001187
1188 if (vt->index != 0)
1189 return -EINVAL;
1190
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001191 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001192
Hans Verkuild118e292011-06-25 10:28:21 -03001193 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001194 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001195 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001196 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001197 return 0;
1198}
1199
1200static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1201{
Hans Verkuil2f824412011-03-12 06:43:28 -03001202 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001203 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1204 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001205
Hans Verkuil79afcb12008-06-21 09:02:36 -03001206 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001207 for (f = 0; f < 2; f++) {
1208 for (l = 0; l < 24; l++) {
1209 if (valid_service_line(f, l, itv->is_50hz))
1210 cap->service_lines[f][l] = set;
1211 }
1212 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001213 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001214 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1215 return -EINVAL;
1216 if (itv->is_60hz) {
1217 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1218 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1219 } else {
1220 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1221 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1222 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001223 } else {
1224 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001225 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001226
1227 set = 0;
1228 for (f = 0; f < 2; f++)
1229 for (l = 0; l < 24; l++)
1230 set |= cap->service_lines[f][l];
1231 cap->service_set = set;
1232 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001233}
1234
1235static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1236{
Hans Verkuil2f824412011-03-12 06:43:28 -03001237 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001238 struct v4l2_enc_idx_entry *e = idx->entry;
1239 int entries;
1240 int i;
1241
1242 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1243 IVTV_MAX_PGM_INDEX;
1244 if (entries > V4L2_ENC_IDX_ENTRIES)
1245 entries = V4L2_ENC_IDX_ENTRIES;
1246 idx->entries = 0;
1247 for (i = 0; i < entries; i++) {
1248 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1249 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1250 idx->entries++;
1251 e++;
1252 }
1253 }
1254 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1255 return 0;
1256}
1257
1258static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1259{
Hans Verkuil2f824412011-03-12 06:43:28 -03001260 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001261 struct ivtv *itv = id->itv;
1262
Hans Verkuil3f038d82008-05-29 16:43:54 -03001263
1264 switch (enc->cmd) {
1265 case V4L2_ENC_CMD_START:
1266 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1267 enc->flags = 0;
1268 return ivtv_start_capture(id);
1269
1270 case V4L2_ENC_CMD_STOP:
1271 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1272 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1273 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1274 return 0;
1275
1276 case V4L2_ENC_CMD_PAUSE:
1277 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1278 enc->flags = 0;
1279
1280 if (!atomic_read(&itv->capturing))
1281 return -EPERM;
1282 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1283 return 0;
1284
1285 ivtv_mute(itv);
1286 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1287 break;
1288
1289 case V4L2_ENC_CMD_RESUME:
1290 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1291 enc->flags = 0;
1292
1293 if (!atomic_read(&itv->capturing))
1294 return -EPERM;
1295
1296 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1297 return 0;
1298
1299 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1300 ivtv_unmute(itv);
1301 break;
1302 default:
1303 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1304 return -EINVAL;
1305 }
1306
1307 return 0;
1308}
1309
1310static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1311{
Hans Verkuil2f824412011-03-12 06:43:28 -03001312 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001313
Hans Verkuil3f038d82008-05-29 16:43:54 -03001314 switch (enc->cmd) {
1315 case V4L2_ENC_CMD_START:
1316 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1317 enc->flags = 0;
1318 return 0;
1319
1320 case V4L2_ENC_CMD_STOP:
1321 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1322 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1323 return 0;
1324
1325 case V4L2_ENC_CMD_PAUSE:
1326 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1327 enc->flags = 0;
1328 return 0;
1329
1330 case V4L2_ENC_CMD_RESUME:
1331 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1332 enc->flags = 0;
1333 return 0;
1334 default:
1335 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1336 return -EINVAL;
1337 }
1338}
1339
1340static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1341{
Hans Verkuil2f824412011-03-12 06:43:28 -03001342 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001343 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001344 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001345
Hans Verkuil3f038d82008-05-29 16:43:54 -03001346 int pixfmt;
1347 static u32 pixel_format[16] = {
1348 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1349 V4L2_PIX_FMT_RGB565,
1350 V4L2_PIX_FMT_RGB555,
1351 V4L2_PIX_FMT_RGB444,
1352 V4L2_PIX_FMT_RGB32,
1353 0,
1354 0,
1355 0,
1356 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1357 V4L2_PIX_FMT_YUV565,
1358 V4L2_PIX_FMT_YUV555,
1359 V4L2_PIX_FMT_YUV444,
1360 V4L2_PIX_FMT_YUV32,
1361 0,
1362 0,
1363 0,
1364 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001365
Hans Verkuil3f038d82008-05-29 16:43:54 -03001366 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1367 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001368 if (!itv->osd_video_pbase)
1369 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001370
Hans Verkuil3f038d82008-05-29 16:43:54 -03001371 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1372 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001373
Hans Verkuil3f038d82008-05-29 16:43:54 -03001374 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1375 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1376 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001377
Hans Verkuil3f038d82008-05-29 16:43:54 -03001378 fb->fmt.pixelformat = pixel_format[pixfmt];
1379 fb->fmt.width = itv->osd_rect.width;
1380 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001381 fb->fmt.field = V4L2_FIELD_INTERLACED;
1382 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001383 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1384 fb->fmt.field = V4L2_FIELD_INTERLACED;
1385 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001386 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1387 fb->fmt.bytesperline *= 2;
1388 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1389 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1390 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001391 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001392 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001393 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001394
Hans Verkuil3f038d82008-05-29 16:43:54 -03001395 if (itv->osd_chroma_key_state)
1396 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001397
Hans Verkuil3f038d82008-05-29 16:43:54 -03001398 if (itv->osd_global_alpha_state)
1399 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001400
Ian Armstrongec9faa12008-10-06 03:06:08 -03001401 if (yi->track_osd)
1402 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1403
Hans Verkuil3f038d82008-05-29 16:43:54 -03001404 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001405
Hans Verkuil3f038d82008-05-29 16:43:54 -03001406 /* no local alpha for RGB565 or unknown formats */
1407 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001408 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001409
Hans Verkuil3f038d82008-05-29 16:43:54 -03001410 /* 16-bit formats have inverted local alpha */
1411 if (pixfmt == 2 || pixfmt == 3)
1412 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1413 else
1414 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001415
Hans Verkuil3f038d82008-05-29 16:43:54 -03001416 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001417 /* 16-bit formats have inverted local alpha */
1418 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001419 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001420 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001422 }
1423
Hans Verkuil3f038d82008-05-29 16:43:54 -03001424 return 0;
1425}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001426
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1428{
Hans Verkuil2f824412011-03-12 06:43:28 -03001429 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001430 struct ivtv *itv = id->itv;
1431 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001432
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001434 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001435 if (!itv->osd_video_pbase)
1436 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001437
1438 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1439 itv->osd_local_alpha_state =
1440 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1441 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1442 ivtv_set_osd_alpha(itv);
1443 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001444 return ivtv_g_fbuf(file, fh, fb);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001445}
1446
1447static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1448{
Hans Verkuil2f824412011-03-12 06:43:28 -03001449 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001450 struct ivtv *itv = id->itv;
1451
1452 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1453 return -EINVAL;
1454
1455 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1456
1457 return 0;
1458}
1459
Hans Verkuil09250192010-03-27 14:10:13 -03001460static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1461{
1462 switch (sub->type) {
1463 case V4L2_EVENT_VSYNC:
1464 case V4L2_EVENT_EOS:
Hans Verkuil51388702011-06-28 10:40:42 -03001465 case V4L2_EVENT_CTRL:
Hans Verkuilf1e393d2011-06-13 19:24:17 -03001466 return v4l2_event_subscribe(fh, sub, 0);
Hans Verkuil09250192010-03-27 14:10:13 -03001467 default:
1468 return -EINVAL;
1469 }
Hans Verkuil09250192010-03-27 14:10:13 -03001470}
1471
Hans Verkuil3f038d82008-05-29 16:43:54 -03001472static int ivtv_log_status(struct file *file, void *fh)
1473{
Hans Verkuil2f824412011-03-12 06:43:28 -03001474 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001475 u32 data[CX2341X_MBOX_MAX_DATA];
1476
1477 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1478 struct v4l2_input vidin;
1479 struct v4l2_audio audin;
1480 int i;
1481
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001482 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1483 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001484 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1485 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1486 struct tveeprom tv;
1487
1488 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001489 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001490 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001491 ivtv_get_input(itv, itv->active_input, &vidin);
1492 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1493 IVTV_INFO("Video Input: %s\n", vidin.name);
1494 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1495 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1496 if (has_output) {
1497 struct v4l2_output vidout;
1498 struct v4l2_audioout audout;
1499 int mode = itv->output_mode;
1500 static const char * const output_modes[5] = {
1501 "None",
1502 "MPEG Streaming",
1503 "YUV Streaming",
1504 "YUV Frames",
1505 "Passthrough",
1506 };
1507 static const char * const audio_modes[5] = {
1508 "Stereo",
1509 "Left",
1510 "Right",
1511 "Mono",
1512 "Swapped"
1513 };
1514 static const char * const alpha_mode[4] = {
1515 "None",
1516 "Global",
1517 "Local",
1518 "Global and Local"
1519 };
1520 static const char * const pixel_format[16] = {
1521 "ARGB Indexed",
1522 "RGB 5:6:5",
1523 "ARGB 1:5:5:5",
1524 "ARGB 1:4:4:4",
1525 "ARGB 8:8:8:8",
1526 "5",
1527 "6",
1528 "7",
1529 "AYUV Indexed",
1530 "YUV 5:6:5",
1531 "AYUV 1:5:5:5",
1532 "AYUV 1:4:4:4",
1533 "AYUV 8:8:8:8",
1534 "13",
1535 "14",
1536 "15",
1537 };
1538
1539 ivtv_get_output(itv, itv->active_output, &vidout);
1540 ivtv_get_audio_output(itv, 0, &audout);
1541 IVTV_INFO("Video Output: %s\n", vidout.name);
1542 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1543 audio_modes[itv->audio_stereo_mode],
1544 audio_modes[itv->audio_bilingual_mode]);
1545 if (mode < 0 || mode > OUT_PASSTHROUGH)
1546 mode = OUT_NONE;
1547 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1548 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1549 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1550 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1551 data[0] & 1 ? "On" : "Off",
1552 alpha_mode[(data[0] >> 1) & 0x3],
1553 pixel_format[(data[0] >> 3) & 0xf]);
1554 }
1555 IVTV_INFO("Tuner: %s\n",
1556 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001557 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001558 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1559 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1560 struct ivtv_stream *s = &itv->streams[i];
1561
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001562 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001563 continue;
1564 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1565 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1566 (s->buffers * s->buf_size) / 1024, s->buffers);
1567 }
1568
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001569 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1570 (long long)itv->mpg_data_received,
1571 (long long)itv->vbi_data_inserted);
1572 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1573 itv->instance);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001574
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001575 return 0;
1576}
1577
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001578static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001579{
Hans Verkuil09250192010-03-27 14:10:13 -03001580 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001581 struct ivtv *itv = id->itv;
1582 int nonblocking = filp->f_flags & O_NONBLOCK;
1583 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001584 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001585
1586 switch (cmd) {
1587 case IVTV_IOC_DMA_FRAME: {
1588 struct ivtv_dma_frame *args = arg;
1589
1590 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1591 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1592 return -EINVAL;
1593 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1594 return -EINVAL;
1595 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1596 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001597 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001598 return -EBUSY;
1599 }
1600 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1601 ivtv_release_stream(s);
1602 return -EBUSY;
1603 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001604 /* Mark that this file handle started the UDMA_YUV mode */
1605 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001606 if (args->y_source == NULL)
1607 return 0;
1608 return ivtv_yuv_prep_frame(itv, args);
1609 }
1610
1611 case VIDEO_GET_PTS: {
1612 u32 data[CX2341X_MBOX_MAX_DATA];
1613 u64 *pts = arg;
1614
1615 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1616 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1617 *pts = s->dma_pts;
1618 break;
1619 }
1620 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1621 return -EINVAL;
1622
1623 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1624 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1625 (u64)itv->last_dec_timing[1];
1626 break;
1627 }
1628 *pts = 0;
1629 if (atomic_read(&itv->decoding)) {
1630 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1631 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1632 return -EIO;
1633 }
1634 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1635 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1636 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1637 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1638 }
1639 break;
1640 }
1641
1642 case VIDEO_GET_FRAME_COUNT: {
1643 u32 data[CX2341X_MBOX_MAX_DATA];
1644 u64 *frame = arg;
1645
1646 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1647 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1648 *frame = 0;
1649 break;
1650 }
1651 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1652 return -EINVAL;
1653
1654 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1655 *frame = itv->last_dec_timing[0];
1656 break;
1657 }
1658 *frame = 0;
1659 if (atomic_read(&itv->decoding)) {
1660 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1661 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1662 return -EIO;
1663 }
1664 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1665 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1666 *frame = data[0];
1667 }
1668 break;
1669 }
1670
1671 case VIDEO_PLAY: {
1672 struct video_command vc;
1673
1674 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1675 memset(&vc, 0, sizeof(vc));
1676 vc.cmd = VIDEO_CMD_PLAY;
1677 return ivtv_video_command(itv, id, &vc, 0);
1678 }
1679
1680 case VIDEO_STOP: {
1681 struct video_command vc;
1682
1683 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1684 memset(&vc, 0, sizeof(vc));
1685 vc.cmd = VIDEO_CMD_STOP;
1686 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1687 return ivtv_video_command(itv, id, &vc, 0);
1688 }
1689
1690 case VIDEO_FREEZE: {
1691 struct video_command vc;
1692
1693 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1694 memset(&vc, 0, sizeof(vc));
1695 vc.cmd = VIDEO_CMD_FREEZE;
1696 return ivtv_video_command(itv, id, &vc, 0);
1697 }
1698
1699 case VIDEO_CONTINUE: {
1700 struct video_command vc;
1701
1702 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1703 memset(&vc, 0, sizeof(vc));
1704 vc.cmd = VIDEO_CMD_CONTINUE;
1705 return ivtv_video_command(itv, id, &vc, 0);
1706 }
1707
1708 case VIDEO_COMMAND:
1709 case VIDEO_TRY_COMMAND: {
1710 struct video_command *vc = arg;
1711 int try = (cmd == VIDEO_TRY_COMMAND);
1712
1713 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001714 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001715 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001716 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001717 return ivtv_video_command(itv, id, vc, try);
1718 }
1719
1720 case VIDEO_GET_EVENT: {
1721 struct video_event *ev = arg;
1722 DEFINE_WAIT(wait);
1723
1724 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1725 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1726 return -EINVAL;
1727 memset(ev, 0, sizeof(*ev));
1728 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1729
1730 while (1) {
1731 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1732 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1733 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1734 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001735 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1736 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1737 if (itv->output_mode == OUT_UDMA_YUV &&
1738 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1739 IVTV_YUV_MODE_PROGRESSIVE) {
1740 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1741 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001742 }
1743 if (ev->type)
1744 return 0;
1745 if (nonblocking)
1746 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001747 /* Wait for event. Note that serialize_lock is locked,
1748 so to allow other processes to access the driver while
1749 we are waiting unlock first and later lock again. */
1750 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001751 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001752 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1753 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001754 schedule();
1755 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001756 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001757 if (signal_pending(current)) {
1758 /* return if a signal was received */
1759 IVTV_DEBUG_INFO("User stopped wait for event\n");
1760 return -EINTR;
1761 }
1762 }
1763 break;
1764 }
1765
Hans Verkuilce680252010-04-06 15:58:53 -03001766 case VIDEO_SELECT_SOURCE:
1767 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1768 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1769 return -EINVAL;
1770 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1771
1772 case AUDIO_SET_MUTE:
1773 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1774 itv->speed_mute_audio = iarg;
1775 return 0;
1776
1777 case AUDIO_CHANNEL_SELECT:
1778 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1779 if (iarg > AUDIO_STEREO_SWAPPED)
1780 return -EINVAL;
1781 itv->audio_stereo_mode = iarg;
1782 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1783 return 0;
1784
1785 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1786 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1787 if (iarg > AUDIO_STEREO_SWAPPED)
1788 return -EINVAL;
1789 itv->audio_bilingual_mode = iarg;
1790 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1791 return 0;
1792
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001793 default:
1794 return -EINVAL;
1795 }
1796 return 0;
1797}
1798
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001799static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1800 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001801{
Hans Verkuil2f824412011-03-12 06:43:28 -03001802 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001803
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001804 if (!valid_prio) {
1805 switch (cmd) {
1806 case VIDEO_PLAY:
1807 case VIDEO_STOP:
1808 case VIDEO_FREEZE:
1809 case VIDEO_CONTINUE:
1810 case VIDEO_COMMAND:
1811 case VIDEO_SELECT_SOURCE:
1812 case AUDIO_SET_MUTE:
1813 case AUDIO_CHANNEL_SELECT:
1814 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1815 return -EBUSY;
1816 }
1817 }
1818
Hans Verkuild46c17d2007-03-10 17:59:15 -03001819 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001820 case VIDIOC_INT_RESET: {
1821 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001822
Hans Verkuil3f038d82008-05-29 16:43:54 -03001823 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1824 ivtv_reset_ir_gpio(itv);
1825 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001826 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001827 break;
1828 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001829
Hans Verkuilac9575f2009-02-14 19:58:33 -03001830 case IVTV_IOC_DMA_FRAME:
1831 case VIDEO_GET_PTS:
1832 case VIDEO_GET_FRAME_COUNT:
1833 case VIDEO_GET_EVENT:
1834 case VIDEO_PLAY:
1835 case VIDEO_STOP:
1836 case VIDEO_FREEZE:
1837 case VIDEO_CONTINUE:
1838 case VIDEO_COMMAND:
1839 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001840 case VIDEO_SELECT_SOURCE:
1841 case AUDIO_SET_MUTE:
1842 case AUDIO_CHANNEL_SELECT:
1843 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001844 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1845
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001846 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -03001847 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001848 }
1849 return 0;
1850}
1851
Hans Verkuilcdc03782011-10-11 06:06:58 -03001852long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001853{
Hans Verkuil37f89f92008-06-22 11:57:31 -03001854 struct video_device *vfd = video_devdata(filp);
Hans Verkuil09882f02008-10-18 13:42:24 -03001855 long ret;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001856
Hans Verkuil37f89f92008-06-22 11:57:31 -03001857 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1858 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
Hans Verkuilbec43662008-12-30 06:58:20 -03001859 ret = video_ioctl2(filp, cmd, arg);
Hans Verkuil37f89f92008-06-22 11:57:31 -03001860 vfd->debug = 0;
1861 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001862}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001863
Hans Verkuila3998102008-07-21 02:57:38 -03001864static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1865 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001866 .vidioc_s_audio = ivtv_s_audio,
1867 .vidioc_g_audio = ivtv_g_audio,
1868 .vidioc_enumaudio = ivtv_enumaudio,
1869 .vidioc_s_audout = ivtv_s_audout,
1870 .vidioc_g_audout = ivtv_g_audout,
1871 .vidioc_enum_input = ivtv_enum_input,
1872 .vidioc_enum_output = ivtv_enum_output,
1873 .vidioc_enumaudout = ivtv_enumaudout,
1874 .vidioc_cropcap = ivtv_cropcap,
1875 .vidioc_s_crop = ivtv_s_crop,
1876 .vidioc_g_crop = ivtv_g_crop,
1877 .vidioc_g_input = ivtv_g_input,
1878 .vidioc_s_input = ivtv_s_input,
1879 .vidioc_g_output = ivtv_g_output,
1880 .vidioc_s_output = ivtv_s_output,
1881 .vidioc_g_frequency = ivtv_g_frequency,
1882 .vidioc_s_frequency = ivtv_s_frequency,
1883 .vidioc_s_tuner = ivtv_s_tuner,
1884 .vidioc_g_tuner = ivtv_g_tuner,
1885 .vidioc_g_enc_index = ivtv_g_enc_index,
1886 .vidioc_g_fbuf = ivtv_g_fbuf,
1887 .vidioc_s_fbuf = ivtv_s_fbuf,
1888 .vidioc_g_std = ivtv_g_std,
1889 .vidioc_s_std = ivtv_s_std,
1890 .vidioc_overlay = ivtv_overlay,
1891 .vidioc_log_status = ivtv_log_status,
1892 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1893 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1894 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1895 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1896 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1897 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1898 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1899 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1900 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1901 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1902 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1903 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1904 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1905 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1906 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1907 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1908 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1909 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1910 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1911 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1912 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1913 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1914 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1915 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1916#ifdef CONFIG_VIDEO_ADV_DEBUG
1917 .vidioc_g_register = ivtv_g_register,
1918 .vidioc_s_register = ivtv_s_register,
1919#endif
1920 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001921 .vidioc_subscribe_event = ivtv_subscribe_event,
1922 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001923};
1924
Hans Verkuil3f038d82008-05-29 16:43:54 -03001925void ivtv_set_funcs(struct video_device *vdev)
1926{
Hans Verkuila3998102008-07-21 02:57:38 -03001927 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001928}