blob: 4d8ee18c3feb17978d048c3bbec8c5e4efe79763 [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 Verkuilec105a42009-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;
Hans Verkuile88360c2008-06-21 08:00:56 -0300354 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
355 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300356 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
357 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300358 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300359 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300360 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
361 pixfmt->sizeimage = 128 * 1024;
362 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300363 }
364 return 0;
365}
366
Hans Verkuil3f038d82008-05-29 16:43:54 -0300367static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300368{
Hans Verkuil2f824412011-03-12 06:43:28 -0300369 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300370 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300371
Hans Verkuile88360c2008-06-21 08:00:56 -0300372 vbifmt->sampling_rate = 27000000;
373 vbifmt->offset = 248;
374 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
375 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
376 vbifmt->start[0] = itv->vbi.start[0];
377 vbifmt->start[1] = itv->vbi.start[1];
378 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
379 vbifmt->flags = 0;
380 vbifmt->reserved[0] = 0;
381 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300382 return 0;
383}
384
385static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
386{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300387 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300388 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300389 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300390
Hans Verkuile88360c2008-06-21 08:00:56 -0300391 vbifmt->reserved[0] = 0;
392 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300393 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300394
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
396 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
397 V4L2_SLICED_VBI_525;
398 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuilc5c46f22012-09-05 12:27:19 -0300399 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300400 return 0;
401 }
402
Hans Verkuil4ff07902010-03-14 12:18:18 -0300403 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300404 vbifmt->service_set = ivtv_get_service_set(vbifmt);
405 return 0;
406}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300407
Hans Verkuil3f038d82008-05-29 16:43:54 -0300408static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
409{
Hans Verkuil2f824412011-03-12 06:43:28 -0300410 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300411 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300412 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300413
Hans Verkuil3f038d82008-05-29 16:43:54 -0300414 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300415 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300416 pixfmt->width = itv->main_rect.width;
417 pixfmt->height = itv->main_rect.height;
418 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
419 pixfmt->field = V4L2_FIELD_INTERLACED;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300420 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
421 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
422 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300423 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300424 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
425 break;
426 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300427 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300428 break;
429 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 break;
432 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
434 pixfmt->bytesperline = 720;
435 pixfmt->width = itv->yuv_info.v4l2_src_w;
436 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300437 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300438 pixfmt->sizeimage =
439 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300441 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
442 pixfmt->sizeimage = 128 * 1024;
443 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300444 }
445 return 0;
446}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447
Hans Verkuil3f038d82008-05-29 16:43:54 -0300448static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
449{
Hans Verkuil2f824412011-03-12 06:43:28 -0300450 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300451 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300452
453 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
454 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300455 winfmt->chromakey = itv->osd_chroma_key;
456 winfmt->global_alpha = itv->osd_global_alpha;
457 winfmt->field = V4L2_FIELD_INTERLACED;
458 winfmt->clips = NULL;
459 winfmt->clipcount = 0;
460 winfmt->bitmap = NULL;
461 winfmt->w.top = winfmt->w.left = 0;
462 winfmt->w.width = itv->osd_rect.width;
463 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300464 return 0;
465}
466
467static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
468{
469 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
470}
471
472static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
473{
Hans Verkuil2f824412011-03-12 06:43:28 -0300474 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300475 struct ivtv *itv = id->itv;
476 int w = fmt->fmt.pix.width;
477 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300478 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300479
480 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300481 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300482 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
483 /* YUV height must be a multiple of 32 */
484 h &= ~0x1f;
485 min_h = 32;
486 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300487 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300488 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300489 ivtv_g_fmt_vid_cap(file, fh, fmt);
490 fmt->fmt.pix.width = w;
491 fmt->fmt.pix.height = h;
492 return 0;
493}
494
495static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
496{
497 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
498}
499
500static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
501{
502 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300503 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300504 struct ivtv *itv = id->itv;
505
506 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
507 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300508
509 /* set sliced VBI capture format */
510 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300511 vbifmt->reserved[0] = 0;
512 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300513
514 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300515 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300516 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300517 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300518 return 0;
519}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300520
Hans Verkuil3f038d82008-05-29 16:43:54 -0300521static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
522{
Hans Verkuil2f824412011-03-12 06:43:28 -0300523 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300524 s32 w = fmt->fmt.pix.width;
525 s32 h = fmt->fmt.pix.height;
526 int field = fmt->fmt.pix.field;
527 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300528
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300529 w = min(w, 720);
530 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300531 /* Why can the height be 576 even when the output is NTSC?
532
533 Internally the buffers of the PVR350 are always set to 720x576. The
534 decoded video frame will always be placed in the top left corner of
535 this buffer. For any video which is not 720x576, the buffer will
536 then be cropped to remove the unused right and lower areas, with
537 the remaining image being scaled by the hardware to fit the display
538 area. The video can be scaled both up and down, so a 720x480 video
539 can be displayed full-screen on PAL and a 720x576 video can be
540 displayed without cropping on NTSC.
541
542 Note that the scaling only occurs on the video stream, the osd
543 resolution is locked to the broadcast standard and not scaled.
544
545 Thanks to Ian Armstrong for this explanation. */
546 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300547 h = max(h, 2);
548 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300549 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300550 fmt->fmt.pix.width = w;
551 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552 return ret;
553}
554
555static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
556{
Hans Verkuil2f824412011-03-12 06:43:28 -0300557 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300558 u32 chromakey = fmt->fmt.win.chromakey;
559 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300560
561 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
562 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300563 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
564 fmt->fmt.win.chromakey = chromakey;
565 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300566 return 0;
567}
568
569static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
570{
571 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
572}
573
574static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
575{
Hans Verkuil2f824412011-03-12 06:43:28 -0300576 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300577 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300578 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300579 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300580 int w = fmt->fmt.pix.width;
581 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300582
583 if (ret)
584 return ret;
585
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300586 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300587 return 0;
588
589 if (atomic_read(&itv->capturing) > 0)
590 return -EBUSY;
591
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300592 itv->cxhdl.width = w;
593 itv->cxhdl.height = h;
594 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300595 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300596 mbus_fmt.width = fmt->fmt.pix.width;
597 mbus_fmt.height = h;
Boris BREZILLON43ba4642014-11-10 14:28:30 -0300598 mbus_fmt.code = MEDIA_BUS_FMT_FIXED;
Hans Verkuil475977a2010-05-08 16:28:51 -0300599 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300600 return ivtv_g_fmt_vid_cap(file, fh, fmt);
601}
602
603static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
604{
Hans Verkuil2f824412011-03-12 06:43:28 -0300605 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300606
Hans Verkuila8b86432008-10-04 08:05:30 -0300607 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
608 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300609 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300610 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300611 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300612 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
613}
614
615static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
616{
617 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300618 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300619 struct ivtv *itv = id->itv;
620 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
621
622 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
623 return ret;
624
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300625 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300626 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300627 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300628 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300629 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300630 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
631 return 0;
632}
633
Hans Verkuil3f038d82008-05-29 16:43:54 -0300634static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300635{
Hans Verkuil2f824412011-03-12 06:43:28 -0300636 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300637 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300638 struct yuv_playback_info *yi = &itv->yuv_info;
639 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 if (ret)
642 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
645 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300646
Hans Verkuil3f038d82008-05-29 16:43:54 -0300647 /* Return now if we already have some frame data */
648 if (yi->stream_size)
649 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300650
Hans Verkuil3f038d82008-05-29 16:43:54 -0300651 yi->v4l2_src_w = fmt->fmt.pix.width;
652 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300653
Hans Verkuil3f038d82008-05-29 16:43:54 -0300654 switch (fmt->fmt.pix.field) {
655 case V4L2_FIELD_NONE:
656 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300657 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300658 case V4L2_FIELD_ANY:
659 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300661 case V4L2_FIELD_INTERLACED_BT:
662 yi->lace_mode =
663 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
664 break;
665 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300666 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300667 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
668 break;
669 }
670 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
671
672 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
673 itv->dma_data_req_size =
674 1080 * ((yi->v4l2_src_h + 31) & ~31);
675
Hans Verkuil3f038d82008-05-29 16:43:54 -0300676 return 0;
677}
678
679static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
680{
Hans Verkuil2f824412011-03-12 06:43:28 -0300681 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300682 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
683
684 if (ret == 0) {
685 itv->osd_chroma_key = fmt->fmt.win.chromakey;
686 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
687 ivtv_set_osd_alpha(itv);
688 }
689 return ret;
690}
691
Hans Verkuil36ecd492008-06-25 06:00:17 -0300692#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilb5656e82013-03-24 08:24:19 -0300693static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300694{
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300695 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300696
Hans Verkuile9dab582013-05-29 07:00:10 -0300697 if (reg & 0x3)
698 return -EINVAL;
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 Verkuilaecde8b52008-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 Verkuil0e8025b92012-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 Verkuil4f996592012-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 */
Laurent Pinchart8774bed2014-04-28 16:53:01 -03001091 ivtv_call_all(itv, video, 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;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001385 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1386 fb->fmt.bytesperline *= 2;
1387 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1388 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1389 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001390 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001391 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001392 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001393
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 if (itv->osd_chroma_key_state)
1395 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001396
Hans Verkuil3f038d82008-05-29 16:43:54 -03001397 if (itv->osd_global_alpha_state)
1398 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001399
Ian Armstrongec9faa12008-10-06 03:06:08 -03001400 if (yi->track_osd)
1401 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1402
Hans Verkuil3f038d82008-05-29 16:43:54 -03001403 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001404
Hans Verkuil3f038d82008-05-29 16:43:54 -03001405 /* no local alpha for RGB565 or unknown formats */
1406 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001407 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001408
Hans Verkuil3f038d82008-05-29 16:43:54 -03001409 /* 16-bit formats have inverted local alpha */
1410 if (pixfmt == 2 || pixfmt == 3)
1411 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1412 else
1413 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001414
Hans Verkuil3f038d82008-05-29 16:43:54 -03001415 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001416 /* 16-bit formats have inverted local alpha */
1417 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001418 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001419 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001420 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001421 }
1422
Hans Verkuil3f038d82008-05-29 16:43:54 -03001423 return 0;
1424}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001425
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001426static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427{
Hans Verkuil2f824412011-03-12 06:43:28 -03001428 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001429 struct ivtv *itv = id->itv;
1430 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001431
Hans Verkuil3f038d82008-05-29 16:43:54 -03001432 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001433 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001434 if (!itv->osd_video_pbase)
1435 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001436
1437 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1438 itv->osd_local_alpha_state =
1439 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1440 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1441 ivtv_set_osd_alpha(itv);
1442 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001443 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001444}
1445
1446static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1447{
Hans Verkuil2f824412011-03-12 06:43:28 -03001448 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001449 struct ivtv *itv = id->itv;
1450
1451 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1452 return -EINVAL;
1453
1454 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1455
1456 return 0;
1457}
1458
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001459static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001460{
1461 switch (sub->type) {
1462 case V4L2_EVENT_VSYNC:
1463 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001464 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001465 case V4L2_EVENT_CTRL:
1466 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001467 default:
1468 return -EINVAL;
1469 }
Hans Verkuil09250192010-03-27 14:10:13 -03001470}
1471
Hans Verkuil3f038d82008-05-29 16:43:54 -03001472static int ivtv_log_status(struct file *file, void *fh)
1473{
Hans Verkuil2f824412011-03-12 06:43:28 -03001474 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001475 u32 data[CX2341X_MBOX_MAX_DATA];
1476
1477 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1478 struct v4l2_input vidin;
1479 struct v4l2_audio audin;
1480 int i;
1481
Hans Verkuil3f038d82008-05-29 16:43:54 -03001482 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1483 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1484 struct tveeprom tv;
1485
1486 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001487 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001488 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001489 ivtv_get_input(itv, itv->active_input, &vidin);
1490 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1491 IVTV_INFO("Video Input: %s\n", vidin.name);
1492 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1493 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1494 if (has_output) {
1495 struct v4l2_output vidout;
1496 struct v4l2_audioout audout;
1497 int mode = itv->output_mode;
1498 static const char * const output_modes[5] = {
1499 "None",
1500 "MPEG Streaming",
1501 "YUV Streaming",
1502 "YUV Frames",
1503 "Passthrough",
1504 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001505 static const char * const alpha_mode[4] = {
1506 "None",
1507 "Global",
1508 "Local",
1509 "Global and Local"
1510 };
1511 static const char * const pixel_format[16] = {
1512 "ARGB Indexed",
1513 "RGB 5:6:5",
1514 "ARGB 1:5:5:5",
1515 "ARGB 1:4:4:4",
1516 "ARGB 8:8:8:8",
1517 "5",
1518 "6",
1519 "7",
1520 "AYUV Indexed",
1521 "YUV 5:6:5",
1522 "AYUV 1:5:5:5",
1523 "AYUV 1:4:4:4",
1524 "AYUV 8:8:8:8",
1525 "13",
1526 "14",
1527 "15",
1528 };
1529
1530 ivtv_get_output(itv, itv->active_output, &vidout);
1531 ivtv_get_audio_output(itv, 0, &audout);
1532 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001533 if (mode < 0 || mode > OUT_PASSTHROUGH)
1534 mode = OUT_NONE;
1535 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1536 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1537 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1538 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1539 data[0] & 1 ? "On" : "Off",
1540 alpha_mode[(data[0] >> 1) & 0x3],
1541 pixel_format[(data[0] >> 3) & 0xf]);
1542 }
1543 IVTV_INFO("Tuner: %s\n",
1544 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001545 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001546 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1547 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1548 struct ivtv_stream *s = &itv->streams[i];
1549
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001550 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001551 continue;
1552 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1553 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1554 (s->buffers * s->buf_size) / 1024, s->buffers);
1555 }
1556
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001557 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1558 (long long)itv->mpg_data_received,
1559 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001560 return 0;
1561}
1562
Hans Verkuilda8ec562011-11-24 09:58:53 -03001563static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1564{
1565 struct ivtv_open_id *id = fh2id(file->private_data);
1566 struct ivtv *itv = id->itv;
1567
1568 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1569 return ivtv_video_command(itv, id, dec, false);
1570}
1571
1572static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1573{
1574 struct ivtv_open_id *id = fh2id(file->private_data);
1575 struct ivtv *itv = id->itv;
1576
1577 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1578 return ivtv_video_command(itv, id, dec, true);
1579}
1580
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001581static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001582{
Hans Verkuil09250192010-03-27 14:10:13 -03001583 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001584 struct ivtv *itv = id->itv;
1585 int nonblocking = filp->f_flags & O_NONBLOCK;
1586 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001587 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001588
1589 switch (cmd) {
1590 case IVTV_IOC_DMA_FRAME: {
1591 struct ivtv_dma_frame *args = arg;
1592
1593 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1594 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1595 return -EINVAL;
1596 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1597 return -EINVAL;
1598 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1599 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001600 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001601 return -EBUSY;
1602 }
1603 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1604 ivtv_release_stream(s);
1605 return -EBUSY;
1606 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001607 /* Mark that this file handle started the UDMA_YUV mode */
1608 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001609 if (args->y_source == NULL)
1610 return 0;
1611 return ivtv_yuv_prep_frame(itv, args);
1612 }
1613
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001614 case IVTV_IOC_PASSTHROUGH_MODE:
1615 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1616 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1617 return -EINVAL;
1618 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1619
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001620 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001621 s64 *pts = arg;
1622 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001623
1624 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1625 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1626 *pts = s->dma_pts;
1627 break;
1628 }
1629 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1630 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001631 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001632 }
1633
1634 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001635 s64 *frame = arg;
1636 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001637
1638 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1639 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1640 *frame = 0;
1641 break;
1642 }
1643 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1644 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001645 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001646 }
1647
1648 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001649 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001650
1651 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001652 memset(&dc, 0, sizeof(dc));
1653 dc.cmd = V4L2_DEC_CMD_START;
1654 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001655 }
1656
1657 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001658 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001659
1660 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001661 memset(&dc, 0, sizeof(dc));
1662 dc.cmd = V4L2_DEC_CMD_STOP;
1663 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1664 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001665 }
1666
1667 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001668 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001669
1670 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001671 memset(&dc, 0, sizeof(dc));
1672 dc.cmd = V4L2_DEC_CMD_PAUSE;
1673 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001674 }
1675
1676 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001677 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001678
1679 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001680 memset(&dc, 0, sizeof(dc));
1681 dc.cmd = V4L2_DEC_CMD_RESUME;
1682 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001683 }
1684
1685 case VIDEO_COMMAND:
1686 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001687 /* Note: struct v4l2_decoder_cmd has the same layout as
1688 struct video_command */
1689 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001690 int try = (cmd == VIDEO_TRY_COMMAND);
1691
1692 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001693 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001694 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001695 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1696 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001697 }
1698
1699 case VIDEO_GET_EVENT: {
1700 struct video_event *ev = arg;
1701 DEFINE_WAIT(wait);
1702
1703 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1704 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1705 return -EINVAL;
1706 memset(ev, 0, sizeof(*ev));
1707 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1708
1709 while (1) {
1710 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1711 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1712 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1713 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001714 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1715 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1716 if (itv->output_mode == OUT_UDMA_YUV &&
1717 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1718 IVTV_YUV_MODE_PROGRESSIVE) {
1719 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1720 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001721 }
1722 if (ev->type)
1723 return 0;
1724 if (nonblocking)
1725 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001726 /* Wait for event. Note that serialize_lock is locked,
1727 so to allow other processes to access the driver while
1728 we are waiting unlock first and later lock again. */
1729 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001730 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a42009-05-02 11:10:23 -03001731 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1732 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001733 schedule();
1734 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001735 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001736 if (signal_pending(current)) {
1737 /* return if a signal was received */
1738 IVTV_DEBUG_INFO("User stopped wait for event\n");
1739 return -EINTR;
1740 }
1741 }
1742 break;
1743 }
1744
Hans Verkuilce680252010-04-06 15:58:53 -03001745 case VIDEO_SELECT_SOURCE:
1746 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1747 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1748 return -EINVAL;
1749 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1750
1751 case AUDIO_SET_MUTE:
1752 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1753 itv->speed_mute_audio = iarg;
1754 return 0;
1755
1756 case AUDIO_CHANNEL_SELECT:
1757 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1758 if (iarg > AUDIO_STEREO_SWAPPED)
1759 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001760 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001761
1762 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1763 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1764 if (iarg > AUDIO_STEREO_SWAPPED)
1765 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001766 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001767
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001768 default:
1769 return -EINVAL;
1770 }
1771 return 0;
1772}
1773
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001774static long ivtv_default(struct file *file, void *fh, bool valid_prio,
Mauro Carvalho Chehab6d43be72013-03-26 08:04:52 -03001775 unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001776{
Hans Verkuil2f824412011-03-12 06:43:28 -03001777 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001778
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001779 if (!valid_prio) {
1780 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001781 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001782 case VIDEO_PLAY:
1783 case VIDEO_STOP:
1784 case VIDEO_FREEZE:
1785 case VIDEO_CONTINUE:
1786 case VIDEO_COMMAND:
1787 case VIDEO_SELECT_SOURCE:
1788 case AUDIO_SET_MUTE:
1789 case AUDIO_CHANNEL_SELECT:
1790 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1791 return -EBUSY;
1792 }
1793 }
1794
Hans Verkuild46c17d2007-03-10 17:59:15 -03001795 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001796 case VIDIOC_INT_RESET: {
1797 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001798
Hans Verkuil3f038d82008-05-29 16:43:54 -03001799 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1800 ivtv_reset_ir_gpio(itv);
1801 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001802 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001803 break;
1804 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001805
Hans Verkuilac9575f2009-02-14 19:58:33 -03001806 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001807 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001808 case VIDEO_GET_PTS:
1809 case VIDEO_GET_FRAME_COUNT:
1810 case VIDEO_GET_EVENT:
1811 case VIDEO_PLAY:
1812 case VIDEO_STOP:
1813 case VIDEO_FREEZE:
1814 case VIDEO_CONTINUE:
1815 case VIDEO_COMMAND:
1816 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001817 case VIDEO_SELECT_SOURCE:
1818 case AUDIO_SET_MUTE:
1819 case AUDIO_CHANNEL_SELECT:
1820 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001821 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1822
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001823 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001824 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001825 }
1826 return 0;
1827}
1828
Hans Verkuila3998102008-07-21 02:57:38 -03001829static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1830 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001831 .vidioc_s_audio = ivtv_s_audio,
1832 .vidioc_g_audio = ivtv_g_audio,
1833 .vidioc_enumaudio = ivtv_enumaudio,
1834 .vidioc_s_audout = ivtv_s_audout,
1835 .vidioc_g_audout = ivtv_g_audout,
1836 .vidioc_enum_input = ivtv_enum_input,
1837 .vidioc_enum_output = ivtv_enum_output,
1838 .vidioc_enumaudout = ivtv_enumaudout,
1839 .vidioc_cropcap = ivtv_cropcap,
1840 .vidioc_s_crop = ivtv_s_crop,
1841 .vidioc_g_crop = ivtv_g_crop,
1842 .vidioc_g_input = ivtv_g_input,
1843 .vidioc_s_input = ivtv_s_input,
1844 .vidioc_g_output = ivtv_g_output,
1845 .vidioc_s_output = ivtv_s_output,
1846 .vidioc_g_frequency = ivtv_g_frequency,
1847 .vidioc_s_frequency = ivtv_s_frequency,
1848 .vidioc_s_tuner = ivtv_s_tuner,
1849 .vidioc_g_tuner = ivtv_g_tuner,
1850 .vidioc_g_enc_index = ivtv_g_enc_index,
1851 .vidioc_g_fbuf = ivtv_g_fbuf,
1852 .vidioc_s_fbuf = ivtv_s_fbuf,
1853 .vidioc_g_std = ivtv_g_std,
1854 .vidioc_s_std = ivtv_s_std,
1855 .vidioc_overlay = ivtv_overlay,
1856 .vidioc_log_status = ivtv_log_status,
1857 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1858 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1859 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001860 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1861 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001862 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1863 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1864 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1865 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1866 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1867 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1868 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1869 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1870 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1871 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1872 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1873 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1874 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1875 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1876 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1877 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1878 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1879 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1880 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1881 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
Hans Verkuila3998102008-07-21 02:57:38 -03001882#ifdef CONFIG_VIDEO_ADV_DEBUG
1883 .vidioc_g_register = ivtv_g_register,
1884 .vidioc_s_register = ivtv_s_register,
1885#endif
1886 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001887 .vidioc_subscribe_event = ivtv_subscribe_event,
1888 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001889};
1890
Hans Verkuil3f038d82008-05-29 16:43:54 -03001891void ivtv_set_funcs(struct video_device *vdev)
1892{
Hans Verkuila3998102008-07-21 02:57:38 -03001893 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001894}