blob: 944300f7c60b97d9c6f00e395d9c65c3002851df [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 Verkuilb5656e82013-03-24 08:24:19 -0300699 if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300700 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300701 else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
702 reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300703 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Hans Verkuilb5656e82013-03-24 08:24:19 -0300704 else if (reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300705 reg_start = itv->enc_mem;
706 else
707 return -EINVAL;
708
Hans Verkuilb5656e82013-03-24 08:24:19 -0300709 if (get)
710 *val = readl(reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300711 else
Hans Verkuilb5656e82013-03-24 08:24:19 -0300712 writel(*val, reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300713 return 0;
714}
715
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300716static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300717{
Hans Verkuil2f824412011-03-12 06:43:28 -0300718 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300719
Hans Verkuil4bd81932013-05-29 06:59:38 -0300720 reg->size = 4;
721 return ivtv_itvc(itv, true, reg->reg, &reg->val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300722}
723
Hans Verkuil977ba3b2013-03-24 08:28:46 -0300724static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300725{
Hans Verkuil2f824412011-03-12 06:43:28 -0300726 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil4bd81932013-05-29 06:59:38 -0300727 u64 val = reg->val;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300728
Hans Verkuil4bd81932013-05-29 06:59:38 -0300729 return ivtv_itvc(itv, false, reg->reg, &val);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300730}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300731#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300732
Hans Verkuil3f038d82008-05-29 16:43:54 -0300733static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
734{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300735 struct ivtv_open_id *id = fh2id(file->private_data);
736 struct ivtv *itv = id->itv;
737 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300738
Hans Verkuil3f038d82008-05-29 16:43:54 -0300739 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
740 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300741 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300742 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
743 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300744 return 0;
745}
746
747static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
748{
Hans Verkuil2f824412011-03-12 06:43:28 -0300749 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300750
751 return ivtv_get_audio_input(itv, vin->index, vin);
752}
753
754static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
755{
Hans Verkuil2f824412011-03-12 06:43:28 -0300756 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300757
758 vin->index = itv->audio_input;
759 return ivtv_get_audio_input(itv, vin->index, vin);
760}
761
Hans Verkuil0e8025b2012-09-04 11:59:31 -0300762static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300763{
Hans Verkuil2f824412011-03-12 06:43:28 -0300764 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300765
766 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300767 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300768
769 itv->audio_input = vout->index;
770 ivtv_audio_set_io(itv);
771
772 return 0;
773}
774
775static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
776{
Hans Verkuil2f824412011-03-12 06:43:28 -0300777 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300778
779 /* set it to defaults from our table */
780 return ivtv_get_audio_output(itv, vin->index, vin);
781}
782
783static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
784{
Hans Verkuil2f824412011-03-12 06:43:28 -0300785 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300786
787 vin->index = 0;
788 return ivtv_get_audio_output(itv, vin->index, vin);
789}
790
Hans Verkuilba9425b2012-09-04 12:03:49 -0300791static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300792{
Hans Verkuil2f824412011-03-12 06:43:28 -0300793 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300794
Hans Verkuilba9425b2012-09-04 12:03:49 -0300795 if (itv->card->video_outputs == NULL || vout->index != 0)
796 return -EINVAL;
797 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300798}
799
800static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
801{
Hans Verkuil2f824412011-03-12 06:43:28 -0300802 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300803
804 /* set it to defaults from our table */
805 return ivtv_get_input(itv, vin->index, vin);
806}
807
808static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
809{
Hans Verkuil2f824412011-03-12 06:43:28 -0300810 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300811
812 return ivtv_get_output(itv, vout->index, vout);
813}
814
815static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
816{
Hans Verkuil2f824412011-03-12 06:43:28 -0300817 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300818 struct ivtv *itv = id->itv;
819 struct yuv_playback_info *yi = &itv->yuv_info;
820 int streamtype;
821
822 streamtype = id->type;
823
824 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
825 return -EINVAL;
826 cropcap->bounds.top = cropcap->bounds.left = 0;
827 cropcap->bounds.width = 720;
828 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
829 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
830 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
831 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
832 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
833 if (yi->track_osd) {
834 cropcap->bounds.width = yi->osd_full_w;
835 cropcap->bounds.height = yi->osd_full_h;
836 } else {
837 cropcap->bounds.width = 720;
838 cropcap->bounds.height =
839 itv->is_out_50hz ? 576 : 480;
840 }
841 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
842 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
843 } else {
844 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
845 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
846 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
847 }
848 cropcap->defrect = cropcap->bounds;
849 return 0;
850}
851
Hans Verkuil4f9965942012-09-05 05:10:48 -0300852static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300853{
Hans Verkuil2f824412011-03-12 06:43:28 -0300854 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300855 struct ivtv *itv = id->itv;
856 struct yuv_playback_info *yi = &itv->yuv_info;
857 int streamtype;
858
859 streamtype = id->type;
860
Hans Verkuil3f038d82008-05-29 16:43:54 -0300861 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
862 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
863 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
864 yi->main_rect = crop->c;
865 return 0;
866 } else {
867 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
868 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
869 itv->main_rect = crop->c;
870 return 0;
871 }
872 }
873 return -EINVAL;
874 }
875 return -EINVAL;
876}
877
878static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
879{
Hans Verkuil2f824412011-03-12 06:43:28 -0300880 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300881 struct ivtv *itv = id->itv;
882 struct yuv_playback_info *yi = &itv->yuv_info;
883 int streamtype;
884
885 streamtype = id->type;
886
887 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
888 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
889 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
890 crop->c = yi->main_rect;
891 else
892 crop->c = itv->main_rect;
893 return 0;
894 }
895 return -EINVAL;
896}
897
898static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
899{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300900 static const struct v4l2_fmtdesc hm12 = {
901 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
902 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
903 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300904 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300905 static const struct v4l2_fmtdesc mpeg = {
906 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
907 "MPEG", V4L2_PIX_FMT_MPEG,
908 { 0, 0, 0, 0 }
909 };
910 struct ivtv *itv = fh2id(fh)->itv;
911 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300912
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300913 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300914 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300915 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
916 *fmt = mpeg;
917 else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
918 *fmt = hm12;
919 else
920 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300921 return 0;
922}
923
924static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
925{
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300926 static const struct v4l2_fmtdesc hm12 = {
927 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0,
928 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
929 { 0, 0, 0, 0 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300930 };
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300931 static const struct v4l2_fmtdesc mpeg = {
932 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_FMT_FLAG_COMPRESSED,
933 "MPEG", V4L2_PIX_FMT_MPEG,
934 { 0, 0, 0, 0 }
935 };
936 struct ivtv *itv = fh2id(fh)->itv;
937 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300938
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300939 if (fmt->index)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300940 return -EINVAL;
Hans Verkuilbfd063c2012-10-01 07:22:06 -0300941 if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
942 *fmt = mpeg;
943 else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
944 *fmt = hm12;
945 else
Hans Verkuil3f038d82008-05-29 16:43:54 -0300946 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300947 return 0;
948}
949
950static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
951{
Hans Verkuil2f824412011-03-12 06:43:28 -0300952 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300953
954 *i = itv->active_input;
955
956 return 0;
957}
958
959int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
960{
Hans Verkuil2f824412011-03-12 06:43:28 -0300961 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300962 v4l2_std_id std;
963 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300964
Mauro Carvalho Chehabd6eb0b92012-10-27 12:52:19 -0300965 if (inp >= itv->nof_inputs)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300966 return -EINVAL;
967
968 if (inp == itv->active_input) {
969 IVTV_DEBUG_INFO("Input unchanged\n");
970 return 0;
971 }
972
973 if (atomic_read(&itv->capturing) > 0) {
974 return -EBUSY;
975 }
976
977 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
978 itv->active_input, inp);
979
980 itv->active_input = inp;
981 /* Set the audio input to whatever is appropriate for the
982 input type. */
983 itv->audio_input = itv->card->video_inputs[inp].audio_index;
984
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300985 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
986 std = itv->tuner_std;
987 else
988 std = V4L2_STD_ALL;
989 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
990 itv->streams[i].vdev->tvnorms = std;
991
Hans Verkuil3f038d82008-05-29 16:43:54 -0300992 /* prevent others from messing with the streams until
993 we're finished changing inputs. */
994 ivtv_mute(itv);
995 ivtv_video_set_io(itv);
996 ivtv_audio_set_io(itv);
997 ivtv_unmute(itv);
998
999 return 0;
1000}
1001
1002static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1003{
Hans Verkuil2f824412011-03-12 06:43:28 -03001004 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001005
1006 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1007 return -EINVAL;
1008
1009 *i = itv->active_output;
1010
1011 return 0;
1012}
1013
1014static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1015{
Hans Verkuil2f824412011-03-12 06:43:28 -03001016 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001017
1018 if (outp >= itv->card->nof_outputs)
1019 return -EINVAL;
1020
1021 if (outp == itv->active_output) {
1022 IVTV_DEBUG_INFO("Output unchanged\n");
1023 return 0;
1024 }
1025 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1026 itv->active_output, outp);
1027
1028 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001029 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1030 SAA7127_INPUT_TYPE_NORMAL,
1031 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001032
1033 return 0;
1034}
1035
1036static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1037{
Hans Verkuil2f824412011-03-12 06:43:28 -03001038 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001039 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001040
Hans Verkuildff274f2012-10-01 06:45:36 -03001041 if (s->vdev->vfl_dir)
1042 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001043 if (vf->tuner != 0)
1044 return -EINVAL;
1045
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001046 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001047 return 0;
1048}
1049
Hans Verkuilb530a442013-03-19 04:09:26 -03001050int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001051{
Hans Verkuil2f824412011-03-12 06:43:28 -03001052 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001053 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001054
Hans Verkuildff274f2012-10-01 06:45:36 -03001055 if (s->vdev->vfl_dir)
1056 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001057 if (vf->tuner != 0)
1058 return -EINVAL;
1059
1060 ivtv_mute(itv);
1061 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001062 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001063 ivtv_unmute(itv);
1064 return 0;
1065}
1066
1067static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1068{
Hans Verkuil2f824412011-03-12 06:43:28 -03001069 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001070
1071 *std = itv->std;
1072 return 0;
1073}
1074
Hans Verkuil314527a2013-03-15 06:10:40 -03001075void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001076{
Hans Verkuil314527a2013-03-15 06:10:40 -03001077 itv->std = std;
1078 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001079 itv->is_50hz = !itv->is_60hz;
1080 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1081 itv->cxhdl.width = 720;
1082 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001083 itv->vbi.count = itv->is_50hz ? 18 : 12;
1084 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1085 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1086
1087 if (itv->hw_flags & IVTV_HW_CX25840)
1088 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1089
Hans Verkuil3f038d82008-05-29 16:43:54 -03001090 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001091 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001092}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001093
Hans Verkuil314527a2013-03-15 06:10:40 -03001094void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001095{
1096 struct yuv_playback_info *yi = &itv->yuv_info;
1097 DEFINE_WAIT(wait);
1098 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001099
Ian Armstrongc5874c92011-05-29 21:33:17 -03001100 /* set display standard */
Hans Verkuil314527a2013-03-15 06:10:40 -03001101 itv->std_out = std;
1102 itv->is_out_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
Ian Armstrongc5874c92011-05-29 21:33:17 -03001103 itv->is_out_50hz = !itv->is_out_60hz;
1104 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001105
Ian Armstrongc5874c92011-05-29 21:33:17 -03001106 /*
1107 * The next firmware call is time sensitive. Time it to
1108 * avoid risk of a hard lock, by trying to ensure the call
1109 * happens within the first 100 lines of the top field.
1110 * Make 4 attempts to sync to the decoder before giving up.
1111 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001112 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001113 for (f = 0; f < 4; f++) {
1114 prepare_to_wait(&itv->vsync_waitq, &wait,
1115 TASK_UNINTERRUPTIBLE);
1116 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1117 break;
1118 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001119 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001120 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001121 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001122
1123 if (f == 4)
1124 IVTV_WARN("Mode change failed to sync to decoder\n");
1125
1126 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1127 itv->main_rect.left = 0;
1128 itv->main_rect.top = 0;
1129 itv->main_rect.width = 720;
1130 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1131 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1132 720, itv->main_rect.height, 0, 0);
1133 yi->main_rect = itv->main_rect;
1134 if (!itv->osd_info) {
1135 yi->osd_full_w = 720;
1136 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1137 }
1138}
1139
Hans Verkuil314527a2013-03-15 06:10:40 -03001140static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001141{
1142 struct ivtv *itv = fh2id(fh)->itv;
1143
Hans Verkuil314527a2013-03-15 06:10:40 -03001144 if ((std & V4L2_STD_ALL) == 0)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001145 return -EINVAL;
1146
Hans Verkuil314527a2013-03-15 06:10:40 -03001147 if (std == itv->std)
Ian Armstrongc5874c92011-05-29 21:33:17 -03001148 return 0;
1149
1150 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1151 atomic_read(&itv->capturing) > 0 ||
1152 atomic_read(&itv->decoding) > 0) {
1153 /* Switching standard would mess with already running
1154 streams, prevent that by returning EBUSY. */
1155 return -EBUSY;
1156 }
1157
1158 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1159 (unsigned long long)itv->std);
1160
1161 ivtv_s_std_enc(itv, std);
1162 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1163 ivtv_s_std_dec(itv, std);
1164
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001165 return 0;
1166}
1167
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001168static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001169{
Hans Verkuil2f824412011-03-12 06:43:28 -03001170 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001171 struct ivtv *itv = id->itv;
1172
1173 if (vt->index != 0)
1174 return -EINVAL;
1175
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001176 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001177
1178 return 0;
1179}
1180
1181static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1182{
Hans Verkuil2f824412011-03-12 06:43:28 -03001183 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001184
1185 if (vt->index != 0)
1186 return -EINVAL;
1187
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001188 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001189
Hans Verkuild118e292011-06-25 10:28:21 -03001190 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001191 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001192 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001193 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001194 return 0;
1195}
1196
1197static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1198{
Hans Verkuil2f824412011-03-12 06:43:28 -03001199 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001200 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1201 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001202
Hans Verkuil79afcb12008-06-21 09:02:36 -03001203 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001204 for (f = 0; f < 2; f++) {
1205 for (l = 0; l < 24; l++) {
1206 if (valid_service_line(f, l, itv->is_50hz))
1207 cap->service_lines[f][l] = set;
1208 }
1209 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001210 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001211 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1212 return -EINVAL;
1213 if (itv->is_60hz) {
1214 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1215 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1216 } else {
1217 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1218 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1219 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001220 } else {
1221 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001222 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001223
1224 set = 0;
1225 for (f = 0; f < 2; f++)
1226 for (l = 0; l < 24; l++)
1227 set |= cap->service_lines[f][l];
1228 cap->service_set = set;
1229 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001230}
1231
1232static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1233{
Hans Verkuil2f824412011-03-12 06:43:28 -03001234 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001235 struct v4l2_enc_idx_entry *e = idx->entry;
1236 int entries;
1237 int i;
1238
1239 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1240 IVTV_MAX_PGM_INDEX;
1241 if (entries > V4L2_ENC_IDX_ENTRIES)
1242 entries = V4L2_ENC_IDX_ENTRIES;
1243 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001244 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1245 if (!atomic_read(&itv->capturing))
1246 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001247 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 Verkuile6eb28c2012-09-04 10:26:45 -03001427static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001428{
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 Verkuile6eb28c2012-09-04 10:26:45 -03001444 return 0;
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 Verkuil85f5fe32012-09-04 11:46:09 -03001460static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001461{
1462 switch (sub->type) {
1463 case V4L2_EVENT_VSYNC:
1464 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001465 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001466 case V4L2_EVENT_CTRL:
1467 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001468 default:
1469 return -EINVAL;
1470 }
Hans Verkuil09250192010-03-27 14:10:13 -03001471}
1472
Hans Verkuil3f038d82008-05-29 16:43:54 -03001473static int ivtv_log_status(struct file *file, void *fh)
1474{
Hans Verkuil2f824412011-03-12 06:43:28 -03001475 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001476 u32 data[CX2341X_MBOX_MAX_DATA];
1477
1478 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1479 struct v4l2_input vidin;
1480 struct v4l2_audio audin;
1481 int i;
1482
Hans Verkuil3f038d82008-05-29 16:43:54 -03001483 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1484 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1485 struct tveeprom tv;
1486
1487 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001488 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001489 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001490 ivtv_get_input(itv, itv->active_input, &vidin);
1491 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1492 IVTV_INFO("Video Input: %s\n", vidin.name);
1493 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1494 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1495 if (has_output) {
1496 struct v4l2_output vidout;
1497 struct v4l2_audioout audout;
1498 int mode = itv->output_mode;
1499 static const char * const output_modes[5] = {
1500 "None",
1501 "MPEG Streaming",
1502 "YUV Streaming",
1503 "YUV Frames",
1504 "Passthrough",
1505 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001506 static const char * const alpha_mode[4] = {
1507 "None",
1508 "Global",
1509 "Local",
1510 "Global and Local"
1511 };
1512 static const char * const pixel_format[16] = {
1513 "ARGB Indexed",
1514 "RGB 5:6:5",
1515 "ARGB 1:5:5:5",
1516 "ARGB 1:4:4:4",
1517 "ARGB 8:8:8:8",
1518 "5",
1519 "6",
1520 "7",
1521 "AYUV Indexed",
1522 "YUV 5:6:5",
1523 "AYUV 1:5:5:5",
1524 "AYUV 1:4:4:4",
1525 "AYUV 8:8:8:8",
1526 "13",
1527 "14",
1528 "15",
1529 };
1530
1531 ivtv_get_output(itv, itv->active_output, &vidout);
1532 ivtv_get_audio_output(itv, 0, &audout);
1533 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001534 if (mode < 0 || mode > OUT_PASSTHROUGH)
1535 mode = OUT_NONE;
1536 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1537 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1538 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1539 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1540 data[0] & 1 ? "On" : "Off",
1541 alpha_mode[(data[0] >> 1) & 0x3],
1542 pixel_format[(data[0] >> 3) & 0xf]);
1543 }
1544 IVTV_INFO("Tuner: %s\n",
1545 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001546 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001547 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1548 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1549 struct ivtv_stream *s = &itv->streams[i];
1550
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001551 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001552 continue;
1553 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1554 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1555 (s->buffers * s->buf_size) / 1024, s->buffers);
1556 }
1557
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001558 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1559 (long long)itv->mpg_data_received,
1560 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001561 return 0;
1562}
1563
Hans Verkuilda8ec562011-11-24 09:58:53 -03001564static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1565{
1566 struct ivtv_open_id *id = fh2id(file->private_data);
1567 struct ivtv *itv = id->itv;
1568
1569 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1570 return ivtv_video_command(itv, id, dec, false);
1571}
1572
1573static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1574{
1575 struct ivtv_open_id *id = fh2id(file->private_data);
1576 struct ivtv *itv = id->itv;
1577
1578 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1579 return ivtv_video_command(itv, id, dec, true);
1580}
1581
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001582static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001583{
Hans Verkuil09250192010-03-27 14:10:13 -03001584 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001585 struct ivtv *itv = id->itv;
1586 int nonblocking = filp->f_flags & O_NONBLOCK;
1587 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001588 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001589
1590 switch (cmd) {
1591 case IVTV_IOC_DMA_FRAME: {
1592 struct ivtv_dma_frame *args = arg;
1593
1594 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1595 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1596 return -EINVAL;
1597 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1598 return -EINVAL;
1599 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1600 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001601 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001602 return -EBUSY;
1603 }
1604 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1605 ivtv_release_stream(s);
1606 return -EBUSY;
1607 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001608 /* Mark that this file handle started the UDMA_YUV mode */
1609 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001610 if (args->y_source == NULL)
1611 return 0;
1612 return ivtv_yuv_prep_frame(itv, args);
1613 }
1614
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001615 case IVTV_IOC_PASSTHROUGH_MODE:
1616 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1617 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1618 return -EINVAL;
1619 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1620
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001621 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001622 s64 *pts = arg;
1623 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001624
1625 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1626 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1627 *pts = s->dma_pts;
1628 break;
1629 }
1630 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1631 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001632 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001633 }
1634
1635 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001636 s64 *frame = arg;
1637 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001638
1639 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1640 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1641 *frame = 0;
1642 break;
1643 }
1644 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1645 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001646 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001647 }
1648
1649 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001650 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001651
1652 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001653 memset(&dc, 0, sizeof(dc));
1654 dc.cmd = V4L2_DEC_CMD_START;
1655 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001656 }
1657
1658 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001659 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001660
1661 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001662 memset(&dc, 0, sizeof(dc));
1663 dc.cmd = V4L2_DEC_CMD_STOP;
1664 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1665 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001666 }
1667
1668 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001669 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001670
1671 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001672 memset(&dc, 0, sizeof(dc));
1673 dc.cmd = V4L2_DEC_CMD_PAUSE;
1674 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001675 }
1676
1677 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001678 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001679
1680 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001681 memset(&dc, 0, sizeof(dc));
1682 dc.cmd = V4L2_DEC_CMD_RESUME;
1683 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001684 }
1685
1686 case VIDEO_COMMAND:
1687 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001688 /* Note: struct v4l2_decoder_cmd has the same layout as
1689 struct video_command */
1690 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001691 int try = (cmd == VIDEO_TRY_COMMAND);
1692
1693 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001694 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001695 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001696 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1697 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001698 }
1699
1700 case VIDEO_GET_EVENT: {
1701 struct video_event *ev = arg;
1702 DEFINE_WAIT(wait);
1703
1704 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1705 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1706 return -EINVAL;
1707 memset(ev, 0, sizeof(*ev));
1708 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1709
1710 while (1) {
1711 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1712 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1713 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1714 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001715 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1716 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1717 if (itv->output_mode == OUT_UDMA_YUV &&
1718 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1719 IVTV_YUV_MODE_PROGRESSIVE) {
1720 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1721 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001722 }
1723 if (ev->type)
1724 return 0;
1725 if (nonblocking)
1726 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001727 /* Wait for event. Note that serialize_lock is locked,
1728 so to allow other processes to access the driver while
1729 we are waiting unlock first and later lock again. */
1730 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001731 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001732 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1733 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001734 schedule();
1735 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001736 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001737 if (signal_pending(current)) {
1738 /* return if a signal was received */
1739 IVTV_DEBUG_INFO("User stopped wait for event\n");
1740 return -EINTR;
1741 }
1742 }
1743 break;
1744 }
1745
Hans Verkuilce680252010-04-06 15:58:53 -03001746 case VIDEO_SELECT_SOURCE:
1747 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1748 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1749 return -EINVAL;
1750 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1751
1752 case AUDIO_SET_MUTE:
1753 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1754 itv->speed_mute_audio = iarg;
1755 return 0;
1756
1757 case AUDIO_CHANNEL_SELECT:
1758 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1759 if (iarg > AUDIO_STEREO_SWAPPED)
1760 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001761 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001762
1763 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1764 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1765 if (iarg > AUDIO_STEREO_SWAPPED)
1766 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001767 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001768
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001769 default:
1770 return -EINVAL;
1771 }
1772 return 0;
1773}
1774
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001775static long ivtv_default(struct file *file, void *fh, bool valid_prio,
Mauro Carvalho Chehab6d43be72013-03-26 08:04:52 -03001776 unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001777{
Hans Verkuil2f824412011-03-12 06:43:28 -03001778 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001779
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001780 if (!valid_prio) {
1781 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001782 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001783 case VIDEO_PLAY:
1784 case VIDEO_STOP:
1785 case VIDEO_FREEZE:
1786 case VIDEO_CONTINUE:
1787 case VIDEO_COMMAND:
1788 case VIDEO_SELECT_SOURCE:
1789 case AUDIO_SET_MUTE:
1790 case AUDIO_CHANNEL_SELECT:
1791 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1792 return -EBUSY;
1793 }
1794 }
1795
Hans Verkuild46c17d2007-03-10 17:59:15 -03001796 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001797 case VIDIOC_INT_RESET: {
1798 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001799
Hans Verkuil3f038d82008-05-29 16:43:54 -03001800 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1801 ivtv_reset_ir_gpio(itv);
1802 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001803 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001804 break;
1805 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001806
Hans Verkuilac9575f2009-02-14 19:58:33 -03001807 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001808 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001809 case VIDEO_GET_PTS:
1810 case VIDEO_GET_FRAME_COUNT:
1811 case VIDEO_GET_EVENT:
1812 case VIDEO_PLAY:
1813 case VIDEO_STOP:
1814 case VIDEO_FREEZE:
1815 case VIDEO_CONTINUE:
1816 case VIDEO_COMMAND:
1817 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001818 case VIDEO_SELECT_SOURCE:
1819 case AUDIO_SET_MUTE:
1820 case AUDIO_CHANNEL_SELECT:
1821 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001822 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1823
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001824 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001825 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001826 }
1827 return 0;
1828}
1829
Hans Verkuila3998102008-07-21 02:57:38 -03001830static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1831 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001832 .vidioc_s_audio = ivtv_s_audio,
1833 .vidioc_g_audio = ivtv_g_audio,
1834 .vidioc_enumaudio = ivtv_enumaudio,
1835 .vidioc_s_audout = ivtv_s_audout,
1836 .vidioc_g_audout = ivtv_g_audout,
1837 .vidioc_enum_input = ivtv_enum_input,
1838 .vidioc_enum_output = ivtv_enum_output,
1839 .vidioc_enumaudout = ivtv_enumaudout,
1840 .vidioc_cropcap = ivtv_cropcap,
1841 .vidioc_s_crop = ivtv_s_crop,
1842 .vidioc_g_crop = ivtv_g_crop,
1843 .vidioc_g_input = ivtv_g_input,
1844 .vidioc_s_input = ivtv_s_input,
1845 .vidioc_g_output = ivtv_g_output,
1846 .vidioc_s_output = ivtv_s_output,
1847 .vidioc_g_frequency = ivtv_g_frequency,
1848 .vidioc_s_frequency = ivtv_s_frequency,
1849 .vidioc_s_tuner = ivtv_s_tuner,
1850 .vidioc_g_tuner = ivtv_g_tuner,
1851 .vidioc_g_enc_index = ivtv_g_enc_index,
1852 .vidioc_g_fbuf = ivtv_g_fbuf,
1853 .vidioc_s_fbuf = ivtv_s_fbuf,
1854 .vidioc_g_std = ivtv_g_std,
1855 .vidioc_s_std = ivtv_s_std,
1856 .vidioc_overlay = ivtv_overlay,
1857 .vidioc_log_status = ivtv_log_status,
1858 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1859 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1860 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001861 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1862 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001863 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1864 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1865 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1866 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1867 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1868 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1869 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1870 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1871 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1872 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1873 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1874 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1875 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1876 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1877 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1878 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1879 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1880 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1881 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1882 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
Hans Verkuila3998102008-07-21 02:57:38 -03001883#ifdef CONFIG_VIDEO_ADV_DEBUG
1884 .vidioc_g_register = ivtv_g_register,
1885 .vidioc_s_register = ivtv_s_register,
1886#endif
1887 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001888 .vidioc_subscribe_event = ivtv_subscribe_event,
1889 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001890};
1891
Hans Verkuil3f038d82008-05-29 16:43:54 -03001892void ivtv_set_funcs(struct video_device *vdev)
1893{
Hans Verkuila3998102008-07-21 02:57:38 -03001894 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001895}