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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/module.h>
23 #include <linux/errno.h>
24 #include <linux/kernel.h>
25 #include <linux/init.h>
26 #include <linux/types.h>
27 #include <linux/videodev2.h>
29 #include <media/tuner.h>
30 #include <media/drv-intf/cx2341x.h>
31 #include <media/v4l2-common.h>
33 MODULE_DESCRIPTION("cx23415/6/8 driver");
34 MODULE_AUTHOR("Hans Verkuil");
35 MODULE_LICENSE("GPL");
38 module_param(debug
, int, 0644);
39 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
41 /********************** COMMON CODE *********************/
43 /* definitions for audio properties bits 29-28 */
44 #define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
45 #define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
46 #define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
48 static const char *cx2341x_get_name(u32 id
)
51 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
52 return "Spatial Filter Mode";
53 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
54 return "Spatial Filter";
55 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
56 return "Spatial Luma Filter Type";
57 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
58 return "Spatial Chroma Filter Type";
59 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
60 return "Temporal Filter Mode";
61 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
62 return "Temporal Filter";
63 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
64 return "Median Filter Type";
65 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
66 return "Median Luma Filter Maximum";
67 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
68 return "Median Luma Filter Minimum";
69 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
70 return "Median Chroma Filter Maximum";
71 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
72 return "Median Chroma Filter Minimum";
73 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
74 return "Insert Navigation Packets";
79 static const char **cx2341x_get_menu(u32 id
)
81 static const char *cx2341x_video_spatial_filter_mode_menu
[] = {
87 static const char *cx2341x_video_luma_spatial_filter_type_menu
[] = {
92 "2D Symmetric non-separable",
96 static const char *cx2341x_video_chroma_spatial_filter_type_menu
[] = {
102 static const char *cx2341x_video_temporal_filter_mode_menu
[] = {
108 static const char *cx2341x_video_median_filter_type_menu
[] = {
112 "Horizontal/Vertical",
118 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
119 return cx2341x_video_spatial_filter_mode_menu
;
120 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
121 return cx2341x_video_luma_spatial_filter_type_menu
;
122 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
123 return cx2341x_video_chroma_spatial_filter_type_menu
;
124 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
125 return cx2341x_video_temporal_filter_mode_menu
;
126 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
127 return cx2341x_video_median_filter_type_menu
;
132 static void cx2341x_ctrl_fill(u32 id
, const char **name
, enum v4l2_ctrl_type
*type
,
133 s32
*min
, s32
*max
, s32
*step
, s32
*def
, u32
*flags
)
135 *name
= cx2341x_get_name(id
);
139 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
140 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
141 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
142 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
143 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
144 *type
= V4L2_CTRL_TYPE_MENU
;
148 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
149 *type
= V4L2_CTRL_TYPE_BOOLEAN
;
154 *type
= V4L2_CTRL_TYPE_INTEGER
;
158 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
159 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
160 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
161 *flags
|= V4L2_CTRL_FLAG_UPDATE
;
163 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
164 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
165 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
166 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
167 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
168 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
169 *flags
|= V4L2_CTRL_FLAG_SLIDER
;
171 case V4L2_CID_MPEG_VIDEO_ENCODING
:
172 *flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
178 /********************** OLD CODE *********************/
180 /* Must be sorted from low to high control ID! */
181 const u32 cx2341x_mpeg_ctrls
[] = {
183 V4L2_CID_MPEG_STREAM_TYPE
,
184 V4L2_CID_MPEG_STREAM_VBI_FMT
,
185 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
,
186 V4L2_CID_MPEG_AUDIO_ENCODING
,
187 V4L2_CID_MPEG_AUDIO_L2_BITRATE
,
188 V4L2_CID_MPEG_AUDIO_MODE
,
189 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
,
190 V4L2_CID_MPEG_AUDIO_EMPHASIS
,
191 V4L2_CID_MPEG_AUDIO_CRC
,
192 V4L2_CID_MPEG_AUDIO_MUTE
,
193 V4L2_CID_MPEG_AUDIO_AC3_BITRATE
,
194 V4L2_CID_MPEG_VIDEO_ENCODING
,
195 V4L2_CID_MPEG_VIDEO_ASPECT
,
196 V4L2_CID_MPEG_VIDEO_B_FRAMES
,
197 V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
198 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
,
199 V4L2_CID_MPEG_VIDEO_BITRATE_MODE
,
200 V4L2_CID_MPEG_VIDEO_BITRATE
,
201 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
,
202 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
,
203 V4L2_CID_MPEG_VIDEO_MUTE
,
204 V4L2_CID_MPEG_VIDEO_MUTE_YUV
,
205 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
,
206 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
,
207 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
,
208 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
,
209 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
,
210 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
,
211 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
,
212 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
,
213 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
,
214 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
,
215 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
,
216 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
,
219 EXPORT_SYMBOL(cx2341x_mpeg_ctrls
);
221 static const struct cx2341x_mpeg_params default_params
= {
224 .port
= CX2341X_PORT_MEMORY
,
230 .stream_type
= V4L2_MPEG_STREAM_TYPE_MPEG2_PS
,
231 .stream_vbi_fmt
= V4L2_MPEG_STREAM_VBI_FMT_NONE
,
232 .stream_insert_nav_packets
= 0,
235 .audio_sampling_freq
= V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
,
236 .audio_encoding
= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
237 .audio_l2_bitrate
= V4L2_MPEG_AUDIO_L2_BITRATE_224K
,
238 .audio_ac3_bitrate
= V4L2_MPEG_AUDIO_AC3_BITRATE_224K
,
239 .audio_mode
= V4L2_MPEG_AUDIO_MODE_STEREO
,
240 .audio_mode_extension
= V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
,
241 .audio_emphasis
= V4L2_MPEG_AUDIO_EMPHASIS_NONE
,
242 .audio_crc
= V4L2_MPEG_AUDIO_CRC_NONE
,
246 .video_encoding
= V4L2_MPEG_VIDEO_ENCODING_MPEG_2
,
247 .video_aspect
= V4L2_MPEG_VIDEO_ASPECT_4x3
,
249 .video_gop_size
= 12,
250 .video_gop_closure
= 1,
251 .video_bitrate_mode
= V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
,
252 .video_bitrate
= 6000000,
253 .video_bitrate_peak
= 8000000,
254 .video_temporal_decimation
= 0,
256 .video_mute_yuv
= 0x008080, /* YCbCr value for black */
258 /* encoding filters */
259 .video_spatial_filter_mode
=
260 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
261 .video_spatial_filter
= 0,
262 .video_luma_spatial_filter_type
=
263 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR
,
264 .video_chroma_spatial_filter_type
=
265 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
266 .video_temporal_filter_mode
=
267 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
268 .video_temporal_filter
= 8,
269 .video_median_filter_type
=
270 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
271 .video_luma_median_filter_top
= 255,
272 .video_luma_median_filter_bottom
= 0,
273 .video_chroma_median_filter_top
= 255,
274 .video_chroma_median_filter_bottom
= 0,
276 /* Map the control ID to the correct field in the cx2341x_mpeg_params
277 struct. Return -EINVAL if the ID is unknown, else return 0. */
278 static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params
*params
,
279 struct v4l2_ext_control
*ctrl
)
282 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
283 ctrl
->value
= params
->audio_sampling_freq
;
285 case V4L2_CID_MPEG_AUDIO_ENCODING
:
286 ctrl
->value
= params
->audio_encoding
;
288 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
289 ctrl
->value
= params
->audio_l2_bitrate
;
291 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
292 ctrl
->value
= params
->audio_ac3_bitrate
;
294 case V4L2_CID_MPEG_AUDIO_MODE
:
295 ctrl
->value
= params
->audio_mode
;
297 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
298 ctrl
->value
= params
->audio_mode_extension
;
300 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
301 ctrl
->value
= params
->audio_emphasis
;
303 case V4L2_CID_MPEG_AUDIO_CRC
:
304 ctrl
->value
= params
->audio_crc
;
306 case V4L2_CID_MPEG_AUDIO_MUTE
:
307 ctrl
->value
= params
->audio_mute
;
309 case V4L2_CID_MPEG_VIDEO_ENCODING
:
310 ctrl
->value
= params
->video_encoding
;
312 case V4L2_CID_MPEG_VIDEO_ASPECT
:
313 ctrl
->value
= params
->video_aspect
;
315 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
316 ctrl
->value
= params
->video_b_frames
;
318 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
319 ctrl
->value
= params
->video_gop_size
;
321 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
322 ctrl
->value
= params
->video_gop_closure
;
324 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
325 ctrl
->value
= params
->video_bitrate_mode
;
327 case V4L2_CID_MPEG_VIDEO_BITRATE
:
328 ctrl
->value
= params
->video_bitrate
;
330 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
331 ctrl
->value
= params
->video_bitrate_peak
;
333 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
334 ctrl
->value
= params
->video_temporal_decimation
;
336 case V4L2_CID_MPEG_VIDEO_MUTE
:
337 ctrl
->value
= params
->video_mute
;
339 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
:
340 ctrl
->value
= params
->video_mute_yuv
;
342 case V4L2_CID_MPEG_STREAM_TYPE
:
343 ctrl
->value
= params
->stream_type
;
345 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
346 ctrl
->value
= params
->stream_vbi_fmt
;
348 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
349 ctrl
->value
= params
->video_spatial_filter_mode
;
351 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
352 ctrl
->value
= params
->video_spatial_filter
;
354 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
355 ctrl
->value
= params
->video_luma_spatial_filter_type
;
357 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
358 ctrl
->value
= params
->video_chroma_spatial_filter_type
;
360 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
361 ctrl
->value
= params
->video_temporal_filter_mode
;
363 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
364 ctrl
->value
= params
->video_temporal_filter
;
366 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
367 ctrl
->value
= params
->video_median_filter_type
;
369 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
370 ctrl
->value
= params
->video_luma_median_filter_top
;
372 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
373 ctrl
->value
= params
->video_luma_median_filter_bottom
;
375 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
376 ctrl
->value
= params
->video_chroma_median_filter_top
;
378 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
379 ctrl
->value
= params
->video_chroma_median_filter_bottom
;
381 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
382 ctrl
->value
= params
->stream_insert_nav_packets
;
390 /* Map the control ID to the correct field in the cx2341x_mpeg_params
391 struct. Return -EINVAL if the ID is unknown, else return 0. */
392 static int cx2341x_set_ctrl(struct cx2341x_mpeg_params
*params
, int busy
,
393 struct v4l2_ext_control
*ctrl
)
396 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
399 params
->audio_sampling_freq
= ctrl
->value
;
401 case V4L2_CID_MPEG_AUDIO_ENCODING
:
404 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
)
405 if (ctrl
->value
!= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
&&
406 ctrl
->value
!= V4L2_MPEG_AUDIO_ENCODING_AC3
)
408 params
->audio_encoding
= ctrl
->value
;
410 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
413 params
->audio_l2_bitrate
= ctrl
->value
;
415 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
418 if (!(params
->capabilities
& CX2341X_CAP_HAS_AC3
))
420 params
->audio_ac3_bitrate
= ctrl
->value
;
422 case V4L2_CID_MPEG_AUDIO_MODE
:
423 params
->audio_mode
= ctrl
->value
;
425 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
426 params
->audio_mode_extension
= ctrl
->value
;
428 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
429 params
->audio_emphasis
= ctrl
->value
;
431 case V4L2_CID_MPEG_AUDIO_CRC
:
432 params
->audio_crc
= ctrl
->value
;
434 case V4L2_CID_MPEG_AUDIO_MUTE
:
435 params
->audio_mute
= ctrl
->value
;
437 case V4L2_CID_MPEG_VIDEO_ASPECT
:
438 params
->video_aspect
= ctrl
->value
;
440 case V4L2_CID_MPEG_VIDEO_B_FRAMES
: {
441 int b
= ctrl
->value
+ 1;
442 int gop
= params
->video_gop_size
;
443 params
->video_b_frames
= ctrl
->value
;
444 params
->video_gop_size
= b
* ((gop
+ b
- 1) / b
);
445 /* Max GOP size = 34 */
446 while (params
->video_gop_size
> 34)
447 params
->video_gop_size
-= b
;
450 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
: {
451 int b
= params
->video_b_frames
+ 1;
452 int gop
= ctrl
->value
;
453 params
->video_gop_size
= b
* ((gop
+ b
- 1) / b
);
454 /* Max GOP size = 34 */
455 while (params
->video_gop_size
> 34)
456 params
->video_gop_size
-= b
;
457 ctrl
->value
= params
->video_gop_size
;
460 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
461 params
->video_gop_closure
= ctrl
->value
;
463 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
466 /* MPEG-1 only allows CBR */
467 if (params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
&&
468 ctrl
->value
!= V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
)
470 params
->video_bitrate_mode
= ctrl
->value
;
472 case V4L2_CID_MPEG_VIDEO_BITRATE
:
475 params
->video_bitrate
= ctrl
->value
;
477 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
480 params
->video_bitrate_peak
= ctrl
->value
;
482 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
483 params
->video_temporal_decimation
= ctrl
->value
;
485 case V4L2_CID_MPEG_VIDEO_MUTE
:
486 params
->video_mute
= (ctrl
->value
!= 0);
488 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
:
489 params
->video_mute_yuv
= ctrl
->value
;
491 case V4L2_CID_MPEG_STREAM_TYPE
:
494 params
->stream_type
= ctrl
->value
;
495 params
->video_encoding
=
496 (params
->stream_type
== V4L2_MPEG_STREAM_TYPE_MPEG1_SS
||
497 params
->stream_type
== V4L2_MPEG_STREAM_TYPE_MPEG1_VCD
) ?
498 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
:
499 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
;
500 if (params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
501 /* MPEG-1 implies CBR */
502 params
->video_bitrate_mode
=
503 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
;
505 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
506 params
->stream_vbi_fmt
= ctrl
->value
;
508 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
509 params
->video_spatial_filter_mode
= ctrl
->value
;
511 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
512 params
->video_spatial_filter
= ctrl
->value
;
514 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
515 params
->video_luma_spatial_filter_type
= ctrl
->value
;
517 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
518 params
->video_chroma_spatial_filter_type
= ctrl
->value
;
520 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
521 params
->video_temporal_filter_mode
= ctrl
->value
;
523 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
524 params
->video_temporal_filter
= ctrl
->value
;
526 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
527 params
->video_median_filter_type
= ctrl
->value
;
529 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
530 params
->video_luma_median_filter_top
= ctrl
->value
;
532 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
533 params
->video_luma_median_filter_bottom
= ctrl
->value
;
535 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
536 params
->video_chroma_median_filter_top
= ctrl
->value
;
538 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
539 params
->video_chroma_median_filter_bottom
= ctrl
->value
;
541 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
542 params
->stream_insert_nav_packets
= ctrl
->value
;
550 static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl
*qctrl
,
551 s32 min
, s32 max
, s32 step
, s32 def
)
557 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
558 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
559 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
560 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
561 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
562 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
563 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
564 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
565 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
566 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
567 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
568 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
569 cx2341x_ctrl_fill(qctrl
->id
, &name
, &qctrl
->type
,
570 &min
, &max
, &step
, &def
, &qctrl
->flags
);
571 qctrl
->minimum
= min
;
572 qctrl
->maximum
= max
;
574 qctrl
->default_value
= def
;
575 qctrl
->reserved
[0] = qctrl
->reserved
[1] = 0;
576 strlcpy(qctrl
->name
, name
, sizeof(qctrl
->name
));
580 return v4l2_ctrl_query_fill(qctrl
, min
, max
, step
, def
);
584 int cx2341x_ctrl_query(const struct cx2341x_mpeg_params
*params
,
585 struct v4l2_queryctrl
*qctrl
)
590 case V4L2_CID_MPEG_CLASS
:
591 return v4l2_ctrl_query_fill(qctrl
, 0, 0, 0, 0);
592 case V4L2_CID_MPEG_STREAM_TYPE
:
593 return v4l2_ctrl_query_fill(qctrl
,
594 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
,
595 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD
, 1,
596 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
);
598 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
599 if (params
->capabilities
& CX2341X_CAP_HAS_SLICED_VBI
)
600 return v4l2_ctrl_query_fill(qctrl
,
601 V4L2_MPEG_STREAM_VBI_FMT_NONE
,
602 V4L2_MPEG_STREAM_VBI_FMT_IVTV
, 1,
603 V4L2_MPEG_STREAM_VBI_FMT_NONE
);
604 return cx2341x_ctrl_query_fill(qctrl
,
605 V4L2_MPEG_STREAM_VBI_FMT_NONE
,
606 V4L2_MPEG_STREAM_VBI_FMT_NONE
, 1,
607 default_params
.stream_vbi_fmt
);
609 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
610 return v4l2_ctrl_query_fill(qctrl
,
611 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100
,
612 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
, 1,
613 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
);
615 case V4L2_CID_MPEG_AUDIO_ENCODING
:
616 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
) {
618 * The state of L2 & AC3 bitrate controls can change
619 * when this control changes, but v4l2_ctrl_query_fill()
620 * already sets V4L2_CTRL_FLAG_UPDATE for
621 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
623 return v4l2_ctrl_query_fill(qctrl
,
624 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
625 V4L2_MPEG_AUDIO_ENCODING_AC3
, 1,
626 default_params
.audio_encoding
);
629 return v4l2_ctrl_query_fill(qctrl
,
630 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
,
631 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
, 1,
632 default_params
.audio_encoding
);
634 case V4L2_CID_MPEG_AUDIO_L2_BITRATE
:
635 err
= v4l2_ctrl_query_fill(qctrl
,
636 V4L2_MPEG_AUDIO_L2_BITRATE_192K
,
637 V4L2_MPEG_AUDIO_L2_BITRATE_384K
, 1,
638 default_params
.audio_l2_bitrate
);
641 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
&&
642 params
->audio_encoding
!= V4L2_MPEG_AUDIO_ENCODING_LAYER_2
)
643 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
646 case V4L2_CID_MPEG_AUDIO_MODE
:
647 return v4l2_ctrl_query_fill(qctrl
,
648 V4L2_MPEG_AUDIO_MODE_STEREO
,
649 V4L2_MPEG_AUDIO_MODE_MONO
, 1,
650 V4L2_MPEG_AUDIO_MODE_STEREO
);
652 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
:
653 err
= v4l2_ctrl_query_fill(qctrl
,
654 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
,
655 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16
, 1,
656 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
);
658 params
->audio_mode
!= V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
)
659 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
662 case V4L2_CID_MPEG_AUDIO_EMPHASIS
:
663 return v4l2_ctrl_query_fill(qctrl
,
664 V4L2_MPEG_AUDIO_EMPHASIS_NONE
,
665 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
, 1,
666 V4L2_MPEG_AUDIO_EMPHASIS_NONE
);
668 case V4L2_CID_MPEG_AUDIO_CRC
:
669 return v4l2_ctrl_query_fill(qctrl
,
670 V4L2_MPEG_AUDIO_CRC_NONE
,
671 V4L2_MPEG_AUDIO_CRC_CRC16
, 1,
672 V4L2_MPEG_AUDIO_CRC_NONE
);
674 case V4L2_CID_MPEG_AUDIO_MUTE
:
675 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 0);
677 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE
:
678 err
= v4l2_ctrl_query_fill(qctrl
,
679 V4L2_MPEG_AUDIO_AC3_BITRATE_48K
,
680 V4L2_MPEG_AUDIO_AC3_BITRATE_448K
, 1,
681 default_params
.audio_ac3_bitrate
);
684 if (params
->capabilities
& CX2341X_CAP_HAS_AC3
) {
685 if (params
->audio_encoding
!=
686 V4L2_MPEG_AUDIO_ENCODING_AC3
)
687 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
689 qctrl
->flags
|= V4L2_CTRL_FLAG_DISABLED
;
692 case V4L2_CID_MPEG_VIDEO_ENCODING
:
693 /* this setting is read-only for the cx2341x since the
694 V4L2_CID_MPEG_STREAM_TYPE really determines the
696 err
= v4l2_ctrl_query_fill(qctrl
,
697 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
,
698 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
, 1,
699 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
);
701 qctrl
->flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
704 case V4L2_CID_MPEG_VIDEO_ASPECT
:
705 return v4l2_ctrl_query_fill(qctrl
,
706 V4L2_MPEG_VIDEO_ASPECT_1x1
,
707 V4L2_MPEG_VIDEO_ASPECT_221x100
, 1,
708 V4L2_MPEG_VIDEO_ASPECT_4x3
);
710 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
711 return v4l2_ctrl_query_fill(qctrl
, 0, 33, 1, 2);
713 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
714 return v4l2_ctrl_query_fill(qctrl
, 1, 34, 1,
715 params
->is_50hz
? 12 : 15);
717 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
718 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 1);
720 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE
:
721 err
= v4l2_ctrl_query_fill(qctrl
,
722 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
,
723 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
, 1,
724 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
);
726 params
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
727 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
730 case V4L2_CID_MPEG_VIDEO_BITRATE
:
731 return v4l2_ctrl_query_fill(qctrl
, 0, 27000000, 1, 6000000);
733 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
:
734 err
= v4l2_ctrl_query_fill(qctrl
, 0, 27000000, 1, 8000000);
736 params
->video_bitrate_mode
==
737 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
)
738 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
741 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
742 return v4l2_ctrl_query_fill(qctrl
, 0, 255, 1, 0);
744 case V4L2_CID_MPEG_VIDEO_MUTE
:
745 return v4l2_ctrl_query_fill(qctrl
, 0, 1, 1, 0);
747 case V4L2_CID_MPEG_VIDEO_MUTE_YUV
: /* Init YUV (really YCbCr) to black */
748 return v4l2_ctrl_query_fill(qctrl
, 0, 0xffffff, 1, 0x008080);
750 /* CX23415/6 specific */
751 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
752 return cx2341x_ctrl_query_fill(qctrl
,
753 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
754 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
, 1,
755 default_params
.video_spatial_filter_mode
);
757 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
758 cx2341x_ctrl_query_fill(qctrl
, 0, 15, 1,
759 default_params
.video_spatial_filter
);
760 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
761 if (params
->video_spatial_filter_mode
==
762 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
763 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
766 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
767 cx2341x_ctrl_query_fill(qctrl
,
768 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF
,
769 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE
,
771 default_params
.video_luma_spatial_filter_type
);
772 if (params
->video_spatial_filter_mode
==
773 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
774 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
777 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
778 cx2341x_ctrl_query_fill(qctrl
,
779 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF
,
780 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
782 default_params
.video_chroma_spatial_filter_type
);
783 if (params
->video_spatial_filter_mode
==
784 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
)
785 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
788 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
789 return cx2341x_ctrl_query_fill(qctrl
,
790 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
791 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
, 1,
792 default_params
.video_temporal_filter_mode
);
794 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
:
795 cx2341x_ctrl_query_fill(qctrl
, 0, 31, 1,
796 default_params
.video_temporal_filter
);
797 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
798 if (params
->video_temporal_filter_mode
==
799 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
)
800 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
803 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
804 return cx2341x_ctrl_query_fill(qctrl
,
805 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
806 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG
, 1,
807 default_params
.video_median_filter_type
);
809 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
810 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
811 default_params
.video_luma_median_filter_top
);
812 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
813 if (params
->video_median_filter_type
==
814 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
815 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
818 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
:
819 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
820 default_params
.video_luma_median_filter_bottom
);
821 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
822 if (params
->video_median_filter_type
==
823 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
824 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
827 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
:
828 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
829 default_params
.video_chroma_median_filter_top
);
830 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
831 if (params
->video_median_filter_type
==
832 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
833 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
836 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
:
837 cx2341x_ctrl_query_fill(qctrl
, 0, 255, 1,
838 default_params
.video_chroma_median_filter_bottom
);
839 qctrl
->flags
|= V4L2_CTRL_FLAG_SLIDER
;
840 if (params
->video_median_filter_type
==
841 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
)
842 qctrl
->flags
|= V4L2_CTRL_FLAG_INACTIVE
;
845 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
846 return cx2341x_ctrl_query_fill(qctrl
, 0, 1, 1,
847 default_params
.stream_insert_nav_packets
);
854 EXPORT_SYMBOL(cx2341x_ctrl_query
);
856 const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params
*p
, u32 id
)
858 static const char * const mpeg_stream_type_without_ts
[] = {
859 "MPEG-2 Program Stream",
861 "MPEG-1 System Stream",
862 "MPEG-2 DVD-compatible Stream",
863 "MPEG-1 VCD-compatible Stream",
864 "MPEG-2 SVCD-compatible Stream",
868 static const char *mpeg_stream_type_with_ts
[] = {
869 "MPEG-2 Program Stream",
870 "MPEG-2 Transport Stream",
871 "MPEG-1 System Stream",
872 "MPEG-2 DVD-compatible Stream",
873 "MPEG-1 VCD-compatible Stream",
874 "MPEG-2 SVCD-compatible Stream",
878 static const char *mpeg_audio_encoding_l2_ac3
[] = {
888 case V4L2_CID_MPEG_STREAM_TYPE
:
889 return (p
->capabilities
& CX2341X_CAP_HAS_TS
) ?
890 mpeg_stream_type_with_ts
: mpeg_stream_type_without_ts
;
891 case V4L2_CID_MPEG_AUDIO_ENCODING
:
892 return (p
->capabilities
& CX2341X_CAP_HAS_AC3
) ?
893 mpeg_audio_encoding_l2_ac3
: v4l2_ctrl_get_menu(id
);
894 case V4L2_CID_MPEG_AUDIO_L1_BITRATE
:
895 case V4L2_CID_MPEG_AUDIO_L3_BITRATE
:
897 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
:
898 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
899 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
:
900 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
:
901 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
:
902 return cx2341x_get_menu(id
);
904 return v4l2_ctrl_get_menu(id
);
907 EXPORT_SYMBOL(cx2341x_ctrl_get_menu
);
909 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params
*params
)
911 params
->audio_properties
=
912 (params
->audio_sampling_freq
<< 0) |
913 (params
->audio_mode
<< 8) |
914 (params
->audio_mode_extension
<< 10) |
915 (((params
->audio_emphasis
== V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
)
916 ? 3 : params
->audio_emphasis
) << 12) |
917 (params
->audio_crc
<< 14);
919 if ((params
->capabilities
& CX2341X_CAP_HAS_AC3
) &&
920 params
->audio_encoding
== V4L2_MPEG_AUDIO_ENCODING_AC3
) {
921 params
->audio_properties
|=
922 /* Not sure if this MPEG Layer II setting is required */
923 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2
) << 2) |
924 (params
->audio_ac3_bitrate
<< 4) |
925 (CX2341X_AUDIO_ENCODING_METHOD_AC3
<< 28);
927 /* Assuming MPEG Layer II */
928 params
->audio_properties
|=
929 ((3 - params
->audio_encoding
) << 2) |
930 ((1 + params
->audio_l2_bitrate
) << 4);
934 /* Check for correctness of the ctrl's value based on the data from
935 struct v4l2_queryctrl and the available menu items. Note that
936 menu_items may be NULL, in that case it is ignored. */
937 static int v4l2_ctrl_check(struct v4l2_ext_control
*ctrl
, struct v4l2_queryctrl
*qctrl
,
938 const char * const *menu_items
)
940 if (qctrl
->flags
& V4L2_CTRL_FLAG_DISABLED
)
942 if (qctrl
->flags
& V4L2_CTRL_FLAG_GRABBED
)
944 if (qctrl
->type
== V4L2_CTRL_TYPE_STRING
)
946 if (qctrl
->type
== V4L2_CTRL_TYPE_BUTTON
||
947 qctrl
->type
== V4L2_CTRL_TYPE_INTEGER64
||
948 qctrl
->type
== V4L2_CTRL_TYPE_CTRL_CLASS
)
950 if (ctrl
->value
< qctrl
->minimum
|| ctrl
->value
> qctrl
->maximum
)
952 if (qctrl
->type
== V4L2_CTRL_TYPE_MENU
&& menu_items
!= NULL
) {
953 if (menu_items
[ctrl
->value
] == NULL
||
954 menu_items
[ctrl
->value
][0] == '\0')
957 if (qctrl
->type
== V4L2_CTRL_TYPE_BITMASK
&&
958 (ctrl
->value
& ~qctrl
->maximum
))
963 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params
*params
, int busy
,
964 struct v4l2_ext_controls
*ctrls
, unsigned int cmd
)
969 if (cmd
== VIDIOC_G_EXT_CTRLS
) {
970 for (i
= 0; i
< ctrls
->count
; i
++) {
971 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
973 err
= cx2341x_get_ctrl(params
, ctrl
);
975 ctrls
->error_idx
= i
;
981 for (i
= 0; i
< ctrls
->count
; i
++) {
982 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
983 struct v4l2_queryctrl qctrl
;
984 const char * const *menu_items
= NULL
;
987 err
= cx2341x_ctrl_query(params
, &qctrl
);
990 if (qctrl
.type
== V4L2_CTRL_TYPE_MENU
)
991 menu_items
= cx2341x_ctrl_get_menu(params
, qctrl
.id
);
992 err
= v4l2_ctrl_check(ctrl
, &qctrl
, menu_items
);
995 err
= cx2341x_set_ctrl(params
, busy
, ctrl
);
1000 params
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
1001 params
->video_bitrate_peak
< params
->video_bitrate
) {
1003 ctrls
->error_idx
= ctrls
->count
;
1006 ctrls
->error_idx
= i
;
1008 cx2341x_calc_audio_properties(params
);
1011 EXPORT_SYMBOL(cx2341x_ext_ctrls
);
1013 void cx2341x_fill_defaults(struct cx2341x_mpeg_params
*p
)
1015 *p
= default_params
;
1016 cx2341x_calc_audio_properties(p
);
1018 EXPORT_SYMBOL(cx2341x_fill_defaults
);
1020 static int cx2341x_api(void *priv
, cx2341x_mbox_func func
,
1021 u32 cmd
, int args
, ...)
1023 u32 data
[CX2341X_MBOX_MAX_DATA
];
1027 va_start(vargs
, args
);
1029 for (i
= 0; i
< args
; i
++)
1030 data
[i
] = va_arg(vargs
, int);
1032 return func(priv
, cmd
, args
, 0, data
);
1035 #define NEQ(field) (old->field != new->field)
1037 int cx2341x_update(void *priv
, cx2341x_mbox_func func
,
1038 const struct cx2341x_mpeg_params
*old
,
1039 const struct cx2341x_mpeg_params
*new)
1041 static int mpeg_stream_type
[] = {
1051 int force
= (old
== NULL
);
1052 u16 temporal
= new->video_temporal_filter
;
1054 cx2341x_api(priv
, func
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, new->port
, 0);
1056 if (force
|| NEQ(is_50hz
)) {
1057 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_RATE
, 1,
1059 if (err
) return err
;
1062 if (force
|| NEQ(width
) || NEQ(height
) || NEQ(video_encoding
)) {
1064 u16 h
= new->height
;
1066 if (new->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1070 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_SIZE
, 2,
1072 if (err
) return err
;
1074 if (force
|| NEQ(stream_type
)) {
1075 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_STREAM_TYPE
, 1,
1076 mpeg_stream_type
[new->stream_type
]);
1077 if (err
) return err
;
1079 if (force
|| NEQ(video_aspect
)) {
1080 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_ASPECT_RATIO
, 1,
1081 1 + new->video_aspect
);
1082 if (err
) return err
;
1084 if (force
|| NEQ(video_b_frames
) || NEQ(video_gop_size
)) {
1085 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1086 new->video_gop_size
, new->video_b_frames
+ 1);
1087 if (err
) return err
;
1089 if (force
|| NEQ(video_gop_closure
)) {
1090 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_CLOSURE
, 1,
1091 new->video_gop_closure
);
1092 if (err
) return err
;
1094 if (force
|| NEQ(audio_properties
)) {
1095 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_AUDIO_PROPERTIES
,
1096 1, new->audio_properties
);
1097 if (err
) return err
;
1099 if (force
|| NEQ(audio_mute
)) {
1100 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_AUDIO
, 1,
1102 if (err
) return err
;
1104 if (force
|| NEQ(video_bitrate_mode
) || NEQ(video_bitrate
) ||
1105 NEQ(video_bitrate_peak
)) {
1106 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_BIT_RATE
, 5,
1107 new->video_bitrate_mode
, new->video_bitrate
,
1108 new->video_bitrate_peak
/ 400, 0, 0);
1109 if (err
) return err
;
1111 if (force
|| NEQ(video_spatial_filter_mode
) ||
1112 NEQ(video_temporal_filter_mode
) ||
1113 NEQ(video_median_filter_type
)) {
1114 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_MODE
,
1115 2, new->video_spatial_filter_mode
|
1116 (new->video_temporal_filter_mode
<< 1),
1117 new->video_median_filter_type
);
1118 if (err
) return err
;
1120 if (force
|| NEQ(video_luma_median_filter_bottom
) ||
1121 NEQ(video_luma_median_filter_top
) ||
1122 NEQ(video_chroma_median_filter_bottom
) ||
1123 NEQ(video_chroma_median_filter_top
)) {
1124 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1125 new->video_luma_median_filter_bottom
,
1126 new->video_luma_median_filter_top
,
1127 new->video_chroma_median_filter_bottom
,
1128 new->video_chroma_median_filter_top
);
1129 if (err
) return err
;
1131 if (force
|| NEQ(video_luma_spatial_filter_type
) ||
1132 NEQ(video_chroma_spatial_filter_type
)) {
1133 err
= cx2341x_api(priv
, func
,
1134 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
,
1135 2, new->video_luma_spatial_filter_type
,
1136 new->video_chroma_spatial_filter_type
);
1137 if (err
) return err
;
1139 if (force
|| NEQ(video_spatial_filter
) ||
1140 old
->video_temporal_filter
!= temporal
) {
1141 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_PROPS
,
1142 2, new->video_spatial_filter
, temporal
);
1143 if (err
) return err
;
1145 if (force
|| NEQ(video_temporal_decimation
)) {
1146 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_DROP_RATE
,
1147 1, new->video_temporal_decimation
);
1148 if (err
) return err
;
1150 if (force
|| NEQ(video_mute
) ||
1151 (new->video_mute
&& NEQ(video_mute_yuv
))) {
1152 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_VIDEO
, 1,
1153 new->video_mute
| (new->video_mute_yuv
<< 8));
1154 if (err
) return err
;
1156 if (force
|| NEQ(stream_insert_nav_packets
)) {
1157 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MISC
, 2,
1158 7, new->stream_insert_nav_packets
);
1159 if (err
) return err
;
1163 EXPORT_SYMBOL(cx2341x_update
);
1165 static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params
*p
, u32 id
)
1167 const char * const *menu
= cx2341x_ctrl_get_menu(p
, id
);
1168 struct v4l2_ext_control ctrl
;
1173 if (cx2341x_get_ctrl(p
, &ctrl
))
1175 while (ctrl
.value
-- && *menu
) menu
++;
1184 void cx2341x_log_status(const struct cx2341x_mpeg_params
*p
, const char *prefix
)
1186 int is_mpeg1
= p
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
;
1189 printk(KERN_INFO
"%s: Stream: %s",
1191 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_TYPE
));
1192 if (p
->stream_insert_nav_packets
)
1193 printk(" (with navigation packets)");
1195 printk(KERN_INFO
"%s: VBI Format: %s\n",
1197 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_VBI_FMT
));
1200 printk(KERN_INFO
"%s: Video: %dx%d, %d fps%s\n",
1202 p
->width
/ (is_mpeg1
? 2 : 1), p
->height
/ (is_mpeg1
? 2 : 1),
1203 p
->is_50hz
? 25 : 30,
1204 (p
->video_mute
) ? " (muted)" : "");
1205 printk(KERN_INFO
"%s: Video: %s, %s, %s, %d",
1207 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ENCODING
),
1208 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ASPECT
),
1209 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_BITRATE_MODE
),
1211 if (p
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
)
1212 printk(", Peak %d", p
->video_bitrate_peak
);
1215 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
1217 p
->video_gop_size
, p
->video_b_frames
,
1218 p
->video_gop_closure
? "" : "No ");
1219 if (p
->video_temporal_decimation
)
1220 printk(KERN_INFO
"%s: Video: Temporal Decimation %d\n",
1221 prefix
, p
->video_temporal_decimation
);
1224 printk(KERN_INFO
"%s: Audio: %s, %s, %s, %s%s",
1226 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
),
1227 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_ENCODING
),
1228 cx2341x_menu_item(p
,
1229 p
->audio_encoding
== V4L2_MPEG_AUDIO_ENCODING_AC3
1230 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1231 : V4L2_CID_MPEG_AUDIO_L2_BITRATE
),
1232 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_MODE
),
1233 p
->audio_mute
? " (muted)" : "");
1234 if (p
->audio_mode
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
)
1235 printk(", %s", cx2341x_menu_item(p
,
1236 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
));
1237 printk(", %s, %s\n",
1238 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_EMPHASIS
),
1239 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_CRC
));
1241 /* Encoding filters */
1242 printk(KERN_INFO
"%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1244 cx2341x_menu_item(p
,
1245 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
),
1246 cx2341x_menu_item(p
,
1247 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
),
1248 cx2341x_menu_item(p
,
1249 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
),
1250 p
->video_spatial_filter
);
1252 printk(KERN_INFO
"%s: Temporal Filter: %s, %d\n",
1254 cx2341x_menu_item(p
,
1255 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
),
1256 p
->video_temporal_filter
);
1258 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1260 cx2341x_menu_item(p
,
1261 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
),
1262 p
->video_luma_median_filter_bottom
,
1263 p
->video_luma_median_filter_top
,
1264 p
->video_chroma_median_filter_bottom
,
1265 p
->video_chroma_median_filter_top
);
1267 EXPORT_SYMBOL(cx2341x_log_status
);
1271 /********************** NEW CODE *********************/
1273 static inline struct cx2341x_handler
*to_cxhdl(struct v4l2_ctrl
*ctrl
)
1275 return container_of(ctrl
->handler
, struct cx2341x_handler
, hdl
);
1278 static int cx2341x_hdl_api(struct cx2341x_handler
*hdl
,
1279 u32 cmd
, int args
, ...)
1281 u32 data
[CX2341X_MBOX_MAX_DATA
];
1285 va_start(vargs
, args
);
1287 for (i
= 0; i
< args
; i
++)
1288 data
[i
] = va_arg(vargs
, int);
1290 return hdl
->func(hdl
->priv
, cmd
, args
, 0, data
);
1293 /* ctrl->handler->lock is held, so it is safe to access cur.val */
1294 static inline int cx2341x_neq(struct v4l2_ctrl
*ctrl
)
1296 return ctrl
&& ctrl
->val
!= ctrl
->cur
.val
;
1299 static int cx2341x_try_ctrl(struct v4l2_ctrl
*ctrl
)
1301 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1302 s32 val
= ctrl
->val
;
1305 case V4L2_CID_MPEG_VIDEO_B_FRAMES
: {
1306 /* video gop cluster */
1308 int gop
= hdl
->video_gop_size
->val
;
1310 gop
= b
* ((gop
+ b
- 1) / b
);
1312 /* Max GOP size = 34 */
1315 hdl
->video_gop_size
->val
= gop
;
1319 case V4L2_CID_MPEG_STREAM_TYPE
:
1320 /* stream type cluster */
1321 hdl
->video_encoding
->val
=
1322 (hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_SS
||
1323 hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_VCD
) ?
1324 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
:
1325 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
;
1326 if (hdl
->video_encoding
->val
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
1327 /* MPEG-1 implies CBR */
1328 hdl
->video_bitrate_mode
->val
=
1329 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
;
1330 /* peak bitrate shall be >= normal bitrate */
1331 if (hdl
->video_bitrate_mode
->val
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
1332 hdl
->video_bitrate_peak
->val
< hdl
->video_bitrate
->val
)
1333 hdl
->video_bitrate_peak
->val
= hdl
->video_bitrate
->val
;
1339 static int cx2341x_s_ctrl(struct v4l2_ctrl
*ctrl
)
1341 static const int mpeg_stream_type
[] = {
1349 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1350 s32 val
= ctrl
->val
;
1355 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
1356 if (hdl
->ops
&& hdl
->ops
->s_stream_vbi_fmt
)
1357 return hdl
->ops
->s_stream_vbi_fmt(hdl
, val
);
1360 case V4L2_CID_MPEG_VIDEO_ASPECT
:
1361 return cx2341x_hdl_api(hdl
,
1362 CX2341X_ENC_SET_ASPECT_RATIO
, 1, val
+ 1);
1364 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
1365 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_CLOSURE
, 1, val
);
1367 case V4L2_CID_MPEG_AUDIO_MUTE
:
1368 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_AUDIO
, 1, val
);
1370 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
1371 return cx2341x_hdl_api(hdl
,
1372 CX2341X_ENC_SET_FRAME_DROP_RATE
, 1, val
);
1374 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
1375 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MISC
, 2, 7, val
);
1377 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
1378 /* audio properties cluster */
1379 props
= (hdl
->audio_sampling_freq
->val
<< 0) |
1380 (hdl
->audio_mode
->val
<< 8) |
1381 (hdl
->audio_mode_extension
->val
<< 10) |
1382 (hdl
->audio_crc
->val
<< 14);
1383 if (hdl
->audio_emphasis
->val
== V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
)
1386 props
|= hdl
->audio_emphasis
->val
<< 12;
1388 if (hdl
->audio_encoding
->val
== V4L2_MPEG_AUDIO_ENCODING_AC3
) {
1391 /* Not sure if this MPEG Layer II setting is required */
1392 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2
) << 2) |
1394 (hdl
->audio_ac3_bitrate
->val
<< 4) |
1395 (CX2341X_AUDIO_ENCODING_METHOD_AC3
<< 28);
1397 /* Assuming MPEG Layer II */
1399 ((3 - hdl
->audio_encoding
->val
) << 2) |
1400 ((1 + hdl
->audio_l2_bitrate
->val
) << 4);
1402 err
= cx2341x_hdl_api(hdl
,
1403 CX2341X_ENC_SET_AUDIO_PROPERTIES
, 1, props
);
1407 hdl
->audio_properties
= props
;
1408 if (hdl
->audio_ac3_bitrate
) {
1409 int is_ac3
= hdl
->audio_encoding
->val
==
1410 V4L2_MPEG_AUDIO_ENCODING_AC3
;
1412 v4l2_ctrl_activate(hdl
->audio_ac3_bitrate
, is_ac3
);
1413 v4l2_ctrl_activate(hdl
->audio_l2_bitrate
, !is_ac3
);
1415 v4l2_ctrl_activate(hdl
->audio_mode_extension
,
1416 hdl
->audio_mode
->val
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
);
1417 if (cx2341x_neq(hdl
->audio_sampling_freq
) &&
1418 hdl
->ops
&& hdl
->ops
->s_audio_sampling_freq
)
1419 return hdl
->ops
->s_audio_sampling_freq(hdl
, hdl
->audio_sampling_freq
->val
);
1420 if (cx2341x_neq(hdl
->audio_mode
) &&
1421 hdl
->ops
&& hdl
->ops
->s_audio_mode
)
1422 return hdl
->ops
->s_audio_mode(hdl
, hdl
->audio_mode
->val
);
1425 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
1426 /* video gop cluster */
1427 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1428 hdl
->video_gop_size
->val
,
1429 hdl
->video_b_frames
->val
+ 1);
1431 case V4L2_CID_MPEG_STREAM_TYPE
:
1432 /* stream type cluster */
1433 err
= cx2341x_hdl_api(hdl
,
1434 CX2341X_ENC_SET_STREAM_TYPE
, 1, mpeg_stream_type
[val
]);
1438 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_BIT_RATE
, 5,
1439 hdl
->video_bitrate_mode
->val
,
1440 hdl
->video_bitrate
->val
,
1441 hdl
->video_bitrate_peak
->val
/ 400, 0, 0);
1445 v4l2_ctrl_activate(hdl
->video_bitrate_mode
,
1446 hdl
->video_encoding
->val
!= V4L2_MPEG_VIDEO_ENCODING_MPEG_1
);
1447 v4l2_ctrl_activate(hdl
->video_bitrate_peak
,
1448 hdl
->video_bitrate_mode
->val
!= V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
);
1449 if (cx2341x_neq(hdl
->video_encoding
) &&
1450 hdl
->ops
&& hdl
->ops
->s_video_encoding
)
1451 return hdl
->ops
->s_video_encoding(hdl
, hdl
->video_encoding
->val
);
1454 case V4L2_CID_MPEG_VIDEO_MUTE
:
1455 /* video mute cluster */
1456 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_VIDEO
, 1,
1457 hdl
->video_mute
->val
|
1458 (hdl
->video_mute_yuv
->val
<< 8));
1460 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
: {
1463 /* video filter mode */
1464 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_MODE
, 2,
1465 hdl
->video_spatial_filter_mode
->val
|
1466 (hdl
->video_temporal_filter_mode
->val
<< 1),
1467 hdl
->video_median_filter_type
->val
);
1471 active_filter
= hdl
->video_spatial_filter_mode
->val
!=
1472 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
;
1473 v4l2_ctrl_activate(hdl
->video_spatial_filter
, active_filter
);
1474 v4l2_ctrl_activate(hdl
->video_luma_spatial_filter_type
, active_filter
);
1475 v4l2_ctrl_activate(hdl
->video_chroma_spatial_filter_type
, active_filter
);
1476 active_filter
= hdl
->video_temporal_filter_mode
->val
!=
1477 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
;
1478 v4l2_ctrl_activate(hdl
->video_temporal_filter
, active_filter
);
1479 active_filter
= hdl
->video_median_filter_type
->val
!=
1480 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
;
1481 v4l2_ctrl_activate(hdl
->video_luma_median_filter_bottom
, active_filter
);
1482 v4l2_ctrl_activate(hdl
->video_luma_median_filter_top
, active_filter
);
1483 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_bottom
, active_filter
);
1484 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_top
, active_filter
);
1488 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
1489 /* video filter type cluster */
1490 return cx2341x_hdl_api(hdl
,
1491 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
, 2,
1492 hdl
->video_luma_spatial_filter_type
->val
,
1493 hdl
->video_chroma_spatial_filter_type
->val
);
1495 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
1496 /* video filter cluster */
1497 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_PROPS
, 2,
1498 hdl
->video_spatial_filter
->val
,
1499 hdl
->video_temporal_filter
->val
);
1501 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
1502 /* video median cluster */
1503 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1504 hdl
->video_luma_median_filter_bottom
->val
,
1505 hdl
->video_luma_median_filter_top
->val
,
1506 hdl
->video_chroma_median_filter_bottom
->val
,
1507 hdl
->video_chroma_median_filter_top
->val
);
1512 static const struct v4l2_ctrl_ops cx2341x_ops
= {
1513 .try_ctrl
= cx2341x_try_ctrl
,
1514 .s_ctrl
= cx2341x_s_ctrl
,
1517 static struct v4l2_ctrl
*cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler
*hdl
,
1518 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1520 struct v4l2_ctrl_config cfg
;
1522 memset(&cfg
, 0, sizeof(cfg
));
1523 cx2341x_ctrl_fill(id
, &cfg
.name
, &cfg
.type
, &min
, &max
, &step
, &def
, &cfg
.flags
);
1524 cfg
.ops
= &cx2341x_ops
;
1529 if (cfg
.type
== V4L2_CTRL_TYPE_MENU
) {
1531 cfg
.menu_skip_mask
= step
;
1532 cfg
.qmenu
= cx2341x_get_menu(id
);
1535 cfg
.menu_skip_mask
= 0;
1537 return v4l2_ctrl_new_custom(hdl
, &cfg
, NULL
);
1540 static struct v4l2_ctrl
*cx2341x_ctrl_new_std(struct v4l2_ctrl_handler
*hdl
,
1541 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1543 return v4l2_ctrl_new_std(hdl
, &cx2341x_ops
, id
, min
, max
, step
, def
);
1546 static struct v4l2_ctrl
*cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler
*hdl
,
1547 u32 id
, s32 max
, s32 mask
, s32 def
)
1549 return v4l2_ctrl_new_std_menu(hdl
, &cx2341x_ops
, id
, max
, mask
, def
);
1552 int cx2341x_handler_init(struct cx2341x_handler
*cxhdl
,
1553 unsigned nr_of_controls_hint
)
1555 struct v4l2_ctrl_handler
*hdl
= &cxhdl
->hdl
;
1556 u32 caps
= cxhdl
->capabilities
;
1557 int has_sliced_vbi
= caps
& CX2341X_CAP_HAS_SLICED_VBI
;
1558 int has_ac3
= caps
& CX2341X_CAP_HAS_AC3
;
1559 int has_ts
= caps
& CX2341X_CAP_HAS_TS
;
1562 cxhdl
->height
= 480;
1564 v4l2_ctrl_handler_init(hdl
, nr_of_controls_hint
);
1566 /* Add controls in ascending control ID order for fastest
1568 cxhdl
->stream_type
= cx2341x_ctrl_new_menu(hdl
,
1569 V4L2_CID_MPEG_STREAM_TYPE
,
1570 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD
, has_ts
? 0 : 2,
1571 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
);
1572 cxhdl
->stream_vbi_fmt
= cx2341x_ctrl_new_menu(hdl
,
1573 V4L2_CID_MPEG_STREAM_VBI_FMT
,
1574 V4L2_MPEG_STREAM_VBI_FMT_IVTV
, has_sliced_vbi
? 0 : 2,
1575 V4L2_MPEG_STREAM_VBI_FMT_NONE
);
1576 cxhdl
->audio_sampling_freq
= cx2341x_ctrl_new_menu(hdl
,
1577 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
,
1578 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
, 0,
1579 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
);
1580 cxhdl
->audio_encoding
= cx2341x_ctrl_new_menu(hdl
,
1581 V4L2_CID_MPEG_AUDIO_ENCODING
,
1582 V4L2_MPEG_AUDIO_ENCODING_AC3
, has_ac3
? ~0x12 : ~0x2,
1583 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
);
1584 cxhdl
->audio_l2_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1585 V4L2_CID_MPEG_AUDIO_L2_BITRATE
,
1586 V4L2_MPEG_AUDIO_L2_BITRATE_384K
, 0x1ff,
1587 V4L2_MPEG_AUDIO_L2_BITRATE_224K
);
1588 cxhdl
->audio_mode
= cx2341x_ctrl_new_menu(hdl
,
1589 V4L2_CID_MPEG_AUDIO_MODE
,
1590 V4L2_MPEG_AUDIO_MODE_MONO
, 0,
1591 V4L2_MPEG_AUDIO_MODE_STEREO
);
1592 cxhdl
->audio_mode_extension
= cx2341x_ctrl_new_menu(hdl
,
1593 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
,
1594 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16
, 0,
1595 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
);
1596 cxhdl
->audio_emphasis
= cx2341x_ctrl_new_menu(hdl
,
1597 V4L2_CID_MPEG_AUDIO_EMPHASIS
,
1598 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
, 0,
1599 V4L2_MPEG_AUDIO_EMPHASIS_NONE
);
1600 cxhdl
->audio_crc
= cx2341x_ctrl_new_menu(hdl
,
1601 V4L2_CID_MPEG_AUDIO_CRC
,
1602 V4L2_MPEG_AUDIO_CRC_CRC16
, 0,
1603 V4L2_MPEG_AUDIO_CRC_NONE
);
1605 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_AUDIO_MUTE
, 0, 1, 1, 0);
1607 cxhdl
->audio_ac3_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1608 V4L2_CID_MPEG_AUDIO_AC3_BITRATE
,
1609 V4L2_MPEG_AUDIO_AC3_BITRATE_448K
, 0x03,
1610 V4L2_MPEG_AUDIO_AC3_BITRATE_224K
);
1611 cxhdl
->video_encoding
= cx2341x_ctrl_new_menu(hdl
,
1612 V4L2_CID_MPEG_VIDEO_ENCODING
,
1613 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
, 0,
1614 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
);
1615 cx2341x_ctrl_new_menu(hdl
,
1616 V4L2_CID_MPEG_VIDEO_ASPECT
,
1617 V4L2_MPEG_VIDEO_ASPECT_221x100
, 0,
1618 V4L2_MPEG_VIDEO_ASPECT_4x3
);
1619 cxhdl
->video_b_frames
= cx2341x_ctrl_new_std(hdl
,
1620 V4L2_CID_MPEG_VIDEO_B_FRAMES
, 0, 33, 1, 2);
1621 cxhdl
->video_gop_size
= cx2341x_ctrl_new_std(hdl
,
1622 V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1623 1, 34, 1, cxhdl
->is_50hz
? 12 : 15);
1624 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
, 0, 1, 1, 1);
1625 cxhdl
->video_bitrate_mode
= cx2341x_ctrl_new_menu(hdl
,
1626 V4L2_CID_MPEG_VIDEO_BITRATE_MODE
,
1627 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
, 0,
1628 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
);
1629 cxhdl
->video_bitrate
= cx2341x_ctrl_new_std(hdl
,
1630 V4L2_CID_MPEG_VIDEO_BITRATE
,
1631 0, 27000000, 1, 6000000);
1632 cxhdl
->video_bitrate_peak
= cx2341x_ctrl_new_std(hdl
,
1633 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
,
1634 0, 27000000, 1, 8000000);
1635 cx2341x_ctrl_new_std(hdl
,
1636 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
, 0, 255, 1, 0);
1637 cxhdl
->video_mute
= cx2341x_ctrl_new_std(hdl
,
1638 V4L2_CID_MPEG_VIDEO_MUTE
, 0, 1, 1, 0);
1639 cxhdl
->video_mute_yuv
= cx2341x_ctrl_new_std(hdl
,
1640 V4L2_CID_MPEG_VIDEO_MUTE_YUV
, 0, 0xffffff, 1, 0x008080);
1642 /* CX23415/6 specific */
1643 cxhdl
->video_spatial_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1644 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
,
1645 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
1646 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
, 0,
1647 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
);
1648 cxhdl
->video_spatial_filter
= cx2341x_ctrl_new_custom(hdl
,
1649 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
,
1651 cxhdl
->video_luma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1652 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
,
1653 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF
,
1654 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE
,
1656 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1657 cxhdl
->video_chroma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1658 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
,
1659 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF
,
1660 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
1662 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1663 cxhdl
->video_temporal_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1664 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
,
1665 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
1666 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
,
1668 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
);
1669 cxhdl
->video_temporal_filter
= cx2341x_ctrl_new_custom(hdl
,
1670 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
,
1672 cxhdl
->video_median_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1673 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
,
1674 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
1675 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG
,
1677 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
);
1678 cxhdl
->video_luma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1679 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
,
1681 cxhdl
->video_luma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1682 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
,
1684 cxhdl
->video_chroma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1685 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
,
1687 cxhdl
->video_chroma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1688 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
,
1690 cx2341x_ctrl_new_custom(hdl
, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
,
1694 int err
= hdl
->error
;
1696 v4l2_ctrl_handler_free(hdl
);
1700 v4l2_ctrl_cluster(8, &cxhdl
->audio_sampling_freq
);
1701 v4l2_ctrl_cluster(2, &cxhdl
->video_b_frames
);
1702 v4l2_ctrl_cluster(5, &cxhdl
->stream_type
);
1703 v4l2_ctrl_cluster(2, &cxhdl
->video_mute
);
1704 v4l2_ctrl_cluster(3, &cxhdl
->video_spatial_filter_mode
);
1705 v4l2_ctrl_cluster(2, &cxhdl
->video_luma_spatial_filter_type
);
1706 v4l2_ctrl_cluster(2, &cxhdl
->video_spatial_filter
);
1707 v4l2_ctrl_cluster(4, &cxhdl
->video_luma_median_filter_top
);
1711 EXPORT_SYMBOL(cx2341x_handler_init
);
1713 void cx2341x_handler_set_50hz(struct cx2341x_handler
*cxhdl
, int is_50hz
)
1715 cxhdl
->is_50hz
= is_50hz
;
1716 cxhdl
->video_gop_size
->default_value
= cxhdl
->is_50hz
? 12 : 15;
1718 EXPORT_SYMBOL(cx2341x_handler_set_50hz
);
1720 int cx2341x_handler_setup(struct cx2341x_handler
*cxhdl
)
1722 int h
= cxhdl
->height
;
1723 int w
= cxhdl
->width
;
1726 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, cxhdl
->port
, 0);
1729 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_RATE
, 1, cxhdl
->is_50hz
);
1733 if (v4l2_ctrl_g_ctrl(cxhdl
->video_encoding
) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1737 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_SIZE
, 2, h
, w
);
1740 return v4l2_ctrl_handler_setup(&cxhdl
->hdl
);
1742 EXPORT_SYMBOL(cx2341x_handler_setup
);
1744 void cx2341x_handler_set_busy(struct cx2341x_handler
*cxhdl
, int busy
)
1746 v4l2_ctrl_grab(cxhdl
->audio_sampling_freq
, busy
);
1747 v4l2_ctrl_grab(cxhdl
->audio_encoding
, busy
);
1748 v4l2_ctrl_grab(cxhdl
->audio_l2_bitrate
, busy
);
1749 v4l2_ctrl_grab(cxhdl
->audio_ac3_bitrate
, busy
);
1750 v4l2_ctrl_grab(cxhdl
->stream_vbi_fmt
, busy
);
1751 v4l2_ctrl_grab(cxhdl
->stream_type
, busy
);
1752 v4l2_ctrl_grab(cxhdl
->video_bitrate_mode
, busy
);
1753 v4l2_ctrl_grab(cxhdl
->video_bitrate
, busy
);
1754 v4l2_ctrl_grab(cxhdl
->video_bitrate_peak
, busy
);
1756 EXPORT_SYMBOL(cx2341x_handler_set_busy
);