blob: 807b275a847e696b762c10d083874b618d30ee89 [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>
Hans Verkuil09250192010-03-27 14:10:13 -030037#include <media/v4l2-event.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030038#include <linux/dvb/audio.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030039
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030040u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030041{
42 switch (type) {
43 case V4L2_SLICED_TELETEXT_B:
44 return IVTV_SLICED_TYPE_TELETEXT_B;
45 case V4L2_SLICED_CAPTION_525:
46 return IVTV_SLICED_TYPE_CAPTION_525;
47 case V4L2_SLICED_WSS_625:
48 return IVTV_SLICED_TYPE_WSS_625;
49 case V4L2_SLICED_VPS:
50 return IVTV_SLICED_TYPE_VPS;
51 default:
52 return 0;
53 }
54}
55
56static int valid_service_line(int field, int line, int is_pal)
57{
58 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
59 (!is_pal && line >= 10 && line < 22);
60}
61
62static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
63{
64 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
65 int i;
66
67 set = set & valid_set;
68 if (set == 0 || !valid_service_line(field, line, is_pal)) {
69 return 0;
70 }
71 if (!is_pal) {
72 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
73 return V4L2_SLICED_CAPTION_525;
74 }
75 else {
76 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
77 return V4L2_SLICED_VPS;
78 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
79 return V4L2_SLICED_WSS_625;
80 if (line == 23)
81 return 0;
82 }
83 for (i = 0; i < 32; i++) {
84 if ((1 << i) & set)
85 return 1 << i;
86 }
87 return 0;
88}
89
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030090void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030091{
92 u16 set = fmt->service_set;
93 int f, l;
94
95 fmt->service_set = 0;
96 for (f = 0; f < 2; f++) {
97 for (l = 0; l < 24; l++) {
98 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
99 }
100 }
101}
102
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300103static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300104{
105 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300106
107 for (f = 0; f < 2; f++) {
108 for (l = 0; l < 24; l++) {
109 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 -0300110 }
111 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300112}
113
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300114u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300115{
116 int f, l;
117 u16 set = 0;
118
119 for (f = 0; f < 2; f++) {
120 for (l = 0; l < 24; l++) {
121 set |= fmt->service_lines[f][l];
122 }
123 }
124 return set;
125}
126
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300127void ivtv_set_osd_alpha(struct ivtv *itv)
128{
129 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
130 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300131 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 -0300132}
133
134int ivtv_set_speed(struct ivtv *itv, int speed)
135{
136 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300137 int single_step = (speed == 1 || speed == -1);
138 DEFINE_WAIT(wait);
139
140 if (speed == 0) speed = 1000;
141
142 /* No change? */
143 if (speed == itv->speed && !single_step)
144 return 0;
145
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300146 if (single_step && (speed < 0) == (itv->speed < 0)) {
147 /* Single step video and no need to change direction */
148 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
149 itv->speed = speed;
150 return 0;
151 }
152 if (single_step)
153 /* Need to change direction */
154 speed = speed < 0 ? -1000 : 1000;
155
156 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
157 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
158 data[1] = (speed < 0);
159 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300160 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300161 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
162 data[5] = 0;
163 data[6] = 0;
164
165 if (speed == 1500 || speed == -1500) data[0] |= 1;
166 else if (speed == 2000 || speed == -2000) data[0] |= 2;
167 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
168 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
169
170 /* If not decoding, just change speed setting */
171 if (atomic_read(&itv->decoding) > 0) {
172 int got_sig = 0;
173
174 /* Stop all DMA and decoding activity */
175 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
176
177 /* Wait for any DMA to finish */
Hans Verkuilcdc03782011-10-11 06:06:58 -0300178 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300179 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -0300180 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300181 got_sig = signal_pending(current);
182 if (got_sig)
183 break;
184 got_sig = 0;
185 schedule();
186 }
187 finish_wait(&itv->dma_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -0300188 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300189 if (got_sig)
190 return -EINTR;
191
192 /* Change Speed safely */
193 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
194 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
195 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
196 }
197 if (single_step) {
198 speed = (speed < 0) ? -1 : 1;
199 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
200 }
201 itv->speed = speed;
202 return 0;
203}
204
205static int ivtv_validate_speed(int cur_speed, int new_speed)
206{
207 int fact = new_speed < 0 ? -1 : 1;
208 int s;
209
Hans Verkuil94dee762008-04-26 09:26:13 -0300210 if (cur_speed == 0)
211 cur_speed = 1000;
212 if (new_speed < 0)
213 new_speed = -new_speed;
214 if (cur_speed < 0)
215 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300216
217 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300218 if (new_speed > 1500)
219 return fact * 2000;
220 if (new_speed > 1000)
221 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300222 }
223 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300224 if (new_speed >= 2000)
225 return fact * 2000;
226 if (new_speed >= 1500)
227 return fact * 1500;
228 if (new_speed >= 1000)
229 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300230 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300231 if (new_speed == 0)
232 return 1000;
233 if (new_speed == 1 || new_speed == 1000)
234 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300235
236 s = new_speed;
237 new_speed = 1000 / new_speed;
238 if (1000 / cur_speed == new_speed)
239 new_speed += (cur_speed < s) ? -1 : 1;
240 if (new_speed > 60) return 1000 / (fact * 60);
241 return 1000 / (fact * new_speed);
242}
243
244static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300245 struct v4l2_decoder_cmd *dc, int try)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300246{
247 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
248
249 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
250 return -EINVAL;
251
Hans Verkuilda8ec562011-11-24 09:58:53 -0300252 switch (dc->cmd) {
253 case V4L2_DEC_CMD_START: {
254 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
255 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
256 if (dc->start.speed < 0)
257 dc->start.format = V4L2_DEC_START_FMT_GOP;
258 else
259 dc->start.format = V4L2_DEC_START_FMT_NONE;
260 if (dc->start.speed != 500 && dc->start.speed != 1500)
261 dc->flags = dc->start.speed == 1000 ? 0 :
262 V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300263 if (try) break;
264
Hans Verkuilda8ec562011-11-24 09:58:53 -0300265 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300266 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
267 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300268 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
269 /* forces ivtv_set_speed to be called */
270 itv->speed = 0;
271 }
Hans Verkuilda8ec562011-11-24 09:58:53 -0300272 return ivtv_start_decoding(id, dc->start.speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300273 }
274
Hans Verkuilda8ec562011-11-24 09:58:53 -0300275 case V4L2_DEC_CMD_STOP:
276 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
277 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
278 dc->stop.pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300279 if (try) break;
280 if (atomic_read(&itv->decoding) == 0)
281 return 0;
282 if (itv->output_mode != OUT_MPG)
283 return -EBUSY;
284
285 itv->output_mode = OUT_NONE;
Hans Verkuilda8ec562011-11-24 09:58:53 -0300286 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300287
Hans Verkuilda8ec562011-11-24 09:58:53 -0300288 case V4L2_DEC_CMD_PAUSE:
289 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300290 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300291 if (!atomic_read(&itv->decoding))
292 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300293 if (itv->output_mode != OUT_MPG)
294 return -EBUSY;
295 if (atomic_read(&itv->decoding) > 0) {
296 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300297 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300298 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300299 }
300 break;
301
Hans Verkuilda8ec562011-11-24 09:58:53 -0300302 case V4L2_DEC_CMD_RESUME:
303 dc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300304 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300305 if (!atomic_read(&itv->decoding))
306 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300307 if (itv->output_mode != OUT_MPG)
308 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300309 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
310 int speed = itv->speed;
311 itv->speed = 0;
312 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300313 }
314 break;
315
316 default:
317 return -EINVAL;
318 }
319 return 0;
320}
321
Hans Verkuil3f038d82008-05-29 16:43:54 -0300322static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300323{
Hans Verkuil2f824412011-03-12 06:43:28 -0300324 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300325 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300326
Hans Verkuile88360c2008-06-21 08:00:56 -0300327 vbifmt->reserved[0] = 0;
328 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300329 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300330 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300331 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil30634e82012-09-05 10:38:10 -0300332 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300333 if (itv->is_60hz) {
334 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
335 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
336 } else {
337 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
338 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
339 }
340 vbifmt->service_set = ivtv_get_service_set(vbifmt);
341 return 0;
342}
343
344static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
345{
Hans Verkuil2f824412011-03-12 06:43:28 -0300346 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300347 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300348 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300349
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300350 pixfmt->width = itv->cxhdl.width;
351 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300352 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
353 pixfmt->field = V4L2_FIELD_INTERLACED;
354 pixfmt->priv = 0;
355 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
356 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300357 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
358 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300359 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300360 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300361 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
362 pixfmt->sizeimage = 128 * 1024;
363 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300364 }
365 return 0;
366}
367
Hans Verkuil3f038d82008-05-29 16:43:54 -0300368static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300369{
Hans Verkuil2f824412011-03-12 06:43:28 -0300370 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300371 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300372
Hans Verkuile88360c2008-06-21 08:00:56 -0300373 vbifmt->sampling_rate = 27000000;
374 vbifmt->offset = 248;
375 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
376 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
377 vbifmt->start[0] = itv->vbi.start[0];
378 vbifmt->start[1] = itv->vbi.start[1];
379 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
380 vbifmt->flags = 0;
381 vbifmt->reserved[0] = 0;
382 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300383 return 0;
384}
385
386static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
387{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300388 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300389 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300390 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300391
Hans Verkuile88360c2008-06-21 08:00:56 -0300392 vbifmt->reserved[0] = 0;
393 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300394 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300395
Hans Verkuil3f038d82008-05-29 16:43:54 -0300396 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
397 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
398 V4L2_SLICED_VBI_525;
399 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuilc5c46f22012-09-05 12:27:19 -0300400 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300401 return 0;
402 }
403
Hans Verkuil4ff07902010-03-14 12:18:18 -0300404 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300405 vbifmt->service_set = ivtv_get_service_set(vbifmt);
406 return 0;
407}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300408
Hans Verkuil3f038d82008-05-29 16:43:54 -0300409static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
410{
Hans Verkuil2f824412011-03-12 06:43:28 -0300411 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300412 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300413 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300414
Hans Verkuil3f038d82008-05-29 16:43:54 -0300415 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300416 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300417 pixfmt->width = itv->main_rect.width;
418 pixfmt->height = itv->main_rect.height;
419 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
420 pixfmt->field = V4L2_FIELD_INTERLACED;
421 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300422 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
423 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
424 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300425 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300426 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
427 break;
428 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300429 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300430 break;
431 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300432 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300433 break;
434 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300435 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
436 pixfmt->bytesperline = 720;
437 pixfmt->width = itv->yuv_info.v4l2_src_w;
438 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300439 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300440 pixfmt->sizeimage =
441 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300442 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300443 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
444 pixfmt->sizeimage = 128 * 1024;
445 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300446 }
447 return 0;
448}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300449
Hans Verkuil3f038d82008-05-29 16:43:54 -0300450static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
451{
Hans Verkuil2f824412011-03-12 06:43:28 -0300452 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300453 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300454
455 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
456 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300457 winfmt->chromakey = itv->osd_chroma_key;
458 winfmt->global_alpha = itv->osd_global_alpha;
459 winfmt->field = V4L2_FIELD_INTERLACED;
460 winfmt->clips = NULL;
461 winfmt->clipcount = 0;
462 winfmt->bitmap = NULL;
463 winfmt->w.top = winfmt->w.left = 0;
464 winfmt->w.width = itv->osd_rect.width;
465 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300466 return 0;
467}
468
469static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
470{
471 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
472}
473
474static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
475{
Hans Verkuil2f824412011-03-12 06:43:28 -0300476 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300477 struct ivtv *itv = id->itv;
478 int w = fmt->fmt.pix.width;
479 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300480 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300481
482 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300483 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300484 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
485 /* YUV height must be a multiple of 32 */
486 h &= ~0x1f;
487 min_h = 32;
488 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300489 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300490 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300491 ivtv_g_fmt_vid_cap(file, fh, fmt);
492 fmt->fmt.pix.width = w;
493 fmt->fmt.pix.height = h;
494 return 0;
495}
496
497static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
498{
499 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
500}
501
502static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
503{
504 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300505 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300506 struct ivtv *itv = id->itv;
507
508 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
509 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300510
511 /* set sliced VBI capture format */
512 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300513 vbifmt->reserved[0] = 0;
514 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300515
516 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300517 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300518 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300519 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300520 return 0;
521}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300522
Hans Verkuil3f038d82008-05-29 16:43:54 -0300523static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
524{
Hans Verkuil2f824412011-03-12 06:43:28 -0300525 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300526 s32 w = fmt->fmt.pix.width;
527 s32 h = fmt->fmt.pix.height;
528 int field = fmt->fmt.pix.field;
529 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300530
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300531 w = min(w, 720);
532 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300533 /* Why can the height be 576 even when the output is NTSC?
534
535 Internally the buffers of the PVR350 are always set to 720x576. The
536 decoded video frame will always be placed in the top left corner of
537 this buffer. For any video which is not 720x576, the buffer will
538 then be cropped to remove the unused right and lower areas, with
539 the remaining image being scaled by the hardware to fit the display
540 area. The video can be scaled both up and down, so a 720x480 video
541 can be displayed full-screen on PAL and a 720x576 video can be
542 displayed without cropping on NTSC.
543
544 Note that the scaling only occurs on the video stream, the osd
545 resolution is locked to the broadcast standard and not scaled.
546
547 Thanks to Ian Armstrong for this explanation. */
548 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300549 h = max(h, 2);
550 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300551 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300552 fmt->fmt.pix.width = w;
553 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300554 return ret;
555}
556
557static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
558{
Hans Verkuil2f824412011-03-12 06:43:28 -0300559 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300560 u32 chromakey = fmt->fmt.win.chromakey;
561 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300562
563 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
564 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300565 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
566 fmt->fmt.win.chromakey = chromakey;
567 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300568 return 0;
569}
570
571static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
572{
573 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
574}
575
576static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
577{
Hans Verkuil2f824412011-03-12 06:43:28 -0300578 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300579 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300580 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300581 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300582 int w = fmt->fmt.pix.width;
583 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300584
585 if (ret)
586 return ret;
587
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300588 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300589 return 0;
590
591 if (atomic_read(&itv->capturing) > 0)
592 return -EBUSY;
593
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300594 itv->cxhdl.width = w;
595 itv->cxhdl.height = h;
596 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300597 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300598 mbus_fmt.width = fmt->fmt.pix.width;
599 mbus_fmt.height = h;
600 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
601 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300602 return ivtv_g_fmt_vid_cap(file, fh, fmt);
603}
604
605static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
606{
Hans Verkuil2f824412011-03-12 06:43:28 -0300607 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300608
Hans Verkuila8b86432008-10-04 08:05:30 -0300609 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
610 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300611 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300612 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300613 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300614 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
615}
616
617static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
618{
619 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300620 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300621 struct ivtv *itv = id->itv;
622 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
623
624 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
625 return ret;
626
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300627 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300628 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300629 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300630 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300631 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300632 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
633 return 0;
634}
635
Hans Verkuil3f038d82008-05-29 16:43:54 -0300636static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300637{
Hans Verkuil2f824412011-03-12 06:43:28 -0300638 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300639 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300640 struct yuv_playback_info *yi = &itv->yuv_info;
641 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300642
Hans Verkuil3f038d82008-05-29 16:43:54 -0300643 if (ret)
644 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300645
Hans Verkuil3f038d82008-05-29 16:43:54 -0300646 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
647 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300648
Hans Verkuil3f038d82008-05-29 16:43:54 -0300649 /* Return now if we already have some frame data */
650 if (yi->stream_size)
651 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300652
Hans Verkuil3f038d82008-05-29 16:43:54 -0300653 yi->v4l2_src_w = fmt->fmt.pix.width;
654 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300655
Hans Verkuil3f038d82008-05-29 16:43:54 -0300656 switch (fmt->fmt.pix.field) {
657 case V4L2_FIELD_NONE:
658 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300659 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300660 case V4L2_FIELD_ANY:
661 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300662 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300663 case V4L2_FIELD_INTERLACED_BT:
664 yi->lace_mode =
665 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
666 break;
667 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300668 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300669 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
670 break;
671 }
672 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
673
674 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
675 itv->dma_data_req_size =
676 1080 * ((yi->v4l2_src_h + 31) & ~31);
677
Hans Verkuil3f038d82008-05-29 16:43:54 -0300678 return 0;
679}
680
681static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
682{
Hans Verkuil2f824412011-03-12 06:43:28 -0300683 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300684 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
685
686 if (ret == 0) {
687 itv->osd_chroma_key = fmt->fmt.win.chromakey;
688 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
689 ivtv_set_osd_alpha(itv);
690 }
691 return ret;
692}
693
Hans Verkuil36ecd492008-06-25 06:00:17 -0300694#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilb5656e82013-03-24 08:24:19 -0300695static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300696{
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300697 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300698
Hans Verkuile9dab582013-05-29 07:00:10 -0300699 if (reg & 0x3)
700 return -EINVAL;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300701 if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300702 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300703 else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
704 reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300705 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300706 else if (reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300707 reg_start = itv->enc_mem;
708 else
709 return -EINVAL;
710
Hans Verkuilb5656e82013-03-24 08:24:19 -0300711 if (get)
712 *val = readl(reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300713 else
Hans Verkuilb5656e82013-03-24 08:24:19 -0300714 writel(*val, reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300715 return 0;
716}
717
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300718static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300719{
Hans Verkuil2f824412011-03-12 06:43:28 -0300720 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300721
Hans Verkuil4bd81932013-05-29 06:59:38 -0300722 reg->size = 4;
723 return ivtv_itvc(itv, true, reg->reg, &reg->val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300724}
725
Hans Verkuil977ba3b2013-03-24 08:28:46 -0300726static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300727{
Hans Verkuil2f824412011-03-12 06:43:28 -0300728 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil4bd81932013-05-29 06:59:38 -0300729 u64 val = reg->val;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300730
Hans Verkuil4bd81932013-05-29 06:59:38 -0300731 return ivtv_itvc(itv, false, reg->reg, &val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300732}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300733#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300734
Hans Verkuil3f038d82008-05-29 16:43:54 -0300735static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
736{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300737 struct ivtv_open_id *id = fh2id(file->private_data);
738 struct ivtv *itv = id->itv;
739 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300740
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
742 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300743 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300744 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
745 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300746 return 0;
747}
748
749static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
750{
Hans Verkuil2f824412011-03-12 06:43:28 -0300751 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752
753 return ivtv_get_audio_input(itv, vin->index, vin);
754}
755
756static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
757{
Hans Verkuil2f824412011-03-12 06:43:28 -0300758 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300759
760 vin->index = itv->audio_input;
761 return ivtv_get_audio_input(itv, vin->index, vin);
762}
763
Hans Verkuil0e8025b2012-09-04 11:59:31 -0300764static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300765{
Hans Verkuil2f824412011-03-12 06:43:28 -0300766 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300767
768 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300769 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300770
771 itv->audio_input = vout->index;
772 ivtv_audio_set_io(itv);
773
774 return 0;
775}
776
777static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
778{
Hans Verkuil2f824412011-03-12 06:43:28 -0300779 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300780
781 /* set it to defaults from our table */
782 return ivtv_get_audio_output(itv, vin->index, vin);
783}
784
785static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
786{
Hans Verkuil2f824412011-03-12 06:43:28 -0300787 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300788
789 vin->index = 0;
790 return ivtv_get_audio_output(itv, vin->index, vin);
791}
792
Hans Verkuilba9425b2012-09-04 12:03:49 -0300793static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300794{
Hans Verkuil2f824412011-03-12 06:43:28 -0300795 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300796
Hans Verkuilba9425b2012-09-04 12:03:49 -0300797 if (itv->card->video_outputs == NULL || vout->index != 0)
798 return -EINVAL;
799 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300800}
801
802static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *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 /* set it to defaults from our table */
807 return ivtv_get_input(itv, vin->index, vin);
808}
809
810static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *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_output(itv, vout->index, vout);
815}
816
817static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
818{
Hans Verkuil2f824412011-03-12 06:43:28 -0300819 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300820 struct ivtv *itv = id->itv;
821 struct yuv_playback_info *yi = &itv->yuv_info;
822 int streamtype;
823
824 streamtype = id->type;
825
826 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
827 return -EINVAL;
828 cropcap->bounds.top = cropcap->bounds.left = 0;
829 cropcap->bounds.width = 720;
830 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
831 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
832 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
833 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
834 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
835 if (yi->track_osd) {
836 cropcap->bounds.width = yi->osd_full_w;
837 cropcap->bounds.height = yi->osd_full_h;
838 } else {
839 cropcap->bounds.width = 720;
840 cropcap->bounds.height =
841 itv->is_out_50hz ? 576 : 480;
842 }
843 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
844 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
845 } else {
846 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
847 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
848 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
849 }
850 cropcap->defrect = cropcap->bounds;
851 return 0;
852}
853
Hans Verkuil4f9965942012-09-05 05:10:48 -0300854static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300855{
Hans Verkuil2f824412011-03-12 06:43:28 -0300856 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300857 struct ivtv *itv = id->itv;
858 struct yuv_playback_info *yi = &itv->yuv_info;
859 int streamtype;
860
861 streamtype = id->type;
862
Hans Verkuil3f038d82008-05-29 16:43:54 -0300863 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
864 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
865 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
866 yi->main_rect = crop->c;
867 return 0;
868 } else {
869 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
870 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
871 itv->main_rect = crop->c;
872 return 0;
873 }
874 }
875 return -EINVAL;
876 }
877 return -EINVAL;
878}
879
880static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
881{
Hans Verkuil2f824412011-03-12 06:43:28 -0300882 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300883 struct ivtv *itv = id->itv;
884 struct yuv_playback_info *yi = &itv->yuv_info;
885 int streamtype;
886
887 streamtype = id->type;
888
889 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
890 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
891 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
892 crop->c = yi->main_rect;
893 else
894 crop->c = itv->main_rect;
895 return 0;
896 }
897 return -EINVAL;
898}
899
900static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
901{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300902 static const struct v4l2_fmtdesc hm12 = {
903 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
904 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
905 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300906 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300907 static const struct v4l2_fmtdesc mpeg = {
908 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
909 "MPEG", V4L2_PIX_FMT_MPEG,
910 { 0, 0, 0, 0 }
911 };
912 struct ivtv *itv = fh2id(fh)->itv;
913 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300914
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300915 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300916 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300917 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
918 *fmt = mpeg;
919 else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
920 *fmt = hm12;
921 else
922 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300923 return 0;
924}
925
926static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
927{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300928 static const struct v4l2_fmtdesc hm12 = {
929 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0,
930 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
931 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300932 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300933 static const struct v4l2_fmtdesc mpeg = {
934 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_FMT_FLAG_COMPRESSED,
935 "MPEG", V4L2_PIX_FMT_MPEG,
936 { 0, 0, 0, 0 }
937 };
938 struct ivtv *itv = fh2id(fh)->itv;
939 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300940
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300941 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300942 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300943 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
944 *fmt = mpeg;
945 else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
946 *fmt = hm12;
947 else
Hans Verkuil3f038d82008-05-29 16:43:54 -0300948 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300949 return 0;
950}
951
952static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
953{
Hans Verkuil2f824412011-03-12 06:43:28 -0300954 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300955
956 *i = itv->active_input;
957
958 return 0;
959}
960
961int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
962{
Hans Verkuil2f824412011-03-12 06:43:28 -0300963 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300964 v4l2_std_id std;
965 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300966
Mauro Carvalho Chehabd6eb0b92012-10-27 12:52:19 -0300967 if (inp >= itv->nof_inputs)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300968 return -EINVAL;
969
970 if (inp == itv->active_input) {
971 IVTV_DEBUG_INFO("Input unchanged\n");
972 return 0;
973 }
974
975 if (atomic_read(&itv->capturing) > 0) {
976 return -EBUSY;
977 }
978
979 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
980 itv->active_input, inp);
981
982 itv->active_input = inp;
983 /* Set the audio input to whatever is appropriate for the
984 input type. */
985 itv->audio_input = itv->card->video_inputs[inp].audio_index;
986
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300987 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
988 std = itv->tuner_std;
989 else
990 std = V4L2_STD_ALL;
991 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
992 itv->streams[i].vdev->tvnorms = std;
993
Hans Verkuil3f038d82008-05-29 16:43:54 -0300994 /* prevent others from messing with the streams until
995 we're finished changing inputs. */
996 ivtv_mute(itv);
997 ivtv_video_set_io(itv);
998 ivtv_audio_set_io(itv);
999 ivtv_unmute(itv);
1000
1001 return 0;
1002}
1003
1004static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1005{
Hans Verkuil2f824412011-03-12 06:43:28 -03001006 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001007
1008 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1009 return -EINVAL;
1010
1011 *i = itv->active_output;
1012
1013 return 0;
1014}
1015
1016static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1017{
Hans Verkuil2f824412011-03-12 06:43:28 -03001018 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001019
1020 if (outp >= itv->card->nof_outputs)
1021 return -EINVAL;
1022
1023 if (outp == itv->active_output) {
1024 IVTV_DEBUG_INFO("Output unchanged\n");
1025 return 0;
1026 }
1027 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1028 itv->active_output, outp);
1029
1030 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001031 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1032 SAA7127_INPUT_TYPE_NORMAL,
1033 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001034
1035 return 0;
1036}
1037
1038static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1039{
Hans Verkuil2f824412011-03-12 06:43:28 -03001040 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001041 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001042
Hans Verkuildff274f2012-10-01 06:45:36 -03001043 if (s->vdev->vfl_dir)
1044 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001045 if (vf->tuner != 0)
1046 return -EINVAL;
1047
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001048 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001049 return 0;
1050}
1051
Hans Verkuilb530a442013-03-19 04:09:26 -03001052int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001053{
Hans Verkuil2f824412011-03-12 06:43:28 -03001054 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001055 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001056
Hans Verkuildff274f2012-10-01 06:45:36 -03001057 if (s->vdev->vfl_dir)
1058 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001059 if (vf->tuner != 0)
1060 return -EINVAL;
1061
1062 ivtv_mute(itv);
1063 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001064 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001065 ivtv_unmute(itv);
1066 return 0;
1067}
1068
1069static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1070{
Hans Verkuil2f824412011-03-12 06:43:28 -03001071 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001072
1073 *std = itv->std;
1074 return 0;
1075}
1076
Hans Verkuil314527a2013-03-15 06:10:40 -03001077void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001078{
Hans Verkuil314527a2013-03-15 06:10:40 -03001079 itv->std = std;
1080 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001081 itv->is_50hz = !itv->is_60hz;
1082 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1083 itv->cxhdl.width = 720;
1084 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001085 itv->vbi.count = itv->is_50hz ? 18 : 12;
1086 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1087 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1088
1089 if (itv->hw_flags & IVTV_HW_CX25840)
1090 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1091
Hans Verkuil3f038d82008-05-29 16:43:54 -03001092 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001093 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001094}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001095
Hans Verkuil314527a2013-03-15 06:10:40 -03001096void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001097{
1098 struct yuv_playback_info *yi = &itv->yuv_info;
1099 DEFINE_WAIT(wait);
1100 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001101
Ian Armstrongc5874c92011-05-29 21:33:17 -03001102 /* set display standard */
Hans Verkuil314527a2013-03-15 06:10:40 -03001103 itv->std_out = std;
1104 itv->is_out_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Ian Armstrongc5874c92011-05-29 21:33:17 -03001105 itv->is_out_50hz = !itv->is_out_60hz;
1106 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001107
Ian Armstrongc5874c92011-05-29 21:33:17 -03001108 /*
1109 * The next firmware call is time sensitive. Time it to
1110 * avoid risk of a hard lock, by trying to ensure the call
1111 * happens within the first 100 lines of the top field.
1112 * Make 4 attempts to sync to the decoder before giving up.
1113 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001114 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001115 for (f = 0; f < 4; f++) {
1116 prepare_to_wait(&itv->vsync_waitq, &wait,
1117 TASK_UNINTERRUPTIBLE);
1118 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1119 break;
1120 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001121 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001122 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001123 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001124
1125 if (f == 4)
1126 IVTV_WARN("Mode change failed to sync to decoder\n");
1127
1128 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1129 itv->main_rect.left = 0;
1130 itv->main_rect.top = 0;
1131 itv->main_rect.width = 720;
1132 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1133 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1134 720, itv->main_rect.height, 0, 0);
1135 yi->main_rect = itv->main_rect;
1136 if (!itv->osd_info) {
1137 yi->osd_full_w = 720;
1138 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1139 }
1140}
1141
Hans Verkuil314527a2013-03-15 06:10:40 -03001142static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001143{
1144 struct ivtv *itv = fh2id(fh)->itv;
1145
Hans Verkuil314527a2013-03-15 06:10:40 -03001146 if ((std & V4L2_STD_ALL) == 0)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001147 return -EINVAL;
1148
Hans Verkuil314527a2013-03-15 06:10:40 -03001149 if (std == itv->std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001150 return 0;
1151
1152 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1153 atomic_read(&itv->capturing) > 0 ||
1154 atomic_read(&itv->decoding) > 0) {
1155 /* Switching standard would mess with already running
1156 streams, prevent that by returning EBUSY. */
1157 return -EBUSY;
1158 }
1159
1160 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1161 (unsigned long long)itv->std);
1162
1163 ivtv_s_std_enc(itv, std);
1164 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1165 ivtv_s_std_dec(itv, std);
1166
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001167 return 0;
1168}
1169
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001170static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001171{
Hans Verkuil2f824412011-03-12 06:43:28 -03001172 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001173 struct ivtv *itv = id->itv;
1174
1175 if (vt->index != 0)
1176 return -EINVAL;
1177
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001178 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001179
1180 return 0;
1181}
1182
1183static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1184{
Hans Verkuil2f824412011-03-12 06:43:28 -03001185 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001186
1187 if (vt->index != 0)
1188 return -EINVAL;
1189
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001190 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001191
Hans Verkuild118e292011-06-25 10:28:21 -03001192 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001193 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001194 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001195 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001196 return 0;
1197}
1198
1199static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1200{
Hans Verkuil2f824412011-03-12 06:43:28 -03001201 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001202 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1203 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001204
Hans Verkuil79afcb12008-06-21 09:02:36 -03001205 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001206 for (f = 0; f < 2; f++) {
1207 for (l = 0; l < 24; l++) {
1208 if (valid_service_line(f, l, itv->is_50hz))
1209 cap->service_lines[f][l] = set;
1210 }
1211 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001212 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001213 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1214 return -EINVAL;
1215 if (itv->is_60hz) {
1216 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1217 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1218 } else {
1219 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1220 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1221 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001222 } else {
1223 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001224 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001225
1226 set = 0;
1227 for (f = 0; f < 2; f++)
1228 for (l = 0; l < 24; l++)
1229 set |= cap->service_lines[f][l];
1230 cap->service_set = set;
1231 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001232}
1233
1234static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1235{
Hans Verkuil2f824412011-03-12 06:43:28 -03001236 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001237 struct v4l2_enc_idx_entry *e = idx->entry;
1238 int entries;
1239 int i;
1240
1241 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1242 IVTV_MAX_PGM_INDEX;
1243 if (entries > V4L2_ENC_IDX_ENTRIES)
1244 entries = V4L2_ENC_IDX_ENTRIES;
1245 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001246 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1247 if (!atomic_read(&itv->capturing))
1248 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001249 for (i = 0; i < entries; i++) {
1250 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1251 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1252 idx->entries++;
1253 e++;
1254 }
1255 }
1256 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1257 return 0;
1258}
1259
1260static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1261{
Hans Verkuil2f824412011-03-12 06:43:28 -03001262 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001263 struct ivtv *itv = id->itv;
1264
Hans Verkuil3f038d82008-05-29 16:43:54 -03001265
1266 switch (enc->cmd) {
1267 case V4L2_ENC_CMD_START:
1268 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1269 enc->flags = 0;
1270 return ivtv_start_capture(id);
1271
1272 case V4L2_ENC_CMD_STOP:
1273 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1274 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1275 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1276 return 0;
1277
1278 case V4L2_ENC_CMD_PAUSE:
1279 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1280 enc->flags = 0;
1281
1282 if (!atomic_read(&itv->capturing))
1283 return -EPERM;
1284 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1285 return 0;
1286
1287 ivtv_mute(itv);
1288 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1289 break;
1290
1291 case V4L2_ENC_CMD_RESUME:
1292 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1293 enc->flags = 0;
1294
1295 if (!atomic_read(&itv->capturing))
1296 return -EPERM;
1297
1298 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1299 return 0;
1300
1301 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1302 ivtv_unmute(itv);
1303 break;
1304 default:
1305 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1306 return -EINVAL;
1307 }
1308
1309 return 0;
1310}
1311
1312static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1313{
Hans Verkuil2f824412011-03-12 06:43:28 -03001314 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001315
Hans Verkuil3f038d82008-05-29 16:43:54 -03001316 switch (enc->cmd) {
1317 case V4L2_ENC_CMD_START:
1318 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1319 enc->flags = 0;
1320 return 0;
1321
1322 case V4L2_ENC_CMD_STOP:
1323 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1324 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1325 return 0;
1326
1327 case V4L2_ENC_CMD_PAUSE:
1328 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1329 enc->flags = 0;
1330 return 0;
1331
1332 case V4L2_ENC_CMD_RESUME:
1333 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1334 enc->flags = 0;
1335 return 0;
1336 default:
1337 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1338 return -EINVAL;
1339 }
1340}
1341
1342static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1343{
Hans Verkuil2f824412011-03-12 06:43:28 -03001344 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001345 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001346 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001347
Hans Verkuil3f038d82008-05-29 16:43:54 -03001348 int pixfmt;
1349 static u32 pixel_format[16] = {
1350 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1351 V4L2_PIX_FMT_RGB565,
1352 V4L2_PIX_FMT_RGB555,
1353 V4L2_PIX_FMT_RGB444,
1354 V4L2_PIX_FMT_RGB32,
1355 0,
1356 0,
1357 0,
1358 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1359 V4L2_PIX_FMT_YUV565,
1360 V4L2_PIX_FMT_YUV555,
1361 V4L2_PIX_FMT_YUV444,
1362 V4L2_PIX_FMT_YUV32,
1363 0,
1364 0,
1365 0,
1366 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001367
Hans Verkuil3f038d82008-05-29 16:43:54 -03001368 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1369 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001370 if (!itv->osd_video_pbase)
1371 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001372
Hans Verkuil3f038d82008-05-29 16:43:54 -03001373 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1374 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001375
Hans Verkuil3f038d82008-05-29 16:43:54 -03001376 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1377 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1378 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001379
Hans Verkuil3f038d82008-05-29 16:43:54 -03001380 fb->fmt.pixelformat = pixel_format[pixfmt];
1381 fb->fmt.width = itv->osd_rect.width;
1382 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001383 fb->fmt.field = V4L2_FIELD_INTERLACED;
1384 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001385 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1386 fb->fmt.field = V4L2_FIELD_INTERLACED;
1387 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001388 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1389 fb->fmt.bytesperline *= 2;
1390 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1391 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1392 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001393 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001395 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001396
Hans Verkuil3f038d82008-05-29 16:43:54 -03001397 if (itv->osd_chroma_key_state)
1398 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001399
Hans Verkuil3f038d82008-05-29 16:43:54 -03001400 if (itv->osd_global_alpha_state)
1401 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001402
Ian Armstrongec9faa12008-10-06 03:06:08 -03001403 if (yi->track_osd)
1404 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1405
Hans Verkuil3f038d82008-05-29 16:43:54 -03001406 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001407
Hans Verkuil3f038d82008-05-29 16:43:54 -03001408 /* no local alpha for RGB565 or unknown formats */
1409 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001410 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001411
Hans Verkuil3f038d82008-05-29 16:43:54 -03001412 /* 16-bit formats have inverted local alpha */
1413 if (pixfmt == 2 || pixfmt == 3)
1414 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1415 else
1416 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001417
Hans Verkuil3f038d82008-05-29 16:43:54 -03001418 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001419 /* 16-bit formats have inverted local alpha */
1420 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001422 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001423 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001424 }
1425
Hans Verkuil3f038d82008-05-29 16:43:54 -03001426 return 0;
1427}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001428
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001429static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001430{
Hans Verkuil2f824412011-03-12 06:43:28 -03001431 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001432 struct ivtv *itv = id->itv;
1433 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001434
Hans Verkuil3f038d82008-05-29 16:43:54 -03001435 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001436 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001437 if (!itv->osd_video_pbase)
1438 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001439
1440 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1441 itv->osd_local_alpha_state =
1442 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1443 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1444 ivtv_set_osd_alpha(itv);
1445 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001446 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001447}
1448
1449static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1450{
Hans Verkuil2f824412011-03-12 06:43:28 -03001451 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001452 struct ivtv *itv = id->itv;
1453
1454 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1455 return -EINVAL;
1456
1457 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1458
1459 return 0;
1460}
1461
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001462static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001463{
1464 switch (sub->type) {
1465 case V4L2_EVENT_VSYNC:
1466 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001467 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001468 case V4L2_EVENT_CTRL:
1469 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001470 default:
1471 return -EINVAL;
1472 }
Hans Verkuil09250192010-03-27 14:10:13 -03001473}
1474
Hans Verkuil3f038d82008-05-29 16:43:54 -03001475static int ivtv_log_status(struct file *file, void *fh)
1476{
Hans Verkuil2f824412011-03-12 06:43:28 -03001477 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001478 u32 data[CX2341X_MBOX_MAX_DATA];
1479
1480 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1481 struct v4l2_input vidin;
1482 struct v4l2_audio audin;
1483 int i;
1484
Hans Verkuil3f038d82008-05-29 16:43:54 -03001485 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1486 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1487 struct tveeprom tv;
1488
1489 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001490 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001491 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001492 ivtv_get_input(itv, itv->active_input, &vidin);
1493 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1494 IVTV_INFO("Video Input: %s\n", vidin.name);
1495 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1496 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1497 if (has_output) {
1498 struct v4l2_output vidout;
1499 struct v4l2_audioout audout;
1500 int mode = itv->output_mode;
1501 static const char * const output_modes[5] = {
1502 "None",
1503 "MPEG Streaming",
1504 "YUV Streaming",
1505 "YUV Frames",
1506 "Passthrough",
1507 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001508 static const char * const alpha_mode[4] = {
1509 "None",
1510 "Global",
1511 "Local",
1512 "Global and Local"
1513 };
1514 static const char * const pixel_format[16] = {
1515 "ARGB Indexed",
1516 "RGB 5:6:5",
1517 "ARGB 1:5:5:5",
1518 "ARGB 1:4:4:4",
1519 "ARGB 8:8:8:8",
1520 "5",
1521 "6",
1522 "7",
1523 "AYUV Indexed",
1524 "YUV 5:6:5",
1525 "AYUV 1:5:5:5",
1526 "AYUV 1:4:4:4",
1527 "AYUV 8:8:8:8",
1528 "13",
1529 "14",
1530 "15",
1531 };
1532
1533 ivtv_get_output(itv, itv->active_output, &vidout);
1534 ivtv_get_audio_output(itv, 0, &audout);
1535 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001536 if (mode < 0 || mode > OUT_PASSTHROUGH)
1537 mode = OUT_NONE;
1538 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1539 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1540 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1541 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1542 data[0] & 1 ? "On" : "Off",
1543 alpha_mode[(data[0] >> 1) & 0x3],
1544 pixel_format[(data[0] >> 3) & 0xf]);
1545 }
1546 IVTV_INFO("Tuner: %s\n",
1547 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001548 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001549 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1550 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1551 struct ivtv_stream *s = &itv->streams[i];
1552
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001553 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001554 continue;
1555 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1556 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1557 (s->buffers * s->buf_size) / 1024, s->buffers);
1558 }
1559
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001560 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1561 (long long)itv->mpg_data_received,
1562 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001563 return 0;
1564}
1565
Hans Verkuilda8ec562011-11-24 09:58:53 -03001566static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1567{
1568 struct ivtv_open_id *id = fh2id(file->private_data);
1569 struct ivtv *itv = id->itv;
1570
1571 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1572 return ivtv_video_command(itv, id, dec, false);
1573}
1574
1575static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1576{
1577 struct ivtv_open_id *id = fh2id(file->private_data);
1578 struct ivtv *itv = id->itv;
1579
1580 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1581 return ivtv_video_command(itv, id, dec, true);
1582}
1583
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001584static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001585{
Hans Verkuil09250192010-03-27 14:10:13 -03001586 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001587 struct ivtv *itv = id->itv;
1588 int nonblocking = filp->f_flags & O_NONBLOCK;
1589 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001590 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001591
1592 switch (cmd) {
1593 case IVTV_IOC_DMA_FRAME: {
1594 struct ivtv_dma_frame *args = arg;
1595
1596 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1597 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1598 return -EINVAL;
1599 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1600 return -EINVAL;
1601 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1602 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001603 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001604 return -EBUSY;
1605 }
1606 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1607 ivtv_release_stream(s);
1608 return -EBUSY;
1609 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001610 /* Mark that this file handle started the UDMA_YUV mode */
1611 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001612 if (args->y_source == NULL)
1613 return 0;
1614 return ivtv_yuv_prep_frame(itv, args);
1615 }
1616
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001617 case IVTV_IOC_PASSTHROUGH_MODE:
1618 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1619 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1620 return -EINVAL;
1621 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1622
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001623 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001624 s64 *pts = arg;
1625 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001626
1627 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1628 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1629 *pts = s->dma_pts;
1630 break;
1631 }
1632 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1633 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001634 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001635 }
1636
1637 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001638 s64 *frame = arg;
1639 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001640
1641 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1642 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1643 *frame = 0;
1644 break;
1645 }
1646 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1647 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001648 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001649 }
1650
1651 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001652 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001653
1654 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001655 memset(&dc, 0, sizeof(dc));
1656 dc.cmd = V4L2_DEC_CMD_START;
1657 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001658 }
1659
1660 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001661 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001662
1663 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001664 memset(&dc, 0, sizeof(dc));
1665 dc.cmd = V4L2_DEC_CMD_STOP;
1666 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1667 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001668 }
1669
1670 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001671 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001672
1673 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001674 memset(&dc, 0, sizeof(dc));
1675 dc.cmd = V4L2_DEC_CMD_PAUSE;
1676 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001677 }
1678
1679 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001680 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001681
1682 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001683 memset(&dc, 0, sizeof(dc));
1684 dc.cmd = V4L2_DEC_CMD_RESUME;
1685 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001686 }
1687
1688 case VIDEO_COMMAND:
1689 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001690 /* Note: struct v4l2_decoder_cmd has the same layout as
1691 struct video_command */
1692 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001693 int try = (cmd == VIDEO_TRY_COMMAND);
1694
1695 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001696 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001697 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001698 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1699 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001700 }
1701
1702 case VIDEO_GET_EVENT: {
1703 struct video_event *ev = arg;
1704 DEFINE_WAIT(wait);
1705
1706 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1707 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1708 return -EINVAL;
1709 memset(ev, 0, sizeof(*ev));
1710 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1711
1712 while (1) {
1713 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1714 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1715 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1716 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001717 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1718 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1719 if (itv->output_mode == OUT_UDMA_YUV &&
1720 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1721 IVTV_YUV_MODE_PROGRESSIVE) {
1722 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1723 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001724 }
1725 if (ev->type)
1726 return 0;
1727 if (nonblocking)
1728 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001729 /* Wait for event. Note that serialize_lock is locked,
1730 so to allow other processes to access the driver while
1731 we are waiting unlock first and later lock again. */
1732 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001733 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001734 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1735 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001736 schedule();
1737 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001738 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001739 if (signal_pending(current)) {
1740 /* return if a signal was received */
1741 IVTV_DEBUG_INFO("User stopped wait for event\n");
1742 return -EINTR;
1743 }
1744 }
1745 break;
1746 }
1747
Hans Verkuilce680252010-04-06 15:58:53 -03001748 case VIDEO_SELECT_SOURCE:
1749 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1750 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1751 return -EINVAL;
1752 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1753
1754 case AUDIO_SET_MUTE:
1755 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1756 itv->speed_mute_audio = iarg;
1757 return 0;
1758
1759 case AUDIO_CHANNEL_SELECT:
1760 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1761 if (iarg > AUDIO_STEREO_SWAPPED)
1762 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001763 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001764
1765 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1766 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1767 if (iarg > AUDIO_STEREO_SWAPPED)
1768 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001769 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001770
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001771 default:
1772 return -EINVAL;
1773 }
1774 return 0;
1775}
1776
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001777static long ivtv_default(struct file *file, void *fh, bool valid_prio,
Mauro Carvalho Chehab6d43be72013-03-26 08:04:52 -03001778 unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001779{
Hans Verkuil2f824412011-03-12 06:43:28 -03001780 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001781
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001782 if (!valid_prio) {
1783 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001784 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001785 case VIDEO_PLAY:
1786 case VIDEO_STOP:
1787 case VIDEO_FREEZE:
1788 case VIDEO_CONTINUE:
1789 case VIDEO_COMMAND:
1790 case VIDEO_SELECT_SOURCE:
1791 case AUDIO_SET_MUTE:
1792 case AUDIO_CHANNEL_SELECT:
1793 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1794 return -EBUSY;
1795 }
1796 }
1797
Hans Verkuild46c17d2007-03-10 17:59:15 -03001798 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001799 case VIDIOC_INT_RESET: {
1800 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001801
Hans Verkuil3f038d82008-05-29 16:43:54 -03001802 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1803 ivtv_reset_ir_gpio(itv);
1804 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001805 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001806 break;
1807 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001808
Hans Verkuilac9575f2009-02-14 19:58:33 -03001809 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001810 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001811 case VIDEO_GET_PTS:
1812 case VIDEO_GET_FRAME_COUNT:
1813 case VIDEO_GET_EVENT:
1814 case VIDEO_PLAY:
1815 case VIDEO_STOP:
1816 case VIDEO_FREEZE:
1817 case VIDEO_CONTINUE:
1818 case VIDEO_COMMAND:
1819 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001820 case VIDEO_SELECT_SOURCE:
1821 case AUDIO_SET_MUTE:
1822 case AUDIO_CHANNEL_SELECT:
1823 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001824 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1825
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001826 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001827 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001828 }
1829 return 0;
1830}
1831
Hans Verkuila3998102008-07-21 02:57:38 -03001832static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1833 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001834 .vidioc_s_audio = ivtv_s_audio,
1835 .vidioc_g_audio = ivtv_g_audio,
1836 .vidioc_enumaudio = ivtv_enumaudio,
1837 .vidioc_s_audout = ivtv_s_audout,
1838 .vidioc_g_audout = ivtv_g_audout,
1839 .vidioc_enum_input = ivtv_enum_input,
1840 .vidioc_enum_output = ivtv_enum_output,
1841 .vidioc_enumaudout = ivtv_enumaudout,
1842 .vidioc_cropcap = ivtv_cropcap,
1843 .vidioc_s_crop = ivtv_s_crop,
1844 .vidioc_g_crop = ivtv_g_crop,
1845 .vidioc_g_input = ivtv_g_input,
1846 .vidioc_s_input = ivtv_s_input,
1847 .vidioc_g_output = ivtv_g_output,
1848 .vidioc_s_output = ivtv_s_output,
1849 .vidioc_g_frequency = ivtv_g_frequency,
1850 .vidioc_s_frequency = ivtv_s_frequency,
1851 .vidioc_s_tuner = ivtv_s_tuner,
1852 .vidioc_g_tuner = ivtv_g_tuner,
1853 .vidioc_g_enc_index = ivtv_g_enc_index,
1854 .vidioc_g_fbuf = ivtv_g_fbuf,
1855 .vidioc_s_fbuf = ivtv_s_fbuf,
1856 .vidioc_g_std = ivtv_g_std,
1857 .vidioc_s_std = ivtv_s_std,
1858 .vidioc_overlay = ivtv_overlay,
1859 .vidioc_log_status = ivtv_log_status,
1860 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1861 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1862 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001863 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1864 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001865 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1866 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1867 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1868 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1869 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1870 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1871 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1872 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1873 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1874 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1875 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1876 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1877 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1878 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1879 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1880 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1881 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1882 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1883 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1884 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
Hans Verkuila3998102008-07-21 02:57:38 -03001885#ifdef CONFIG_VIDEO_ADV_DEBUG
1886 .vidioc_g_register = ivtv_g_register,
1887 .vidioc_s_register = ivtv_s_register,
1888#endif
1889 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001890 .vidioc_subscribe_event = ivtv_subscribe_event,
1891 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001892};
1893
Hans Verkuil3f038d82008-05-29 16:43:54 -03001894void ivtv_set_funcs(struct video_device *vdev)
1895{
Hans Verkuila3998102008-07-21 02:57:38 -03001896 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001897}