2 * cx2341x - generic code for cx23415/6/8 based devices
4 * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <linux/module.h>
19 #include <linux/errno.h>
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/types.h>
23 #include <linux/videodev2.h>
25 #include <media/tuner.h>
26 #include <media/drv-intf/cx2341x.h>
27 #include <media/v4l2-common.h>
29 MODULE_DESCRIPTION("cx23415/6/8 driver");
30 MODULE_AUTHOR("Hans Verkuil");
31 MODULE_LICENSE("GPL");
34 module_param(debug
, int, 0644);
35 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
37 /********************** COMMON CODE *********************/
39 /* definitions for audio properties bits 29-28 */
40 #define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
41 #define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
42 #define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
44 static const char *cx2341x_get_name(u32 id
)
47 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
48 return "Spatial Filter Mode";
49 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
50 return "Spatial Filter";
51 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
52 return "Spatial Luma Filter Type";
53 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
54 return "Spatial Chroma Filter Type";
55 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
56 return "Temporal Filter Mode";
57 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
58 return "Temporal Filter";
59 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
60 return "Median Filter Type";
61 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
62 return "Median Luma Filter Maximum";
63 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
64 return "Median Luma Filter Minimum";
65 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
66 return "Median Chroma Filter Maximum";
67 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
68 return "Median Chroma Filter Minimum";
69 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
70 return "Insert Navigation Packets";
75 static const char **cx2341x_get_menu(u32 id
)
77 static const char *cx2341x_video_spatial_filter_mode_menu
[] = {
83 static const char *cx2341x_video_luma_spatial_filter_type_menu
[] = {
88 "2D Symmetric non-separable",
92 static const char *cx2341x_video_chroma_spatial_filter_type_menu
[] = {
98 static const char *cx2341x_video_temporal_filter_mode_menu
[] = {
104 static const char *cx2341x_video_median_filter_type_menu
[] = {
108 "Horizontal/Vertical",
114 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
115 return cx2341x_video_spatial_filter_mode_menu
;
116 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
117 return cx2341x_video_luma_spatial_filter_type_menu
;
118 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
119 return cx2341x_video_chroma_spatial_filter_type_menu
;
120 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
121 return cx2341x_video_temporal_filter_mode_menu
;
122 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
123 return cx2341x_video_median_filter_type_menu
;
128 static void cx2341x_ctrl_fill(u32 id
, const char **name
, enum v4l2_ctrl_type
*type
,
129 s32
*min
, s32
*max
, s32
*step
, s32
*def
, u32
*flags
)
131 *name
= cx2341x_get_name(id
);
135 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
136 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
137 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
138 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
139 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
140 *type
= V4L2_CTRL_TYPE_MENU
;
144 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
145 *type
= V4L2_CTRL_TYPE_BOOLEAN
;
150 *type
= V4L2_CTRL_TYPE_INTEGER
;
154 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
155 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
156 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
157 *flags
|= V4L2_CTRL_FLAG_UPDATE
;
159 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
160 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
161 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
162 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
163 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
164 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
165 *flags
|= V4L2_CTRL_FLAG_SLIDER
;
167 case V4L2_CID_MPEG_VIDEO_ENCODING
:
168 *flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
174 /********************** OLD CODE *********************/
176 /* Must be sorted from low to high control ID! */
177 const u32 cx2341x_mpeg_ctrls
[] = {
179 V4L2_CID_MPEG_STREAM_TYPE
,
180 V4L2_CID_MPEG_STREAM_VBI_FMT
,
181 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
,
182 V4L2_CID_MPEG_AUDIO_ENCODING
,
183 V4L2_CID_MPEG_AUDIO_L2_BITRATE
,
184 V4L2_CID_MPEG_AUDIO_MODE
,
185 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
,
186 V4L2_CID_MPEG_AUDIO_EMPHASIS
,
187 V4L2_CID_MPEG_AUDIO_CRC
,
188 V4L2_CID_MPEG_AUDIO_MUTE
,
189 V4L2_CID_MPEG_AUDIO_AC3_BITRATE
,
190 V4L2_CID_MPEG_VIDEO_ENCODING
,
191 V4L2_CID_MPEG_VIDEO_ASPECT
,
192 V4L2_CID_MPEG_VIDEO_B_FRAMES
,
193 V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
194 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
,
195 V4L2_CID_MPEG_VIDEO_BITRATE_MODE
,
196 V4L2_CID_MPEG_VIDEO_BITRATE
,
197 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
,
198 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
,
199 V4L2_CID_MPEG_VIDEO_MUTE
,
200 V4L2_CID_MPEG_VIDEO_MUTE_YUV
,
201 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
,
202 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
,
203 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
,
204 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
,
205 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
,
206 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
,
207 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
,
208 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
,
209 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
,
210 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
,
211 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
,
212 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
,
215 EXPORT_SYMBOL(cx2341x_mpeg_ctrls
);
217 static const struct cx2341x_mpeg_params default_params
= {
220 .port
= CX2341X_PORT_MEMORY
,
226 .stream_type
= V4L2_MPEG_STREAM_TYPE_MPEG2_PS
,
227 .stream_vbi_fmt
= V4L2_MPEG_STREAM_VBI_FMT_NONE
,
228 .stream_insert_nav_packets
= 0,
231 .audio_sampling_freq
= V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
,
232 .audio_encoding
= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
233 .audio_l2_bitrate
= V4L2_MPEG_AUDIO_L2_BITRATE_224K
,
234 .audio_ac3_bitrate
= V4L2_MPEG_AUDIO_AC3_BITRATE_224K
,
235 .audio_mode
= V4L2_MPEG_AUDIO_MODE_STEREO
,
236 .audio_mode_extension
= V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
,
237 .audio_emphasis
= V4L2_MPEG_AUDIO_EMPHASIS_NONE
,
238 .audio_crc
= V4L2_MPEG_AUDIO_CRC_NONE
,
242 .video_encoding
= V4L2_MPEG_VIDEO_ENCODING_MPEG_2
,
243 .video_aspect
= V4L2_MPEG_VIDEO_ASPECT_4x3
,
245 .video_gop_size
= 12,
246 .video_gop_closure
= 1,
247 .video_bitrate_mode
= V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
,
248 .video_bitrate
= 6000000,
249 .video_bitrate_peak
= 8000000,
250 .video_temporal_decimation
= 0,
252 .video_mute_yuv
= 0x008080, /* YCbCr value for black */
254 /* encoding filters */
255 .video_spatial_filter_mode
=
256 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
257 .video_spatial_filter
= 0,
258 .video_luma_spatial_filter_type
=
259 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR
,
260 .video_chroma_spatial_filter_type
=
261 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
262 .video_temporal_filter_mode
=
263 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
264 .video_temporal_filter
= 8,
265 .video_median_filter_type
=
266 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
267 .video_luma_median_filter_top
= 255,
268 .video_luma_median_filter_bottom
= 0,
269 .video_chroma_median_filter_top
= 255,
270 .video_chroma_median_filter_bottom
= 0,
272 /* Map the control ID to the correct field in the cx2341x_mpeg_params
273 struct. Return -EINVAL if the ID is unknown, else return 0. */
274 static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params
*params
,
275 struct v4l2_ext_control
*ctrl
)
278 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
279 ctrl
->value
= params
->audio_sampling_freq
;
281 case V4L2_CID_MPEG_AUDIO_ENCODING
:
282 ctrl
->value
= params
->audio_encoding
;
284 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
285 ctrl
->value
= params
->audio_l2_bitrate
;
287 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
288 ctrl
->value
= params
->audio_ac3_bitrate
;
290 case V4L2_CID_MPEG_AUDIO_MODE
:
291 ctrl
->value
= params
->audio_mode
;
293 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
294 ctrl
->value
= params
->audio_mode_extension
;
296 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
297 ctrl
->value
= params
->audio_emphasis
;
299 case V4L2_CID_MPEG_AUDIO_CRC
:
300 ctrl
->value
= params
->audio_crc
;
302 case V4L2_CID_MPEG_AUDIO_MUTE
:
303 ctrl
->value
= params
->audio_mute
;
305 case V4L2_CID_MPEG_VIDEO_ENCODING
:
306 ctrl
->value
= params
->video_encoding
;
308 case V4L2_CID_MPEG_VIDEO_ASPECT
:
309 ctrl
->value
= params
->video_aspect
;
311 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
312 ctrl
->value
= params
->video_b_frames
;
314 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
315 ctrl
->value
= params
->video_gop_size
;
317 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
318 ctrl
->value
= params
->video_gop_closure
;
320 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
321 ctrl
->value
= params
->video_bitrate_mode
;
323 case V4L2_CID_MPEG_VIDEO_BITRATE
:
324 ctrl
->value
= params
->video_bitrate
;
326 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
327 ctrl
->value
= params
->video_bitrate_peak
;
329 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
330 ctrl
->value
= params
->video_temporal_decimation
;
332 case V4L2_CID_MPEG_VIDEO_MUTE
:
333 ctrl
->value
= params
->video_mute
;
335 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
:
336 ctrl
->value
= params
->video_mute_yuv
;
338 case V4L2_CID_MPEG_STREAM_TYPE
:
339 ctrl
->value
= params
->stream_type
;
341 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
342 ctrl
->value
= params
->stream_vbi_fmt
;
344 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
345 ctrl
->value
= params
->video_spatial_filter_mode
;
347 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
348 ctrl
->value
= params
->video_spatial_filter
;
350 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
351 ctrl
->value
= params
->video_luma_spatial_filter_type
;
353 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
354 ctrl
->value
= params
->video_chroma_spatial_filter_type
;
356 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
357 ctrl
->value
= params
->video_temporal_filter_mode
;
359 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
360 ctrl
->value
= params
->video_temporal_filter
;
362 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
363 ctrl
->value
= params
->video_median_filter_type
;
365 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
366 ctrl
->value
= params
->video_luma_median_filter_top
;
368 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
369 ctrl
->value
= params
->video_luma_median_filter_bottom
;
371 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
372 ctrl
->value
= params
->video_chroma_median_filter_top
;
374 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
375 ctrl
->value
= params
->video_chroma_median_filter_bottom
;
377 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
378 ctrl
->value
= params
->stream_insert_nav_packets
;
386 /* Map the control ID to the correct field in the cx2341x_mpeg_params
387 struct. Return -EINVAL if the ID is unknown, else return 0. */
388 static int cx2341x_set_ctrl(struct cx2341x_mpeg_params
*params
, int busy
,
389 struct v4l2_ext_control
*ctrl
)
392 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
395 params
->audio_sampling_freq
= ctrl
->value
;
397 case V4L2_CID_MPEG_AUDIO_ENCODING
:
400 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
)
401 if (ctrl
->value
!= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
&&
402 ctrl
->value
!= V4L2_MPEG_AUDIO_ENCODING_AC3
)
404 params
->audio_encoding
= ctrl
->value
;
406 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
409 params
->audio_l2_bitrate
= ctrl
->value
;
411 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
414 if (!(params
->capabilities
& CX2341X_CAP_HAS_AC3
))
416 params
->audio_ac3_bitrate
= ctrl
->value
;
418 case V4L2_CID_MPEG_AUDIO_MODE
:
419 params
->audio_mode
= ctrl
->value
;
421 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
422 params
->audio_mode_extension
= ctrl
->value
;
424 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
425 params
->audio_emphasis
= ctrl
->value
;
427 case V4L2_CID_MPEG_AUDIO_CRC
:
428 params
->audio_crc
= ctrl
->value
;
430 case V4L2_CID_MPEG_AUDIO_MUTE
:
431 params
->audio_mute
= ctrl
->value
;
433 case V4L2_CID_MPEG_VIDEO_ASPECT
:
434 params
->video_aspect
= ctrl
->value
;
436 case V4L2_CID_MPEG_VIDEO_B_FRAMES
: {
437 int b
= ctrl
->value
+ 1;
438 int gop
= params
->video_gop_size
;
439 params
->video_b_frames
= ctrl
->value
;
440 params
->video_gop_size
= b
* ((gop
+ b
- 1) / b
);
441 /* Max GOP size = 34 */
442 while (params
->video_gop_size
> 34)
443 params
->video_gop_size
-= b
;
446 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
: {
447 int b
= params
->video_b_frames
+ 1;
448 int gop
= ctrl
->value
;
449 params
->video_gop_size
= b
* ((gop
+ b
- 1) / b
);
450 /* Max GOP size = 34 */
451 while (params
->video_gop_size
> 34)
452 params
->video_gop_size
-= b
;
453 ctrl
->value
= params
->video_gop_size
;
456 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
457 params
->video_gop_closure
= ctrl
->value
;
459 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
462 /* MPEG-1 only allows CBR */
463 if (params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
&&
464 ctrl
->value
!= V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
)
466 params
->video_bitrate_mode
= ctrl
->value
;
468 case V4L2_CID_MPEG_VIDEO_BITRATE
:
471 params
->video_bitrate
= ctrl
->value
;
473 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
476 params
->video_bitrate_peak
= ctrl
->value
;
478 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
479 params
->video_temporal_decimation
= ctrl
->value
;
481 case V4L2_CID_MPEG_VIDEO_MUTE
:
482 params
->video_mute
= (ctrl
->value
!= 0);
484 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
:
485 params
->video_mute_yuv
= ctrl
->value
;
487 case V4L2_CID_MPEG_STREAM_TYPE
:
490 params
->stream_type
= ctrl
->value
;
491 params
->video_encoding
=
492 (params
->stream_type
== V4L2_MPEG_STREAM_TYPE_MPEG1_SS
||
493 params
->stream_type
== V4L2_MPEG_STREAM_TYPE_MPEG1_VCD
) ?
494 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
:
495 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
;
496 if (params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
497 /* MPEG-1 implies CBR */
498 params
->video_bitrate_mode
=
499 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
;
501 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
502 params
->stream_vbi_fmt
= ctrl
->value
;
504 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
505 params
->video_spatial_filter_mode
= ctrl
->value
;
507 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
508 params
->video_spatial_filter
= ctrl
->value
;
510 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
511 params
->video_luma_spatial_filter_type
= ctrl
->value
;
513 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
514 params
->video_chroma_spatial_filter_type
= ctrl
->value
;
516 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
517 params
->video_temporal_filter_mode
= ctrl
->value
;
519 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
520 params
->video_temporal_filter
= ctrl
->value
;
522 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
523 params
->video_median_filter_type
= ctrl
->value
;
525 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
526 params
->video_luma_median_filter_top
= ctrl
->value
;
528 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
529 params
->video_luma_median_filter_bottom
= ctrl
->value
;
531 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
532 params
->video_chroma_median_filter_top
= ctrl
->value
;
534 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
535 params
->video_chroma_median_filter_bottom
= ctrl
->value
;
537 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
538 params
->stream_insert_nav_packets
= ctrl
->value
;
546 static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl
*qctrl
,
547 s32 min
, s32 max
, s32 step
, s32 def
)
553 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
554 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
555 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
556 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
557 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
558 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
559 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
560 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
561 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
562 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
563 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
564 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
565 cx2341x_ctrl_fill(qctrl
->id
, &name
, &qctrl
->type
,
566 &min
, &max
, &step
, &def
, &qctrl
->flags
);
567 qctrl
->minimum
= min
;
568 qctrl
->maximum
= max
;
570 qctrl
->default_value
= def
;
571 qctrl
->reserved
[0] = qctrl
->reserved
[1] = 0;
572 strscpy(qctrl
->name
, name
, sizeof(qctrl
->name
));
576 return v4l2_ctrl_query_fill(qctrl
, min
, max
, step
, def
);
580 int cx2341x_ctrl_query(const struct cx2341x_mpeg_params
*params
,
581 struct v4l2_queryctrl
*qctrl
)
586 case V4L2_CID_MPEG_CLASS
:
587 return v4l2_ctrl_query_fill(qctrl
, 0, 0, 0, 0);
588 case V4L2_CID_MPEG_STREAM_TYPE
:
589 return v4l2_ctrl_query_fill(qctrl
,
590 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
,
591 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD
, 1,
592 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
);
594 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
595 if (params
->capabilities
& CX2341X_CAP_HAS_SLICED_VBI
)
596 return v4l2_ctrl_query_fill(qctrl
,
597 V4L2_MPEG_STREAM_VBI_FMT_NONE
,
598 V4L2_MPEG_STREAM_VBI_FMT_IVTV
, 1,
599 V4L2_MPEG_STREAM_VBI_FMT_NONE
);
600 return cx2341x_ctrl_query_fill(qctrl
,
601 V4L2_MPEG_STREAM_VBI_FMT_NONE
,
602 V4L2_MPEG_STREAM_VBI_FMT_NONE
, 1,
603 default_params
.stream_vbi_fmt
);
605 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
606 return v4l2_ctrl_query_fill(qctrl
,
607 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100
,
608 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
, 1,
609 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
);
611 case V4L2_CID_MPEG_AUDIO_ENCODING
:
612 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
) {
614 * The state of L2 & AC3 bitrate controls can change
615 * when this control changes, but v4l2_ctrl_query_fill()
616 * already sets V4L2_CTRL_FLAG_UPDATE for
617 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
619 return v4l2_ctrl_query_fill(qctrl
,
620 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
621 V4L2_MPEG_AUDIO_ENCODING_AC3
, 1,
622 default_params
.audio_encoding
);
625 return v4l2_ctrl_query_fill(qctrl
,
626 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
627 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
, 1,
628 default_params
.audio_encoding
);
630 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
631 err
= v4l2_ctrl_query_fill(qctrl
,
632 V4L2_MPEG_AUDIO_L2_BITRATE_192K
,
633 V4L2_MPEG_AUDIO_L2_BITRATE_384K
, 1,
634 default_params
.audio_l2_bitrate
);
637 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
&&
638 params
->audio_encoding
!= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
)
639 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
642 case V4L2_CID_MPEG_AUDIO_MODE
:
643 return v4l2_ctrl_query_fill(qctrl
,
644 V4L2_MPEG_AUDIO_MODE_STEREO
,
645 V4L2_MPEG_AUDIO_MODE_MONO
, 1,
646 V4L2_MPEG_AUDIO_MODE_STEREO
);
648 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
649 err
= v4l2_ctrl_query_fill(qctrl
,
650 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
,
651 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16
, 1,
652 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
);
654 params
->audio_mode
!= V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
)
655 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
658 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
659 return v4l2_ctrl_query_fill(qctrl
,
660 V4L2_MPEG_AUDIO_EMPHASIS_NONE
,
661 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
, 1,
662 V4L2_MPEG_AUDIO_EMPHASIS_NONE
);
664 case V4L2_CID_MPEG_AUDIO_CRC
:
665 return v4l2_ctrl_query_fill(qctrl
,
666 V4L2_MPEG_AUDIO_CRC_NONE
,
667 V4L2_MPEG_AUDIO_CRC_CRC16
, 1,
668 V4L2_MPEG_AUDIO_CRC_NONE
);
670 case V4L2_CID_MPEG_AUDIO_MUTE
:
671 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 0);
673 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
674 err
= v4l2_ctrl_query_fill(qctrl
,
675 V4L2_MPEG_AUDIO_AC3_BITRATE_48K
,
676 V4L2_MPEG_AUDIO_AC3_BITRATE_448K
, 1,
677 default_params
.audio_ac3_bitrate
);
680 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
) {
681 if (params
->audio_encoding
!=
682 V4L2_MPEG_AUDIO_ENCODING_AC3
)
683 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
685 qctrl
->flags
|= V4L2_CTRL_FLAG_DISABLED
;
688 case V4L2_CID_MPEG_VIDEO_ENCODING
:
689 /* this setting is read-only for the cx2341x since the
690 V4L2_CID_MPEG_STREAM_TYPE really determines the
692 err
= v4l2_ctrl_query_fill(qctrl
,
693 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
,
694 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
, 1,
695 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
);
697 qctrl
->flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
700 case V4L2_CID_MPEG_VIDEO_ASPECT
:
701 return v4l2_ctrl_query_fill(qctrl
,
702 V4L2_MPEG_VIDEO_ASPECT_1x1
,
703 V4L2_MPEG_VIDEO_ASPECT_221x100
, 1,
704 V4L2_MPEG_VIDEO_ASPECT_4x3
);
706 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
707 return v4l2_ctrl_query_fill(qctrl
, 0, 33, 1, 2);
709 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
710 return v4l2_ctrl_query_fill(qctrl
, 1, 34, 1,
711 params
->is_50hz
? 12 : 15);
713 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
714 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 1);
716 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
717 err
= v4l2_ctrl_query_fill(qctrl
,
718 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
,
719 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
, 1,
720 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
);
722 params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
723 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
726 case V4L2_CID_MPEG_VIDEO_BITRATE
:
727 return v4l2_ctrl_query_fill(qctrl
, 0, 27000000, 1, 6000000);
729 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
730 err
= v4l2_ctrl_query_fill(qctrl
, 0, 27000000, 1, 8000000);
732 params
->video_bitrate_mode
==
733 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
)
734 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
737 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
738 return v4l2_ctrl_query_fill(qctrl
, 0, 255, 1, 0);
740 case V4L2_CID_MPEG_VIDEO_MUTE
:
741 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 0);
743 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
: /* Init YUV (really YCbCr) to black */
744 return v4l2_ctrl_query_fill(qctrl
, 0, 0xffffff, 1, 0x008080);
746 /* CX23415/6 specific */
747 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
748 return cx2341x_ctrl_query_fill(qctrl
,
749 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
750 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
, 1,
751 default_params
.video_spatial_filter_mode
);
753 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
754 cx2341x_ctrl_query_fill(qctrl
, 0, 15, 1,
755 default_params
.video_spatial_filter
);
756 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
757 if (params
->video_spatial_filter_mode
==
758 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
759 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
762 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
763 cx2341x_ctrl_query_fill(qctrl
,
764 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF
,
765 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE
,
767 default_params
.video_luma_spatial_filter_type
);
768 if (params
->video_spatial_filter_mode
==
769 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
770 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
773 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
774 cx2341x_ctrl_query_fill(qctrl
,
775 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF
,
776 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
778 default_params
.video_chroma_spatial_filter_type
);
779 if (params
->video_spatial_filter_mode
==
780 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
781 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
784 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
785 return cx2341x_ctrl_query_fill(qctrl
,
786 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
787 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
, 1,
788 default_params
.video_temporal_filter_mode
);
790 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
791 cx2341x_ctrl_query_fill(qctrl
, 0, 31, 1,
792 default_params
.video_temporal_filter
);
793 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
794 if (params
->video_temporal_filter_mode
==
795 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
)
796 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
799 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
800 return cx2341x_ctrl_query_fill(qctrl
,
801 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
802 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG
, 1,
803 default_params
.video_median_filter_type
);
805 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
806 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
807 default_params
.video_luma_median_filter_top
);
808 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
809 if (params
->video_median_filter_type
==
810 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
811 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
814 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
815 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
816 default_params
.video_luma_median_filter_bottom
);
817 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
818 if (params
->video_median_filter_type
==
819 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
820 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
823 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
824 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
825 default_params
.video_chroma_median_filter_top
);
826 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
827 if (params
->video_median_filter_type
==
828 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
829 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
832 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
833 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
834 default_params
.video_chroma_median_filter_bottom
);
835 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
836 if (params
->video_median_filter_type
==
837 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
838 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
841 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
842 return cx2341x_ctrl_query_fill(qctrl
, 0, 1, 1,
843 default_params
.stream_insert_nav_packets
);
850 EXPORT_SYMBOL(cx2341x_ctrl_query
);
852 const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params
*p
, u32 id
)
854 static const char * const mpeg_stream_type_without_ts
[] = {
855 "MPEG-2 Program Stream",
857 "MPEG-1 System Stream",
858 "MPEG-2 DVD-compatible Stream",
859 "MPEG-1 VCD-compatible Stream",
860 "MPEG-2 SVCD-compatible Stream",
864 static const char *mpeg_stream_type_with_ts
[] = {
865 "MPEG-2 Program Stream",
866 "MPEG-2 Transport Stream",
867 "MPEG-1 System Stream",
868 "MPEG-2 DVD-compatible Stream",
869 "MPEG-1 VCD-compatible Stream",
870 "MPEG-2 SVCD-compatible Stream",
874 static const char *mpeg_audio_encoding_l2_ac3
[] = {
884 case V4L2_CID_MPEG_STREAM_TYPE
:
885 return (p
->capabilities
& CX2341X_CAP_HAS_TS
) ?
886 mpeg_stream_type_with_ts
: mpeg_stream_type_without_ts
;
887 case V4L2_CID_MPEG_AUDIO_ENCODING
:
888 return (p
->capabilities
& CX2341X_CAP_HAS_AC3
) ?
889 mpeg_audio_encoding_l2_ac3
: v4l2_ctrl_get_menu(id
);
890 case V4L2_CID_MPEG_AUDIO_L1_BITRATE
:
891 case V4L2_CID_MPEG_AUDIO_L3_BITRATE
:
893 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
894 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
895 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
896 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
897 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
898 return cx2341x_get_menu(id
);
900 return v4l2_ctrl_get_menu(id
);
903 EXPORT_SYMBOL(cx2341x_ctrl_get_menu
);
905 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params
*params
)
907 params
->audio_properties
=
908 (params
->audio_sampling_freq
<< 0) |
909 (params
->audio_mode
<< 8) |
910 (params
->audio_mode_extension
<< 10) |
911 (((params
->audio_emphasis
== V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
)
912 ? 3 : params
->audio_emphasis
) << 12) |
913 (params
->audio_crc
<< 14);
915 if ((params
->capabilities
& CX2341X_CAP_HAS_AC3
) &&
916 params
->audio_encoding
== V4L2_MPEG_AUDIO_ENCODING_AC3
) {
917 params
->audio_properties
|=
918 /* Not sure if this MPEG Layer II setting is required */
919 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2
) << 2) |
920 (params
->audio_ac3_bitrate
<< 4) |
921 (CX2341X_AUDIO_ENCODING_METHOD_AC3
<< 28);
923 /* Assuming MPEG Layer II */
924 params
->audio_properties
|=
925 ((3 - params
->audio_encoding
) << 2) |
926 ((1 + params
->audio_l2_bitrate
) << 4);
930 /* Check for correctness of the ctrl's value based on the data from
931 struct v4l2_queryctrl and the available menu items. Note that
932 menu_items may be NULL, in that case it is ignored. */
933 static int v4l2_ctrl_check(struct v4l2_ext_control
*ctrl
, struct v4l2_queryctrl
*qctrl
,
934 const char * const *menu_items
)
936 if (qctrl
->flags
& V4L2_CTRL_FLAG_DISABLED
)
938 if (qctrl
->flags
& V4L2_CTRL_FLAG_GRABBED
)
940 if (qctrl
->type
== V4L2_CTRL_TYPE_STRING
)
942 if (qctrl
->type
== V4L2_CTRL_TYPE_BUTTON
||
943 qctrl
->type
== V4L2_CTRL_TYPE_INTEGER64
||
944 qctrl
->type
== V4L2_CTRL_TYPE_CTRL_CLASS
)
946 if (ctrl
->value
< qctrl
->minimum
|| ctrl
->value
> qctrl
->maximum
)
948 if (qctrl
->type
== V4L2_CTRL_TYPE_MENU
&& menu_items
!= NULL
) {
949 if (menu_items
[ctrl
->value
] == NULL
||
950 menu_items
[ctrl
->value
][0] == '\0')
953 if (qctrl
->type
== V4L2_CTRL_TYPE_BITMASK
&&
954 (ctrl
->value
& ~qctrl
->maximum
))
959 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params
*params
, int busy
,
960 struct v4l2_ext_controls
*ctrls
, unsigned int cmd
)
965 if (cmd
== VIDIOC_G_EXT_CTRLS
) {
966 for (i
= 0; i
< ctrls
->count
; i
++) {
967 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
969 err
= cx2341x_get_ctrl(params
, ctrl
);
971 ctrls
->error_idx
= i
;
977 for (i
= 0; i
< ctrls
->count
; i
++) {
978 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
979 struct v4l2_queryctrl qctrl
;
980 const char * const *menu_items
= NULL
;
983 err
= cx2341x_ctrl_query(params
, &qctrl
);
986 if (qctrl
.type
== V4L2_CTRL_TYPE_MENU
)
987 menu_items
= cx2341x_ctrl_get_menu(params
, qctrl
.id
);
988 err
= v4l2_ctrl_check(ctrl
, &qctrl
, menu_items
);
991 err
= cx2341x_set_ctrl(params
, busy
, ctrl
);
996 params
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
997 params
->video_bitrate_peak
< params
->video_bitrate
) {
999 ctrls
->error_idx
= ctrls
->count
;
1002 ctrls
->error_idx
= i
;
1004 cx2341x_calc_audio_properties(params
);
1007 EXPORT_SYMBOL(cx2341x_ext_ctrls
);
1009 void cx2341x_fill_defaults(struct cx2341x_mpeg_params
*p
)
1011 *p
= default_params
;
1012 cx2341x_calc_audio_properties(p
);
1014 EXPORT_SYMBOL(cx2341x_fill_defaults
);
1016 static int cx2341x_api(void *priv
, cx2341x_mbox_func func
,
1017 u32 cmd
, int args
, ...)
1019 u32 data
[CX2341X_MBOX_MAX_DATA
];
1023 va_start(vargs
, args
);
1025 for (i
= 0; i
< args
; i
++)
1026 data
[i
] = va_arg(vargs
, int);
1028 return func(priv
, cmd
, args
, 0, data
);
1031 #define NEQ(field) (old->field != new->field)
1033 int cx2341x_update(void *priv
, cx2341x_mbox_func func
,
1034 const struct cx2341x_mpeg_params
*old
,
1035 const struct cx2341x_mpeg_params
*new)
1037 static int mpeg_stream_type
[] = {
1047 int force
= (old
== NULL
);
1048 u16 temporal
= new->video_temporal_filter
;
1050 cx2341x_api(priv
, func
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, new->port
, 0);
1052 if (force
|| NEQ(is_50hz
)) {
1053 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_RATE
, 1,
1055 if (err
) return err
;
1058 if (force
|| NEQ(width
) || NEQ(height
) || NEQ(video_encoding
)) {
1060 u16 h
= new->height
;
1062 if (new->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1066 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_SIZE
, 2,
1068 if (err
) return err
;
1070 if (force
|| NEQ(stream_type
)) {
1071 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_STREAM_TYPE
, 1,
1072 mpeg_stream_type
[new->stream_type
]);
1073 if (err
) return err
;
1075 if (force
|| NEQ(video_aspect
)) {
1076 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_ASPECT_RATIO
, 1,
1077 1 + new->video_aspect
);
1078 if (err
) return err
;
1080 if (force
|| NEQ(video_b_frames
) || NEQ(video_gop_size
)) {
1081 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1082 new->video_gop_size
, new->video_b_frames
+ 1);
1083 if (err
) return err
;
1085 if (force
|| NEQ(video_gop_closure
)) {
1086 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_CLOSURE
, 1,
1087 new->video_gop_closure
);
1088 if (err
) return err
;
1090 if (force
|| NEQ(audio_properties
)) {
1091 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_AUDIO_PROPERTIES
,
1092 1, new->audio_properties
);
1093 if (err
) return err
;
1095 if (force
|| NEQ(audio_mute
)) {
1096 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_AUDIO
, 1,
1098 if (err
) return err
;
1100 if (force
|| NEQ(video_bitrate_mode
) || NEQ(video_bitrate
) ||
1101 NEQ(video_bitrate_peak
)) {
1102 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_BIT_RATE
, 5,
1103 new->video_bitrate_mode
, new->video_bitrate
,
1104 new->video_bitrate_peak
/ 400, 0, 0);
1105 if (err
) return err
;
1107 if (force
|| NEQ(video_spatial_filter_mode
) ||
1108 NEQ(video_temporal_filter_mode
) ||
1109 NEQ(video_median_filter_type
)) {
1110 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_MODE
,
1111 2, new->video_spatial_filter_mode
|
1112 (new->video_temporal_filter_mode
<< 1),
1113 new->video_median_filter_type
);
1114 if (err
) return err
;
1116 if (force
|| NEQ(video_luma_median_filter_bottom
) ||
1117 NEQ(video_luma_median_filter_top
) ||
1118 NEQ(video_chroma_median_filter_bottom
) ||
1119 NEQ(video_chroma_median_filter_top
)) {
1120 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1121 new->video_luma_median_filter_bottom
,
1122 new->video_luma_median_filter_top
,
1123 new->video_chroma_median_filter_bottom
,
1124 new->video_chroma_median_filter_top
);
1125 if (err
) return err
;
1127 if (force
|| NEQ(video_luma_spatial_filter_type
) ||
1128 NEQ(video_chroma_spatial_filter_type
)) {
1129 err
= cx2341x_api(priv
, func
,
1130 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
,
1131 2, new->video_luma_spatial_filter_type
,
1132 new->video_chroma_spatial_filter_type
);
1133 if (err
) return err
;
1135 if (force
|| NEQ(video_spatial_filter
) ||
1136 old
->video_temporal_filter
!= temporal
) {
1137 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_PROPS
,
1138 2, new->video_spatial_filter
, temporal
);
1139 if (err
) return err
;
1141 if (force
|| NEQ(video_temporal_decimation
)) {
1142 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_DROP_RATE
,
1143 1, new->video_temporal_decimation
);
1144 if (err
) return err
;
1146 if (force
|| NEQ(video_mute
) ||
1147 (new->video_mute
&& NEQ(video_mute_yuv
))) {
1148 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_VIDEO
, 1,
1149 new->video_mute
| (new->video_mute_yuv
<< 8));
1150 if (err
) return err
;
1152 if (force
|| NEQ(stream_insert_nav_packets
)) {
1153 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MISC
, 2,
1154 7, new->stream_insert_nav_packets
);
1155 if (err
) return err
;
1159 EXPORT_SYMBOL(cx2341x_update
);
1161 static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params
*p
, u32 id
)
1163 const char * const *menu
= cx2341x_ctrl_get_menu(p
, id
);
1164 struct v4l2_ext_control ctrl
;
1169 if (cx2341x_get_ctrl(p
, &ctrl
))
1171 while (ctrl
.value
-- && *menu
) menu
++;
1180 void cx2341x_log_status(const struct cx2341x_mpeg_params
*p
, const char *prefix
)
1182 int is_mpeg1
= p
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
;
1185 printk(KERN_INFO
"%s: Stream: %s",
1187 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_TYPE
));
1188 if (p
->stream_insert_nav_packets
)
1189 printk(KERN_CONT
" (with navigation packets)");
1190 printk(KERN_CONT
"\n");
1191 printk(KERN_INFO
"%s: VBI Format: %s\n",
1193 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_VBI_FMT
));
1196 printk(KERN_INFO
"%s: Video: %dx%d, %d fps%s\n",
1198 p
->width
/ (is_mpeg1
? 2 : 1), p
->height
/ (is_mpeg1
? 2 : 1),
1199 p
->is_50hz
? 25 : 30,
1200 (p
->video_mute
) ? " (muted)" : "");
1201 printk(KERN_INFO
"%s: Video: %s, %s, %s, %d",
1203 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ENCODING
),
1204 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ASPECT
),
1205 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_BITRATE_MODE
),
1207 if (p
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
)
1208 printk(KERN_CONT
", Peak %d", p
->video_bitrate_peak
);
1209 printk(KERN_CONT
"\n");
1211 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
1213 p
->video_gop_size
, p
->video_b_frames
,
1214 p
->video_gop_closure
? "" : "No ");
1215 if (p
->video_temporal_decimation
)
1216 printk(KERN_INFO
"%s: Video: Temporal Decimation %d\n",
1217 prefix
, p
->video_temporal_decimation
);
1220 printk(KERN_INFO
"%s: Audio: %s, %s, %s, %s%s",
1222 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
),
1223 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_ENCODING
),
1224 cx2341x_menu_item(p
,
1225 p
->audio_encoding
== V4L2_MPEG_AUDIO_ENCODING_AC3
1226 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1227 : V4L2_CID_MPEG_AUDIO_L2_BITRATE
),
1228 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_MODE
),
1229 p
->audio_mute
? " (muted)" : "");
1230 if (p
->audio_mode
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
)
1231 printk(KERN_CONT
", %s", cx2341x_menu_item(p
,
1232 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
));
1233 printk(KERN_CONT
", %s, %s\n",
1234 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_EMPHASIS
),
1235 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_CRC
));
1237 /* Encoding filters */
1238 printk(KERN_INFO
"%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1240 cx2341x_menu_item(p
,
1241 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
),
1242 cx2341x_menu_item(p
,
1243 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
),
1244 cx2341x_menu_item(p
,
1245 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
),
1246 p
->video_spatial_filter
);
1248 printk(KERN_INFO
"%s: Temporal Filter: %s, %d\n",
1250 cx2341x_menu_item(p
,
1251 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
),
1252 p
->video_temporal_filter
);
1254 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1256 cx2341x_menu_item(p
,
1257 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
),
1258 p
->video_luma_median_filter_bottom
,
1259 p
->video_luma_median_filter_top
,
1260 p
->video_chroma_median_filter_bottom
,
1261 p
->video_chroma_median_filter_top
);
1263 EXPORT_SYMBOL(cx2341x_log_status
);
1267 /********************** NEW CODE *********************/
1269 static inline struct cx2341x_handler
*to_cxhdl(struct v4l2_ctrl
*ctrl
)
1271 return container_of(ctrl
->handler
, struct cx2341x_handler
, hdl
);
1274 static int cx2341x_hdl_api(struct cx2341x_handler
*hdl
,
1275 u32 cmd
, int args
, ...)
1277 u32 data
[CX2341X_MBOX_MAX_DATA
];
1281 va_start(vargs
, args
);
1283 for (i
= 0; i
< args
; i
++)
1284 data
[i
] = va_arg(vargs
, int);
1286 return hdl
->func(hdl
->priv
, cmd
, args
, 0, data
);
1289 /* ctrl->handler->lock is held, so it is safe to access cur.val */
1290 static inline int cx2341x_neq(struct v4l2_ctrl
*ctrl
)
1292 return ctrl
&& ctrl
->val
!= ctrl
->cur
.val
;
1295 static int cx2341x_try_ctrl(struct v4l2_ctrl
*ctrl
)
1297 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1298 s32 val
= ctrl
->val
;
1301 case V4L2_CID_MPEG_VIDEO_B_FRAMES
: {
1302 /* video gop cluster */
1304 int gop
= hdl
->video_gop_size
->val
;
1306 gop
= b
* ((gop
+ b
- 1) / b
);
1308 /* Max GOP size = 34 */
1311 hdl
->video_gop_size
->val
= gop
;
1315 case V4L2_CID_MPEG_STREAM_TYPE
:
1316 /* stream type cluster */
1317 hdl
->video_encoding
->val
=
1318 (hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_SS
||
1319 hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_VCD
) ?
1320 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
:
1321 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
;
1322 if (hdl
->video_encoding
->val
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
1323 /* MPEG-1 implies CBR */
1324 hdl
->video_bitrate_mode
->val
=
1325 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
;
1326 /* peak bitrate shall be >= normal bitrate */
1327 if (hdl
->video_bitrate_mode
->val
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
1328 hdl
->video_bitrate_peak
->val
< hdl
->video_bitrate
->val
)
1329 hdl
->video_bitrate_peak
->val
= hdl
->video_bitrate
->val
;
1335 static int cx2341x_s_ctrl(struct v4l2_ctrl
*ctrl
)
1337 static const int mpeg_stream_type
[] = {
1345 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1346 s32 val
= ctrl
->val
;
1351 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
1352 if (hdl
->ops
&& hdl
->ops
->s_stream_vbi_fmt
)
1353 return hdl
->ops
->s_stream_vbi_fmt(hdl
, val
);
1356 case V4L2_CID_MPEG_VIDEO_ASPECT
:
1357 return cx2341x_hdl_api(hdl
,
1358 CX2341X_ENC_SET_ASPECT_RATIO
, 1, val
+ 1);
1360 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
1361 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_CLOSURE
, 1, val
);
1363 case V4L2_CID_MPEG_AUDIO_MUTE
:
1364 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_AUDIO
, 1, val
);
1366 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
1367 return cx2341x_hdl_api(hdl
,
1368 CX2341X_ENC_SET_FRAME_DROP_RATE
, 1, val
);
1370 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
1371 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MISC
, 2, 7, val
);
1373 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
1374 /* audio properties cluster */
1375 props
= (hdl
->audio_sampling_freq
->val
<< 0) |
1376 (hdl
->audio_mode
->val
<< 8) |
1377 (hdl
->audio_mode_extension
->val
<< 10) |
1378 (hdl
->audio_crc
->val
<< 14);
1379 if (hdl
->audio_emphasis
->val
== V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
)
1382 props
|= hdl
->audio_emphasis
->val
<< 12;
1384 if (hdl
->audio_encoding
->val
== V4L2_MPEG_AUDIO_ENCODING_AC3
) {
1387 /* Not sure if this MPEG Layer II setting is required */
1388 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2
) << 2) |
1390 (hdl
->audio_ac3_bitrate
->val
<< 4) |
1391 (CX2341X_AUDIO_ENCODING_METHOD_AC3
<< 28);
1393 /* Assuming MPEG Layer II */
1395 ((3 - hdl
->audio_encoding
->val
) << 2) |
1396 ((1 + hdl
->audio_l2_bitrate
->val
) << 4);
1398 err
= cx2341x_hdl_api(hdl
,
1399 CX2341X_ENC_SET_AUDIO_PROPERTIES
, 1, props
);
1403 hdl
->audio_properties
= props
;
1404 if (hdl
->audio_ac3_bitrate
) {
1405 int is_ac3
= hdl
->audio_encoding
->val
==
1406 V4L2_MPEG_AUDIO_ENCODING_AC3
;
1408 v4l2_ctrl_activate(hdl
->audio_ac3_bitrate
, is_ac3
);
1409 v4l2_ctrl_activate(hdl
->audio_l2_bitrate
, !is_ac3
);
1411 v4l2_ctrl_activate(hdl
->audio_mode_extension
,
1412 hdl
->audio_mode
->val
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
);
1413 if (cx2341x_neq(hdl
->audio_sampling_freq
) &&
1414 hdl
->ops
&& hdl
->ops
->s_audio_sampling_freq
)
1415 return hdl
->ops
->s_audio_sampling_freq(hdl
, hdl
->audio_sampling_freq
->val
);
1416 if (cx2341x_neq(hdl
->audio_mode
) &&
1417 hdl
->ops
&& hdl
->ops
->s_audio_mode
)
1418 return hdl
->ops
->s_audio_mode(hdl
, hdl
->audio_mode
->val
);
1421 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
1422 /* video gop cluster */
1423 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1424 hdl
->video_gop_size
->val
,
1425 hdl
->video_b_frames
->val
+ 1);
1427 case V4L2_CID_MPEG_STREAM_TYPE
:
1428 /* stream type cluster */
1429 err
= cx2341x_hdl_api(hdl
,
1430 CX2341X_ENC_SET_STREAM_TYPE
, 1, mpeg_stream_type
[val
]);
1434 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_BIT_RATE
, 5,
1435 hdl
->video_bitrate_mode
->val
,
1436 hdl
->video_bitrate
->val
,
1437 hdl
->video_bitrate_peak
->val
/ 400, 0, 0);
1441 v4l2_ctrl_activate(hdl
->video_bitrate_mode
,
1442 hdl
->video_encoding
->val
!= V4L2_MPEG_VIDEO_ENCODING_MPEG_1
);
1443 v4l2_ctrl_activate(hdl
->video_bitrate_peak
,
1444 hdl
->video_bitrate_mode
->val
!= V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
);
1445 if (cx2341x_neq(hdl
->video_encoding
) &&
1446 hdl
->ops
&& hdl
->ops
->s_video_encoding
)
1447 return hdl
->ops
->s_video_encoding(hdl
, hdl
->video_encoding
->val
);
1450 case V4L2_CID_MPEG_VIDEO_MUTE
:
1451 /* video mute cluster */
1452 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_VIDEO
, 1,
1453 hdl
->video_mute
->val
|
1454 (hdl
->video_mute_yuv
->val
<< 8));
1456 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
: {
1459 /* video filter mode */
1460 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_MODE
, 2,
1461 hdl
->video_spatial_filter_mode
->val
|
1462 (hdl
->video_temporal_filter_mode
->val
<< 1),
1463 hdl
->video_median_filter_type
->val
);
1467 active_filter
= hdl
->video_spatial_filter_mode
->val
!=
1468 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
;
1469 v4l2_ctrl_activate(hdl
->video_spatial_filter
, active_filter
);
1470 v4l2_ctrl_activate(hdl
->video_luma_spatial_filter_type
, active_filter
);
1471 v4l2_ctrl_activate(hdl
->video_chroma_spatial_filter_type
, active_filter
);
1472 active_filter
= hdl
->video_temporal_filter_mode
->val
!=
1473 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
;
1474 v4l2_ctrl_activate(hdl
->video_temporal_filter
, active_filter
);
1475 active_filter
= hdl
->video_median_filter_type
->val
!=
1476 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
;
1477 v4l2_ctrl_activate(hdl
->video_luma_median_filter_bottom
, active_filter
);
1478 v4l2_ctrl_activate(hdl
->video_luma_median_filter_top
, active_filter
);
1479 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_bottom
, active_filter
);
1480 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_top
, active_filter
);
1484 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
1485 /* video filter type cluster */
1486 return cx2341x_hdl_api(hdl
,
1487 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
, 2,
1488 hdl
->video_luma_spatial_filter_type
->val
,
1489 hdl
->video_chroma_spatial_filter_type
->val
);
1491 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
1492 /* video filter cluster */
1493 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_PROPS
, 2,
1494 hdl
->video_spatial_filter
->val
,
1495 hdl
->video_temporal_filter
->val
);
1497 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
1498 /* video median cluster */
1499 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1500 hdl
->video_luma_median_filter_bottom
->val
,
1501 hdl
->video_luma_median_filter_top
->val
,
1502 hdl
->video_chroma_median_filter_bottom
->val
,
1503 hdl
->video_chroma_median_filter_top
->val
);
1508 static const struct v4l2_ctrl_ops cx2341x_ops
= {
1509 .try_ctrl
= cx2341x_try_ctrl
,
1510 .s_ctrl
= cx2341x_s_ctrl
,
1513 static struct v4l2_ctrl
*cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler
*hdl
,
1514 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1516 struct v4l2_ctrl_config cfg
;
1518 memset(&cfg
, 0, sizeof(cfg
));
1519 cx2341x_ctrl_fill(id
, &cfg
.name
, &cfg
.type
, &min
, &max
, &step
, &def
, &cfg
.flags
);
1520 cfg
.ops
= &cx2341x_ops
;
1525 if (cfg
.type
== V4L2_CTRL_TYPE_MENU
) {
1527 cfg
.menu_skip_mask
= step
;
1528 cfg
.qmenu
= cx2341x_get_menu(id
);
1531 cfg
.menu_skip_mask
= 0;
1533 return v4l2_ctrl_new_custom(hdl
, &cfg
, NULL
);
1536 static struct v4l2_ctrl
*cx2341x_ctrl_new_std(struct v4l2_ctrl_handler
*hdl
,
1537 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1539 return v4l2_ctrl_new_std(hdl
, &cx2341x_ops
, id
, min
, max
, step
, def
);
1542 static struct v4l2_ctrl
*cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler
*hdl
,
1543 u32 id
, s32 max
, s32 mask
, s32 def
)
1545 return v4l2_ctrl_new_std_menu(hdl
, &cx2341x_ops
, id
, max
, mask
, def
);
1548 int cx2341x_handler_init(struct cx2341x_handler
*cxhdl
,
1549 unsigned nr_of_controls_hint
)
1551 struct v4l2_ctrl_handler
*hdl
= &cxhdl
->hdl
;
1552 u32 caps
= cxhdl
->capabilities
;
1553 int has_sliced_vbi
= caps
& CX2341X_CAP_HAS_SLICED_VBI
;
1554 int has_ac3
= caps
& CX2341X_CAP_HAS_AC3
;
1555 int has_ts
= caps
& CX2341X_CAP_HAS_TS
;
1558 cxhdl
->height
= 480;
1560 v4l2_ctrl_handler_init(hdl
, nr_of_controls_hint
);
1562 /* Add controls in ascending control ID order for fastest
1564 cxhdl
->stream_type
= cx2341x_ctrl_new_menu(hdl
,
1565 V4L2_CID_MPEG_STREAM_TYPE
,
1566 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD
, has_ts
? 0 : 2,
1567 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
);
1568 cxhdl
->stream_vbi_fmt
= cx2341x_ctrl_new_menu(hdl
,
1569 V4L2_CID_MPEG_STREAM_VBI_FMT
,
1570 V4L2_MPEG_STREAM_VBI_FMT_IVTV
, has_sliced_vbi
? 0 : 2,
1571 V4L2_MPEG_STREAM_VBI_FMT_NONE
);
1572 cxhdl
->audio_sampling_freq
= cx2341x_ctrl_new_menu(hdl
,
1573 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
,
1574 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
, 0,
1575 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
);
1576 cxhdl
->audio_encoding
= cx2341x_ctrl_new_menu(hdl
,
1577 V4L2_CID_MPEG_AUDIO_ENCODING
,
1578 V4L2_MPEG_AUDIO_ENCODING_AC3
, has_ac3
? ~0x12 : ~0x2,
1579 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
);
1580 cxhdl
->audio_l2_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1581 V4L2_CID_MPEG_AUDIO_L2_BITRATE
,
1582 V4L2_MPEG_AUDIO_L2_BITRATE_384K
, 0x1ff,
1583 V4L2_MPEG_AUDIO_L2_BITRATE_224K
);
1584 cxhdl
->audio_mode
= cx2341x_ctrl_new_menu(hdl
,
1585 V4L2_CID_MPEG_AUDIO_MODE
,
1586 V4L2_MPEG_AUDIO_MODE_MONO
, 0,
1587 V4L2_MPEG_AUDIO_MODE_STEREO
);
1588 cxhdl
->audio_mode_extension
= cx2341x_ctrl_new_menu(hdl
,
1589 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
,
1590 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16
, 0,
1591 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
);
1592 cxhdl
->audio_emphasis
= cx2341x_ctrl_new_menu(hdl
,
1593 V4L2_CID_MPEG_AUDIO_EMPHASIS
,
1594 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
, 0,
1595 V4L2_MPEG_AUDIO_EMPHASIS_NONE
);
1596 cxhdl
->audio_crc
= cx2341x_ctrl_new_menu(hdl
,
1597 V4L2_CID_MPEG_AUDIO_CRC
,
1598 V4L2_MPEG_AUDIO_CRC_CRC16
, 0,
1599 V4L2_MPEG_AUDIO_CRC_NONE
);
1601 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_AUDIO_MUTE
, 0, 1, 1, 0);
1603 cxhdl
->audio_ac3_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1604 V4L2_CID_MPEG_AUDIO_AC3_BITRATE
,
1605 V4L2_MPEG_AUDIO_AC3_BITRATE_448K
, 0x03,
1606 V4L2_MPEG_AUDIO_AC3_BITRATE_224K
);
1607 cxhdl
->video_encoding
= cx2341x_ctrl_new_menu(hdl
,
1608 V4L2_CID_MPEG_VIDEO_ENCODING
,
1609 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
, 0,
1610 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
);
1611 cx2341x_ctrl_new_menu(hdl
,
1612 V4L2_CID_MPEG_VIDEO_ASPECT
,
1613 V4L2_MPEG_VIDEO_ASPECT_221x100
, 0,
1614 V4L2_MPEG_VIDEO_ASPECT_4x3
);
1615 cxhdl
->video_b_frames
= cx2341x_ctrl_new_std(hdl
,
1616 V4L2_CID_MPEG_VIDEO_B_FRAMES
, 0, 33, 1, 2);
1617 cxhdl
->video_gop_size
= cx2341x_ctrl_new_std(hdl
,
1618 V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1619 1, 34, 1, cxhdl
->is_50hz
? 12 : 15);
1620 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
, 0, 1, 1, 1);
1621 cxhdl
->video_bitrate_mode
= cx2341x_ctrl_new_menu(hdl
,
1622 V4L2_CID_MPEG_VIDEO_BITRATE_MODE
,
1623 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
, 0,
1624 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
);
1625 cxhdl
->video_bitrate
= cx2341x_ctrl_new_std(hdl
,
1626 V4L2_CID_MPEG_VIDEO_BITRATE
,
1627 0, 27000000, 1, 6000000);
1628 cxhdl
->video_bitrate_peak
= cx2341x_ctrl_new_std(hdl
,
1629 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
,
1630 0, 27000000, 1, 8000000);
1631 cx2341x_ctrl_new_std(hdl
,
1632 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
, 0, 255, 1, 0);
1633 cxhdl
->video_mute
= cx2341x_ctrl_new_std(hdl
,
1634 V4L2_CID_MPEG_VIDEO_MUTE
, 0, 1, 1, 0);
1635 cxhdl
->video_mute_yuv
= cx2341x_ctrl_new_std(hdl
,
1636 V4L2_CID_MPEG_VIDEO_MUTE_YUV
, 0, 0xffffff, 1, 0x008080);
1638 /* CX23415/6 specific */
1639 cxhdl
->video_spatial_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1640 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
,
1641 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
1642 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
, 0,
1643 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
);
1644 cxhdl
->video_spatial_filter
= cx2341x_ctrl_new_custom(hdl
,
1645 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
,
1647 cxhdl
->video_luma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1648 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
,
1649 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF
,
1650 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE
,
1652 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1653 cxhdl
->video_chroma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1654 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
,
1655 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF
,
1656 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
1658 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1659 cxhdl
->video_temporal_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1660 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
,
1661 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
1662 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
,
1664 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
);
1665 cxhdl
->video_temporal_filter
= cx2341x_ctrl_new_custom(hdl
,
1666 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
,
1668 cxhdl
->video_median_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1669 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
,
1670 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
1671 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG
,
1673 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
);
1674 cxhdl
->video_luma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1675 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
,
1677 cxhdl
->video_luma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1678 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
,
1680 cxhdl
->video_chroma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1681 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
,
1683 cxhdl
->video_chroma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1684 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
,
1686 cx2341x_ctrl_new_custom(hdl
, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
,
1690 int err
= hdl
->error
;
1692 v4l2_ctrl_handler_free(hdl
);
1696 v4l2_ctrl_cluster(8, &cxhdl
->audio_sampling_freq
);
1697 v4l2_ctrl_cluster(2, &cxhdl
->video_b_frames
);
1698 v4l2_ctrl_cluster(5, &cxhdl
->stream_type
);
1699 v4l2_ctrl_cluster(2, &cxhdl
->video_mute
);
1700 v4l2_ctrl_cluster(3, &cxhdl
->video_spatial_filter_mode
);
1701 v4l2_ctrl_cluster(2, &cxhdl
->video_luma_spatial_filter_type
);
1702 v4l2_ctrl_cluster(2, &cxhdl
->video_spatial_filter
);
1703 v4l2_ctrl_cluster(4, &cxhdl
->video_luma_median_filter_top
);
1707 EXPORT_SYMBOL(cx2341x_handler_init
);
1709 void cx2341x_handler_set_50hz(struct cx2341x_handler
*cxhdl
, int is_50hz
)
1711 cxhdl
->is_50hz
= is_50hz
;
1712 cxhdl
->video_gop_size
->default_value
= cxhdl
->is_50hz
? 12 : 15;
1714 EXPORT_SYMBOL(cx2341x_handler_set_50hz
);
1716 int cx2341x_handler_setup(struct cx2341x_handler
*cxhdl
)
1718 int h
= cxhdl
->height
;
1719 int w
= cxhdl
->width
;
1722 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, cxhdl
->port
, 0);
1725 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_RATE
, 1, cxhdl
->is_50hz
);
1729 if (v4l2_ctrl_g_ctrl(cxhdl
->video_encoding
) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1733 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_SIZE
, 2, h
, w
);
1736 return v4l2_ctrl_handler_setup(&cxhdl
->hdl
);
1738 EXPORT_SYMBOL(cx2341x_handler_setup
);
1740 void cx2341x_handler_set_busy(struct cx2341x_handler
*cxhdl
, int busy
)
1742 v4l2_ctrl_grab(cxhdl
->audio_sampling_freq
, busy
);
1743 v4l2_ctrl_grab(cxhdl
->audio_encoding
, busy
);
1744 v4l2_ctrl_grab(cxhdl
->audio_l2_bitrate
, busy
);
1745 v4l2_ctrl_grab(cxhdl
->audio_ac3_bitrate
, busy
);
1746 v4l2_ctrl_grab(cxhdl
->stream_vbi_fmt
, busy
);
1747 v4l2_ctrl_grab(cxhdl
->stream_type
, busy
);
1748 v4l2_ctrl_grab(cxhdl
->video_bitrate_mode
, busy
);
1749 v4l2_ctrl_grab(cxhdl
->video_bitrate
, busy
);
1750 v4l2_ctrl_grab(cxhdl
->video_bitrate_peak
, busy
);
1752 EXPORT_SYMBOL(cx2341x_handler_set_busy
);