diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-05-29 15:43:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:10:31 -0400 |
commit | 3f038d80039f60e4340eaedd13369e0d2c758b80 (patch) | |
tree | 994cafb1cb1900b97155b2d3233814632c856adc /drivers | |
parent | 539a7555b31e65e66fb84c881d07d2bf18c974d0 (diff) |
V4L/DVB (8079): ivtv: Convert to video_ioctl2.
Based on an initial conversion patch from Douglas Landgraf.
Signed-off-by: Douglas Schilling Landgraf <dougsland@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-controls.c | 196 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-controls.h | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 10 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 2089 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.h | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 3 |
6 files changed, 1228 insertions, 1087 deletions
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index c7e449f6397b..06723bac99c5 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c | |||
@@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = { | |||
47 | NULL | 47 | NULL |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) | 50 | |
51 | int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) | ||
51 | { | 52 | { |
53 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
52 | const char *name; | 54 | const char *name; |
53 | 55 | ||
54 | IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); | 56 | IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); |
@@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) | |||
87 | return 0; | 89 | return 0; |
88 | } | 90 | } |
89 | 91 | ||
90 | static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu) | 92 | int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) |
91 | { | 93 | { |
94 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
92 | struct v4l2_queryctrl qctrl; | 95 | struct v4l2_queryctrl qctrl; |
93 | 96 | ||
97 | IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); | ||
94 | qctrl.id = qmenu->id; | 98 | qctrl.id = qmenu->id; |
95 | ivtv_queryctrl(itv, &qctrl); | 99 | ivtv_queryctrl(file, fh, &qctrl); |
96 | return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); | 100 | return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); |
97 | } | 101 | } |
98 | 102 | ||
99 | static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) | 103 | int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) |
100 | { | 104 | { |
105 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
101 | s32 v = vctrl->value; | 106 | s32 v = vctrl->value; |
102 | 107 | ||
103 | IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); | 108 | IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); |
@@ -125,8 +130,10 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) | |||
125 | return 0; | 130 | return 0; |
126 | } | 131 | } |
127 | 132 | ||
128 | static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) | 133 | int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) |
129 | { | 134 | { |
135 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
136 | |||
130 | IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); | 137 | IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); |
131 | 138 | ||
132 | switch (vctrl->id) { | 139 | switch (vctrl->id) { |
@@ -191,119 +198,96 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm | |||
191 | return 0; | 198 | return 0; |
192 | } | 199 | } |
193 | 200 | ||
194 | int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) | 201 | int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) |
195 | { | 202 | { |
203 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
196 | struct v4l2_control ctrl; | 204 | struct v4l2_control ctrl; |
197 | 205 | ||
198 | switch (cmd) { | 206 | if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { |
199 | case VIDIOC_QUERYMENU: | 207 | int i; |
200 | IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); | 208 | int err = 0; |
201 | return ivtv_querymenu(itv, arg); | 209 | |
202 | 210 | for (i = 0; i < c->count; i++) { | |
203 | case VIDIOC_QUERYCTRL: | 211 | ctrl.id = c->controls[i].id; |
204 | return ivtv_queryctrl(itv, arg); | 212 | ctrl.value = c->controls[i].value; |
205 | 213 | err = ivtv_g_ctrl(file, fh, &ctrl); | |
206 | case VIDIOC_S_CTRL: | 214 | c->controls[i].value = ctrl.value; |
207 | return ivtv_s_ctrl(itv, arg); | 215 | if (err) { |
208 | 216 | c->error_idx = i; | |
209 | case VIDIOC_G_CTRL: | 217 | break; |
210 | return ivtv_g_ctrl(itv, arg); | ||
211 | |||
212 | case VIDIOC_S_EXT_CTRLS: | ||
213 | { | ||
214 | struct v4l2_ext_controls *c = arg; | ||
215 | |||
216 | if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { | ||
217 | int i; | ||
218 | int err = 0; | ||
219 | |||
220 | for (i = 0; i < c->count; i++) { | ||
221 | ctrl.id = c->controls[i].id; | ||
222 | ctrl.value = c->controls[i].value; | ||
223 | err = ivtv_s_ctrl(itv, &ctrl); | ||
224 | c->controls[i].value = ctrl.value; | ||
225 | if (err) { | ||
226 | c->error_idx = i; | ||
227 | break; | ||
228 | } | ||
229 | } | ||
230 | return err; | ||
231 | } | ||
232 | IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); | ||
233 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
234 | static u32 freqs[3] = { 44100, 48000, 32000 }; | ||
235 | struct cx2341x_mpeg_params p = itv->params; | ||
236 | int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd); | ||
237 | unsigned idx; | ||
238 | |||
239 | if (err) | ||
240 | return err; | ||
241 | |||
242 | if (p.video_encoding != itv->params.video_encoding) { | ||
243 | int is_mpeg1 = p.video_encoding == | ||
244 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1; | ||
245 | struct v4l2_format fmt; | ||
246 | |||
247 | /* fix videodecoder resolution */ | ||
248 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
249 | fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); | ||
250 | fmt.fmt.pix.height = itv->params.height; | ||
251 | itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); | ||
252 | } | ||
253 | err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); | ||
254 | if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) { | ||
255 | err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt); | ||
256 | } | 218 | } |
257 | itv->params = p; | ||
258 | itv->dualwatch_stereo_mode = p.audio_properties & 0x0300; | ||
259 | idx = p.audio_properties & 0x03; | ||
260 | /* The audio clock of the digitizer must match the codec sample | ||
261 | rate otherwise you get some very strange effects. */ | ||
262 | if (idx < sizeof(freqs)) | ||
263 | ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]); | ||
264 | return err; | ||
265 | } | 219 | } |
266 | return -EINVAL; | 220 | return err; |
267 | } | 221 | } |
222 | IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); | ||
223 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) | ||
224 | return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS); | ||
225 | return -EINVAL; | ||
226 | } | ||
268 | 227 | ||
269 | case VIDIOC_G_EXT_CTRLS: | 228 | int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) |
270 | { | 229 | { |
271 | struct v4l2_ext_controls *c = arg; | 230 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
272 | 231 | struct v4l2_control ctrl; | |
273 | if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { | 232 | |
274 | int i; | 233 | if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { |
275 | int err = 0; | 234 | int i; |
276 | 235 | int err = 0; | |
277 | for (i = 0; i < c->count; i++) { | 236 | |
278 | ctrl.id = c->controls[i].id; | 237 | for (i = 0; i < c->count; i++) { |
279 | ctrl.value = c->controls[i].value; | 238 | ctrl.id = c->controls[i].id; |
280 | err = ivtv_g_ctrl(itv, &ctrl); | 239 | ctrl.value = c->controls[i].value; |
281 | c->controls[i].value = ctrl.value; | 240 | err = ivtv_s_ctrl(file, fh, &ctrl); |
282 | if (err) { | 241 | c->controls[i].value = ctrl.value; |
283 | c->error_idx = i; | 242 | if (err) { |
284 | break; | 243 | c->error_idx = i; |
285 | } | 244 | break; |
286 | } | 245 | } |
287 | return err; | ||
288 | } | 246 | } |
289 | IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); | 247 | return err; |
290 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) | ||
291 | return cx2341x_ext_ctrls(&itv->params, 0, arg, cmd); | ||
292 | return -EINVAL; | ||
293 | } | 248 | } |
249 | IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); | ||
250 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | ||
251 | static u32 freqs[3] = { 44100, 48000, 32000 }; | ||
252 | struct cx2341x_mpeg_params p = itv->params; | ||
253 | int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS); | ||
254 | unsigned idx; | ||
255 | |||
256 | if (err) | ||
257 | return err; | ||
294 | 258 | ||
295 | case VIDIOC_TRY_EXT_CTRLS: | 259 | if (p.video_encoding != itv->params.video_encoding) { |
296 | { | 260 | int is_mpeg1 = p.video_encoding == |
297 | struct v4l2_ext_controls *c = arg; | 261 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
262 | struct v4l2_format fmt; | ||
298 | 263 | ||
299 | IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); | 264 | /* fix videodecoder resolution */ |
300 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) | 265 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
301 | return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd); | 266 | fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); |
302 | return -EINVAL; | 267 | fmt.fmt.pix.height = itv->params.height; |
268 | itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); | ||
269 | } | ||
270 | err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); | ||
271 | if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) | ||
272 | err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt); | ||
273 | itv->params = p; | ||
274 | itv->dualwatch_stereo_mode = p.audio_properties & 0x0300; | ||
275 | idx = p.audio_properties & 0x03; | ||
276 | /* The audio clock of the digitizer must match the codec sample | ||
277 | rate otherwise you get some very strange effects. */ | ||
278 | if (idx < sizeof(freqs)) | ||
279 | ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]); | ||
280 | return err; | ||
303 | } | 281 | } |
282 | return -EINVAL; | ||
283 | } | ||
304 | 284 | ||
305 | default: | 285 | int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) |
306 | return -EINVAL; | 286 | { |
307 | } | 287 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
308 | return 0; | 288 | |
289 | IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); | ||
290 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) | ||
291 | return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS); | ||
292 | return -EINVAL; | ||
309 | } | 293 | } |
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h index bb8a6a5ed2bc..304204be6b0d 100644 --- a/drivers/media/video/ivtv/ivtv-controls.h +++ b/drivers/media/video/ivtv/ivtv-controls.h | |||
@@ -21,6 +21,12 @@ | |||
21 | #ifndef IVTV_CONTROLS_H | 21 | #ifndef IVTV_CONTROLS_H |
22 | #define IVTV_CONTROLS_H | 22 | #define IVTV_CONTROLS_H |
23 | 23 | ||
24 | int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg); | 24 | int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); |
25 | int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); | ||
26 | int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); | ||
27 | int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); | ||
28 | int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); | ||
29 | int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); | ||
30 | int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a); | ||
25 | 31 | ||
26 | #endif | 32 | #endif |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 323dd68fa1c6..9e6a64903875 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1262,9 +1262,13 @@ err: | |||
1262 | int ivtv_init_on_first_open(struct ivtv *itv) | 1262 | int ivtv_init_on_first_open(struct ivtv *itv) |
1263 | { | 1263 | { |
1264 | struct v4l2_frequency vf; | 1264 | struct v4l2_frequency vf; |
1265 | /* Needed to call ioctls later */ | ||
1266 | struct ivtv_open_id fh; | ||
1265 | int fw_retry_count = 3; | 1267 | int fw_retry_count = 3; |
1266 | int video_input; | 1268 | int video_input; |
1267 | 1269 | ||
1270 | fh.itv = itv; | ||
1271 | |||
1268 | if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) | 1272 | if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) |
1269 | return -ENXIO; | 1273 | return -ENXIO; |
1270 | 1274 | ||
@@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv) | |||
1312 | 1316 | ||
1313 | video_input = itv->active_input; | 1317 | video_input = itv->active_input; |
1314 | itv->active_input++; /* Force update of input */ | 1318 | itv->active_input++; /* Force update of input */ |
1315 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input); | 1319 | ivtv_s_input(NULL, &fh, video_input); |
1316 | 1320 | ||
1317 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code | 1321 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code |
1318 | in one place. */ | 1322 | in one place. */ |
1319 | itv->std++; /* Force full standard initialization */ | 1323 | itv->std++; /* Force full standard initialization */ |
1320 | itv->std_out = itv->std; | 1324 | itv->std_out = itv->std; |
1321 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); | 1325 | ivtv_s_frequency(NULL, &fh, &vf); |
1322 | 1326 | ||
1323 | if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { | 1327 | if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { |
1324 | ivtv_init_mpeg_decoder(itv); | 1328 | ivtv_init_mpeg_decoder(itv); |
1325 | } | 1329 | } |
1326 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); | 1330 | ivtv_s_std(NULL, &fh, &itv->tuner_std); |
1327 | 1331 | ||
1328 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ | 1332 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ |
1329 | if (!itv->has_cx23415) | 1333 | if (!itv->has_cx23415) |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 26cc0f6699fd..49b297e788db 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -373,267 +373,172 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | |||
373 | return 0; | 373 | return 0; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt) | 376 | static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) |
377 | { | 377 | { |
378 | switch (fmt->type) { | 378 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
379 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 379 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; |
380 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
381 | return -EINVAL; | ||
382 | fmt->fmt.pix.width = itv->main_rect.width; | ||
383 | fmt->fmt.pix.height = itv->main_rect.height; | ||
384 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
385 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
386 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
387 | switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { | ||
388 | case IVTV_YUV_MODE_INTERLACED: | ||
389 | fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? | ||
390 | V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; | ||
391 | break; | ||
392 | case IVTV_YUV_MODE_PROGRESSIVE: | ||
393 | fmt->fmt.pix.field = V4L2_FIELD_NONE; | ||
394 | break; | ||
395 | default: | ||
396 | fmt->fmt.pix.field = V4L2_FIELD_ANY; | ||
397 | break; | ||
398 | } | ||
399 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; | ||
400 | fmt->fmt.pix.bytesperline = 720; | ||
401 | fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w; | ||
402 | fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h; | ||
403 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
404 | fmt->fmt.pix.sizeimage = | ||
405 | 1080 * ((fmt->fmt.pix.height + 31) & ~31); | ||
406 | } else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) { | ||
407 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; | ||
408 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
409 | fmt->fmt.pix.sizeimage = | ||
410 | fmt->fmt.pix.height * fmt->fmt.pix.width + | ||
411 | fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); | ||
412 | } else { | ||
413 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
414 | fmt->fmt.pix.sizeimage = 128 * 1024; | ||
415 | } | ||
416 | break; | ||
417 | |||
418 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
419 | fmt->fmt.pix.width = itv->params.width; | ||
420 | fmt->fmt.pix.height = itv->params.height; | ||
421 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
422 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
423 | if (streamtype == IVTV_ENC_STREAM_TYPE_YUV || | ||
424 | streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
425 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; | ||
426 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
427 | fmt->fmt.pix.sizeimage = | ||
428 | fmt->fmt.pix.height * fmt->fmt.pix.width + | ||
429 | fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); | ||
430 | } else { | ||
431 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
432 | fmt->fmt.pix.sizeimage = 128 * 1024; | ||
433 | } | ||
434 | break; | ||
435 | |||
436 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | ||
437 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
438 | return -EINVAL; | ||
439 | fmt->fmt.win.chromakey = itv->osd_chroma_key; | ||
440 | fmt->fmt.win.global_alpha = itv->osd_global_alpha; | ||
441 | break; | ||
442 | |||
443 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
444 | fmt->fmt.vbi.sampling_rate = 27000000; | ||
445 | fmt->fmt.vbi.offset = 248; | ||
446 | fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4; | ||
447 | fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
448 | fmt->fmt.vbi.start[0] = itv->vbi.start[0]; | ||
449 | fmt->fmt.vbi.start[1] = itv->vbi.start[1]; | ||
450 | fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count; | ||
451 | break; | ||
452 | |||
453 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
454 | { | ||
455 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
456 | 380 | ||
457 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) | 381 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) |
458 | return -EINVAL; | 382 | return -EINVAL; |
459 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | 383 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; |
460 | memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); | 384 | if (itv->is_60hz) { |
461 | memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); | 385 | vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; |
462 | if (itv->is_60hz) { | 386 | vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; |
463 | vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; | 387 | } else { |
464 | vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; | 388 | vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; |
465 | } else { | 389 | vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; |
466 | vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
467 | vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; | ||
468 | } | ||
469 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | ||
470 | break; | ||
471 | } | 390 | } |
391 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | ||
392 | return 0; | ||
393 | } | ||
472 | 394 | ||
473 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 395 | static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
474 | { | 396 | { |
475 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | 397 | struct ivtv_open_id *id = fh; |
476 | 398 | struct ivtv *itv = id->itv; | |
477 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | ||
478 | memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); | ||
479 | memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); | ||
480 | |||
481 | if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { | ||
482 | vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : | ||
483 | V4L2_SLICED_VBI_525; | ||
484 | ivtv_expand_service_set(vbifmt, itv->is_50hz); | ||
485 | break; | ||
486 | } | ||
487 | 399 | ||
488 | itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); | 400 | fmt->fmt.pix.width = itv->params.width; |
489 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | 401 | fmt->fmt.pix.height = itv->params.height; |
490 | break; | 402 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
491 | } | 403 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; |
492 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 404 | if (id->type == IVTV_ENC_STREAM_TYPE_YUV || |
493 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 405 | id->type == IVTV_DEC_STREAM_TYPE_YUV) { |
494 | default: | 406 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; |
495 | return -EINVAL; | 407 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ |
408 | fmt->fmt.pix.sizeimage = | ||
409 | fmt->fmt.pix.height * fmt->fmt.pix.width + | ||
410 | fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); | ||
411 | } else { | ||
412 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
413 | fmt->fmt.pix.sizeimage = 128 * 1024; | ||
496 | } | 414 | } |
497 | return 0; | 415 | return 0; |
498 | } | 416 | } |
499 | 417 | ||
500 | static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | 418 | static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
501 | struct v4l2_format *fmt, int set_fmt) | ||
502 | { | 419 | { |
503 | struct yuv_playback_info *yi = &itv->yuv_info; | 420 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
504 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | 421 | |
505 | u16 set; | 422 | fmt->fmt.vbi.sampling_rate = 27000000; |
423 | fmt->fmt.vbi.offset = 248; | ||
424 | fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4; | ||
425 | fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
426 | fmt->fmt.vbi.start[0] = itv->vbi.start[0]; | ||
427 | fmt->fmt.vbi.start[1] = itv->vbi.start[1]; | ||
428 | fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count; | ||
429 | return 0; | ||
430 | } | ||
506 | 431 | ||
507 | if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | 432 | static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
508 | struct v4l2_rect r; | 433 | { |
509 | int field; | 434 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; |
435 | struct ivtv_open_id *id = fh; | ||
436 | struct ivtv *itv = id->itv; | ||
510 | 437 | ||
511 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 438 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; |
512 | return -EINVAL; | ||
513 | field = fmt->fmt.pix.field; | ||
514 | r.top = 0; | ||
515 | r.left = 0; | ||
516 | r.width = fmt->fmt.pix.width; | ||
517 | r.height = fmt->fmt.pix.height; | ||
518 | ivtv_get_fmt(itv, streamtype, fmt); | ||
519 | fmt->fmt.pix.width = r.width; | ||
520 | fmt->fmt.pix.height = r.height; | ||
521 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
522 | fmt->fmt.pix.field = field; | ||
523 | if (fmt->fmt.pix.width < 2) | ||
524 | fmt->fmt.pix.width = 2; | ||
525 | if (fmt->fmt.pix.width > 720) | ||
526 | fmt->fmt.pix.width = 720; | ||
527 | if (fmt->fmt.pix.height < 2) | ||
528 | fmt->fmt.pix.height = 2; | ||
529 | if (fmt->fmt.pix.height > 576) | ||
530 | fmt->fmt.pix.height = 576; | ||
531 | } | ||
532 | if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
533 | /* Return now if we already have some frame data */ | ||
534 | if (yi->stream_size) | ||
535 | return -EBUSY; | ||
536 | 439 | ||
537 | yi->v4l2_src_w = r.width; | 440 | if (id->type == IVTV_DEC_STREAM_TYPE_VBI) { |
538 | yi->v4l2_src_h = r.height; | 441 | vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : |
442 | V4L2_SLICED_VBI_525; | ||
443 | ivtv_expand_service_set(vbifmt, itv->is_50hz); | ||
444 | return 0; | ||
445 | } | ||
539 | 446 | ||
540 | switch (field) { | 447 | itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); |
541 | case V4L2_FIELD_NONE: | 448 | vbifmt->service_set = ivtv_get_service_set(vbifmt); |
542 | yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; | 449 | return 0; |
543 | break; | 450 | } |
544 | case V4L2_FIELD_ANY: | ||
545 | yi->lace_mode = IVTV_YUV_MODE_AUTO; | ||
546 | break; | ||
547 | case V4L2_FIELD_INTERLACED_BT: | ||
548 | yi->lace_mode = | ||
549 | IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD; | ||
550 | break; | ||
551 | case V4L2_FIELD_INTERLACED_TB: | ||
552 | default: | ||
553 | yi->lace_mode = IVTV_YUV_MODE_INTERLACED; | ||
554 | break; | ||
555 | } | ||
556 | yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1; | ||
557 | 451 | ||
558 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | 452 | static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) |
559 | itv->dma_data_req_size = | 453 | { |
560 | 1080 * ((yi->v4l2_src_h + 31) & ~31); | 454 | struct ivtv_open_id *id = fh; |
455 | struct ivtv *itv = id->itv; | ||
561 | 456 | ||
562 | /* Force update of yuv registers */ | 457 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
563 | yi->yuv_forced_update = 1; | 458 | return -EINVAL; |
564 | return 0; | 459 | fmt->fmt.pix.width = itv->main_rect.width; |
460 | fmt->fmt.pix.height = itv->main_rect.height; | ||
461 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
462 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
463 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
464 | switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { | ||
465 | case IVTV_YUV_MODE_INTERLACED: | ||
466 | fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? | ||
467 | V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; | ||
468 | break; | ||
469 | case IVTV_YUV_MODE_PROGRESSIVE: | ||
470 | fmt->fmt.pix.field = V4L2_FIELD_NONE; | ||
471 | break; | ||
472 | default: | ||
473 | fmt->fmt.pix.field = V4L2_FIELD_ANY; | ||
474 | break; | ||
565 | } | 475 | } |
566 | return 0; | 476 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; |
477 | fmt->fmt.pix.bytesperline = 720; | ||
478 | fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w; | ||
479 | fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h; | ||
480 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
481 | fmt->fmt.pix.sizeimage = | ||
482 | 1080 * ((fmt->fmt.pix.height + 31) & ~31); | ||
483 | } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { | ||
484 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; | ||
485 | /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ | ||
486 | fmt->fmt.pix.sizeimage = | ||
487 | fmt->fmt.pix.height * fmt->fmt.pix.width + | ||
488 | fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); | ||
489 | } else { | ||
490 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
491 | fmt->fmt.pix.sizeimage = 128 * 1024; | ||
567 | } | 492 | } |
493 | return 0; | ||
494 | } | ||
568 | 495 | ||
569 | if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) { | 496 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
570 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 497 | { |
571 | return -EINVAL; | 498 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
572 | if (set_fmt) { | ||
573 | itv->osd_chroma_key = fmt->fmt.win.chromakey; | ||
574 | itv->osd_global_alpha = fmt->fmt.win.global_alpha; | ||
575 | ivtv_set_osd_alpha(itv); | ||
576 | } | ||
577 | return 0; | ||
578 | } | ||
579 | 499 | ||
580 | /* set window size */ | 500 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
581 | if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 501 | return -EINVAL; |
582 | struct cx2341x_mpeg_params *p = &itv->params; | 502 | fmt->fmt.win.chromakey = itv->osd_chroma_key; |
583 | int w = fmt->fmt.pix.width; | 503 | fmt->fmt.win.global_alpha = itv->osd_global_alpha; |
584 | int h = fmt->fmt.pix.height; | 504 | return 0; |
585 | 505 | } | |
586 | if (w > 720) w = 720; | ||
587 | else if (w < 1) w = 1; | ||
588 | if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480); | ||
589 | else if (h < 2) h = 2; | ||
590 | ivtv_get_fmt(itv, streamtype, fmt); | ||
591 | fmt->fmt.pix.width = w; | ||
592 | fmt->fmt.pix.height = h; | ||
593 | |||
594 | if (!set_fmt || (p->width == w && p->height == h)) | ||
595 | return 0; | ||
596 | if (atomic_read(&itv->capturing) > 0) | ||
597 | return -EBUSY; | ||
598 | 506 | ||
599 | p->width = w; | 507 | static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) |
600 | p->height = h; | 508 | { |
601 | if (w != 720 || h != (itv->is_50hz ? 576 : 480)) | 509 | return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); |
602 | p->video_temporal_filter = 0; | 510 | } |
603 | else | ||
604 | p->video_temporal_filter = 8; | ||
605 | if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) | ||
606 | fmt->fmt.pix.width /= 2; | ||
607 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | ||
608 | return ivtv_get_fmt(itv, streamtype, fmt); | ||
609 | } | ||
610 | 511 | ||
611 | /* set raw VBI format */ | 512 | static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
612 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 513 | { |
613 | if (set_fmt && atomic_read(&itv->capturing) > 0) { | 514 | struct ivtv_open_id *id = fh; |
614 | return -EBUSY; | 515 | struct ivtv *itv = id->itv; |
615 | } | 516 | int w = fmt->fmt.pix.width; |
616 | if (set_fmt) { | 517 | int h = fmt->fmt.pix.height; |
617 | itv->vbi.sliced_in->service_set = 0; | 518 | |
618 | itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); | 519 | w = min(w, 720); |
619 | } | 520 | w = max(w, 1); |
620 | return ivtv_get_fmt(itv, streamtype, fmt); | 521 | h = min(h, itv->is_50hz ? 576 : 480); |
621 | } | 522 | h = max(h, 2); |
523 | ivtv_g_fmt_vid_cap(file, fh, fmt); | ||
524 | fmt->fmt.pix.width = w; | ||
525 | fmt->fmt.pix.height = h; | ||
526 | return 0; | ||
527 | } | ||
622 | 528 | ||
623 | /* set sliced VBI output | 529 | static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
624 | In principle the user could request that only certain | 530 | { |
625 | VBI types are output and that the others are ignored. | 531 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); |
626 | I.e., suppress CC in the even fields or only output | 532 | } |
627 | WSS and no VPS. Currently though there is no choice. */ | ||
628 | if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) | ||
629 | return ivtv_get_fmt(itv, streamtype, fmt); | ||
630 | 533 | ||
631 | /* any else but sliced VBI capture is an error */ | 534 | static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
632 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | 535 | { |
633 | return -EINVAL; | 536 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; |
537 | struct ivtv_open_id *id = fh; | ||
538 | struct ivtv *itv = id->itv; | ||
634 | 539 | ||
635 | if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) | 540 | if (id->type == IVTV_DEC_STREAM_TYPE_VBI) |
636 | return ivtv_get_fmt(itv, streamtype, fmt); | 541 | return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt); |
637 | 542 | ||
638 | /* set sliced VBI capture format */ | 543 | /* set sliced VBI capture format */ |
639 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; | 544 | vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; |
@@ -641,777 +546,997 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
641 | 546 | ||
642 | if (vbifmt->service_set) | 547 | if (vbifmt->service_set) |
643 | ivtv_expand_service_set(vbifmt, itv->is_50hz); | 548 | ivtv_expand_service_set(vbifmt, itv->is_50hz); |
644 | set = check_service_set(vbifmt, itv->is_50hz); | 549 | check_service_set(vbifmt, itv->is_50hz); |
645 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | 550 | vbifmt->service_set = ivtv_get_service_set(vbifmt); |
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
555 | { | ||
556 | struct ivtv_open_id *id = fh; | ||
557 | s32 w, h; | ||
558 | int field; | ||
559 | int ret; | ||
560 | |||
561 | w = fmt->fmt.pix.width; | ||
562 | h = fmt->fmt.pix.height; | ||
563 | field = fmt->fmt.pix.field; | ||
564 | ret = ivtv_g_fmt_vid_out(file, fh, fmt); | ||
565 | fmt->fmt.pix.width = w; | ||
566 | fmt->fmt.pix.height = h; | ||
567 | if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
568 | fmt->fmt.pix.field = field; | ||
569 | if (fmt->fmt.pix.width < 2) | ||
570 | fmt->fmt.pix.width = 2; | ||
571 | if (fmt->fmt.pix.width > 720) | ||
572 | fmt->fmt.pix.width = 720; | ||
573 | if (fmt->fmt.pix.height < 2) | ||
574 | fmt->fmt.pix.height = 2; | ||
575 | if (fmt->fmt.pix.height > 576) | ||
576 | fmt->fmt.pix.height = 576; | ||
577 | } | ||
578 | return ret; | ||
579 | } | ||
646 | 580 | ||
647 | if (!set_fmt) | 581 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
582 | { | ||
583 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
584 | |||
585 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
586 | return -EINVAL; | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) | ||
591 | { | ||
592 | return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); | ||
593 | } | ||
594 | |||
595 | static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
596 | { | ||
597 | struct ivtv_open_id *id = fh; | ||
598 | struct ivtv *itv = id->itv; | ||
599 | struct cx2341x_mpeg_params *p = &itv->params; | ||
600 | int w = fmt->fmt.pix.width; | ||
601 | int h = fmt->fmt.pix.height; | ||
602 | int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); | ||
603 | |||
604 | if (ret) | ||
605 | return ret; | ||
606 | |||
607 | if (p->width == w && p->height == h) | ||
648 | return 0; | 608 | return 0; |
649 | if (set == 0) | 609 | |
610 | if (atomic_read(&itv->capturing) > 0) | ||
611 | return -EBUSY; | ||
612 | |||
613 | p->width = w; | ||
614 | p->height = h; | ||
615 | if (w != 720 || h != (itv->is_50hz ? 576 : 480)) | ||
616 | p->video_temporal_filter = 0; | ||
617 | else | ||
618 | p->video_temporal_filter = 8; | ||
619 | if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) | ||
620 | fmt->fmt.pix.width /= 2; | ||
621 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | ||
622 | return ivtv_g_fmt_vid_cap(file, fh, fmt); | ||
623 | } | ||
624 | |||
625 | static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
626 | { | ||
627 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
628 | |||
629 | itv->vbi.sliced_in->service_set = 0; | ||
630 | itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); | ||
631 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | ||
632 | } | ||
633 | |||
634 | static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
635 | { | ||
636 | struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; | ||
637 | struct ivtv_open_id *id = fh; | ||
638 | struct ivtv *itv = id->itv; | ||
639 | int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt); | ||
640 | |||
641 | if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) | ||
642 | return ret; | ||
643 | |||
644 | if (check_service_set(vbifmt, itv->is_50hz) == 0) | ||
650 | return -EINVAL; | 645 | return -EINVAL; |
651 | if (atomic_read(&itv->capturing) > 0) { | 646 | if (atomic_read(&itv->capturing) > 0) |
652 | return -EBUSY; | 647 | return -EBUSY; |
653 | } | ||
654 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | 648 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); |
655 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); | 649 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); |
656 | return 0; | 650 | return 0; |
657 | } | 651 | } |
658 | 652 | ||
659 | static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) | 653 | static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) |
660 | { | 654 | { |
661 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 655 | struct ivtv_open_id *id = fh; |
662 | struct ivtv *itv = id->itv; | 656 | struct ivtv *itv = id->itv; |
663 | struct v4l2_register *reg = arg; | 657 | struct yuv_playback_info *yi = &itv->yuv_info; |
658 | int ret = ivtv_try_fmt_vid_out(file, fh, fmt); | ||
664 | 659 | ||
665 | switch (cmd) { | 660 | if (ret) |
666 | /* ioctls to allow direct access to the encoder registers for testing */ | 661 | return ret; |
667 | case VIDIOC_DBG_G_REGISTER: | ||
668 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
669 | return ivtv_itvc(itv, cmd, arg); | ||
670 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | ||
671 | return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); | ||
672 | return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); | ||
673 | |||
674 | case VIDIOC_DBG_S_REGISTER: | ||
675 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
676 | return ivtv_itvc(itv, cmd, arg); | ||
677 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | ||
678 | return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); | ||
679 | return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); | ||
680 | |||
681 | case VIDIOC_G_CHIP_IDENT: { | ||
682 | struct v4l2_chip_ident *chip = arg; | ||
683 | |||
684 | chip->ident = V4L2_IDENT_NONE; | ||
685 | chip->revision = 0; | ||
686 | if (reg->match_type == V4L2_CHIP_MATCH_HOST) { | ||
687 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
688 | chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; | ||
689 | return 0; | ||
690 | } | ||
691 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | ||
692 | return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); | ||
693 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR) | ||
694 | return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | 662 | ||
698 | case VIDIOC_INT_S_AUDIO_ROUTING: { | 663 | if (id->type != IVTV_DEC_STREAM_TYPE_YUV) |
699 | struct v4l2_routing *route = arg; | 664 | return 0; |
700 | 665 | ||
701 | ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); | 666 | /* Return now if we already have some frame data */ |
702 | break; | 667 | if (yi->stream_size) |
703 | } | 668 | return -EBUSY; |
704 | 669 | ||
705 | case VIDIOC_INT_RESET: { | 670 | yi->v4l2_src_w = fmt->fmt.pix.width; |
706 | u32 val = *(u32 *)arg; | 671 | yi->v4l2_src_h = fmt->fmt.pix.height; |
707 | 672 | ||
708 | if ((val == 0 && itv->options.newi2c) || (val & 0x01)) { | 673 | switch (fmt->fmt.pix.field) { |
709 | ivtv_reset_ir_gpio(itv); | 674 | case V4L2_FIELD_NONE: |
710 | } | 675 | yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; |
711 | if (val & 0x02) { | ||
712 | itv->video_dec_func(itv, cmd, NULL); | ||
713 | } | ||
714 | break; | 676 | break; |
715 | } | 677 | case V4L2_FIELD_ANY: |
716 | 678 | yi->lace_mode = IVTV_YUV_MODE_AUTO; | |
679 | break; | ||
680 | case V4L2_FIELD_INTERLACED_BT: | ||
681 | yi->lace_mode = | ||
682 | IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD; | ||
683 | break; | ||
684 | case V4L2_FIELD_INTERLACED_TB: | ||
717 | default: | 685 | default: |
718 | return -EINVAL; | 686 | yi->lace_mode = IVTV_YUV_MODE_INTERLACED; |
687 | break; | ||
719 | } | 688 | } |
689 | yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1; | ||
690 | |||
691 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | ||
692 | itv->dma_data_req_size = | ||
693 | 1080 * ((yi->v4l2_src_h + 31) & ~31); | ||
694 | |||
695 | /* Force update of yuv registers */ | ||
696 | yi->yuv_forced_update = 1; | ||
720 | return 0; | 697 | return 0; |
721 | } | 698 | } |
722 | 699 | ||
723 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) | 700 | static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
724 | { | 701 | { |
725 | struct ivtv_open_id *id = NULL; | 702 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
726 | struct yuv_playback_info *yi = &itv->yuv_info; | 703 | int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt); |
727 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
728 | int streamtype = 0; | ||
729 | 704 | ||
730 | if (filp) { | 705 | if (ret == 0) { |
731 | id = (struct ivtv_open_id *)filp->private_data; | 706 | itv->osd_chroma_key = fmt->fmt.win.chromakey; |
732 | streamtype = id->type; | 707 | itv->osd_global_alpha = fmt->fmt.win.global_alpha; |
708 | ivtv_set_osd_alpha(itv); | ||
733 | } | 709 | } |
710 | return ret; | ||
711 | } | ||
734 | 712 | ||
735 | switch (cmd) { | 713 | static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip) |
736 | case VIDIOC_G_PRIORITY: | 714 | { |
737 | { | 715 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
738 | enum v4l2_priority *p = arg; | ||
739 | 716 | ||
740 | *p = v4l2_prio_max(&itv->prio); | 717 | chip->ident = V4L2_IDENT_NONE; |
741 | break; | 718 | chip->revision = 0; |
719 | if (chip->match_type == V4L2_CHIP_MATCH_HOST) { | ||
720 | if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) | ||
721 | chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; | ||
722 | return 0; | ||
742 | } | 723 | } |
724 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | ||
725 | return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); | ||
726 | if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) | ||
727 | return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); | ||
728 | return -EINVAL; | ||
729 | } | ||
743 | 730 | ||
744 | case VIDIOC_S_PRIORITY: | 731 | static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) |
745 | { | 732 | { |
746 | enum v4l2_priority *prio = arg; | 733 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
747 | 734 | ||
748 | return v4l2_prio_change(&itv->prio, &id->prio, *prio); | 735 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
749 | } | 736 | return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); |
737 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) | ||
738 | return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); | ||
739 | return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); | ||
740 | } | ||
750 | 741 | ||
751 | case VIDIOC_QUERYCAP:{ | 742 | static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg) |
752 | struct v4l2_capability *vcap = arg; | 743 | { |
744 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
753 | 745 | ||
754 | memset(vcap, 0, sizeof(*vcap)); | 746 | if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
755 | strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); | 747 | return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); |
756 | strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); | 748 | if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) |
757 | strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); | 749 | return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); |
758 | vcap->version = IVTV_DRIVER_VERSION; /* version */ | 750 | return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); |
759 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ | 751 | } |
760 | 752 | ||
761 | /* reserved.. must set to 0! */ | 753 | static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p) |
762 | vcap->reserved[0] = vcap->reserved[1] = | 754 | { |
763 | vcap->reserved[2] = vcap->reserved[3] = 0; | 755 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
764 | break; | ||
765 | } | ||
766 | 756 | ||
767 | case VIDIOC_ENUMAUDIO:{ | 757 | *p = v4l2_prio_max(&itv->prio); |
768 | struct v4l2_audio *vin = arg; | ||
769 | 758 | ||
770 | return ivtv_get_audio_input(itv, vin->index, vin); | 759 | return 0; |
771 | } | 760 | } |
772 | 761 | ||
773 | case VIDIOC_G_AUDIO:{ | 762 | static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio) |
774 | struct v4l2_audio *vin = arg; | 763 | { |
764 | struct ivtv_open_id *id = fh; | ||
765 | struct ivtv *itv = id->itv; | ||
775 | 766 | ||
776 | vin->index = itv->audio_input; | 767 | return v4l2_prio_change(&itv->prio, &id->prio, prio); |
777 | return ivtv_get_audio_input(itv, vin->index, vin); | 768 | } |
778 | } | ||
779 | 769 | ||
780 | case VIDIOC_S_AUDIO:{ | 770 | static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) |
781 | struct v4l2_audio *vout = arg; | 771 | { |
772 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
773 | |||
774 | memset(vcap, 0, sizeof(*vcap)); | ||
775 | strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); | ||
776 | strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); | ||
777 | strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); | ||
778 | vcap->version = IVTV_DRIVER_VERSION; /* version */ | ||
779 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ | ||
780 | /* reserved.. must set to 0! */ | ||
781 | vcap->reserved[0] = vcap->reserved[1] = | ||
782 | vcap->reserved[2] = vcap->reserved[3] = 0; | ||
783 | return 0; | ||
784 | } | ||
782 | 785 | ||
783 | if (vout->index >= itv->nof_audio_inputs) | 786 | static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) |
784 | return -EINVAL; | 787 | { |
785 | itv->audio_input = vout->index; | 788 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
786 | ivtv_audio_set_io(itv); | ||
787 | break; | ||
788 | } | ||
789 | 789 | ||
790 | case VIDIOC_ENUMAUDOUT:{ | 790 | return ivtv_get_audio_input(itv, vin->index, vin); |
791 | struct v4l2_audioout *vin = arg; | 791 | } |
792 | 792 | ||
793 | /* set it to defaults from our table */ | 793 | static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) |
794 | return ivtv_get_audio_output(itv, vin->index, vin); | 794 | { |
795 | } | 795 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
796 | 796 | ||
797 | case VIDIOC_G_AUDOUT:{ | 797 | vin->index = itv->audio_input; |
798 | struct v4l2_audioout *vin = arg; | 798 | return ivtv_get_audio_input(itv, vin->index, vin); |
799 | } | ||
799 | 800 | ||
800 | vin->index = 0; | 801 | static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) |
801 | return ivtv_get_audio_output(itv, vin->index, vin); | 802 | { |
802 | } | 803 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
803 | 804 | ||
804 | case VIDIOC_S_AUDOUT:{ | 805 | if (vout->index >= itv->nof_audio_inputs) |
805 | struct v4l2_audioout *vout = arg; | 806 | return -EINVAL; |
806 | 807 | ||
807 | return ivtv_get_audio_output(itv, vout->index, vout); | 808 | itv->audio_input = vout->index; |
808 | } | 809 | ivtv_audio_set_io(itv); |
809 | 810 | ||
810 | case VIDIOC_ENUMINPUT:{ | 811 | return 0; |
811 | struct v4l2_input *vin = arg; | 812 | } |
812 | 813 | ||
813 | /* set it to defaults from our table */ | 814 | static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin) |
814 | return ivtv_get_input(itv, vin->index, vin); | 815 | { |
815 | } | 816 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
816 | 817 | ||
817 | case VIDIOC_ENUMOUTPUT:{ | 818 | /* set it to defaults from our table */ |
818 | struct v4l2_output *vout = arg; | 819 | return ivtv_get_audio_output(itv, vin->index, vin); |
820 | } | ||
819 | 821 | ||
820 | return ivtv_get_output(itv, vout->index, vout); | 822 | static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin) |
821 | } | 823 | { |
824 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
822 | 825 | ||
823 | case VIDIOC_TRY_FMT: | 826 | vin->index = 0; |
824 | case VIDIOC_S_FMT: { | 827 | return ivtv_get_audio_output(itv, vin->index, vin); |
825 | struct v4l2_format *fmt = arg; | 828 | } |
826 | 829 | ||
827 | return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT); | 830 | static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout) |
828 | } | 831 | { |
832 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
829 | 833 | ||
830 | case VIDIOC_G_FMT: { | 834 | return ivtv_get_audio_output(itv, vout->index, vout); |
831 | struct v4l2_format *fmt = arg; | 835 | } |
832 | int type = fmt->type; | ||
833 | 836 | ||
834 | memset(fmt, 0, sizeof(*fmt)); | 837 | static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin) |
835 | fmt->type = type; | 838 | { |
836 | return ivtv_get_fmt(itv, id->type, fmt); | 839 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
837 | } | ||
838 | 840 | ||
839 | case VIDIOC_CROPCAP: { | 841 | /* set it to defaults from our table */ |
840 | struct v4l2_cropcap *cropcap = arg; | 842 | return ivtv_get_input(itv, vin->index, vin); |
843 | } | ||
841 | 844 | ||
842 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | 845 | static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout) |
843 | return -EINVAL; | 846 | { |
844 | cropcap->bounds.top = cropcap->bounds.left = 0; | 847 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
845 | cropcap->bounds.width = 720; | 848 | |
846 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 849 | return ivtv_get_output(itv, vout->index, vout); |
847 | cropcap->bounds.height = itv->is_50hz ? 576 : 480; | 850 | } |
848 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | 851 | |
849 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | 852 | static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) |
850 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 853 | { |
851 | if (yi->track_osd) { | 854 | struct ivtv_open_id *id = fh; |
852 | cropcap->bounds.width = yi->osd_full_w; | 855 | struct ivtv *itv = id->itv; |
853 | cropcap->bounds.height = yi->osd_full_h; | 856 | struct yuv_playback_info *yi = &itv->yuv_info; |
854 | } else { | 857 | int streamtype; |
855 | cropcap->bounds.width = 720; | 858 | |
856 | cropcap->bounds.height = | 859 | streamtype = id->type; |
857 | itv->is_out_50hz ? 576 : 480; | 860 | |
858 | } | 861 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
859 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | 862 | return -EINVAL; |
860 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | 863 | cropcap->bounds.top = cropcap->bounds.left = 0; |
864 | cropcap->bounds.width = 720; | ||
865 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
866 | cropcap->bounds.height = itv->is_50hz ? 576 : 480; | ||
867 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | ||
868 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | ||
869 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
870 | if (yi->track_osd) { | ||
871 | cropcap->bounds.width = yi->osd_full_w; | ||
872 | cropcap->bounds.height = yi->osd_full_h; | ||
861 | } else { | 873 | } else { |
862 | cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; | 874 | cropcap->bounds.width = 720; |
863 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | 875 | cropcap->bounds.height = |
864 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | 876 | itv->is_out_50hz ? 576 : 480; |
865 | } | 877 | } |
866 | cropcap->defrect = cropcap->bounds; | 878 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; |
867 | return 0; | 879 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; |
880 | } else { | ||
881 | cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; | ||
882 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | ||
883 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | ||
868 | } | 884 | } |
885 | cropcap->defrect = cropcap->bounds; | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) | ||
890 | { | ||
891 | struct ivtv_open_id *id = fh; | ||
892 | struct ivtv *itv = id->itv; | ||
893 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
894 | int streamtype; | ||
869 | 895 | ||
870 | case VIDIOC_S_CROP: { | 896 | streamtype = id->type; |
871 | struct v4l2_crop *crop = arg; | ||
872 | 897 | ||
873 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 898 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { |
874 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 899 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); |
875 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 900 | /* Should be replaced */ |
876 | yi->main_rect = crop->c; | 901 | /* v4l_printk_ioctl(VIDIOC_S_CROP); */ |
902 | } | ||
903 | |||
904 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
905 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
906 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
907 | yi->main_rect = crop->c; | ||
908 | return 0; | ||
909 | } else { | ||
910 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
911 | crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { | ||
912 | itv->main_rect = crop->c; | ||
877 | return 0; | 913 | return 0; |
878 | } else { | ||
879 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
880 | crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { | ||
881 | itv->main_rect = crop->c; | ||
882 | return 0; | ||
883 | } | ||
884 | } | 914 | } |
885 | return -EINVAL; | ||
886 | } | 915 | } |
887 | return -EINVAL; | 916 | return -EINVAL; |
888 | } | 917 | } |
918 | return -EINVAL; | ||
919 | } | ||
920 | |||
921 | static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) | ||
922 | { | ||
923 | struct ivtv_open_id *id = fh; | ||
924 | struct ivtv *itv = id->itv; | ||
925 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
926 | int streamtype; | ||
889 | 927 | ||
890 | case VIDIOC_G_CROP: { | 928 | streamtype = id->type; |
891 | struct v4l2_crop *crop = arg; | ||
892 | 929 | ||
893 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 930 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
894 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 931 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { |
895 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) | 932 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) |
896 | crop->c = yi->main_rect; | 933 | crop->c = yi->main_rect; |
897 | else | 934 | else |
898 | crop->c = itv->main_rect; | 935 | crop->c = itv->main_rect; |
899 | return 0; | 936 | return 0; |
937 | } | ||
938 | return -EINVAL; | ||
939 | } | ||
940 | |||
941 | static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | ||
942 | { | ||
943 | static struct v4l2_fmtdesc formats[] = { | ||
944 | { 0, 0, 0, | ||
945 | "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, | ||
946 | { 0, 0, 0, 0 } | ||
947 | }, | ||
948 | { 1, 0, V4L2_FMT_FLAG_COMPRESSED, | ||
949 | "MPEG", V4L2_PIX_FMT_MPEG, | ||
950 | { 0, 0, 0, 0 } | ||
900 | } | 951 | } |
952 | }; | ||
953 | enum v4l2_buf_type type = fmt->type; | ||
954 | |||
955 | if (fmt->index > 1) | ||
901 | return -EINVAL; | 956 | return -EINVAL; |
902 | } | ||
903 | 957 | ||
904 | case VIDIOC_ENUM_FMT: { | 958 | *fmt = formats[fmt->index]; |
905 | static struct v4l2_fmtdesc formats[] = { | 959 | fmt->type = type; |
906 | { 0, 0, 0, | 960 | return 0; |
907 | "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, | 961 | } |
908 | { 0, 0, 0, 0 } | ||
909 | }, | ||
910 | { 1, 0, V4L2_FMT_FLAG_COMPRESSED, | ||
911 | "MPEG", V4L2_PIX_FMT_MPEG, | ||
912 | { 0, 0, 0, 0 } | ||
913 | } | ||
914 | }; | ||
915 | struct v4l2_fmtdesc *fmt = arg; | ||
916 | enum v4l2_buf_type type = fmt->type; | ||
917 | 962 | ||
918 | switch (type) { | 963 | static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) |
919 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 964 | { |
920 | break; | 965 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
921 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 966 | |
922 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 967 | static struct v4l2_fmtdesc formats[] = { |
923 | return -EINVAL; | 968 | { 0, 0, 0, |
924 | break; | 969 | "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, |
925 | default: | 970 | { 0, 0, 0, 0 } |
926 | return -EINVAL; | 971 | }, |
972 | { 1, 0, V4L2_FMT_FLAG_COMPRESSED, | ||
973 | "MPEG", V4L2_PIX_FMT_MPEG, | ||
974 | { 0, 0, 0, 0 } | ||
927 | } | 975 | } |
928 | if (fmt->index > 1) | 976 | }; |
929 | return -EINVAL; | 977 | enum v4l2_buf_type type = fmt->type; |
930 | *fmt = formats[fmt->index]; | 978 | |
931 | fmt->type = type; | 979 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
980 | return -EINVAL; | ||
981 | |||
982 | if (fmt->index > 1) | ||
983 | return -EINVAL; | ||
984 | |||
985 | *fmt = formats[fmt->index]; | ||
986 | fmt->type = type; | ||
987 | |||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) | ||
992 | { | ||
993 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
994 | |||
995 | *i = itv->active_input; | ||
996 | |||
997 | return 0; | ||
998 | } | ||
999 | |||
1000 | int ivtv_s_input(struct file *file, void *fh, unsigned int inp) | ||
1001 | { | ||
1002 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
1003 | |||
1004 | if (inp < 0 || inp >= itv->nof_inputs) | ||
1005 | return -EINVAL; | ||
1006 | |||
1007 | if (inp == itv->active_input) { | ||
1008 | IVTV_DEBUG_INFO("Input unchanged\n"); | ||
932 | return 0; | 1009 | return 0; |
933 | } | 1010 | } |
934 | 1011 | ||
935 | case VIDIOC_G_INPUT:{ | 1012 | if (atomic_read(&itv->capturing) > 0) { |
936 | *(int *)arg = itv->active_input; | 1013 | return -EBUSY; |
937 | break; | ||
938 | } | 1014 | } |
939 | 1015 | ||
940 | case VIDIOC_S_INPUT:{ | 1016 | IVTV_DEBUG_INFO("Changing input from %d to %d\n", |
941 | int inp = *(int *)arg; | 1017 | itv->active_input, inp); |
942 | 1018 | ||
943 | if (inp < 0 || inp >= itv->nof_inputs) | 1019 | itv->active_input = inp; |
944 | return -EINVAL; | 1020 | /* Set the audio input to whatever is appropriate for the |
1021 | input type. */ | ||
1022 | itv->audio_input = itv->card->video_inputs[inp].audio_index; | ||
945 | 1023 | ||
946 | if (inp == itv->active_input) { | 1024 | /* prevent others from messing with the streams until |
947 | IVTV_DEBUG_INFO("Input unchanged\n"); | 1025 | we're finished changing inputs. */ |
948 | break; | 1026 | ivtv_mute(itv); |
949 | } | 1027 | ivtv_video_set_io(itv); |
950 | if (atomic_read(&itv->capturing) > 0) { | 1028 | ivtv_audio_set_io(itv); |
951 | return -EBUSY; | 1029 | ivtv_unmute(itv); |
952 | } | ||
953 | IVTV_DEBUG_INFO("Changing input from %d to %d\n", | ||
954 | itv->active_input, inp); | ||
955 | 1030 | ||
956 | itv->active_input = inp; | 1031 | return 0; |
957 | /* Set the audio input to whatever is appropriate for the | 1032 | } |
958 | input type. */ | ||
959 | itv->audio_input = itv->card->video_inputs[inp].audio_index; | ||
960 | 1033 | ||
961 | /* prevent others from messing with the streams until | 1034 | static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) |
962 | we're finished changing inputs. */ | 1035 | { |
963 | ivtv_mute(itv); | 1036 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
964 | ivtv_video_set_io(itv); | ||
965 | ivtv_audio_set_io(itv); | ||
966 | ivtv_unmute(itv); | ||
967 | break; | ||
968 | } | ||
969 | 1037 | ||
970 | case VIDIOC_G_OUTPUT:{ | 1038 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
971 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 1039 | return -EINVAL; |
972 | return -EINVAL; | ||
973 | *(int *)arg = itv->active_output; | ||
974 | break; | ||
975 | } | ||
976 | 1040 | ||
977 | case VIDIOC_S_OUTPUT:{ | 1041 | *i = itv->active_output; |
978 | int outp = *(int *)arg; | ||
979 | struct v4l2_routing route; | ||
980 | 1042 | ||
981 | if (outp >= itv->card->nof_outputs) | 1043 | return 0; |
982 | return -EINVAL; | 1044 | } |
983 | 1045 | ||
984 | if (outp == itv->active_output) { | 1046 | static int ivtv_s_output(struct file *file, void *fh, unsigned int outp) |
985 | IVTV_DEBUG_INFO("Output unchanged\n"); | 1047 | { |
986 | break; | 1048 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
987 | } | 1049 | struct v4l2_routing route; |
988 | IVTV_DEBUG_INFO("Changing output from %d to %d\n", | ||
989 | itv->active_output, outp); | ||
990 | 1050 | ||
991 | itv->active_output = outp; | 1051 | if (outp >= itv->card->nof_outputs) |
992 | route.input = SAA7127_INPUT_TYPE_NORMAL; | 1052 | return -EINVAL; |
993 | route.output = itv->card->video_outputs[outp].video_output; | 1053 | |
994 | ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 1054 | if (outp == itv->active_output) { |
995 | break; | 1055 | IVTV_DEBUG_INFO("Output unchanged\n"); |
1056 | return 0; | ||
996 | } | 1057 | } |
1058 | IVTV_DEBUG_INFO("Changing output from %d to %d\n", | ||
1059 | itv->active_output, outp); | ||
997 | 1060 | ||
998 | case VIDIOC_G_FREQUENCY:{ | 1061 | itv->active_output = outp; |
999 | struct v4l2_frequency *vf = arg; | 1062 | route.input = SAA7127_INPUT_TYPE_NORMAL; |
1063 | route.output = itv->card->video_outputs[outp].video_output; | ||
1064 | ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); | ||
1000 | 1065 | ||
1001 | if (vf->tuner != 0) | 1066 | return 0; |
1002 | return -EINVAL; | 1067 | } |
1003 | ivtv_call_i2c_clients(itv, cmd, arg); | ||
1004 | break; | ||
1005 | } | ||
1006 | 1068 | ||
1007 | case VIDIOC_S_FREQUENCY:{ | 1069 | static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) |
1008 | struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; | 1070 | { |
1071 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
1009 | 1072 | ||
1010 | if (vf.tuner != 0) | 1073 | if (vf->tuner != 0) |
1011 | return -EINVAL; | 1074 | return -EINVAL; |
1012 | 1075 | ||
1013 | ivtv_mute(itv); | 1076 | ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf); |
1014 | IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency); | 1077 | return 0; |
1015 | ivtv_call_i2c_clients(itv, cmd, &vf); | 1078 | } |
1016 | ivtv_unmute(itv); | ||
1017 | break; | ||
1018 | } | ||
1019 | 1079 | ||
1020 | case VIDIOC_ENUMSTD:{ | 1080 | int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) |
1021 | struct v4l2_standard *vs = arg; | 1081 | { |
1022 | int idx = vs->index; | 1082 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1023 | 1083 | ||
1024 | if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) | 1084 | if (vf->tuner != 0) |
1025 | return -EINVAL; | 1085 | return -EINVAL; |
1026 | 1086 | ||
1027 | *vs = (enum_stds[idx].std & V4L2_STD_525_60) ? | 1087 | ivtv_mute(itv); |
1028 | ivtv_std_60hz : ivtv_std_50hz; | 1088 | IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); |
1029 | vs->index = idx; | 1089 | ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf); |
1030 | vs->id = enum_stds[idx].std; | 1090 | ivtv_unmute(itv); |
1031 | strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name)); | 1091 | return 0; |
1032 | break; | 1092 | } |
1033 | } | ||
1034 | 1093 | ||
1035 | case VIDIOC_G_STD:{ | 1094 | static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) |
1036 | *(v4l2_std_id *) arg = itv->std; | 1095 | { |
1037 | break; | 1096 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1038 | } | ||
1039 | 1097 | ||
1040 | case VIDIOC_S_STD: { | 1098 | *std = itv->std; |
1041 | v4l2_std_id std = *(v4l2_std_id *) arg; | 1099 | return 0; |
1100 | } | ||
1042 | 1101 | ||
1043 | if ((std & V4L2_STD_ALL) == 0) | 1102 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) |
1044 | return -EINVAL; | 1103 | { |
1104 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
1105 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1045 | 1106 | ||
1046 | if (std == itv->std) | 1107 | if ((*std & V4L2_STD_ALL) == 0) |
1047 | break; | 1108 | return -EINVAL; |
1048 | 1109 | ||
1049 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || | 1110 | if (*std == itv->std) |
1050 | atomic_read(&itv->capturing) > 0 || | 1111 | return 0; |
1051 | atomic_read(&itv->decoding) > 0) { | ||
1052 | /* Switching standard would turn off the radio or mess | ||
1053 | with already running streams, prevent that by | ||
1054 | returning EBUSY. */ | ||
1055 | return -EBUSY; | ||
1056 | } | ||
1057 | 1112 | ||
1058 | itv->std = std; | 1113 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || |
1059 | itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0; | 1114 | atomic_read(&itv->capturing) > 0 || |
1060 | itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; | 1115 | atomic_read(&itv->decoding) > 0) { |
1061 | itv->params.width = 720; | 1116 | /* Switching standard would turn off the radio or mess |
1062 | itv->params.height = itv->is_50hz ? 576 : 480; | 1117 | with already running streams, prevent that by |
1063 | itv->vbi.count = itv->is_50hz ? 18 : 12; | 1118 | returning EBUSY. */ |
1064 | itv->vbi.start[0] = itv->is_50hz ? 6 : 10; | 1119 | return -EBUSY; |
1065 | itv->vbi.start[1] = itv->is_50hz ? 318 : 273; | 1120 | } |
1066 | if (itv->hw_flags & IVTV_HW_CX25840) { | 1121 | |
1067 | itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; | 1122 | itv->std = *std; |
1068 | } | 1123 | itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; |
1069 | IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); | 1124 | itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; |
1070 | 1125 | itv->params.width = 720; | |
1071 | /* Tuner */ | 1126 | itv->params.height = itv->is_50hz ? 576 : 480; |
1072 | ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); | 1127 | itv->vbi.count = itv->is_50hz ? 18 : 12; |
1073 | 1128 | itv->vbi.start[0] = itv->is_50hz ? 6 : 10; | |
1074 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | 1129 | itv->vbi.start[1] = itv->is_50hz ? 318 : 273; |
1075 | /* set display standard */ | 1130 | |
1076 | itv->std_out = std; | 1131 | if (itv->hw_flags & IVTV_HW_CX25840) |
1077 | itv->is_out_60hz = itv->is_60hz; | 1132 | itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; |
1078 | itv->is_out_50hz = itv->is_50hz; | 1133 | |
1079 | ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); | 1134 | IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); |
1080 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); | 1135 | |
1081 | itv->main_rect.left = itv->main_rect.top = 0; | 1136 | /* Tuner */ |
1082 | itv->main_rect.width = 720; | 1137 | ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); |
1083 | itv->main_rect.height = itv->params.height; | 1138 | |
1084 | ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | 1139 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { |
1085 | 720, itv->main_rect.height, 0, 0); | 1140 | /* set display standard */ |
1086 | yi->main_rect = itv->main_rect; | 1141 | itv->std_out = *std; |
1087 | if (!itv->osd_info) { | 1142 | itv->is_out_60hz = itv->is_60hz; |
1088 | yi->osd_full_w = 720; | 1143 | itv->is_out_50hz = itv->is_50hz; |
1089 | yi->osd_full_h = itv->is_out_50hz ? 576 : 480; | 1144 | ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); |
1090 | } | 1145 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); |
1146 | itv->main_rect.left = itv->main_rect.top = 0; | ||
1147 | itv->main_rect.width = 720; | ||
1148 | itv->main_rect.height = itv->params.height; | ||
1149 | ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
1150 | 720, itv->main_rect.height, 0, 0); | ||
1151 | yi->main_rect = itv->main_rect; | ||
1152 | if (!itv->osd_info) { | ||
1153 | yi->osd_full_w = 720; | ||
1154 | yi->osd_full_h = itv->is_out_50hz ? 576 : 480; | ||
1091 | } | 1155 | } |
1092 | break; | ||
1093 | } | 1156 | } |
1157 | return 0; | ||
1158 | } | ||
1094 | 1159 | ||
1095 | case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ | 1160 | static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) |
1096 | struct v4l2_tuner *vt = arg; | 1161 | { |
1162 | struct ivtv_open_id *id = fh; | ||
1163 | struct ivtv *itv = id->itv; | ||
1097 | 1164 | ||
1098 | if (vt->index != 0) | 1165 | if (vt->index != 0) |
1099 | return -EINVAL; | 1166 | return -EINVAL; |
1100 | 1167 | ||
1101 | ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); | 1168 | ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); |
1102 | break; | ||
1103 | } | ||
1104 | 1169 | ||
1105 | case VIDIOC_G_TUNER: { | 1170 | return 0; |
1106 | struct v4l2_tuner *vt = arg; | 1171 | } |
1107 | 1172 | ||
1108 | if (vt->index != 0) | 1173 | static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) |
1109 | return -EINVAL; | 1174 | { |
1175 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
1110 | 1176 | ||
1111 | memset(vt, 0, sizeof(*vt)); | 1177 | if (vt->index != 0) |
1112 | ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); | 1178 | return -EINVAL; |
1113 | 1179 | ||
1114 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | 1180 | memset(vt, 0, sizeof(*vt)); |
1115 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); | 1181 | ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); |
1116 | vt->type = V4L2_TUNER_RADIO; | 1182 | |
1117 | } else { | 1183 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { |
1118 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); | 1184 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); |
1119 | vt->type = V4L2_TUNER_ANALOG_TV; | 1185 | vt->type = V4L2_TUNER_RADIO; |
1120 | } | 1186 | } else { |
1121 | break; | 1187 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); |
1188 | vt->type = V4L2_TUNER_ANALOG_TV; | ||
1122 | } | 1189 | } |
1123 | 1190 | ||
1124 | case VIDIOC_G_SLICED_VBI_CAP: { | 1191 | return 0; |
1125 | struct v4l2_sliced_vbi_cap *cap = arg; | 1192 | } |
1126 | int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; | 1193 | |
1127 | int f, l; | 1194 | static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) |
1128 | enum v4l2_buf_type type = cap->type; | 1195 | { |
1129 | 1196 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | |
1130 | memset(cap, 0, sizeof(*cap)); | 1197 | int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; |
1131 | cap->type = type; | 1198 | int f, l; |
1132 | if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { | 1199 | enum v4l2_buf_type type = cap->type; |
1133 | for (f = 0; f < 2; f++) { | 1200 | |
1134 | for (l = 0; l < 24; l++) { | 1201 | memset(cap, 0, sizeof(*cap)); |
1135 | if (valid_service_line(f, l, itv->is_50hz)) { | 1202 | cap->type = type; |
1136 | cap->service_lines[f][l] = set; | 1203 | if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { |
1137 | } | 1204 | for (f = 0; f < 2; f++) { |
1138 | } | 1205 | for (l = 0; l < 24; l++) { |
1206 | if (valid_service_line(f, l, itv->is_50hz)) | ||
1207 | cap->service_lines[f][l] = set; | ||
1139 | } | 1208 | } |
1140 | return 0; | ||
1141 | } | 1209 | } |
1142 | if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { | 1210 | return 0; |
1143 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) | 1211 | } |
1144 | return -EINVAL; | 1212 | if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { |
1145 | if (itv->is_60hz) { | 1213 | if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) |
1146 | cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; | 1214 | return -EINVAL; |
1147 | cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; | 1215 | if (itv->is_60hz) { |
1148 | } else { | 1216 | cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; |
1149 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; | 1217 | cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; |
1150 | cap->service_lines[0][16] = V4L2_SLICED_VPS; | 1218 | } else { |
1151 | } | 1219 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; |
1152 | return 0; | 1220 | cap->service_lines[0][16] = V4L2_SLICED_VPS; |
1153 | } | 1221 | } |
1154 | return -EINVAL; | 1222 | return 0; |
1155 | } | 1223 | } |
1224 | return -EINVAL; | ||
1225 | } | ||
1156 | 1226 | ||
1157 | case VIDIOC_G_ENC_INDEX: { | 1227 | static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) |
1158 | struct v4l2_enc_idx *idx = arg; | 1228 | { |
1159 | struct v4l2_enc_idx_entry *e = idx->entry; | 1229 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1160 | int entries; | 1230 | struct v4l2_enc_idx_entry *e = idx->entry; |
1161 | int i; | 1231 | int entries; |
1162 | 1232 | int i; | |
1163 | entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % | 1233 | |
1164 | IVTV_MAX_PGM_INDEX; | 1234 | entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % |
1165 | if (entries > V4L2_ENC_IDX_ENTRIES) | 1235 | IVTV_MAX_PGM_INDEX; |
1166 | entries = V4L2_ENC_IDX_ENTRIES; | 1236 | if (entries > V4L2_ENC_IDX_ENTRIES) |
1167 | idx->entries = 0; | 1237 | entries = V4L2_ENC_IDX_ENTRIES; |
1168 | for (i = 0; i < entries; i++) { | 1238 | idx->entries = 0; |
1169 | *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; | 1239 | for (i = 0; i < entries; i++) { |
1170 | if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { | 1240 | *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; |
1171 | idx->entries++; | 1241 | if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { |
1172 | e++; | 1242 | idx->entries++; |
1173 | } | 1243 | e++; |
1174 | } | 1244 | } |
1175 | itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; | ||
1176 | break; | ||
1177 | } | 1245 | } |
1246 | itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; | ||
1247 | return 0; | ||
1248 | } | ||
1178 | 1249 | ||
1179 | case VIDIOC_ENCODER_CMD: | 1250 | static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) |
1180 | case VIDIOC_TRY_ENCODER_CMD: { | 1251 | { |
1181 | struct v4l2_encoder_cmd *enc = arg; | 1252 | struct ivtv_open_id *id = fh; |
1182 | int try = cmd == VIDIOC_TRY_ENCODER_CMD; | 1253 | struct ivtv *itv = id->itv; |
1183 | |||
1184 | memset(&enc->raw, 0, sizeof(enc->raw)); | ||
1185 | switch (enc->cmd) { | ||
1186 | case V4L2_ENC_CMD_START: | ||
1187 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); | ||
1188 | enc->flags = 0; | ||
1189 | if (try) | ||
1190 | return 0; | ||
1191 | return ivtv_start_capture(id); | ||
1192 | 1254 | ||
1193 | case V4L2_ENC_CMD_STOP: | 1255 | memset(&enc->raw, 0, sizeof(enc->raw)); |
1194 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); | 1256 | |
1195 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; | 1257 | switch (enc->cmd) { |
1196 | if (try) | 1258 | case V4L2_ENC_CMD_START: |
1197 | return 0; | 1259 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); |
1198 | ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); | 1260 | enc->flags = 0; |
1261 | return ivtv_start_capture(id); | ||
1262 | |||
1263 | case V4L2_ENC_CMD_STOP: | ||
1264 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); | ||
1265 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; | ||
1266 | ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); | ||
1267 | return 0; | ||
1268 | |||
1269 | case V4L2_ENC_CMD_PAUSE: | ||
1270 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); | ||
1271 | enc->flags = 0; | ||
1272 | |||
1273 | if (!atomic_read(&itv->capturing)) | ||
1274 | return -EPERM; | ||
1275 | if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | ||
1199 | return 0; | 1276 | return 0; |
1200 | 1277 | ||
1201 | case V4L2_ENC_CMD_PAUSE: | 1278 | ivtv_mute(itv); |
1202 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); | 1279 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); |
1203 | enc->flags = 0; | 1280 | break; |
1204 | if (try) | ||
1205 | return 0; | ||
1206 | if (!atomic_read(&itv->capturing)) | ||
1207 | return -EPERM; | ||
1208 | if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | ||
1209 | return 0; | ||
1210 | ivtv_mute(itv); | ||
1211 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); | ||
1212 | break; | ||
1213 | 1281 | ||
1214 | case V4L2_ENC_CMD_RESUME: | 1282 | case V4L2_ENC_CMD_RESUME: |
1215 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); | 1283 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); |
1216 | enc->flags = 0; | 1284 | enc->flags = 0; |
1217 | if (try) | 1285 | |
1218 | return 0; | 1286 | if (!atomic_read(&itv->capturing)) |
1219 | if (!atomic_read(&itv->capturing)) | 1287 | return -EPERM; |
1220 | return -EPERM; | 1288 | |
1221 | if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) | 1289 | if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) |
1222 | return 0; | 1290 | return 0; |
1223 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); | 1291 | |
1224 | ivtv_unmute(itv); | 1292 | ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); |
1225 | break; | 1293 | ivtv_unmute(itv); |
1226 | default: | ||
1227 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1228 | return -EINVAL; | ||
1229 | } | ||
1230 | break; | 1294 | break; |
1295 | default: | ||
1296 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1297 | return -EINVAL; | ||
1231 | } | 1298 | } |
1232 | 1299 | ||
1233 | case VIDIOC_G_FBUF: { | 1300 | return 0; |
1234 | struct v4l2_framebuffer *fb = arg; | 1301 | } |
1235 | int pixfmt; | ||
1236 | static u32 pixel_format[16] = { | ||
1237 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ | ||
1238 | V4L2_PIX_FMT_RGB565, | ||
1239 | V4L2_PIX_FMT_RGB555, | ||
1240 | V4L2_PIX_FMT_RGB444, | ||
1241 | V4L2_PIX_FMT_RGB32, | ||
1242 | 0, | ||
1243 | 0, | ||
1244 | 0, | ||
1245 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ | ||
1246 | V4L2_PIX_FMT_YUV565, | ||
1247 | V4L2_PIX_FMT_YUV555, | ||
1248 | V4L2_PIX_FMT_YUV444, | ||
1249 | V4L2_PIX_FMT_YUV32, | ||
1250 | 0, | ||
1251 | 0, | ||
1252 | 0, | ||
1253 | }; | ||
1254 | 1302 | ||
1255 | memset(fb, 0, sizeof(*fb)); | 1303 | static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) |
1256 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1304 | { |
1257 | return -EINVAL; | 1305 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1258 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | 1306 | |
1259 | V4L2_FBUF_CAP_GLOBAL_ALPHA; | 1307 | memset(&enc->raw, 0, sizeof(enc->raw)); |
1260 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | 1308 | |
1261 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | 1309 | switch (enc->cmd) { |
1262 | pixfmt = (data[0] >> 3) & 0xf; | 1310 | case V4L2_ENC_CMD_START: |
1263 | fb->fmt.pixelformat = pixel_format[pixfmt]; | 1311 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); |
1264 | fb->fmt.width = itv->osd_rect.width; | 1312 | enc->flags = 0; |
1265 | fb->fmt.height = itv->osd_rect.height; | 1313 | return 0; |
1266 | fb->base = (void *)itv->osd_video_pbase; | 1314 | |
1267 | if (itv->osd_chroma_key_state) | 1315 | case V4L2_ENC_CMD_STOP: |
1268 | fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; | 1316 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); |
1269 | if (itv->osd_global_alpha_state) | 1317 | enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; |
1270 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; | 1318 | return 0; |
1271 | pixfmt &= 7; | 1319 | |
1272 | /* no local alpha for RGB565 or unknown formats */ | 1320 | case V4L2_ENC_CMD_PAUSE: |
1273 | if (pixfmt == 1 || pixfmt > 4) | 1321 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); |
1274 | break; | 1322 | enc->flags = 0; |
1323 | return 0; | ||
1324 | |||
1325 | case V4L2_ENC_CMD_RESUME: | ||
1326 | IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); | ||
1327 | enc->flags = 0; | ||
1328 | return 0; | ||
1329 | default: | ||
1330 | IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); | ||
1331 | return -EINVAL; | ||
1332 | } | ||
1333 | } | ||
1334 | |||
1335 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | ||
1336 | { | ||
1337 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | ||
1338 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
1339 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
1340 | |||
1341 | int pixfmt; | ||
1342 | static u32 pixel_format[16] = { | ||
1343 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ | ||
1344 | V4L2_PIX_FMT_RGB565, | ||
1345 | V4L2_PIX_FMT_RGB555, | ||
1346 | V4L2_PIX_FMT_RGB444, | ||
1347 | V4L2_PIX_FMT_RGB32, | ||
1348 | 0, | ||
1349 | 0, | ||
1350 | 0, | ||
1351 | V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ | ||
1352 | V4L2_PIX_FMT_YUV565, | ||
1353 | V4L2_PIX_FMT_YUV555, | ||
1354 | V4L2_PIX_FMT_YUV444, | ||
1355 | V4L2_PIX_FMT_YUV32, | ||
1356 | 0, | ||
1357 | 0, | ||
1358 | 0, | ||
1359 | }; | ||
1360 | |||
1361 | memset(fb, 0, sizeof(*fb)); | ||
1362 | |||
1363 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | ||
1364 | return -EINVAL; | ||
1365 | |||
1366 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | ||
1367 | V4L2_FBUF_CAP_GLOBAL_ALPHA; | ||
1368 | |||
1369 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | ||
1370 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1371 | pixfmt = (data[0] >> 3) & 0xf; | ||
1372 | |||
1373 | fb->fmt.pixelformat = pixel_format[pixfmt]; | ||
1374 | fb->fmt.width = itv->osd_rect.width; | ||
1375 | fb->fmt.height = itv->osd_rect.height; | ||
1376 | fb->base = (void *)itv->osd_video_pbase; | ||
1377 | |||
1378 | if (itv->osd_chroma_key_state) | ||
1379 | fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; | ||
1380 | |||
1381 | if (itv->osd_global_alpha_state) | ||
1382 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; | ||
1383 | |||
1384 | pixfmt &= 7; | ||
1385 | |||
1386 | /* no local alpha for RGB565 or unknown formats */ | ||
1387 | if (pixfmt == 1 || pixfmt > 4) | ||
1388 | return 0; | ||
1389 | |||
1390 | /* 16-bit formats have inverted local alpha */ | ||
1391 | if (pixfmt == 2 || pixfmt == 3) | ||
1392 | fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; | ||
1393 | else | ||
1394 | fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; | ||
1395 | |||
1396 | if (itv->osd_local_alpha_state) { | ||
1275 | /* 16-bit formats have inverted local alpha */ | 1397 | /* 16-bit formats have inverted local alpha */ |
1276 | if (pixfmt == 2 || pixfmt == 3) | 1398 | if (pixfmt == 2 || pixfmt == 3) |
1277 | fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; | 1399 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; |
1278 | else | 1400 | else |
1279 | fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; | 1401 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; |
1280 | if (itv->osd_local_alpha_state) { | ||
1281 | /* 16-bit formats have inverted local alpha */ | ||
1282 | if (pixfmt == 2 || pixfmt == 3) | ||
1283 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; | ||
1284 | else | ||
1285 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | ||
1286 | } | ||
1287 | if (yi->track_osd) | ||
1288 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1289 | break; | ||
1290 | } | 1402 | } |
1403 | if (yi->track_osd) | ||
1404 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1291 | 1405 | ||
1292 | case VIDIOC_S_FBUF: { | 1406 | return 0; |
1293 | struct v4l2_framebuffer *fb = arg; | 1407 | } |
1294 | 1408 | ||
1295 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1409 | static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) |
1296 | return -EINVAL; | 1410 | { |
1297 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | 1411 | struct ivtv_open_id *id = fh; |
1298 | itv->osd_local_alpha_state = | 1412 | struct ivtv *itv = id->itv; |
1299 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; | 1413 | struct yuv_playback_info *yi = &itv->yuv_info; |
1300 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | ||
1301 | ivtv_set_osd_alpha(itv); | ||
1302 | yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; | ||
1303 | break; | ||
1304 | } | ||
1305 | 1414 | ||
1306 | case VIDIOC_OVERLAY: { | 1415 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1307 | int *on = arg; | 1416 | return -EINVAL; |
1308 | 1417 | ||
1309 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1418 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; |
1310 | return -EINVAL; | 1419 | itv->osd_local_alpha_state = |
1311 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0); | 1420 | (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; |
1312 | break; | 1421 | itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; |
1313 | } | 1422 | ivtv_set_osd_alpha(itv); |
1423 | yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; | ||
1314 | 1424 | ||
1315 | case VIDIOC_LOG_STATUS: | 1425 | return 0; |
1316 | { | 1426 | } |
1317 | int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; | ||
1318 | struct v4l2_input vidin; | ||
1319 | struct v4l2_audio audin; | ||
1320 | int i; | ||
1321 | 1427 | ||
1322 | IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); | 1428 | static int ivtv_overlay(struct file *file, void *fh, unsigned int on) |
1323 | IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); | 1429 | { |
1324 | if (itv->hw_flags & IVTV_HW_TVEEPROM) { | 1430 | struct ivtv_open_id *id = fh; |
1325 | struct tveeprom tv; | 1431 | struct ivtv *itv = id->itv; |
1326 | 1432 | ||
1327 | ivtv_read_eeprom(itv, &tv); | 1433 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1328 | } | 1434 | return -EINVAL; |
1329 | ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); | 1435 | |
1330 | ivtv_get_input(itv, itv->active_input, &vidin); | 1436 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); |
1331 | ivtv_get_audio_input(itv, itv->audio_input, &audin); | 1437 | |
1332 | IVTV_INFO("Video Input: %s\n", vidin.name); | 1438 | return 0; |
1333 | IVTV_INFO("Audio Input: %s%s\n", audin.name, | 1439 | } |
1334 | (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); | 1440 | |
1335 | if (has_output) { | 1441 | static int ivtv_log_status(struct file *file, void *fh) |
1336 | struct v4l2_output vidout; | 1442 | { |
1337 | struct v4l2_audioout audout; | 1443 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1338 | int mode = itv->output_mode; | 1444 | u32 data[CX2341X_MBOX_MAX_DATA]; |
1339 | static const char * const output_modes[5] = { | 1445 | |
1340 | "None", | 1446 | int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; |
1341 | "MPEG Streaming", | 1447 | struct v4l2_input vidin; |
1342 | "YUV Streaming", | 1448 | struct v4l2_audio audin; |
1343 | "YUV Frames", | 1449 | int i; |
1344 | "Passthrough", | 1450 | |
1345 | }; | 1451 | IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); |
1346 | static const char * const audio_modes[5] = { | 1452 | IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); |
1347 | "Stereo", | 1453 | if (itv->hw_flags & IVTV_HW_TVEEPROM) { |
1348 | "Left", | 1454 | struct tveeprom tv; |
1349 | "Right", | 1455 | |
1350 | "Mono", | 1456 | ivtv_read_eeprom(itv, &tv); |
1351 | "Swapped" | 1457 | } |
1352 | }; | 1458 | ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); |
1353 | static const char * const alpha_mode[4] = { | 1459 | ivtv_get_input(itv, itv->active_input, &vidin); |
1354 | "None", | 1460 | ivtv_get_audio_input(itv, itv->audio_input, &audin); |
1355 | "Global", | 1461 | IVTV_INFO("Video Input: %s\n", vidin.name); |
1356 | "Local", | 1462 | IVTV_INFO("Audio Input: %s%s\n", audin.name, |
1357 | "Global and Local" | 1463 | (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); |
1358 | }; | 1464 | if (has_output) { |
1359 | static const char * const pixel_format[16] = { | 1465 | struct v4l2_output vidout; |
1360 | "ARGB Indexed", | 1466 | struct v4l2_audioout audout; |
1361 | "RGB 5:6:5", | 1467 | int mode = itv->output_mode; |
1362 | "ARGB 1:5:5:5", | 1468 | static const char * const output_modes[5] = { |
1363 | "ARGB 1:4:4:4", | 1469 | "None", |
1364 | "ARGB 8:8:8:8", | 1470 | "MPEG Streaming", |
1365 | "5", | 1471 | "YUV Streaming", |
1366 | "6", | 1472 | "YUV Frames", |
1367 | "7", | 1473 | "Passthrough", |
1368 | "AYUV Indexed", | 1474 | }; |
1369 | "YUV 5:6:5", | 1475 | static const char * const audio_modes[5] = { |
1370 | "AYUV 1:5:5:5", | 1476 | "Stereo", |
1371 | "AYUV 1:4:4:4", | 1477 | "Left", |
1372 | "AYUV 8:8:8:8", | 1478 | "Right", |
1373 | "13", | 1479 | "Mono", |
1374 | "14", | 1480 | "Swapped" |
1375 | "15", | 1481 | }; |
1376 | }; | 1482 | static const char * const alpha_mode[4] = { |
1377 | 1483 | "None", | |
1378 | ivtv_get_output(itv, itv->active_output, &vidout); | 1484 | "Global", |
1379 | ivtv_get_audio_output(itv, 0, &audout); | 1485 | "Local", |
1380 | IVTV_INFO("Video Output: %s\n", vidout.name); | 1486 | "Global and Local" |
1381 | IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, | 1487 | }; |
1382 | audio_modes[itv->audio_stereo_mode], | 1488 | static const char * const pixel_format[16] = { |
1383 | audio_modes[itv->audio_bilingual_mode]); | 1489 | "ARGB Indexed", |
1384 | if (mode < 0 || mode > OUT_PASSTHROUGH) | 1490 | "RGB 5:6:5", |
1385 | mode = OUT_NONE; | 1491 | "ARGB 1:5:5:5", |
1386 | IVTV_INFO("Output Mode: %s\n", output_modes[mode]); | 1492 | "ARGB 1:4:4:4", |
1387 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | 1493 | "ARGB 8:8:8:8", |
1388 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | 1494 | "5", |
1389 | IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", | 1495 | "6", |
1390 | data[0] & 1 ? "On" : "Off", | 1496 | "7", |
1391 | alpha_mode[(data[0] >> 1) & 0x3], | 1497 | "AYUV Indexed", |
1392 | pixel_format[(data[0] >> 3) & 0xf]); | 1498 | "YUV 5:6:5", |
1393 | } | 1499 | "AYUV 1:5:5:5", |
1394 | IVTV_INFO("Tuner: %s\n", | 1500 | "AYUV 1:4:4:4", |
1395 | test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); | 1501 | "AYUV 8:8:8:8", |
1396 | cx2341x_log_status(&itv->params, itv->name); | 1502 | "13", |
1397 | IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); | 1503 | "14", |
1398 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | 1504 | "15", |
1399 | struct ivtv_stream *s = &itv->streams[i]; | 1505 | }; |
1400 | 1506 | ||
1401 | if (s->v4l2dev == NULL || s->buffers == 0) | 1507 | ivtv_get_output(itv, itv->active_output, &vidout); |
1402 | continue; | 1508 | ivtv_get_audio_output(itv, 0, &audout); |
1403 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, | 1509 | IVTV_INFO("Video Output: %s\n", vidout.name); |
1404 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | 1510 | IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, |
1405 | (s->buffers * s->buf_size) / 1024, s->buffers); | 1511 | audio_modes[itv->audio_stereo_mode], |
1406 | } | 1512 | audio_modes[itv->audio_bilingual_mode]); |
1407 | IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); | 1513 | if (mode < 0 || mode > OUT_PASSTHROUGH) |
1408 | IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); | 1514 | mode = OUT_NONE; |
1409 | break; | 1515 | IVTV_INFO("Output Mode: %s\n", output_modes[mode]); |
1516 | ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); | ||
1517 | data[0] |= (read_reg(0x2a00) >> 7) & 0x40; | ||
1518 | IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", | ||
1519 | data[0] & 1 ? "On" : "Off", | ||
1520 | alpha_mode[(data[0] >> 1) & 0x3], | ||
1521 | pixel_format[(data[0] >> 3) & 0xf]); | ||
1410 | } | 1522 | } |
1523 | IVTV_INFO("Tuner: %s\n", | ||
1524 | test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); | ||
1525 | cx2341x_log_status(&itv->params, itv->name); | ||
1526 | IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); | ||
1527 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | ||
1528 | struct ivtv_stream *s = &itv->streams[i]; | ||
1411 | 1529 | ||
1412 | default: | 1530 | if (s->v4l2dev == NULL || s->buffers == 0) |
1413 | return -EINVAL; | 1531 | continue; |
1532 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, | ||
1533 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | ||
1534 | (s->buffers * s->buf_size) / 1024, s->buffers); | ||
1414 | } | 1535 | } |
1536 | |||
1537 | IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); | ||
1538 | IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); | ||
1539 | |||
1415 | return 0; | 1540 | return 0; |
1416 | } | 1541 | } |
1417 | 1542 | ||
@@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
1607 | return 0; | 1732 | return 0; |
1608 | } | 1733 | } |
1609 | 1734 | ||
1610 | static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | 1735 | static int ivtv_default(struct file *file, void *fh, int cmd, void *arg) |
1611 | unsigned int cmd, void *arg) | ||
1612 | { | 1736 | { |
1613 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1737 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1614 | struct ivtv *itv = id->itv; | ||
1615 | int ret; | ||
1616 | 1738 | ||
1617 | /* check priority */ | ||
1618 | switch (cmd) { | 1739 | switch (cmd) { |
1619 | case VIDIOC_S_CTRL: | 1740 | case VIDIOC_INT_S_AUDIO_ROUTING: { |
1620 | case VIDIOC_S_STD: | 1741 | struct v4l2_routing *route = arg; |
1621 | case VIDIOC_S_INPUT: | ||
1622 | case VIDIOC_S_OUTPUT: | ||
1623 | case VIDIOC_S_TUNER: | ||
1624 | case VIDIOC_S_FREQUENCY: | ||
1625 | case VIDIOC_S_FMT: | ||
1626 | case VIDIOC_S_CROP: | ||
1627 | case VIDIOC_S_AUDIO: | ||
1628 | case VIDIOC_S_AUDOUT: | ||
1629 | case VIDIOC_S_EXT_CTRLS: | ||
1630 | case VIDIOC_S_FBUF: | ||
1631 | case VIDIOC_OVERLAY: | ||
1632 | ret = v4l2_prio_check(&itv->prio, &id->prio); | ||
1633 | if (ret) | ||
1634 | return ret; | ||
1635 | } | ||
1636 | |||
1637 | switch (cmd) { | ||
1638 | case VIDIOC_DBG_G_REGISTER: | ||
1639 | case VIDIOC_DBG_S_REGISTER: | ||
1640 | case VIDIOC_G_CHIP_IDENT: | ||
1641 | case VIDIOC_INT_S_AUDIO_ROUTING: | ||
1642 | case VIDIOC_INT_RESET: | ||
1643 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | ||
1644 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | ||
1645 | v4l_printk_ioctl(cmd); | ||
1646 | printk("\n"); | ||
1647 | } | ||
1648 | return ivtv_debug_ioctls(filp, cmd, arg); | ||
1649 | 1742 | ||
1650 | case VIDIOC_G_PRIORITY: | 1743 | ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); |
1651 | case VIDIOC_S_PRIORITY: | 1744 | break; |
1652 | case VIDIOC_QUERYCAP: | 1745 | } |
1653 | case VIDIOC_ENUMINPUT: | ||
1654 | case VIDIOC_G_INPUT: | ||
1655 | case VIDIOC_S_INPUT: | ||
1656 | case VIDIOC_ENUMOUTPUT: | ||
1657 | case VIDIOC_G_OUTPUT: | ||
1658 | case VIDIOC_S_OUTPUT: | ||
1659 | case VIDIOC_G_FMT: | ||
1660 | case VIDIOC_S_FMT: | ||
1661 | case VIDIOC_TRY_FMT: | ||
1662 | case VIDIOC_ENUM_FMT: | ||
1663 | case VIDIOC_CROPCAP: | ||
1664 | case VIDIOC_G_CROP: | ||
1665 | case VIDIOC_S_CROP: | ||
1666 | case VIDIOC_G_FREQUENCY: | ||
1667 | case VIDIOC_S_FREQUENCY: | ||
1668 | case VIDIOC_ENUMSTD: | ||
1669 | case VIDIOC_G_STD: | ||
1670 | case VIDIOC_S_STD: | ||
1671 | case VIDIOC_S_TUNER: | ||
1672 | case VIDIOC_G_TUNER: | ||
1673 | case VIDIOC_ENUMAUDIO: | ||
1674 | case VIDIOC_S_AUDIO: | ||
1675 | case VIDIOC_G_AUDIO: | ||
1676 | case VIDIOC_ENUMAUDOUT: | ||
1677 | case VIDIOC_S_AUDOUT: | ||
1678 | case VIDIOC_G_AUDOUT: | ||
1679 | case VIDIOC_G_SLICED_VBI_CAP: | ||
1680 | case VIDIOC_LOG_STATUS: | ||
1681 | case VIDIOC_G_ENC_INDEX: | ||
1682 | case VIDIOC_ENCODER_CMD: | ||
1683 | case VIDIOC_TRY_ENCODER_CMD: | ||
1684 | case VIDIOC_G_FBUF: | ||
1685 | case VIDIOC_S_FBUF: | ||
1686 | case VIDIOC_OVERLAY: | ||
1687 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | ||
1688 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | ||
1689 | v4l_printk_ioctl(cmd); | ||
1690 | printk("\n"); | ||
1691 | } | ||
1692 | return ivtv_v4l2_ioctls(itv, filp, cmd, arg); | ||
1693 | 1746 | ||
1694 | case VIDIOC_QUERYMENU: | 1747 | case VIDIOC_INT_RESET: { |
1695 | case VIDIOC_QUERYCTRL: | 1748 | u32 val = *(u32 *)arg; |
1696 | case VIDIOC_S_CTRL: | ||
1697 | case VIDIOC_G_CTRL: | ||
1698 | case VIDIOC_S_EXT_CTRLS: | ||
1699 | case VIDIOC_G_EXT_CTRLS: | ||
1700 | case VIDIOC_TRY_EXT_CTRLS: | ||
1701 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | ||
1702 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | ||
1703 | v4l_printk_ioctl(cmd); | ||
1704 | printk("\n"); | ||
1705 | } | ||
1706 | return ivtv_control_ioctls(itv, cmd, arg); | ||
1707 | 1749 | ||
1708 | case IVTV_IOC_DMA_FRAME: | 1750 | if ((val == 0 && itv->options.newi2c) || (val & 0x01)) |
1709 | case VIDEO_GET_PTS: | 1751 | ivtv_reset_ir_gpio(itv); |
1710 | case VIDEO_GET_FRAME_COUNT: | 1752 | if (val & 0x02) |
1711 | case VIDEO_GET_EVENT: | 1753 | itv->video_dec_func(itv, cmd, NULL); |
1712 | case VIDEO_PLAY: | 1754 | break; |
1713 | case VIDEO_STOP: | 1755 | } |
1714 | case VIDEO_FREEZE: | ||
1715 | case VIDEO_CONTINUE: | ||
1716 | case VIDEO_COMMAND: | ||
1717 | case VIDEO_TRY_COMMAND: | ||
1718 | return ivtv_decoder_ioctls(filp, cmd, arg); | ||
1719 | 1756 | ||
1720 | case 0x00005401: /* Handle isatty() calls */ | ||
1721 | return -EINVAL; | ||
1722 | default: | 1757 | default: |
1723 | return v4l_compat_translate_ioctl(inode, filp, cmd, arg, | 1758 | return -EINVAL; |
1724 | ivtv_v4l2_do_ioctl); | ||
1725 | } | 1759 | } |
1726 | return 0; | 1760 | return 0; |
1727 | } | 1761 | } |
@@ -1729,7 +1763,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, | |||
1729 | static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, | 1763 | static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, |
1730 | unsigned int cmd, unsigned long arg) | 1764 | unsigned int cmd, unsigned long arg) |
1731 | { | 1765 | { |
1732 | /* Filter dvb ioctls that cannot be handled by video_usercopy */ | 1766 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; |
1767 | int ret; | ||
1768 | |||
1769 | /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */ | ||
1733 | switch (cmd) { | 1770 | switch (cmd) { |
1734 | case VIDEO_SELECT_SOURCE: | 1771 | case VIDEO_SELECT_SOURCE: |
1735 | IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); | 1772 | IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); |
@@ -1758,10 +1795,49 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f | |||
1758 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | 1795 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); |
1759 | return 0; | 1796 | return 0; |
1760 | 1797 | ||
1798 | case IVTV_IOC_DMA_FRAME: | ||
1799 | case VIDEO_GET_PTS: | ||
1800 | case VIDEO_GET_FRAME_COUNT: | ||
1801 | case VIDEO_GET_EVENT: | ||
1802 | case VIDEO_PLAY: | ||
1803 | case VIDEO_STOP: | ||
1804 | case VIDEO_FREEZE: | ||
1805 | case VIDEO_CONTINUE: | ||
1806 | case VIDEO_COMMAND: | ||
1807 | case VIDEO_TRY_COMMAND: | ||
1808 | return ivtv_decoder_ioctls(filp, cmd, (void *)arg); | ||
1809 | |||
1761 | default: | 1810 | default: |
1762 | break; | 1811 | break; |
1763 | } | 1812 | } |
1764 | return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); | 1813 | |
1814 | /* check priority */ | ||
1815 | switch (cmd) { | ||
1816 | case VIDIOC_S_CTRL: | ||
1817 | case VIDIOC_S_STD: | ||
1818 | case VIDIOC_S_INPUT: | ||
1819 | case VIDIOC_S_OUTPUT: | ||
1820 | case VIDIOC_S_TUNER: | ||
1821 | case VIDIOC_S_FREQUENCY: | ||
1822 | case VIDIOC_S_FMT: | ||
1823 | case VIDIOC_S_CROP: | ||
1824 | case VIDIOC_S_AUDIO: | ||
1825 | case VIDIOC_S_AUDOUT: | ||
1826 | case VIDIOC_S_EXT_CTRLS: | ||
1827 | case VIDIOC_S_FBUF: | ||
1828 | case VIDIOC_OVERLAY: | ||
1829 | ret = v4l2_prio_check(&itv->prio, &id->prio); | ||
1830 | if (ret) | ||
1831 | return ret; | ||
1832 | } | ||
1833 | |||
1834 | if (ivtv_debug & IVTV_DBGFLG_IOCTL) { | ||
1835 | printk(KERN_INFO "ivtv%d ioctl: ", itv->num); | ||
1836 | v4l_printk_ioctl(cmd); | ||
1837 | printk("\n"); | ||
1838 | } | ||
1839 | |||
1840 | return video_ioctl2(inode, filp, cmd, arg); | ||
1765 | } | 1841 | } |
1766 | 1842 | ||
1767 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 1843 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
@@ -1776,3 +1852,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
1776 | mutex_unlock(&itv->serialize_lock); | 1852 | mutex_unlock(&itv->serialize_lock); |
1777 | return res; | 1853 | return res; |
1778 | } | 1854 | } |
1855 | |||
1856 | void ivtv_set_funcs(struct video_device *vdev) | ||
1857 | { | ||
1858 | vdev->vidioc_querycap = ivtv_querycap; | ||
1859 | vdev->vidioc_g_priority = ivtv_g_priority; | ||
1860 | vdev->vidioc_s_priority = ivtv_s_priority; | ||
1861 | vdev->vidioc_s_audio = ivtv_s_audio; | ||
1862 | vdev->vidioc_g_audio = ivtv_g_audio; | ||
1863 | vdev->vidioc_enumaudio = ivtv_enumaudio; | ||
1864 | vdev->vidioc_s_audout = ivtv_s_audout; | ||
1865 | vdev->vidioc_g_audout = ivtv_g_audout; | ||
1866 | vdev->vidioc_enum_input = ivtv_enum_input; | ||
1867 | vdev->vidioc_enum_output = ivtv_enum_output; | ||
1868 | vdev->vidioc_enumaudout = ivtv_enumaudout; | ||
1869 | vdev->vidioc_cropcap = ivtv_cropcap; | ||
1870 | vdev->vidioc_s_crop = ivtv_s_crop; | ||
1871 | vdev->vidioc_g_crop = ivtv_g_crop; | ||
1872 | vdev->vidioc_g_input = ivtv_g_input; | ||
1873 | vdev->vidioc_s_input = ivtv_s_input; | ||
1874 | vdev->vidioc_g_output = ivtv_g_output; | ||
1875 | vdev->vidioc_s_output = ivtv_s_output; | ||
1876 | vdev->vidioc_g_frequency = ivtv_g_frequency; | ||
1877 | vdev->vidioc_s_frequency = ivtv_s_frequency; | ||
1878 | vdev->vidioc_s_tuner = ivtv_s_tuner; | ||
1879 | vdev->vidioc_g_tuner = ivtv_g_tuner; | ||
1880 | vdev->vidioc_g_enc_index = ivtv_g_enc_index; | ||
1881 | vdev->vidioc_g_fbuf = ivtv_g_fbuf; | ||
1882 | vdev->vidioc_s_fbuf = ivtv_s_fbuf; | ||
1883 | vdev->vidioc_g_std = ivtv_g_std; | ||
1884 | vdev->vidioc_s_std = ivtv_s_std; | ||
1885 | vdev->vidioc_overlay = ivtv_overlay; | ||
1886 | vdev->vidioc_log_status = ivtv_log_status; | ||
1887 | vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap; | ||
1888 | vdev->vidioc_encoder_cmd = ivtv_encoder_cmd; | ||
1889 | vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd; | ||
1890 | vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out; | ||
1891 | vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap; | ||
1892 | vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap; | ||
1893 | vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap; | ||
1894 | vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out; | ||
1895 | vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay; | ||
1896 | vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out; | ||
1897 | vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap; | ||
1898 | vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap; | ||
1899 | vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap; | ||
1900 | vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out; | ||
1901 | vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay; | ||
1902 | vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out; | ||
1903 | vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap; | ||
1904 | vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap; | ||
1905 | vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap; | ||
1906 | vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out; | ||
1907 | vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay; | ||
1908 | vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; | ||
1909 | vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; | ||
1910 | vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; | ||
1911 | vdev->vidioc_g_register = ivtv_g_register; | ||
1912 | vdev->vidioc_s_register = ivtv_s_register; | ||
1913 | vdev->vidioc_default = ivtv_default; | ||
1914 | vdev->vidioc_queryctrl = ivtv_queryctrl; | ||
1915 | vdev->vidioc_querymenu = ivtv_querymenu; | ||
1916 | vdev->vidioc_g_ctrl = ivtv_g_ctrl; | ||
1917 | vdev->vidioc_s_ctrl = ivtv_s_ctrl; | ||
1918 | vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; | ||
1919 | vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; | ||
1920 | vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; | ||
1921 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h index 4e67f0ed1fc0..70188588b4f4 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.h +++ b/drivers/media/video/ivtv/ivtv-ioctl.h | |||
@@ -24,10 +24,13 @@ | |||
24 | u16 ivtv_service2vbi(int type); | 24 | u16 ivtv_service2vbi(int type); |
25 | void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); | 25 | void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); |
26 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); | 26 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); |
27 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | ||
28 | unsigned long arg); | ||
29 | int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg); | ||
30 | void ivtv_set_osd_alpha(struct ivtv *itv); | 27 | void ivtv_set_osd_alpha(struct ivtv *itv); |
31 | int ivtv_set_speed(struct ivtv *itv, int speed); | 28 | int ivtv_set_speed(struct ivtv *itv, int speed); |
29 | void ivtv_set_funcs(struct video_device *vdev); | ||
30 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std); | ||
31 | int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); | ||
32 | int ivtv_s_input(struct file *file, void *fh, unsigned int inp); | ||
33 | int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | ||
34 | unsigned long arg); | ||
32 | 35 | ||
33 | #endif | 36 | #endif |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index c854285a4371..f8883b487f4a 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
220 | s->v4l2dev->dev = &itv->dev->dev; | 220 | s->v4l2dev->dev = &itv->dev->dev; |
221 | s->v4l2dev->fops = ivtv_stream_info[type].fops; | 221 | s->v4l2dev->fops = ivtv_stream_info[type].fops; |
222 | s->v4l2dev->release = video_device_release; | 222 | s->v4l2dev->release = video_device_release; |
223 | 223 | s->v4l2dev->tvnorms = V4L2_STD_ALL; | |
224 | ivtv_set_funcs(s->v4l2dev); | ||
224 | return 0; | 225 | return 0; |
225 | } | 226 | } |
226 | 227 | ||