blob: 5537c88420752fced6cfb2ae70bc2262d9b7f67c [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-version.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030028#include "ivtv-routing.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030029#include "ivtv-streams.h"
30#include "ivtv-yuv.h"
31#include "ivtv-ioctl.h"
32#include "ivtv-gpio.h"
33#include "ivtv-controls.h"
34#include "ivtv-cards.h"
35#include <media/saa7127.h>
36#include <media/tveeprom.h>
37#include <media/v4l2-chip-ident.h>
Hans Verkuil09250192010-03-27 14:10:13 -030038#include <media/v4l2-event.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030039#include <linux/dvb/audio.h>
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030040
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030041u16 ivtv_service2vbi(int type)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030042{
43 switch (type) {
44 case V4L2_SLICED_TELETEXT_B:
45 return IVTV_SLICED_TYPE_TELETEXT_B;
46 case V4L2_SLICED_CAPTION_525:
47 return IVTV_SLICED_TYPE_CAPTION_525;
48 case V4L2_SLICED_WSS_625:
49 return IVTV_SLICED_TYPE_WSS_625;
50 case V4L2_SLICED_VPS:
51 return IVTV_SLICED_TYPE_VPS;
52 default:
53 return 0;
54 }
55}
56
57static int valid_service_line(int field, int line, int is_pal)
58{
59 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
60 (!is_pal && line >= 10 && line < 22);
61}
62
63static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
64{
65 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
66 int i;
67
68 set = set & valid_set;
69 if (set == 0 || !valid_service_line(field, line, is_pal)) {
70 return 0;
71 }
72 if (!is_pal) {
73 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
74 return V4L2_SLICED_CAPTION_525;
75 }
76 else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625;
81 if (line == 23)
82 return 0;
83 }
84 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set)
86 return 1 << i;
87 }
88 return 0;
89}
90
Hans Verkuilfeb5bce2008-05-01 09:22:13 -030091void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030092{
93 u16 set = fmt->service_set;
94 int f, l;
95
96 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++) {
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 }
101 }
102}
103
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300104static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300105{
106 int f, l;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300107
108 for (f = 0; f < 2; f++) {
109 for (l = 0; l < 24; l++) {
110 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300111 }
112 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300113}
114
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300115u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300116{
117 int f, l;
118 u16 set = 0;
119
120 for (f = 0; f < 2; f++) {
121 for (l = 0; l < 24; l++) {
122 set |= fmt->service_lines[f][l];
123 }
124 }
125 return set;
126}
127
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300128void ivtv_set_osd_alpha(struct ivtv *itv)
129{
130 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
131 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300132 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300133}
134
135int ivtv_set_speed(struct ivtv *itv, int speed)
136{
137 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300138 int single_step = (speed == 1 || speed == -1);
139 DEFINE_WAIT(wait);
140
141 if (speed == 0) speed = 1000;
142
143 /* No change? */
144 if (speed == itv->speed && !single_step)
145 return 0;
146
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300147 if (single_step && (speed < 0) == (itv->speed < 0)) {
148 /* Single step video and no need to change direction */
149 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
150 itv->speed = speed;
151 return 0;
152 }
153 if (single_step)
154 /* Need to change direction */
155 speed = speed < 0 ? -1000 : 1000;
156
157 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
158 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
159 data[1] = (speed < 0);
160 data[2] = speed < 0 ? 3 : 7;
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300161 data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300162 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
163 data[5] = 0;
164 data[6] = 0;
165
166 if (speed == 1500 || speed == -1500) data[0] |= 1;
167 else if (speed == 2000 || speed == -2000) data[0] |= 2;
168 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
169 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
170
171 /* If not decoding, just change speed setting */
172 if (atomic_read(&itv->decoding) > 0) {
173 int got_sig = 0;
174
175 /* Stop all DMA and decoding activity */
176 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
177
178 /* Wait for any DMA to finish */
Hans Verkuilcdc03782011-10-11 06:06:58 -0300179 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300180 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -0300181 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300182 got_sig = signal_pending(current);
183 if (got_sig)
184 break;
185 got_sig = 0;
186 schedule();
187 }
188 finish_wait(&itv->dma_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -0300189 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300190 if (got_sig)
191 return -EINTR;
192
193 /* Change Speed safely */
194 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
195 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
196 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
197 }
198 if (single_step) {
199 speed = (speed < 0) ? -1 : 1;
200 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
201 }
202 itv->speed = speed;
203 return 0;
204}
205
206static int ivtv_validate_speed(int cur_speed, int new_speed)
207{
208 int fact = new_speed < 0 ? -1 : 1;
209 int s;
210
Hans Verkuil94dee762008-04-26 09:26:13 -0300211 if (cur_speed == 0)
212 cur_speed = 1000;
213 if (new_speed < 0)
214 new_speed = -new_speed;
215 if (cur_speed < 0)
216 cur_speed = -cur_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300217
218 if (cur_speed <= new_speed) {
Hans Verkuil94dee762008-04-26 09:26:13 -0300219 if (new_speed > 1500)
220 return fact * 2000;
221 if (new_speed > 1000)
222 return fact * 1500;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300223 }
224 else {
Hans Verkuil94dee762008-04-26 09:26:13 -0300225 if (new_speed >= 2000)
226 return fact * 2000;
227 if (new_speed >= 1500)
228 return fact * 1500;
229 if (new_speed >= 1000)
230 return fact * 1000;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300231 }
Hans Verkuil94dee762008-04-26 09:26:13 -0300232 if (new_speed == 0)
233 return 1000;
234 if (new_speed == 1 || new_speed == 1000)
235 return fact * new_speed;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300236
237 s = new_speed;
238 new_speed = 1000 / new_speed;
239 if (1000 / cur_speed == new_speed)
240 new_speed += (cur_speed < s) ? -1 : 1;
241 if (new_speed > 60) return 1000 / (fact * 60);
242 return 1000 / (fact * new_speed);
243}
244
245static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300246 struct v4l2_decoder_cmd *dc, int try)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300247{
248 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
249
250 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
251 return -EINVAL;
252
Hans Verkuilda8ec562011-11-24 09:58:53 -0300253 switch (dc->cmd) {
254 case V4L2_DEC_CMD_START: {
255 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
256 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
257 if (dc->start.speed < 0)
258 dc->start.format = V4L2_DEC_START_FMT_GOP;
259 else
260 dc->start.format = V4L2_DEC_START_FMT_NONE;
261 if (dc->start.speed != 500 && dc->start.speed != 1500)
262 dc->flags = dc->start.speed == 1000 ? 0 :
263 V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300264 if (try) break;
265
Hans Verkuilda8ec562011-11-24 09:58:53 -0300266 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300267 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
268 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300269 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
270 /* forces ivtv_set_speed to be called */
271 itv->speed = 0;
272 }
Hans Verkuilda8ec562011-11-24 09:58:53 -0300273 return ivtv_start_decoding(id, dc->start.speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300274 }
275
Hans Verkuilda8ec562011-11-24 09:58:53 -0300276 case V4L2_DEC_CMD_STOP:
277 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
278 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
279 dc->stop.pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300280 if (try) break;
281 if (atomic_read(&itv->decoding) == 0)
282 return 0;
283 if (itv->output_mode != OUT_MPG)
284 return -EBUSY;
285
286 itv->output_mode = OUT_NONE;
Hans Verkuilda8ec562011-11-24 09:58:53 -0300287 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300288
Hans Verkuilda8ec562011-11-24 09:58:53 -0300289 case V4L2_DEC_CMD_PAUSE:
290 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300291 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300292 if (!atomic_read(&itv->decoding))
293 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300294 if (itv->output_mode != OUT_MPG)
295 return -EBUSY;
296 if (atomic_read(&itv->decoding) > 0) {
297 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
Hans Verkuilda8ec562011-11-24 09:58:53 -0300298 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300299 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300300 }
301 break;
302
Hans Verkuilda8ec562011-11-24 09:58:53 -0300303 case V4L2_DEC_CMD_RESUME:
304 dc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300305 if (try) break;
Hans Verkuil1a806402012-09-05 08:39:48 -0300306 if (!atomic_read(&itv->decoding))
307 return -EPERM;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300308 if (itv->output_mode != OUT_MPG)
309 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300310 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
311 int speed = itv->speed;
312 itv->speed = 0;
313 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300314 }
315 break;
316
317 default:
318 return -EINVAL;
319 }
320 return 0;
321}
322
Hans Verkuil3f038d82008-05-29 16:43:54 -0300323static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300324{
Hans Verkuil2f824412011-03-12 06:43:28 -0300325 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300326 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300327
Hans Verkuile88360c2008-06-21 08:00:56 -0300328 vbifmt->reserved[0] = 0;
329 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300330 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300331 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300332 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil30634e82012-09-05 10:38:10 -0300333 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
Hans Verkuil3f038d82008-05-29 16:43:54 -0300334 if (itv->is_60hz) {
335 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
336 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
337 } else {
338 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
339 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
340 }
341 vbifmt->service_set = ivtv_get_service_set(vbifmt);
342 return 0;
343}
344
345static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
346{
Hans Verkuil2f824412011-03-12 06:43:28 -0300347 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300348 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300349 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300350
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300351 pixfmt->width = itv->cxhdl.width;
352 pixfmt->height = itv->cxhdl.height;
Hans Verkuile88360c2008-06-21 08:00:56 -0300353 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
354 pixfmt->field = V4L2_FIELD_INTERLACED;
355 pixfmt->priv = 0;
356 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
357 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
Hans Verkuila4a78712009-02-06 15:31:59 -0300358 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
359 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
Hans Verkuile88360c2008-06-21 08:00:56 -0300360 pixfmt->bytesperline = 720;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300361 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300362 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
363 pixfmt->sizeimage = 128 * 1024;
364 pixfmt->bytesperline = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300365 }
366 return 0;
367}
368
Hans Verkuil3f038d82008-05-29 16:43:54 -0300369static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300370{
Hans Verkuil2f824412011-03-12 06:43:28 -0300371 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300372 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300373
Hans Verkuile88360c2008-06-21 08:00:56 -0300374 vbifmt->sampling_rate = 27000000;
375 vbifmt->offset = 248;
376 vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
377 vbifmt->sample_format = V4L2_PIX_FMT_GREY;
378 vbifmt->start[0] = itv->vbi.start[0];
379 vbifmt->start[1] = itv->vbi.start[1];
380 vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
381 vbifmt->flags = 0;
382 vbifmt->reserved[0] = 0;
383 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300384 return 0;
385}
386
387static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
388{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300389 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300390 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300391 struct ivtv *itv = id->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300392
Hans Verkuile88360c2008-06-21 08:00:56 -0300393 vbifmt->reserved[0] = 0;
394 vbifmt->reserved[1] = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300395 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300396
Hans Verkuil3f038d82008-05-29 16:43:54 -0300397 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
398 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
399 V4L2_SLICED_VBI_525;
400 ivtv_expand_service_set(vbifmt, itv->is_50hz);
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 Verkuilaecde8b2008-12-30 07:14:19 -0300694static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300695{
Hans Verkuil2f824412011-03-12 06:43:28 -0300696 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300697
698 chip->ident = V4L2_IDENT_NONE;
699 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300700 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
701 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300702 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
703 return 0;
704 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300705 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
706 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300707 return -EINVAL;
708 /* TODO: is this correct? */
709 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300710}
711
Hans Verkuil36ecd492008-06-25 06:00:17 -0300712#ifdef CONFIG_VIDEO_ADV_DEBUG
713static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
714{
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300715 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300716 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300717
718 if (!capable(CAP_SYS_ADMIN))
719 return -EPERM;
720 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
721 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
722 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
723 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
724 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300725 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300726 reg_start = itv->enc_mem;
727 else
728 return -EINVAL;
729
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300730 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300731 if (cmd == VIDIOC_DBG_G_REGISTER)
732 regs->val = readl(regs->reg + reg_start);
733 else
734 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300735 return 0;
736}
737
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300738static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300739{
Hans Verkuil2f824412011-03-12 06:43:28 -0300740 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300741
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300742 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300743 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300744 /* TODO: subdev errors should not be ignored, this should become a
745 subdev helper function. */
746 ivtv_call_all(itv, core, g_register, reg);
747 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300748}
749
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300750static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300751{
Hans Verkuil2f824412011-03-12 06:43:28 -0300752 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300753
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300754 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300755 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300756 /* TODO: subdev errors should not be ignored, this should become a
757 subdev helper function. */
758 ivtv_call_all(itv, core, s_register, reg);
759 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300760}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300761#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300762
Hans Verkuil3f038d82008-05-29 16:43:54 -0300763static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
764{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300765 struct ivtv_open_id *id = fh2id(file->private_data);
766 struct ivtv *itv = id->itv;
767 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300768
Hans Verkuil3f038d82008-05-29 16:43:54 -0300769 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
770 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300771 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300772 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
773 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300774 return 0;
775}
776
777static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
778{
Hans Verkuil2f824412011-03-12 06:43:28 -0300779 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300780
781 return ivtv_get_audio_input(itv, vin->index, vin);
782}
783
784static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
785{
Hans Verkuil2f824412011-03-12 06:43:28 -0300786 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300787
788 vin->index = itv->audio_input;
789 return ivtv_get_audio_input(itv, vin->index, vin);
790}
791
Hans Verkuil0e8025b2012-09-04 11:59:31 -0300792static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300793{
Hans Verkuil2f824412011-03-12 06:43:28 -0300794 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300795
796 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300797 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300798
799 itv->audio_input = vout->index;
800 ivtv_audio_set_io(itv);
801
802 return 0;
803}
804
805static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
806{
Hans Verkuil2f824412011-03-12 06:43:28 -0300807 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300808
809 /* set it to defaults from our table */
810 return ivtv_get_audio_output(itv, vin->index, vin);
811}
812
813static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
814{
Hans Verkuil2f824412011-03-12 06:43:28 -0300815 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300816
817 vin->index = 0;
818 return ivtv_get_audio_output(itv, vin->index, vin);
819}
820
Hans Verkuilba9425b2012-09-04 12:03:49 -0300821static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300822{
Hans Verkuil2f824412011-03-12 06:43:28 -0300823 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300824
Hans Verkuilba9425b2012-09-04 12:03:49 -0300825 if (itv->card->video_outputs == NULL || vout->index != 0)
826 return -EINVAL;
827 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300828}
829
830static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
831{
Hans Verkuil2f824412011-03-12 06:43:28 -0300832 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300833
834 /* set it to defaults from our table */
835 return ivtv_get_input(itv, vin->index, vin);
836}
837
838static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
839{
Hans Verkuil2f824412011-03-12 06:43:28 -0300840 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300841
842 return ivtv_get_output(itv, vout->index, vout);
843}
844
845static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
846{
Hans Verkuil2f824412011-03-12 06:43:28 -0300847 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300848 struct ivtv *itv = id->itv;
849 struct yuv_playback_info *yi = &itv->yuv_info;
850 int streamtype;
851
852 streamtype = id->type;
853
854 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
855 return -EINVAL;
856 cropcap->bounds.top = cropcap->bounds.left = 0;
857 cropcap->bounds.width = 720;
858 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
859 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
860 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
861 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
862 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
863 if (yi->track_osd) {
864 cropcap->bounds.width = yi->osd_full_w;
865 cropcap->bounds.height = yi->osd_full_h;
866 } else {
867 cropcap->bounds.width = 720;
868 cropcap->bounds.height =
869 itv->is_out_50hz ? 576 : 480;
870 }
871 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
872 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
873 } else {
874 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
875 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
876 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
877 }
878 cropcap->defrect = cropcap->bounds;
879 return 0;
880}
881
Hans Verkuil4f9965942012-09-05 05:10:48 -0300882static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300883{
Hans Verkuil2f824412011-03-12 06:43:28 -0300884 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300885 struct ivtv *itv = id->itv;
886 struct yuv_playback_info *yi = &itv->yuv_info;
887 int streamtype;
888
889 streamtype = id->type;
890
Hans Verkuil3f038d82008-05-29 16:43:54 -0300891 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
892 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
893 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
894 yi->main_rect = crop->c;
895 return 0;
896 } else {
897 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
898 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
899 itv->main_rect = crop->c;
900 return 0;
901 }
902 }
903 return -EINVAL;
904 }
905 return -EINVAL;
906}
907
908static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
909{
Hans Verkuil2f824412011-03-12 06:43:28 -0300910 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300911 struct ivtv *itv = id->itv;
912 struct yuv_playback_info *yi = &itv->yuv_info;
913 int streamtype;
914
915 streamtype = id->type;
916
917 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
918 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
919 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
920 crop->c = yi->main_rect;
921 else
922 crop->c = itv->main_rect;
923 return 0;
924 }
925 return -EINVAL;
926}
927
928static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
929{
930 static struct v4l2_fmtdesc formats[] = {
931 { 0, 0, 0,
932 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
933 { 0, 0, 0, 0 }
934 },
935 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
936 "MPEG", V4L2_PIX_FMT_MPEG,
937 { 0, 0, 0, 0 }
938 }
939 };
940 enum v4l2_buf_type type = fmt->type;
941
942 if (fmt->index > 1)
943 return -EINVAL;
944
945 *fmt = formats[fmt->index];
946 fmt->type = type;
947 return 0;
948}
949
950static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
951{
Hans Verkuil2f824412011-03-12 06:43:28 -0300952 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300953
954 static struct v4l2_fmtdesc formats[] = {
955 { 0, 0, 0,
956 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
957 { 0, 0, 0, 0 }
958 },
959 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
960 "MPEG", V4L2_PIX_FMT_MPEG,
961 { 0, 0, 0, 0 }
962 }
963 };
964 enum v4l2_buf_type type = fmt->type;
965
966 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
967 return -EINVAL;
968
969 if (fmt->index > 1)
970 return -EINVAL;
971
972 *fmt = formats[fmt->index];
973 fmt->type = type;
974
975 return 0;
976}
977
978static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
979{
Hans Verkuil2f824412011-03-12 06:43:28 -0300980 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300981
982 *i = itv->active_input;
983
984 return 0;
985}
986
987int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
988{
Hans Verkuil2f824412011-03-12 06:43:28 -0300989 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300990 v4l2_std_id std;
991 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300992
993 if (inp < 0 || inp >= itv->nof_inputs)
994 return -EINVAL;
995
996 if (inp == itv->active_input) {
997 IVTV_DEBUG_INFO("Input unchanged\n");
998 return 0;
999 }
1000
1001 if (atomic_read(&itv->capturing) > 0) {
1002 return -EBUSY;
1003 }
1004
1005 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1006 itv->active_input, inp);
1007
1008 itv->active_input = inp;
1009 /* Set the audio input to whatever is appropriate for the
1010 input type. */
1011 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1012
Hans Verkuilf659f0e72012-09-05 08:56:55 -03001013 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
1014 std = itv->tuner_std;
1015 else
1016 std = V4L2_STD_ALL;
1017 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
1018 itv->streams[i].vdev->tvnorms = std;
1019
Hans Verkuil3f038d82008-05-29 16:43:54 -03001020 /* prevent others from messing with the streams until
1021 we're finished changing inputs. */
1022 ivtv_mute(itv);
1023 ivtv_video_set_io(itv);
1024 ivtv_audio_set_io(itv);
1025 ivtv_unmute(itv);
1026
1027 return 0;
1028}
1029
1030static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1031{
Hans Verkuil2f824412011-03-12 06:43:28 -03001032 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001033
1034 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1035 return -EINVAL;
1036
1037 *i = itv->active_output;
1038
1039 return 0;
1040}
1041
1042static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1043{
Hans Verkuil2f824412011-03-12 06:43:28 -03001044 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001045
1046 if (outp >= itv->card->nof_outputs)
1047 return -EINVAL;
1048
1049 if (outp == itv->active_output) {
1050 IVTV_DEBUG_INFO("Output unchanged\n");
1051 return 0;
1052 }
1053 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1054 itv->active_output, outp);
1055
1056 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001057 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1058 SAA7127_INPUT_TYPE_NORMAL,
1059 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001060
1061 return 0;
1062}
1063
1064static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1065{
Hans Verkuil2f824412011-03-12 06:43:28 -03001066 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001067 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001068
Hans Verkuildff274f2012-10-01 06:45:36 -03001069 if (s->vdev->vfl_dir)
1070 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001071 if (vf->tuner != 0)
1072 return -EINVAL;
1073
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001074 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001075 return 0;
1076}
1077
1078int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1079{
Hans Verkuil2f824412011-03-12 06:43:28 -03001080 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001081 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001082
Hans Verkuildff274f2012-10-01 06:45:36 -03001083 if (s->vdev->vfl_dir)
1084 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001085 if (vf->tuner != 0)
1086 return -EINVAL;
1087
1088 ivtv_mute(itv);
1089 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001090 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001091 ivtv_unmute(itv);
1092 return 0;
1093}
1094
1095static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1096{
Hans Verkuil2f824412011-03-12 06:43:28 -03001097 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001098
1099 *std = itv->std;
1100 return 0;
1101}
1102
Ian Armstrongc5874c92011-05-29 21:33:17 -03001103void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001104{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001105 itv->std = *std;
1106 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001107 itv->is_50hz = !itv->is_60hz;
1108 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1109 itv->cxhdl.width = 720;
1110 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001111 itv->vbi.count = itv->is_50hz ? 18 : 12;
1112 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1113 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1114
1115 if (itv->hw_flags & IVTV_HW_CX25840)
1116 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1117
Hans Verkuil3f038d82008-05-29 16:43:54 -03001118 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001119 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001120}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001121
Ian Armstrongc5874c92011-05-29 21:33:17 -03001122void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1123{
1124 struct yuv_playback_info *yi = &itv->yuv_info;
1125 DEFINE_WAIT(wait);
1126 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001127
Ian Armstrongc5874c92011-05-29 21:33:17 -03001128 /* set display standard */
1129 itv->std_out = *std;
1130 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1131 itv->is_out_50hz = !itv->is_out_60hz;
1132 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001133
Ian Armstrongc5874c92011-05-29 21:33:17 -03001134 /*
1135 * The next firmware call is time sensitive. Time it to
1136 * avoid risk of a hard lock, by trying to ensure the call
1137 * happens within the first 100 lines of the top field.
1138 * Make 4 attempts to sync to the decoder before giving up.
1139 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001140 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001141 for (f = 0; f < 4; f++) {
1142 prepare_to_wait(&itv->vsync_waitq, &wait,
1143 TASK_UNINTERRUPTIBLE);
1144 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1145 break;
1146 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001147 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001148 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001149 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001150
1151 if (f == 4)
1152 IVTV_WARN("Mode change failed to sync to decoder\n");
1153
1154 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1155 itv->main_rect.left = 0;
1156 itv->main_rect.top = 0;
1157 itv->main_rect.width = 720;
1158 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1159 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1160 720, itv->main_rect.height, 0, 0);
1161 yi->main_rect = itv->main_rect;
1162 if (!itv->osd_info) {
1163 yi->osd_full_w = 720;
1164 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1165 }
1166}
1167
1168int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1169{
1170 struct ivtv *itv = fh2id(fh)->itv;
1171
1172 if ((*std & V4L2_STD_ALL) == 0)
1173 return -EINVAL;
1174
1175 if (*std == itv->std)
1176 return 0;
1177
1178 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1179 atomic_read(&itv->capturing) > 0 ||
1180 atomic_read(&itv->decoding) > 0) {
1181 /* Switching standard would mess with already running
1182 streams, prevent that by returning EBUSY. */
1183 return -EBUSY;
1184 }
1185
1186 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1187 (unsigned long long)itv->std);
1188
1189 ivtv_s_std_enc(itv, std);
1190 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1191 ivtv_s_std_dec(itv, std);
1192
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001193 return 0;
1194}
1195
Hans Verkuil3f038d82008-05-29 16:43:54 -03001196static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001197{
Hans Verkuil2f824412011-03-12 06:43:28 -03001198 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001199 struct ivtv *itv = id->itv;
1200
1201 if (vt->index != 0)
1202 return -EINVAL;
1203
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001204 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001205
1206 return 0;
1207}
1208
1209static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1210{
Hans Verkuil2f824412011-03-12 06:43:28 -03001211 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001212
1213 if (vt->index != 0)
1214 return -EINVAL;
1215
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001216 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001217
Hans Verkuild118e292011-06-25 10:28:21 -03001218 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001219 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001220 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001221 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001222 return 0;
1223}
1224
1225static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1226{
Hans Verkuil2f824412011-03-12 06:43:28 -03001227 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001228 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1229 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001230
Hans Verkuil79afcb12008-06-21 09:02:36 -03001231 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001232 for (f = 0; f < 2; f++) {
1233 for (l = 0; l < 24; l++) {
1234 if (valid_service_line(f, l, itv->is_50hz))
1235 cap->service_lines[f][l] = set;
1236 }
1237 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001238 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001239 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1240 return -EINVAL;
1241 if (itv->is_60hz) {
1242 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1243 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1244 } else {
1245 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1246 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1247 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001248 } else {
1249 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001250 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001251
1252 set = 0;
1253 for (f = 0; f < 2; f++)
1254 for (l = 0; l < 24; l++)
1255 set |= cap->service_lines[f][l];
1256 cap->service_set = set;
1257 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001258}
1259
1260static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1261{
Hans Verkuil2f824412011-03-12 06:43:28 -03001262 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001263 struct v4l2_enc_idx_entry *e = idx->entry;
1264 int entries;
1265 int i;
1266
1267 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1268 IVTV_MAX_PGM_INDEX;
1269 if (entries > V4L2_ENC_IDX_ENTRIES)
1270 entries = V4L2_ENC_IDX_ENTRIES;
1271 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001272 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1273 if (!atomic_read(&itv->capturing))
1274 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001275 for (i = 0; i < entries; i++) {
1276 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1277 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1278 idx->entries++;
1279 e++;
1280 }
1281 }
1282 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1283 return 0;
1284}
1285
1286static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1287{
Hans Verkuil2f824412011-03-12 06:43:28 -03001288 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001289 struct ivtv *itv = id->itv;
1290
Hans Verkuil3f038d82008-05-29 16:43:54 -03001291
1292 switch (enc->cmd) {
1293 case V4L2_ENC_CMD_START:
1294 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1295 enc->flags = 0;
1296 return ivtv_start_capture(id);
1297
1298 case V4L2_ENC_CMD_STOP:
1299 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1300 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1301 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1302 return 0;
1303
1304 case V4L2_ENC_CMD_PAUSE:
1305 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1306 enc->flags = 0;
1307
1308 if (!atomic_read(&itv->capturing))
1309 return -EPERM;
1310 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1311 return 0;
1312
1313 ivtv_mute(itv);
1314 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1315 break;
1316
1317 case V4L2_ENC_CMD_RESUME:
1318 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1319 enc->flags = 0;
1320
1321 if (!atomic_read(&itv->capturing))
1322 return -EPERM;
1323
1324 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1325 return 0;
1326
1327 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1328 ivtv_unmute(itv);
1329 break;
1330 default:
1331 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1332 return -EINVAL;
1333 }
1334
1335 return 0;
1336}
1337
1338static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1339{
Hans Verkuil2f824412011-03-12 06:43:28 -03001340 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001341
Hans Verkuil3f038d82008-05-29 16:43:54 -03001342 switch (enc->cmd) {
1343 case V4L2_ENC_CMD_START:
1344 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1345 enc->flags = 0;
1346 return 0;
1347
1348 case V4L2_ENC_CMD_STOP:
1349 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1350 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1351 return 0;
1352
1353 case V4L2_ENC_CMD_PAUSE:
1354 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1355 enc->flags = 0;
1356 return 0;
1357
1358 case V4L2_ENC_CMD_RESUME:
1359 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1360 enc->flags = 0;
1361 return 0;
1362 default:
1363 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1364 return -EINVAL;
1365 }
1366}
1367
1368static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1369{
Hans Verkuil2f824412011-03-12 06:43:28 -03001370 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001371 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001372 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001373
Hans Verkuil3f038d82008-05-29 16:43:54 -03001374 int pixfmt;
1375 static u32 pixel_format[16] = {
1376 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1377 V4L2_PIX_FMT_RGB565,
1378 V4L2_PIX_FMT_RGB555,
1379 V4L2_PIX_FMT_RGB444,
1380 V4L2_PIX_FMT_RGB32,
1381 0,
1382 0,
1383 0,
1384 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1385 V4L2_PIX_FMT_YUV565,
1386 V4L2_PIX_FMT_YUV555,
1387 V4L2_PIX_FMT_YUV444,
1388 V4L2_PIX_FMT_YUV32,
1389 0,
1390 0,
1391 0,
1392 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001393
Hans Verkuil3f038d82008-05-29 16:43:54 -03001394 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1395 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001396 if (!itv->osd_video_pbase)
1397 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001398
Hans Verkuil3f038d82008-05-29 16:43:54 -03001399 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1400 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001401
Hans Verkuil3f038d82008-05-29 16:43:54 -03001402 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1403 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1404 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001405
Hans Verkuil3f038d82008-05-29 16:43:54 -03001406 fb->fmt.pixelformat = pixel_format[pixfmt];
1407 fb->fmt.width = itv->osd_rect.width;
1408 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001409 fb->fmt.field = V4L2_FIELD_INTERLACED;
1410 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001411 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1412 fb->fmt.field = V4L2_FIELD_INTERLACED;
1413 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001414 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1415 fb->fmt.bytesperline *= 2;
1416 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1417 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1418 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001419 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001420 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001421 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001422
Hans Verkuil3f038d82008-05-29 16:43:54 -03001423 if (itv->osd_chroma_key_state)
1424 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001425
Hans Verkuil3f038d82008-05-29 16:43:54 -03001426 if (itv->osd_global_alpha_state)
1427 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001428
Ian Armstrongec9faa12008-10-06 03:06:08 -03001429 if (yi->track_osd)
1430 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1431
Hans Verkuil3f038d82008-05-29 16:43:54 -03001432 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001433
Hans Verkuil3f038d82008-05-29 16:43:54 -03001434 /* no local alpha for RGB565 or unknown formats */
1435 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001436 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001437
Hans Verkuil3f038d82008-05-29 16:43:54 -03001438 /* 16-bit formats have inverted local alpha */
1439 if (pixfmt == 2 || pixfmt == 3)
1440 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1441 else
1442 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001443
Hans Verkuil3f038d82008-05-29 16:43:54 -03001444 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001445 /* 16-bit formats have inverted local alpha */
1446 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001447 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001448 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001449 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001450 }
1451
Hans Verkuil3f038d82008-05-29 16:43:54 -03001452 return 0;
1453}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001454
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001455static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001456{
Hans Verkuil2f824412011-03-12 06:43:28 -03001457 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001458 struct ivtv *itv = id->itv;
1459 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001460
Hans Verkuil3f038d82008-05-29 16:43:54 -03001461 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001462 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001463 if (!itv->osd_video_pbase)
1464 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001465
1466 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1467 itv->osd_local_alpha_state =
1468 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1469 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1470 ivtv_set_osd_alpha(itv);
1471 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001472 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001473}
1474
1475static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1476{
Hans Verkuil2f824412011-03-12 06:43:28 -03001477 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001478 struct ivtv *itv = id->itv;
1479
1480 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1481 return -EINVAL;
1482
1483 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1484
1485 return 0;
1486}
1487
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001488static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001489{
1490 switch (sub->type) {
1491 case V4L2_EVENT_VSYNC:
1492 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001493 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001494 case V4L2_EVENT_CTRL:
1495 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001496 default:
1497 return -EINVAL;
1498 }
Hans Verkuil09250192010-03-27 14:10:13 -03001499}
1500
Hans Verkuil3f038d82008-05-29 16:43:54 -03001501static int ivtv_log_status(struct file *file, void *fh)
1502{
Hans Verkuil2f824412011-03-12 06:43:28 -03001503 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001504 u32 data[CX2341X_MBOX_MAX_DATA];
1505
1506 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1507 struct v4l2_input vidin;
1508 struct v4l2_audio audin;
1509 int i;
1510
Hans Verkuil3f038d82008-05-29 16:43:54 -03001511 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1512 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1513 struct tveeprom tv;
1514
1515 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001516 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001517 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001518 ivtv_get_input(itv, itv->active_input, &vidin);
1519 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1520 IVTV_INFO("Video Input: %s\n", vidin.name);
1521 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1522 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1523 if (has_output) {
1524 struct v4l2_output vidout;
1525 struct v4l2_audioout audout;
1526 int mode = itv->output_mode;
1527 static const char * const output_modes[5] = {
1528 "None",
1529 "MPEG Streaming",
1530 "YUV Streaming",
1531 "YUV Frames",
1532 "Passthrough",
1533 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001534 static const char * const alpha_mode[4] = {
1535 "None",
1536 "Global",
1537 "Local",
1538 "Global and Local"
1539 };
1540 static const char * const pixel_format[16] = {
1541 "ARGB Indexed",
1542 "RGB 5:6:5",
1543 "ARGB 1:5:5:5",
1544 "ARGB 1:4:4:4",
1545 "ARGB 8:8:8:8",
1546 "5",
1547 "6",
1548 "7",
1549 "AYUV Indexed",
1550 "YUV 5:6:5",
1551 "AYUV 1:5:5:5",
1552 "AYUV 1:4:4:4",
1553 "AYUV 8:8:8:8",
1554 "13",
1555 "14",
1556 "15",
1557 };
1558
1559 ivtv_get_output(itv, itv->active_output, &vidout);
1560 ivtv_get_audio_output(itv, 0, &audout);
1561 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001562 if (mode < 0 || mode > OUT_PASSTHROUGH)
1563 mode = OUT_NONE;
1564 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1565 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1566 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1567 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1568 data[0] & 1 ? "On" : "Off",
1569 alpha_mode[(data[0] >> 1) & 0x3],
1570 pixel_format[(data[0] >> 3) & 0xf]);
1571 }
1572 IVTV_INFO("Tuner: %s\n",
1573 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001574 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001575 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1576 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1577 struct ivtv_stream *s = &itv->streams[i];
1578
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001579 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001580 continue;
1581 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1582 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1583 (s->buffers * s->buf_size) / 1024, s->buffers);
1584 }
1585
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001586 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1587 (long long)itv->mpg_data_received,
1588 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001589 return 0;
1590}
1591
Hans Verkuilda8ec562011-11-24 09:58:53 -03001592static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1593{
1594 struct ivtv_open_id *id = fh2id(file->private_data);
1595 struct ivtv *itv = id->itv;
1596
1597 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1598 return ivtv_video_command(itv, id, dec, false);
1599}
1600
1601static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1602{
1603 struct ivtv_open_id *id = fh2id(file->private_data);
1604 struct ivtv *itv = id->itv;
1605
1606 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1607 return ivtv_video_command(itv, id, dec, true);
1608}
1609
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001610static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001611{
Hans Verkuil09250192010-03-27 14:10:13 -03001612 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001613 struct ivtv *itv = id->itv;
1614 int nonblocking = filp->f_flags & O_NONBLOCK;
1615 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001616 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001617
1618 switch (cmd) {
1619 case IVTV_IOC_DMA_FRAME: {
1620 struct ivtv_dma_frame *args = arg;
1621
1622 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1623 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1624 return -EINVAL;
1625 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1626 return -EINVAL;
1627 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1628 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001629 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001630 return -EBUSY;
1631 }
1632 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1633 ivtv_release_stream(s);
1634 return -EBUSY;
1635 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001636 /* Mark that this file handle started the UDMA_YUV mode */
1637 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001638 if (args->y_source == NULL)
1639 return 0;
1640 return ivtv_yuv_prep_frame(itv, args);
1641 }
1642
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001643 case IVTV_IOC_PASSTHROUGH_MODE:
1644 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1645 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1646 return -EINVAL;
1647 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1648
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001649 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001650 s64 *pts = arg;
1651 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001652
1653 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1654 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1655 *pts = s->dma_pts;
1656 break;
1657 }
1658 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1659 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001660 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001661 }
1662
1663 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001664 s64 *frame = arg;
1665 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001666
1667 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1668 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1669 *frame = 0;
1670 break;
1671 }
1672 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1673 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001674 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001675 }
1676
1677 case VIDEO_PLAY: {
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_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001681 memset(&dc, 0, sizeof(dc));
1682 dc.cmd = V4L2_DEC_CMD_START;
1683 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001684 }
1685
1686 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001687 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001688
1689 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001690 memset(&dc, 0, sizeof(dc));
1691 dc.cmd = V4L2_DEC_CMD_STOP;
1692 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1693 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001694 }
1695
1696 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001697 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001698
1699 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001700 memset(&dc, 0, sizeof(dc));
1701 dc.cmd = V4L2_DEC_CMD_PAUSE;
1702 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001703 }
1704
1705 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001706 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001707
1708 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001709 memset(&dc, 0, sizeof(dc));
1710 dc.cmd = V4L2_DEC_CMD_RESUME;
1711 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001712 }
1713
1714 case VIDEO_COMMAND:
1715 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001716 /* Note: struct v4l2_decoder_cmd has the same layout as
1717 struct video_command */
1718 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001719 int try = (cmd == VIDEO_TRY_COMMAND);
1720
1721 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001722 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001723 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001724 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1725 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001726 }
1727
1728 case VIDEO_GET_EVENT: {
1729 struct video_event *ev = arg;
1730 DEFINE_WAIT(wait);
1731
1732 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1733 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1734 return -EINVAL;
1735 memset(ev, 0, sizeof(*ev));
1736 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1737
1738 while (1) {
1739 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1740 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1741 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1742 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001743 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1744 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1745 if (itv->output_mode == OUT_UDMA_YUV &&
1746 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1747 IVTV_YUV_MODE_PROGRESSIVE) {
1748 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1749 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001750 }
1751 if (ev->type)
1752 return 0;
1753 if (nonblocking)
1754 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001755 /* Wait for event. Note that serialize_lock is locked,
1756 so to allow other processes to access the driver while
1757 we are waiting unlock first and later lock again. */
1758 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001759 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001760 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1761 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001762 schedule();
1763 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001764 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001765 if (signal_pending(current)) {
1766 /* return if a signal was received */
1767 IVTV_DEBUG_INFO("User stopped wait for event\n");
1768 return -EINTR;
1769 }
1770 }
1771 break;
1772 }
1773
Hans Verkuilce680252010-04-06 15:58:53 -03001774 case VIDEO_SELECT_SOURCE:
1775 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1776 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1777 return -EINVAL;
1778 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1779
1780 case AUDIO_SET_MUTE:
1781 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1782 itv->speed_mute_audio = iarg;
1783 return 0;
1784
1785 case AUDIO_CHANNEL_SELECT:
1786 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1787 if (iarg > AUDIO_STEREO_SWAPPED)
1788 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001789 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001790
1791 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1792 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1793 if (iarg > AUDIO_STEREO_SWAPPED)
1794 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001795 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001796
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001797 default:
1798 return -EINVAL;
1799 }
1800 return 0;
1801}
1802
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001803static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1804 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001805{
Hans Verkuil2f824412011-03-12 06:43:28 -03001806 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001807
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001808 if (!valid_prio) {
1809 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001810 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001811 case VIDEO_PLAY:
1812 case VIDEO_STOP:
1813 case VIDEO_FREEZE:
1814 case VIDEO_CONTINUE:
1815 case VIDEO_COMMAND:
1816 case VIDEO_SELECT_SOURCE:
1817 case AUDIO_SET_MUTE:
1818 case AUDIO_CHANNEL_SELECT:
1819 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1820 return -EBUSY;
1821 }
1822 }
1823
Hans Verkuild46c17d2007-03-10 17:59:15 -03001824 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001825 case VIDIOC_INT_RESET: {
1826 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001827
Hans Verkuil3f038d82008-05-29 16:43:54 -03001828 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1829 ivtv_reset_ir_gpio(itv);
1830 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001831 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001832 break;
1833 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001834
Hans Verkuilac9575f2009-02-14 19:58:33 -03001835 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001836 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001837 case VIDEO_GET_PTS:
1838 case VIDEO_GET_FRAME_COUNT:
1839 case VIDEO_GET_EVENT:
1840 case VIDEO_PLAY:
1841 case VIDEO_STOP:
1842 case VIDEO_FREEZE:
1843 case VIDEO_CONTINUE:
1844 case VIDEO_COMMAND:
1845 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001846 case VIDEO_SELECT_SOURCE:
1847 case AUDIO_SET_MUTE:
1848 case AUDIO_CHANNEL_SELECT:
1849 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001850 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1851
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001852 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001853 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001854 }
1855 return 0;
1856}
1857
Hans Verkuila3998102008-07-21 02:57:38 -03001858static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1859 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001860 .vidioc_s_audio = ivtv_s_audio,
1861 .vidioc_g_audio = ivtv_g_audio,
1862 .vidioc_enumaudio = ivtv_enumaudio,
1863 .vidioc_s_audout = ivtv_s_audout,
1864 .vidioc_g_audout = ivtv_g_audout,
1865 .vidioc_enum_input = ivtv_enum_input,
1866 .vidioc_enum_output = ivtv_enum_output,
1867 .vidioc_enumaudout = ivtv_enumaudout,
1868 .vidioc_cropcap = ivtv_cropcap,
1869 .vidioc_s_crop = ivtv_s_crop,
1870 .vidioc_g_crop = ivtv_g_crop,
1871 .vidioc_g_input = ivtv_g_input,
1872 .vidioc_s_input = ivtv_s_input,
1873 .vidioc_g_output = ivtv_g_output,
1874 .vidioc_s_output = ivtv_s_output,
1875 .vidioc_g_frequency = ivtv_g_frequency,
1876 .vidioc_s_frequency = ivtv_s_frequency,
1877 .vidioc_s_tuner = ivtv_s_tuner,
1878 .vidioc_g_tuner = ivtv_g_tuner,
1879 .vidioc_g_enc_index = ivtv_g_enc_index,
1880 .vidioc_g_fbuf = ivtv_g_fbuf,
1881 .vidioc_s_fbuf = ivtv_s_fbuf,
1882 .vidioc_g_std = ivtv_g_std,
1883 .vidioc_s_std = ivtv_s_std,
1884 .vidioc_overlay = ivtv_overlay,
1885 .vidioc_log_status = ivtv_log_status,
1886 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1887 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1888 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001889 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1890 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001891 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1892 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1893 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1894 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1895 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1896 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1897 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1898 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1899 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1900 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1901 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1902 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1903 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1904 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1905 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1906 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1907 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1908 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1909 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1910 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1911 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1912#ifdef CONFIG_VIDEO_ADV_DEBUG
1913 .vidioc_g_register = ivtv_g_register,
1914 .vidioc_s_register = ivtv_s_register,
1915#endif
1916 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001917 .vidioc_subscribe_event = ivtv_subscribe_event,
1918 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001919};
1920
Hans Verkuil3f038d82008-05-29 16:43:54 -03001921void ivtv_set_funcs(struct video_device *vdev)
1922{
Hans Verkuila3998102008-07-21 02:57:38 -03001923 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001924}