blob: 3b32518dbc02b1997433a6d174aa85ac113d9416 [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 Verkuilc5c46f22012-09-05 12:27:19 -0300401 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300402 return 0;
403 }
404
Hans Verkuil4ff07902010-03-14 12:18:18 -0300405 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300406 vbifmt->service_set = ivtv_get_service_set(vbifmt);
407 return 0;
408}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300409
Hans Verkuil3f038d82008-05-29 16:43:54 -0300410static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
411{
Hans Verkuil2f824412011-03-12 06:43:28 -0300412 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300413 struct ivtv *itv = id->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300414 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300415
Hans Verkuil3f038d82008-05-29 16:43:54 -0300416 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300417 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300418 pixfmt->width = itv->main_rect.width;
419 pixfmt->height = itv->main_rect.height;
420 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
421 pixfmt->field = V4L2_FIELD_INTERLACED;
422 pixfmt->priv = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300423 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
424 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
425 case IVTV_YUV_MODE_INTERLACED:
Hans Verkuile88360c2008-06-21 08:00:56 -0300426 pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
Hans Verkuil3f038d82008-05-29 16:43:54 -0300427 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
428 break;
429 case IVTV_YUV_MODE_PROGRESSIVE:
Hans Verkuile88360c2008-06-21 08:00:56 -0300430 pixfmt->field = V4L2_FIELD_NONE;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300431 break;
432 default:
Hans Verkuile88360c2008-06-21 08:00:56 -0300433 pixfmt->field = V4L2_FIELD_ANY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300434 break;
435 }
Hans Verkuile88360c2008-06-21 08:00:56 -0300436 pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
437 pixfmt->bytesperline = 720;
438 pixfmt->width = itv->yuv_info.v4l2_src_w;
439 pixfmt->height = itv->yuv_info.v4l2_src_h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300440 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
Hans Verkuile88360c2008-06-21 08:00:56 -0300441 pixfmt->sizeimage =
442 1080 * ((pixfmt->height + 31) & ~31);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300443 } else {
Hans Verkuile88360c2008-06-21 08:00:56 -0300444 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
445 pixfmt->sizeimage = 128 * 1024;
446 pixfmt->bytesperline = 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300447 }
448 return 0;
449}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300450
Hans Verkuil3f038d82008-05-29 16:43:54 -0300451static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
452{
Hans Verkuil2f824412011-03-12 06:43:28 -0300453 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300454 struct v4l2_window *winfmt = &fmt->fmt.win;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300455
456 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
457 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300458 winfmt->chromakey = itv->osd_chroma_key;
459 winfmt->global_alpha = itv->osd_global_alpha;
460 winfmt->field = V4L2_FIELD_INTERLACED;
461 winfmt->clips = NULL;
462 winfmt->clipcount = 0;
463 winfmt->bitmap = NULL;
464 winfmt->w.top = winfmt->w.left = 0;
465 winfmt->w.width = itv->osd_rect.width;
466 winfmt->w.height = itv->osd_rect.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300467 return 0;
468}
469
470static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
471{
472 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
473}
474
475static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
476{
Hans Verkuil2f824412011-03-12 06:43:28 -0300477 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300478 struct ivtv *itv = id->itv;
479 int w = fmt->fmt.pix.width;
480 int h = fmt->fmt.pix.height;
Hans Verkuila4a78712009-02-06 15:31:59 -0300481 int min_h = 2;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300482
483 w = min(w, 720);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300484 w = max(w, 2);
Hans Verkuila4a78712009-02-06 15:31:59 -0300485 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
486 /* YUV height must be a multiple of 32 */
487 h &= ~0x1f;
488 min_h = 32;
489 }
Hans Verkuil3f038d82008-05-29 16:43:54 -0300490 h = min(h, itv->is_50hz ? 576 : 480);
Hans Verkuila4a78712009-02-06 15:31:59 -0300491 h = max(h, min_h);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300492 ivtv_g_fmt_vid_cap(file, fh, fmt);
493 fmt->fmt.pix.width = w;
494 fmt->fmt.pix.height = h;
495 return 0;
496}
497
498static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
499{
500 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
501}
502
503static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
504{
505 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300506 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300507 struct ivtv *itv = id->itv;
508
509 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
510 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300511
512 /* set sliced VBI capture format */
513 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
Hans Verkuile88360c2008-06-21 08:00:56 -0300514 vbifmt->reserved[0] = 0;
515 vbifmt->reserved[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300516
517 if (vbifmt->service_set)
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300518 ivtv_expand_service_set(vbifmt, itv->is_50hz);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300519 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300520 vbifmt->service_set = ivtv_get_service_set(vbifmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300521 return 0;
522}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300523
Hans Verkuil3f038d82008-05-29 16:43:54 -0300524static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
525{
Hans Verkuil2f824412011-03-12 06:43:28 -0300526 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuileffc3462008-09-06 08:24:37 -0300527 s32 w = fmt->fmt.pix.width;
528 s32 h = fmt->fmt.pix.height;
529 int field = fmt->fmt.pix.field;
530 int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300531
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300532 w = min(w, 720);
533 w = max(w, 2);
Hans Verkuil962d6992008-10-11 09:00:39 -0300534 /* Why can the height be 576 even when the output is NTSC?
535
536 Internally the buffers of the PVR350 are always set to 720x576. The
537 decoded video frame will always be placed in the top left corner of
538 this buffer. For any video which is not 720x576, the buffer will
539 then be cropped to remove the unused right and lower areas, with
540 the remaining image being scaled by the hardware to fit the display
541 area. The video can be scaled both up and down, so a 720x480 video
542 can be displayed full-screen on PAL and a 720x576 video can be
543 displayed without cropping on NTSC.
544
545 Note that the scaling only occurs on the video stream, the osd
546 resolution is locked to the broadcast standard and not scaled.
547
548 Thanks to Ian Armstrong for this explanation. */
549 h = min(h, 576);
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300550 h = max(h, 2);
551 if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300552 fmt->fmt.pix.field = field;
Hans Verkuileffc3462008-09-06 08:24:37 -0300553 fmt->fmt.pix.width = w;
554 fmt->fmt.pix.height = h;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300555 return ret;
556}
557
558static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
559{
Hans Verkuil2f824412011-03-12 06:43:28 -0300560 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuile88360c2008-06-21 08:00:56 -0300561 u32 chromakey = fmt->fmt.win.chromakey;
562 u8 global_alpha = fmt->fmt.win.global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300563
564 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
565 return -EINVAL;
Hans Verkuile88360c2008-06-21 08:00:56 -0300566 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
567 fmt->fmt.win.chromakey = chromakey;
568 fmt->fmt.win.global_alpha = global_alpha;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300569 return 0;
570}
571
572static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
573{
574 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
575}
576
577static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
578{
Hans Verkuil2f824412011-03-12 06:43:28 -0300579 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300580 struct ivtv *itv = id->itv;
Hans Verkuil475977a2010-05-08 16:28:51 -0300581 struct v4l2_mbus_framefmt mbus_fmt;
Hans Verkuileffc3462008-09-06 08:24:37 -0300582 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300583 int w = fmt->fmt.pix.width;
584 int h = fmt->fmt.pix.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300585
586 if (ret)
587 return ret;
588
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300589 if (itv->cxhdl.width == w && itv->cxhdl.height == h)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300590 return 0;
591
592 if (atomic_read(&itv->capturing) > 0)
593 return -EBUSY;
594
Hans Verkuilf7b80e62010-06-27 06:07:26 -0300595 itv->cxhdl.width = w;
596 itv->cxhdl.height = h;
597 if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300598 fmt->fmt.pix.width /= 2;
Hans Verkuil475977a2010-05-08 16:28:51 -0300599 mbus_fmt.width = fmt->fmt.pix.width;
600 mbus_fmt.height = h;
601 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
602 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300603 return ivtv_g_fmt_vid_cap(file, fh, fmt);
604}
605
606static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
607{
Hans Verkuil2f824412011-03-12 06:43:28 -0300608 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300609
Hans Verkuila8b86432008-10-04 08:05:30 -0300610 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
611 return -EBUSY;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300612 itv->vbi.sliced_in->service_set = 0;
Hans Verkuila8b86432008-10-04 08:05:30 -0300613 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300614 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300615 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
616}
617
618static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
619{
620 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
Hans Verkuil2f824412011-03-12 06:43:28 -0300621 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300622 struct ivtv *itv = id->itv;
623 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
624
625 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
626 return ret;
627
Hans Verkuil854ad9a2008-09-06 09:56:17 -0300628 check_service_set(vbifmt, itv->is_50hz);
Hans Verkuila8b86432008-10-04 08:05:30 -0300629 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300630 return -EBUSY;
Hans Verkuila8b86432008-10-04 08:05:30 -0300631 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
Hans Verkuil4ff07902010-03-14 12:18:18 -0300632 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300633 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
634 return 0;
635}
636
Hans Verkuil3f038d82008-05-29 16:43:54 -0300637static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300638{
Hans Verkuil2f824412011-03-12 06:43:28 -0300639 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300640 struct ivtv *itv = id->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300641 struct yuv_playback_info *yi = &itv->yuv_info;
642 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300643
Hans Verkuil3f038d82008-05-29 16:43:54 -0300644 if (ret)
645 return ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300646
Hans Verkuil3f038d82008-05-29 16:43:54 -0300647 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
648 return 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300649
Hans Verkuil3f038d82008-05-29 16:43:54 -0300650 /* Return now if we already have some frame data */
651 if (yi->stream_size)
652 return -EBUSY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300653
Hans Verkuil3f038d82008-05-29 16:43:54 -0300654 yi->v4l2_src_w = fmt->fmt.pix.width;
655 yi->v4l2_src_h = fmt->fmt.pix.height;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300656
Hans Verkuil3f038d82008-05-29 16:43:54 -0300657 switch (fmt->fmt.pix.field) {
658 case V4L2_FIELD_NONE:
659 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300661 case V4L2_FIELD_ANY:
662 yi->lace_mode = IVTV_YUV_MODE_AUTO;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300663 break;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300664 case V4L2_FIELD_INTERLACED_BT:
665 yi->lace_mode =
666 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
667 break;
668 case V4L2_FIELD_INTERLACED_TB:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300669 default:
Hans Verkuil3f038d82008-05-29 16:43:54 -0300670 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
671 break;
672 }
673 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
674
675 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
676 itv->dma_data_req_size =
677 1080 * ((yi->v4l2_src_h + 31) & ~31);
678
Hans Verkuil3f038d82008-05-29 16:43:54 -0300679 return 0;
680}
681
682static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
683{
Hans Verkuil2f824412011-03-12 06:43:28 -0300684 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300685 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
686
687 if (ret == 0) {
688 itv->osd_chroma_key = fmt->fmt.win.chromakey;
689 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
690 ivtv_set_osd_alpha(itv);
691 }
692 return ret;
693}
694
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300695static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300696{
Hans Verkuil2f824412011-03-12 06:43:28 -0300697 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300698
699 chip->ident = V4L2_IDENT_NONE;
700 chip->revision = 0;
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300701 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
702 if (v4l2_chip_match_host(&chip->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300703 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
704 return 0;
705 }
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300706 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
707 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300708 return -EINVAL;
709 /* TODO: is this correct? */
710 return ivtv_call_all_err(itv, core, g_chip_ident, chip);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300711}
712
Hans Verkuil36ecd492008-06-25 06:00:17 -0300713#ifdef CONFIG_VIDEO_ADV_DEBUG
714static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
715{
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300716 struct v4l2_dbg_register *regs = arg;
Hans Verkuiladb65bc2008-06-25 06:32:44 -0300717 volatile u8 __iomem *reg_start;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300718
719 if (!capable(CAP_SYS_ADMIN))
720 return -EPERM;
721 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
722 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
723 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
724 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
725 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
Roel Kluin223ffe52009-05-02 16:38:47 -0300726 else if (regs->reg < IVTV_ENCODER_SIZE)
Hans Verkuil36ecd492008-06-25 06:00:17 -0300727 reg_start = itv->enc_mem;
728 else
729 return -EINVAL;
730
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300731 regs->size = 4;
Hans Verkuil36ecd492008-06-25 06:00:17 -0300732 if (cmd == VIDIOC_DBG_G_REGISTER)
733 regs->val = readl(regs->reg + reg_start);
734 else
735 writel(regs->val, regs->reg + reg_start);
Hans Verkuil36ecd492008-06-25 06:00:17 -0300736 return 0;
737}
738
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300739static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300740{
Hans Verkuil2f824412011-03-12 06:43:28 -0300741 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300742
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300743 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300744 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300745 /* TODO: subdev errors should not be ignored, this should become a
746 subdev helper function. */
747 ivtv_call_all(itv, core, g_register, reg);
748 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300749}
750
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300751static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300752{
Hans Verkuil2f824412011-03-12 06:43:28 -0300753 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300754
Hans Verkuilaecde8b2008-12-30 07:14:19 -0300755 if (v4l2_chip_match_host(&reg->match))
Hans Verkuil3f038d82008-05-29 16:43:54 -0300756 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300757 /* TODO: subdev errors should not be ignored, this should become a
758 subdev helper function. */
759 ivtv_call_all(itv, core, s_register, reg);
760 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300761}
Hans Verkuil36ecd492008-06-25 06:00:17 -0300762#endif
Hans Verkuil3f038d82008-05-29 16:43:54 -0300763
Hans Verkuil3f038d82008-05-29 16:43:54 -0300764static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
765{
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300766 struct ivtv_open_id *id = fh2id(file->private_data);
767 struct ivtv *itv = id->itv;
768 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -0300769
Hans Verkuil3f038d82008-05-29 16:43:54 -0300770 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
771 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
Hans Verkuil8ac05ae2009-02-07 07:02:27 -0300772 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
Hans Verkuild0c8b2d2011-11-07 07:25:10 -0300773 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
774 vcap->device_caps = s->caps;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300775 return 0;
776}
777
778static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
779{
Hans Verkuil2f824412011-03-12 06:43:28 -0300780 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300781
782 return ivtv_get_audio_input(itv, vin->index, vin);
783}
784
785static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
786{
Hans Verkuil2f824412011-03-12 06:43:28 -0300787 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300788
789 vin->index = itv->audio_input;
790 return ivtv_get_audio_input(itv, vin->index, vin);
791}
792
Hans Verkuil0e8025b2012-09-04 11:59:31 -0300793static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300794{
Hans Verkuil2f824412011-03-12 06:43:28 -0300795 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300796
797 if (vout->index >= itv->nof_audio_inputs)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300798 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300799
800 itv->audio_input = vout->index;
801 ivtv_audio_set_io(itv);
802
803 return 0;
804}
805
806static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
807{
Hans Verkuil2f824412011-03-12 06:43:28 -0300808 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300809
810 /* set it to defaults from our table */
811 return ivtv_get_audio_output(itv, vin->index, vin);
812}
813
814static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
815{
Hans Verkuil2f824412011-03-12 06:43:28 -0300816 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300817
818 vin->index = 0;
819 return ivtv_get_audio_output(itv, vin->index, vin);
820}
821
Hans Verkuilba9425b2012-09-04 12:03:49 -0300822static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300823{
Hans Verkuil2f824412011-03-12 06:43:28 -0300824 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300825
Hans Verkuilba9425b2012-09-04 12:03:49 -0300826 if (itv->card->video_outputs == NULL || vout->index != 0)
827 return -EINVAL;
828 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300829}
830
831static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
832{
Hans Verkuil2f824412011-03-12 06:43:28 -0300833 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300834
835 /* set it to defaults from our table */
836 return ivtv_get_input(itv, vin->index, vin);
837}
838
839static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
840{
Hans Verkuil2f824412011-03-12 06:43:28 -0300841 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300842
843 return ivtv_get_output(itv, vout->index, vout);
844}
845
846static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
847{
Hans Verkuil2f824412011-03-12 06:43:28 -0300848 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300849 struct ivtv *itv = id->itv;
850 struct yuv_playback_info *yi = &itv->yuv_info;
851 int streamtype;
852
853 streamtype = id->type;
854
855 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
856 return -EINVAL;
857 cropcap->bounds.top = cropcap->bounds.left = 0;
858 cropcap->bounds.width = 720;
859 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
860 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
861 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
862 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
863 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
864 if (yi->track_osd) {
865 cropcap->bounds.width = yi->osd_full_w;
866 cropcap->bounds.height = yi->osd_full_h;
867 } else {
868 cropcap->bounds.width = 720;
869 cropcap->bounds.height =
870 itv->is_out_50hz ? 576 : 480;
871 }
872 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
873 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
874 } else {
875 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
876 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
877 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
878 }
879 cropcap->defrect = cropcap->bounds;
880 return 0;
881}
882
Hans Verkuil4f9965942012-09-05 05:10:48 -0300883static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
Hans Verkuil3f038d82008-05-29 16:43:54 -0300884{
Hans Verkuil2f824412011-03-12 06:43:28 -0300885 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300886 struct ivtv *itv = id->itv;
887 struct yuv_playback_info *yi = &itv->yuv_info;
888 int streamtype;
889
890 streamtype = id->type;
891
Hans Verkuil3f038d82008-05-29 16:43:54 -0300892 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
893 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
894 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
895 yi->main_rect = crop->c;
896 return 0;
897 } else {
898 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
899 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
900 itv->main_rect = crop->c;
901 return 0;
902 }
903 }
904 return -EINVAL;
905 }
906 return -EINVAL;
907}
908
909static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
910{
Hans Verkuil2f824412011-03-12 06:43:28 -0300911 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -0300912 struct ivtv *itv = id->itv;
913 struct yuv_playback_info *yi = &itv->yuv_info;
914 int streamtype;
915
916 streamtype = id->type;
917
918 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
919 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
920 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
921 crop->c = yi->main_rect;
922 else
923 crop->c = itv->main_rect;
924 return 0;
925 }
926 return -EINVAL;
927}
928
929static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
930{
931 static struct v4l2_fmtdesc formats[] = {
932 { 0, 0, 0,
933 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
934 { 0, 0, 0, 0 }
935 },
936 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
937 "MPEG", V4L2_PIX_FMT_MPEG,
938 { 0, 0, 0, 0 }
939 }
940 };
941 enum v4l2_buf_type type = fmt->type;
942
943 if (fmt->index > 1)
944 return -EINVAL;
945
946 *fmt = formats[fmt->index];
947 fmt->type = type;
948 return 0;
949}
950
951static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
952{
Hans Verkuil2f824412011-03-12 06:43:28 -0300953 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300954
955 static struct v4l2_fmtdesc formats[] = {
956 { 0, 0, 0,
957 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
958 { 0, 0, 0, 0 }
959 },
960 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
961 "MPEG", V4L2_PIX_FMT_MPEG,
962 { 0, 0, 0, 0 }
963 }
964 };
965 enum v4l2_buf_type type = fmt->type;
966
967 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
968 return -EINVAL;
969
970 if (fmt->index > 1)
971 return -EINVAL;
972
973 *fmt = formats[fmt->index];
974 fmt->type = type;
975
976 return 0;
977}
978
979static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
980{
Hans Verkuil2f824412011-03-12 06:43:28 -0300981 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300982
983 *i = itv->active_input;
984
985 return 0;
986}
987
988int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
989{
Hans Verkuil2f824412011-03-12 06:43:28 -0300990 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuilf659f0e72012-09-05 08:56:55 -0300991 v4l2_std_id std;
992 int i;
Hans Verkuil3f038d82008-05-29 16:43:54 -0300993
994 if (inp < 0 || inp >= itv->nof_inputs)
995 return -EINVAL;
996
997 if (inp == itv->active_input) {
998 IVTV_DEBUG_INFO("Input unchanged\n");
999 return 0;
1000 }
1001
1002 if (atomic_read(&itv->capturing) > 0) {
1003 return -EBUSY;
1004 }
1005
1006 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
1007 itv->active_input, inp);
1008
1009 itv->active_input = inp;
1010 /* Set the audio input to whatever is appropriate for the
1011 input type. */
1012 itv->audio_input = itv->card->video_inputs[inp].audio_index;
1013
Hans Verkuilf659f0e72012-09-05 08:56:55 -03001014 if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
1015 std = itv->tuner_std;
1016 else
1017 std = V4L2_STD_ALL;
1018 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
1019 itv->streams[i].vdev->tvnorms = std;
1020
Hans Verkuil3f038d82008-05-29 16:43:54 -03001021 /* prevent others from messing with the streams until
1022 we're finished changing inputs. */
1023 ivtv_mute(itv);
1024 ivtv_video_set_io(itv);
1025 ivtv_audio_set_io(itv);
1026 ivtv_unmute(itv);
1027
1028 return 0;
1029}
1030
1031static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1032{
Hans Verkuil2f824412011-03-12 06:43:28 -03001033 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001034
1035 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1036 return -EINVAL;
1037
1038 *i = itv->active_output;
1039
1040 return 0;
1041}
1042
1043static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1044{
Hans Verkuil2f824412011-03-12 06:43:28 -03001045 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001046
1047 if (outp >= itv->card->nof_outputs)
1048 return -EINVAL;
1049
1050 if (outp == itv->active_output) {
1051 IVTV_DEBUG_INFO("Output unchanged\n");
1052 return 0;
1053 }
1054 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1055 itv->active_output, outp);
1056
1057 itv->active_output = outp;
Hans Verkuil5325b422009-04-02 11:26:22 -03001058 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
1059 SAA7127_INPUT_TYPE_NORMAL,
1060 itv->card->video_outputs[outp].video_output, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001061
1062 return 0;
1063}
1064
1065static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1066{
Hans Verkuil2f824412011-03-12 06:43:28 -03001067 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001068 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001069
Hans Verkuildff274f2012-10-01 06:45:36 -03001070 if (s->vdev->vfl_dir)
1071 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001072 if (vf->tuner != 0)
1073 return -EINVAL;
1074
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001075 ivtv_call_all(itv, tuner, g_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001076 return 0;
1077}
1078
1079int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1080{
Hans Verkuil2f824412011-03-12 06:43:28 -03001081 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuildff274f2012-10-01 06:45:36 -03001082 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001083
Hans Verkuildff274f2012-10-01 06:45:36 -03001084 if (s->vdev->vfl_dir)
1085 return -ENOTTY;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001086 if (vf->tuner != 0)
1087 return -EINVAL;
1088
1089 ivtv_mute(itv);
1090 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001091 ivtv_call_all(itv, tuner, s_frequency, vf);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001092 ivtv_unmute(itv);
1093 return 0;
1094}
1095
1096static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1097{
Hans Verkuil2f824412011-03-12 06:43:28 -03001098 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001099
1100 *std = itv->std;
1101 return 0;
1102}
1103
Ian Armstrongc5874c92011-05-29 21:33:17 -03001104void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001105{
Hans Verkuil3f038d82008-05-29 16:43:54 -03001106 itv->std = *std;
1107 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
Hans Verkuilf7b80e62010-06-27 06:07:26 -03001108 itv->is_50hz = !itv->is_60hz;
1109 cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
1110 itv->cxhdl.width = 720;
1111 itv->cxhdl.height = itv->is_50hz ? 576 : 480;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001112 itv->vbi.count = itv->is_50hz ? 18 : 12;
1113 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1114 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1115
1116 if (itv->hw_flags & IVTV_HW_CX25840)
1117 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1118
Hans Verkuil3f038d82008-05-29 16:43:54 -03001119 /* Tuner */
Hans Verkuilf41737e2009-04-01 03:52:39 -03001120 ivtv_call_all(itv, core, s_std, itv->std);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001121}
Hans Verkuil3f038d82008-05-29 16:43:54 -03001122
Ian Armstrongc5874c92011-05-29 21:33:17 -03001123void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1124{
1125 struct yuv_playback_info *yi = &itv->yuv_info;
1126 DEFINE_WAIT(wait);
1127 int f;
Ian Armstrong2443bae2010-03-13 20:22:34 -03001128
Ian Armstrongc5874c92011-05-29 21:33:17 -03001129 /* set display standard */
1130 itv->std_out = *std;
1131 itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1132 itv->is_out_50hz = !itv->is_out_60hz;
1133 ivtv_call_all(itv, video, s_std_output, itv->std_out);
Ian Armstrong2443bae2010-03-13 20:22:34 -03001134
Ian Armstrongc5874c92011-05-29 21:33:17 -03001135 /*
1136 * The next firmware call is time sensitive. Time it to
1137 * avoid risk of a hard lock, by trying to ensure the call
1138 * happens within the first 100 lines of the top field.
1139 * Make 4 attempts to sync to the decoder before giving up.
1140 */
Hans Verkuilcdc03782011-10-11 06:06:58 -03001141 mutex_unlock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001142 for (f = 0; f < 4; f++) {
1143 prepare_to_wait(&itv->vsync_waitq, &wait,
1144 TASK_UNINTERRUPTIBLE);
1145 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1146 break;
1147 schedule_timeout(msecs_to_jiffies(25));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001148 }
Ian Armstrongc5874c92011-05-29 21:33:17 -03001149 finish_wait(&itv->vsync_waitq, &wait);
Hans Verkuilcdc03782011-10-11 06:06:58 -03001150 mutex_lock(&itv->serialize_lock);
Ian Armstrongc5874c92011-05-29 21:33:17 -03001151
1152 if (f == 4)
1153 IVTV_WARN("Mode change failed to sync to decoder\n");
1154
1155 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1156 itv->main_rect.left = 0;
1157 itv->main_rect.top = 0;
1158 itv->main_rect.width = 720;
1159 itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
1160 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1161 720, itv->main_rect.height, 0, 0);
1162 yi->main_rect = itv->main_rect;
1163 if (!itv->osd_info) {
1164 yi->osd_full_w = 720;
1165 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1166 }
1167}
1168
1169int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1170{
1171 struct ivtv *itv = fh2id(fh)->itv;
1172
1173 if ((*std & V4L2_STD_ALL) == 0)
1174 return -EINVAL;
1175
1176 if (*std == itv->std)
1177 return 0;
1178
1179 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1180 atomic_read(&itv->capturing) > 0 ||
1181 atomic_read(&itv->decoding) > 0) {
1182 /* Switching standard would mess with already running
1183 streams, prevent that by returning EBUSY. */
1184 return -EBUSY;
1185 }
1186
1187 IVTV_DEBUG_INFO("Switching standard to %llx.\n",
1188 (unsigned long long)itv->std);
1189
1190 ivtv_s_std_enc(itv, std);
1191 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
1192 ivtv_s_std_dec(itv, std);
1193
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001194 return 0;
1195}
1196
Hans Verkuil3f038d82008-05-29 16:43:54 -03001197static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001198{
Hans Verkuil2f824412011-03-12 06:43:28 -03001199 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001200 struct ivtv *itv = id->itv;
1201
1202 if (vt->index != 0)
1203 return -EINVAL;
1204
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001205 ivtv_call_all(itv, tuner, s_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001206
1207 return 0;
1208}
1209
1210static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1211{
Hans Verkuil2f824412011-03-12 06:43:28 -03001212 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001213
1214 if (vt->index != 0)
1215 return -EINVAL;
1216
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001217 ivtv_call_all(itv, tuner, g_tuner, vt);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001218
Hans Verkuild118e292011-06-25 10:28:21 -03001219 if (vt->type == V4L2_TUNER_RADIO)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001220 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
Hans Verkuild118e292011-06-25 10:28:21 -03001221 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001222 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
Hans Verkuil3f038d82008-05-29 16:43:54 -03001223 return 0;
1224}
1225
1226static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1227{
Hans Verkuil2f824412011-03-12 06:43:28 -03001228 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001229 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1230 int f, l;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001231
Hans Verkuil79afcb12008-06-21 09:02:36 -03001232 if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001233 for (f = 0; f < 2; f++) {
1234 for (l = 0; l < 24; l++) {
1235 if (valid_service_line(f, l, itv->is_50hz))
1236 cap->service_lines[f][l] = set;
1237 }
1238 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001239 } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001240 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1241 return -EINVAL;
1242 if (itv->is_60hz) {
1243 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1244 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1245 } else {
1246 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1247 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1248 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001249 } else {
1250 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001251 }
Hans Verkuil2b5d9482011-07-29 07:21:33 -03001252
1253 set = 0;
1254 for (f = 0; f < 2; f++)
1255 for (l = 0; l < 24; l++)
1256 set |= cap->service_lines[f][l];
1257 cap->service_set = set;
1258 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001259}
1260
1261static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1262{
Hans Verkuil2f824412011-03-12 06:43:28 -03001263 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001264 struct v4l2_enc_idx_entry *e = idx->entry;
1265 int entries;
1266 int i;
1267
1268 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1269 IVTV_MAX_PGM_INDEX;
1270 if (entries > V4L2_ENC_IDX_ENTRIES)
1271 entries = V4L2_ENC_IDX_ENTRIES;
1272 idx->entries = 0;
Hans Verkuil1a806402012-09-05 08:39:48 -03001273 idx->entries_cap = IVTV_MAX_PGM_INDEX;
1274 if (!atomic_read(&itv->capturing))
1275 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001276 for (i = 0; i < entries; i++) {
1277 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1278 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1279 idx->entries++;
1280 e++;
1281 }
1282 }
1283 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1284 return 0;
1285}
1286
1287static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1288{
Hans Verkuil2f824412011-03-12 06:43:28 -03001289 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001290 struct ivtv *itv = id->itv;
1291
Hans Verkuil3f038d82008-05-29 16:43:54 -03001292
1293 switch (enc->cmd) {
1294 case V4L2_ENC_CMD_START:
1295 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1296 enc->flags = 0;
1297 return ivtv_start_capture(id);
1298
1299 case V4L2_ENC_CMD_STOP:
1300 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1301 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1302 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1303 return 0;
1304
1305 case V4L2_ENC_CMD_PAUSE:
1306 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1307 enc->flags = 0;
1308
1309 if (!atomic_read(&itv->capturing))
1310 return -EPERM;
1311 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1312 return 0;
1313
1314 ivtv_mute(itv);
1315 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1316 break;
1317
1318 case V4L2_ENC_CMD_RESUME:
1319 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1320 enc->flags = 0;
1321
1322 if (!atomic_read(&itv->capturing))
1323 return -EPERM;
1324
1325 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1326 return 0;
1327
1328 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1329 ivtv_unmute(itv);
1330 break;
1331 default:
1332 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1333 return -EINVAL;
1334 }
1335
1336 return 0;
1337}
1338
1339static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1340{
Hans Verkuil2f824412011-03-12 06:43:28 -03001341 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001342
Hans Verkuil3f038d82008-05-29 16:43:54 -03001343 switch (enc->cmd) {
1344 case V4L2_ENC_CMD_START:
1345 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1346 enc->flags = 0;
1347 return 0;
1348
1349 case V4L2_ENC_CMD_STOP:
1350 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1351 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1352 return 0;
1353
1354 case V4L2_ENC_CMD_PAUSE:
1355 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1356 enc->flags = 0;
1357 return 0;
1358
1359 case V4L2_ENC_CMD_RESUME:
1360 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1361 enc->flags = 0;
1362 return 0;
1363 default:
1364 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1365 return -EINVAL;
1366 }
1367}
1368
1369static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1370{
Hans Verkuil2f824412011-03-12 06:43:28 -03001371 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001372 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil3f038d82008-05-29 16:43:54 -03001373 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001374
Hans Verkuil3f038d82008-05-29 16:43:54 -03001375 int pixfmt;
1376 static u32 pixel_format[16] = {
1377 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1378 V4L2_PIX_FMT_RGB565,
1379 V4L2_PIX_FMT_RGB555,
1380 V4L2_PIX_FMT_RGB444,
1381 V4L2_PIX_FMT_RGB32,
1382 0,
1383 0,
1384 0,
1385 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1386 V4L2_PIX_FMT_YUV565,
1387 V4L2_PIX_FMT_YUV555,
1388 V4L2_PIX_FMT_YUV444,
1389 V4L2_PIX_FMT_YUV32,
1390 0,
1391 0,
1392 0,
1393 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001394
Hans Verkuil3f038d82008-05-29 16:43:54 -03001395 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1396 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001397 if (!itv->osd_video_pbase)
1398 return -EINVAL;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001399
Hans Verkuil3f038d82008-05-29 16:43:54 -03001400 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1401 V4L2_FBUF_CAP_GLOBAL_ALPHA;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001402
Hans Verkuil3f038d82008-05-29 16:43:54 -03001403 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1404 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1405 pixfmt = (data[0] >> 3) & 0xf;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001406
Hans Verkuil3f038d82008-05-29 16:43:54 -03001407 fb->fmt.pixelformat = pixel_format[pixfmt];
1408 fb->fmt.width = itv->osd_rect.width;
1409 fb->fmt.height = itv->osd_rect.height;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001410 fb->fmt.field = V4L2_FIELD_INTERLACED;
1411 fb->fmt.bytesperline = fb->fmt.width;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001412 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1413 fb->fmt.field = V4L2_FIELD_INTERLACED;
1414 fb->fmt.priv = 0;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001415 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
1416 fb->fmt.bytesperline *= 2;
1417 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
1418 fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
1419 fb->fmt.bytesperline *= 2;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001420 fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001421 fb->base = (void *)itv->osd_video_pbase;
Hans Verkuil5cf2cc42008-06-21 09:06:59 -03001422 fb->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001423
Hans Verkuil3f038d82008-05-29 16:43:54 -03001424 if (itv->osd_chroma_key_state)
1425 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001426
Hans Verkuil3f038d82008-05-29 16:43:54 -03001427 if (itv->osd_global_alpha_state)
1428 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001429
Ian Armstrongec9faa12008-10-06 03:06:08 -03001430 if (yi->track_osd)
1431 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1432
Hans Verkuil3f038d82008-05-29 16:43:54 -03001433 pixfmt &= 7;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001434
Hans Verkuil3f038d82008-05-29 16:43:54 -03001435 /* no local alpha for RGB565 or unknown formats */
1436 if (pixfmt == 1 || pixfmt > 4)
Hans Verkuil987e00b2007-05-29 13:03:27 -03001437 return 0;
Hans Verkuil987e00b2007-05-29 13:03:27 -03001438
Hans Verkuil3f038d82008-05-29 16:43:54 -03001439 /* 16-bit formats have inverted local alpha */
1440 if (pixfmt == 2 || pixfmt == 3)
1441 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1442 else
1443 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001444
Hans Verkuil3f038d82008-05-29 16:43:54 -03001445 if (itv->osd_local_alpha_state) {
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001446 /* 16-bit formats have inverted local alpha */
1447 if (pixfmt == 2 || pixfmt == 3)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001448 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
Hans Verkuil2d4d5f12007-08-23 21:15:24 -03001449 else
Hans Verkuil3f038d82008-05-29 16:43:54 -03001450 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001451 }
1452
Hans Verkuil3f038d82008-05-29 16:43:54 -03001453 return 0;
1454}
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001455
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001456static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001457{
Hans Verkuil2f824412011-03-12 06:43:28 -03001458 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001459 struct ivtv *itv = id->itv;
1460 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001461
Hans Verkuil3f038d82008-05-29 16:43:54 -03001462 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001463 return -EINVAL;
Hans Verkuil37f89f92008-06-22 11:57:31 -03001464 if (!itv->osd_video_pbase)
1465 return -EINVAL;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001466
1467 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1468 itv->osd_local_alpha_state =
1469 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1470 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1471 ivtv_set_osd_alpha(itv);
1472 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
Hans Verkuile6eb28c2012-09-04 10:26:45 -03001473 return 0;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001474}
1475
1476static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1477{
Hans Verkuil2f824412011-03-12 06:43:28 -03001478 struct ivtv_open_id *id = fh2id(fh);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001479 struct ivtv *itv = id->itv;
1480
1481 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1482 return -EINVAL;
1483
1484 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1485
1486 return 0;
1487}
1488
Hans Verkuil85f5fe32012-09-04 11:46:09 -03001489static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
Hans Verkuil09250192010-03-27 14:10:13 -03001490{
1491 switch (sub->type) {
1492 case V4L2_EVENT_VSYNC:
1493 case V4L2_EVENT_EOS:
Hans de Goedec53c2542012-04-08 12:59:46 -03001494 return v4l2_event_subscribe(fh, sub, 0, NULL);
Hans de Goede3e3661492012-04-08 12:59:47 -03001495 case V4L2_EVENT_CTRL:
1496 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuil09250192010-03-27 14:10:13 -03001497 default:
1498 return -EINVAL;
1499 }
Hans Verkuil09250192010-03-27 14:10:13 -03001500}
1501
Hans Verkuil3f038d82008-05-29 16:43:54 -03001502static int ivtv_log_status(struct file *file, void *fh)
1503{
Hans Verkuil2f824412011-03-12 06:43:28 -03001504 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001505 u32 data[CX2341X_MBOX_MAX_DATA];
1506
1507 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1508 struct v4l2_input vidin;
1509 struct v4l2_audio audin;
1510 int i;
1511
Hans Verkuil3f038d82008-05-29 16:43:54 -03001512 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1513 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1514 struct tveeprom tv;
1515
1516 ivtv_read_eeprom(itv, &tv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001517 }
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001518 ivtv_call_all(itv, core, log_status);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001519 ivtv_get_input(itv, itv->active_input, &vidin);
1520 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1521 IVTV_INFO("Video Input: %s\n", vidin.name);
1522 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1523 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1524 if (has_output) {
1525 struct v4l2_output vidout;
1526 struct v4l2_audioout audout;
1527 int mode = itv->output_mode;
1528 static const char * const output_modes[5] = {
1529 "None",
1530 "MPEG Streaming",
1531 "YUV Streaming",
1532 "YUV Frames",
1533 "Passthrough",
1534 };
Hans Verkuil3f038d82008-05-29 16:43:54 -03001535 static const char * const alpha_mode[4] = {
1536 "None",
1537 "Global",
1538 "Local",
1539 "Global and Local"
1540 };
1541 static const char * const pixel_format[16] = {
1542 "ARGB Indexed",
1543 "RGB 5:6:5",
1544 "ARGB 1:5:5:5",
1545 "ARGB 1:4:4:4",
1546 "ARGB 8:8:8:8",
1547 "5",
1548 "6",
1549 "7",
1550 "AYUV Indexed",
1551 "YUV 5:6:5",
1552 "AYUV 1:5:5:5",
1553 "AYUV 1:4:4:4",
1554 "AYUV 8:8:8:8",
1555 "13",
1556 "14",
1557 "15",
1558 };
1559
1560 ivtv_get_output(itv, itv->active_output, &vidout);
1561 ivtv_get_audio_output(itv, 0, &audout);
1562 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001563 if (mode < 0 || mode > OUT_PASSTHROUGH)
1564 mode = OUT_NONE;
1565 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1566 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1567 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1568 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1569 data[0] & 1 ? "On" : "Off",
1570 alpha_mode[(data[0] >> 1) & 0x3],
1571 pixel_format[(data[0] >> 3) & 0xf]);
1572 }
1573 IVTV_INFO("Tuner: %s\n",
1574 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
Hans Verkuileb2ba852012-03-02 13:02:11 -03001575 v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001576 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1577 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1578 struct ivtv_stream *s = &itv->streams[i];
1579
Hans Verkuil8ac05ae2009-02-07 07:02:27 -03001580 if (s->vdev == NULL || s->buffers == 0)
Hans Verkuil3f038d82008-05-29 16:43:54 -03001581 continue;
1582 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1583 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1584 (s->buffers * s->buf_size) / 1024, s->buffers);
1585 }
1586
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001587 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1588 (long long)itv->mpg_data_received,
1589 (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001590 return 0;
1591}
1592
Hans Verkuilda8ec562011-11-24 09:58:53 -03001593static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1594{
1595 struct ivtv_open_id *id = fh2id(file->private_data);
1596 struct ivtv *itv = id->itv;
1597
1598 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1599 return ivtv_video_command(itv, id, dec, false);
1600}
1601
1602static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1603{
1604 struct ivtv_open_id *id = fh2id(file->private_data);
1605 struct ivtv *itv = id->itv;
1606
1607 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1608 return ivtv_video_command(itv, id, dec, true);
1609}
1610
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001611static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001612{
Hans Verkuil09250192010-03-27 14:10:13 -03001613 struct ivtv_open_id *id = fh2id(filp->private_data);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001614 struct ivtv *itv = id->itv;
1615 int nonblocking = filp->f_flags & O_NONBLOCK;
1616 struct ivtv_stream *s = &itv->streams[id->type];
Hans Verkuilce680252010-04-06 15:58:53 -03001617 unsigned long iarg = (unsigned long)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001618
1619 switch (cmd) {
1620 case IVTV_IOC_DMA_FRAME: {
1621 struct ivtv_dma_frame *args = arg;
1622
1623 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1624 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1625 return -EINVAL;
1626 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1627 return -EINVAL;
1628 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1629 return 0;
Ian Armstrong42b03fe2008-06-21 11:09:46 -03001630 if (ivtv_start_decoding(id, id->type)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001631 return -EBUSY;
1632 }
1633 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1634 ivtv_release_stream(s);
1635 return -EBUSY;
1636 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001637 /* Mark that this file handle started the UDMA_YUV mode */
1638 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001639 if (args->y_source == NULL)
1640 return 0;
1641 return ivtv_yuv_prep_frame(itv, args);
1642 }
1643
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001644 case IVTV_IOC_PASSTHROUGH_MODE:
1645 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1646 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1647 return -EINVAL;
1648 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1649
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001650 case VIDEO_GET_PTS: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001651 s64 *pts = arg;
1652 s64 frame;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001653
1654 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1655 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1656 *pts = s->dma_pts;
1657 break;
1658 }
1659 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1660 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001661 return ivtv_g_pts_frame(itv, pts, &frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001662 }
1663
1664 case VIDEO_GET_FRAME_COUNT: {
Hans Verkuildebf8002011-12-15 10:32:53 -03001665 s64 *frame = arg;
1666 s64 pts;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001667
1668 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1669 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1670 *frame = 0;
1671 break;
1672 }
1673 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1674 return -EINVAL;
Hans Verkuildebf8002011-12-15 10:32:53 -03001675 return ivtv_g_pts_frame(itv, &pts, frame);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001676 }
1677
1678 case VIDEO_PLAY: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001679 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001680
1681 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001682 memset(&dc, 0, sizeof(dc));
1683 dc.cmd = V4L2_DEC_CMD_START;
1684 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001685 }
1686
1687 case VIDEO_STOP: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001688 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001689
1690 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001691 memset(&dc, 0, sizeof(dc));
1692 dc.cmd = V4L2_DEC_CMD_STOP;
1693 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1694 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001695 }
1696
1697 case VIDEO_FREEZE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001698 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001699
1700 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001701 memset(&dc, 0, sizeof(dc));
1702 dc.cmd = V4L2_DEC_CMD_PAUSE;
1703 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001704 }
1705
1706 case VIDEO_CONTINUE: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001707 struct v4l2_decoder_cmd dc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001708
1709 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
Hans Verkuilda8ec562011-11-24 09:58:53 -03001710 memset(&dc, 0, sizeof(dc));
1711 dc.cmd = V4L2_DEC_CMD_RESUME;
1712 return ivtv_video_command(itv, id, &dc, 0);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001713 }
1714
1715 case VIDEO_COMMAND:
1716 case VIDEO_TRY_COMMAND: {
Hans Verkuilda8ec562011-11-24 09:58:53 -03001717 /* Note: struct v4l2_decoder_cmd has the same layout as
1718 struct video_command */
1719 struct v4l2_decoder_cmd *dc = arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001720 int try = (cmd == VIDEO_TRY_COMMAND);
1721
1722 if (try)
Hans Verkuilda8ec562011-11-24 09:58:53 -03001723 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001724 else
Hans Verkuilda8ec562011-11-24 09:58:53 -03001725 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1726 return ivtv_video_command(itv, id, dc, try);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001727 }
1728
1729 case VIDEO_GET_EVENT: {
1730 struct video_event *ev = arg;
1731 DEFINE_WAIT(wait);
1732
1733 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1734 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1735 return -EINVAL;
1736 memset(ev, 0, sizeof(*ev));
1737 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1738
1739 while (1) {
1740 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1741 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1742 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1743 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001744 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1745 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1746 if (itv->output_mode == OUT_UDMA_YUV &&
1747 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1748 IVTV_YUV_MODE_PROGRESSIVE) {
1749 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1750 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001751 }
1752 if (ev->type)
1753 return 0;
1754 if (nonblocking)
1755 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001756 /* Wait for event. Note that serialize_lock is locked,
1757 so to allow other processes to access the driver while
1758 we are waiting unlock first and later lock again. */
1759 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001760 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
Hans Verkuilec105a422009-05-02 11:10:23 -03001761 if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
1762 !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001763 schedule();
1764 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001765 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001766 if (signal_pending(current)) {
1767 /* return if a signal was received */
1768 IVTV_DEBUG_INFO("User stopped wait for event\n");
1769 return -EINTR;
1770 }
1771 }
1772 break;
1773 }
1774
Hans Verkuilce680252010-04-06 15:58:53 -03001775 case VIDEO_SELECT_SOURCE:
1776 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1777 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1778 return -EINVAL;
1779 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1780
1781 case AUDIO_SET_MUTE:
1782 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1783 itv->speed_mute_audio = iarg;
1784 return 0;
1785
1786 case AUDIO_CHANNEL_SELECT:
1787 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1788 if (iarg > AUDIO_STEREO_SWAPPED)
1789 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001790 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001791
1792 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1793 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1794 if (iarg > AUDIO_STEREO_SWAPPED)
1795 return -EINVAL;
Hans Verkuilbc169e32012-03-31 05:18:19 -03001796 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
Hans Verkuilce680252010-04-06 15:58:53 -03001797
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001798 default:
1799 return -EINVAL;
1800 }
1801 return 0;
1802}
1803
Hans Verkuil99cd47bc2011-03-11 19:00:56 -03001804static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1805 int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001806{
Hans Verkuil2f824412011-03-12 06:43:28 -03001807 struct ivtv *itv = fh2id(fh)->itv;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001808
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001809 if (!valid_prio) {
1810 switch (cmd) {
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001811 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilcc0a2d42011-03-11 19:03:41 -03001812 case VIDEO_PLAY:
1813 case VIDEO_STOP:
1814 case VIDEO_FREEZE:
1815 case VIDEO_CONTINUE:
1816 case VIDEO_COMMAND:
1817 case VIDEO_SELECT_SOURCE:
1818 case AUDIO_SET_MUTE:
1819 case AUDIO_CHANNEL_SELECT:
1820 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1821 return -EBUSY;
1822 }
1823 }
1824
Hans Verkuild46c17d2007-03-10 17:59:15 -03001825 switch (cmd) {
Hans Verkuil3f038d82008-05-29 16:43:54 -03001826 case VIDIOC_INT_RESET: {
1827 u32 val = *(u32 *)arg;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001828
Hans Verkuil3f038d82008-05-29 16:43:54 -03001829 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1830 ivtv_reset_ir_gpio(itv);
1831 if (val & 0x02)
Hans Verkuil67ec09f2008-11-29 19:38:23 -03001832 v4l2_subdev_call(itv->sd_video, core, reset, 0);
Hans Verkuil3f038d82008-05-29 16:43:54 -03001833 break;
1834 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001835
Hans Verkuilac9575f2009-02-14 19:58:33 -03001836 case IVTV_IOC_DMA_FRAME:
Hans Verkuil6e82a6a22011-12-15 10:40:23 -03001837 case IVTV_IOC_PASSTHROUGH_MODE:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001838 case VIDEO_GET_PTS:
1839 case VIDEO_GET_FRAME_COUNT:
1840 case VIDEO_GET_EVENT:
1841 case VIDEO_PLAY:
1842 case VIDEO_STOP:
1843 case VIDEO_FREEZE:
1844 case VIDEO_CONTINUE:
1845 case VIDEO_COMMAND:
1846 case VIDEO_TRY_COMMAND:
Hans Verkuilce680252010-04-06 15:58:53 -03001847 case VIDEO_SELECT_SOURCE:
1848 case AUDIO_SET_MUTE:
1849 case AUDIO_CHANNEL_SELECT:
1850 case AUDIO_BILINGUAL_CHANNEL_SELECT:
Hans Verkuilac9575f2009-02-14 19:58:33 -03001851 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1852
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001853 default:
Hans Verkuild1c754a2012-04-19 12:36:03 -03001854 return -ENOTTY;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001855 }
1856 return 0;
1857}
1858
Hans Verkuila3998102008-07-21 02:57:38 -03001859static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1860 .vidioc_querycap = ivtv_querycap,
Hans Verkuila3998102008-07-21 02:57:38 -03001861 .vidioc_s_audio = ivtv_s_audio,
1862 .vidioc_g_audio = ivtv_g_audio,
1863 .vidioc_enumaudio = ivtv_enumaudio,
1864 .vidioc_s_audout = ivtv_s_audout,
1865 .vidioc_g_audout = ivtv_g_audout,
1866 .vidioc_enum_input = ivtv_enum_input,
1867 .vidioc_enum_output = ivtv_enum_output,
1868 .vidioc_enumaudout = ivtv_enumaudout,
1869 .vidioc_cropcap = ivtv_cropcap,
1870 .vidioc_s_crop = ivtv_s_crop,
1871 .vidioc_g_crop = ivtv_g_crop,
1872 .vidioc_g_input = ivtv_g_input,
1873 .vidioc_s_input = ivtv_s_input,
1874 .vidioc_g_output = ivtv_g_output,
1875 .vidioc_s_output = ivtv_s_output,
1876 .vidioc_g_frequency = ivtv_g_frequency,
1877 .vidioc_s_frequency = ivtv_s_frequency,
1878 .vidioc_s_tuner = ivtv_s_tuner,
1879 .vidioc_g_tuner = ivtv_g_tuner,
1880 .vidioc_g_enc_index = ivtv_g_enc_index,
1881 .vidioc_g_fbuf = ivtv_g_fbuf,
1882 .vidioc_s_fbuf = ivtv_s_fbuf,
1883 .vidioc_g_std = ivtv_g_std,
1884 .vidioc_s_std = ivtv_s_std,
1885 .vidioc_overlay = ivtv_overlay,
1886 .vidioc_log_status = ivtv_log_status,
1887 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1888 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1889 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
Hans Verkuilda8ec562011-11-24 09:58:53 -03001890 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1891 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
Hans Verkuila3998102008-07-21 02:57:38 -03001892 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1893 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1894 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
1895 .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
1896 .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
1897 .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
1898 .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
1899 .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
1900 .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
1901 .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
1902 .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
1903 .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
1904 .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
1905 .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
1906 .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
1907 .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
1908 .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
1909 .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
1910 .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
1911 .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
1912 .vidioc_g_chip_ident = ivtv_g_chip_ident,
1913#ifdef CONFIG_VIDEO_ADV_DEBUG
1914 .vidioc_g_register = ivtv_g_register,
1915 .vidioc_s_register = ivtv_s_register,
1916#endif
1917 .vidioc_default = ivtv_default,
Hans Verkuil09250192010-03-27 14:10:13 -03001918 .vidioc_subscribe_event = ivtv_subscribe_event,
1919 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001920};
1921
Hans Verkuil3f038d82008-05-29 16:43:54 -03001922void ivtv_set_funcs(struct video_device *vdev)
1923{
Hans Verkuila3998102008-07-21 02:57:38 -03001924 vdev->ioctl_ops = &ivtv_ioctl_ops;
Hans Verkuil3f038d82008-05-29 16:43:54 -03001925}