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/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 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params
*params
, int busy
,
935 struct v4l2_ext_controls
*ctrls
, unsigned int cmd
)
940 if (cmd
== VIDIOC_G_EXT_CTRLS
) {
941 for (i
= 0; i
< ctrls
->count
; i
++) {
942 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
944 err
= cx2341x_get_ctrl(params
, ctrl
);
946 ctrls
->error_idx
= i
;
952 for (i
= 0; i
< ctrls
->count
; i
++) {
953 struct v4l2_ext_control
*ctrl
= ctrls
->controls
+ i
;
954 struct v4l2_queryctrl qctrl
;
955 const char * const *menu_items
= NULL
;
958 err
= cx2341x_ctrl_query(params
, &qctrl
);
961 if (qctrl
.type
== V4L2_CTRL_TYPE_MENU
)
962 menu_items
= cx2341x_ctrl_get_menu(params
, qctrl
.id
);
963 err
= v4l2_ctrl_check(ctrl
, &qctrl
, menu_items
);
966 err
= cx2341x_set_ctrl(params
, busy
, ctrl
);
971 params
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
972 params
->video_bitrate_peak
< params
->video_bitrate
) {
974 ctrls
->error_idx
= ctrls
->count
;
977 ctrls
->error_idx
= i
;
979 cx2341x_calc_audio_properties(params
);
982 EXPORT_SYMBOL(cx2341x_ext_ctrls
);
984 void cx2341x_fill_defaults(struct cx2341x_mpeg_params
*p
)
987 cx2341x_calc_audio_properties(p
);
989 EXPORT_SYMBOL(cx2341x_fill_defaults
);
991 static int cx2341x_api(void *priv
, cx2341x_mbox_func func
,
992 u32 cmd
, int args
, ...)
994 u32 data
[CX2341X_MBOX_MAX_DATA
];
998 va_start(vargs
, args
);
1000 for (i
= 0; i
< args
; i
++)
1001 data
[i
] = va_arg(vargs
, int);
1003 return func(priv
, cmd
, args
, 0, data
);
1006 #define NEQ(field) (old->field != new->field)
1008 int cx2341x_update(void *priv
, cx2341x_mbox_func func
,
1009 const struct cx2341x_mpeg_params
*old
,
1010 const struct cx2341x_mpeg_params
*new)
1012 static int mpeg_stream_type
[] = {
1022 int force
= (old
== NULL
);
1023 u16 temporal
= new->video_temporal_filter
;
1025 cx2341x_api(priv
, func
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, new->port
, 0);
1027 if (force
|| NEQ(is_50hz
)) {
1028 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_RATE
, 1,
1030 if (err
) return err
;
1033 if (force
|| NEQ(width
) || NEQ(height
) || NEQ(video_encoding
)) {
1035 u16 h
= new->height
;
1037 if (new->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1041 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_SIZE
, 2,
1043 if (err
) return err
;
1045 if (force
|| NEQ(stream_type
)) {
1046 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_STREAM_TYPE
, 1,
1047 mpeg_stream_type
[new->stream_type
]);
1048 if (err
) return err
;
1050 if (force
|| NEQ(video_aspect
)) {
1051 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_ASPECT_RATIO
, 1,
1052 1 + new->video_aspect
);
1053 if (err
) return err
;
1055 if (force
|| NEQ(video_b_frames
) || NEQ(video_gop_size
)) {
1056 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1057 new->video_gop_size
, new->video_b_frames
+ 1);
1058 if (err
) return err
;
1060 if (force
|| NEQ(video_gop_closure
)) {
1061 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_GOP_CLOSURE
, 1,
1062 new->video_gop_closure
);
1063 if (err
) return err
;
1065 if (force
|| NEQ(audio_properties
)) {
1066 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_AUDIO_PROPERTIES
,
1067 1, new->audio_properties
);
1068 if (err
) return err
;
1070 if (force
|| NEQ(audio_mute
)) {
1071 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_AUDIO
, 1,
1073 if (err
) return err
;
1075 if (force
|| NEQ(video_bitrate_mode
) || NEQ(video_bitrate
) ||
1076 NEQ(video_bitrate_peak
)) {
1077 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_BIT_RATE
, 5,
1078 new->video_bitrate_mode
, new->video_bitrate
,
1079 new->video_bitrate_peak
/ 400, 0, 0);
1080 if (err
) return err
;
1082 if (force
|| NEQ(video_spatial_filter_mode
) ||
1083 NEQ(video_temporal_filter_mode
) ||
1084 NEQ(video_median_filter_type
)) {
1085 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_MODE
,
1086 2, new->video_spatial_filter_mode
|
1087 (new->video_temporal_filter_mode
<< 1),
1088 new->video_median_filter_type
);
1089 if (err
) return err
;
1091 if (force
|| NEQ(video_luma_median_filter_bottom
) ||
1092 NEQ(video_luma_median_filter_top
) ||
1093 NEQ(video_chroma_median_filter_bottom
) ||
1094 NEQ(video_chroma_median_filter_top
)) {
1095 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1096 new->video_luma_median_filter_bottom
,
1097 new->video_luma_median_filter_top
,
1098 new->video_chroma_median_filter_bottom
,
1099 new->video_chroma_median_filter_top
);
1100 if (err
) return err
;
1102 if (force
|| NEQ(video_luma_spatial_filter_type
) ||
1103 NEQ(video_chroma_spatial_filter_type
)) {
1104 err
= cx2341x_api(priv
, func
,
1105 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
,
1106 2, new->video_luma_spatial_filter_type
,
1107 new->video_chroma_spatial_filter_type
);
1108 if (err
) return err
;
1110 if (force
|| NEQ(video_spatial_filter
) ||
1111 old
->video_temporal_filter
!= temporal
) {
1112 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_DNR_FILTER_PROPS
,
1113 2, new->video_spatial_filter
, temporal
);
1114 if (err
) return err
;
1116 if (force
|| NEQ(video_temporal_decimation
)) {
1117 err
= cx2341x_api(priv
, func
, CX2341X_ENC_SET_FRAME_DROP_RATE
,
1118 1, new->video_temporal_decimation
);
1119 if (err
) return err
;
1121 if (force
|| NEQ(video_mute
) ||
1122 (new->video_mute
&& NEQ(video_mute_yuv
))) {
1123 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MUTE_VIDEO
, 1,
1124 new->video_mute
| (new->video_mute_yuv
<< 8));
1125 if (err
) return err
;
1127 if (force
|| NEQ(stream_insert_nav_packets
)) {
1128 err
= cx2341x_api(priv
, func
, CX2341X_ENC_MISC
, 2,
1129 7, new->stream_insert_nav_packets
);
1130 if (err
) return err
;
1134 EXPORT_SYMBOL(cx2341x_update
);
1136 static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params
*p
, u32 id
)
1138 const char * const *menu
= cx2341x_ctrl_get_menu(p
, id
);
1139 struct v4l2_ext_control ctrl
;
1144 if (cx2341x_get_ctrl(p
, &ctrl
))
1146 while (ctrl
.value
-- && *menu
) menu
++;
1155 void cx2341x_log_status(const struct cx2341x_mpeg_params
*p
, const char *prefix
)
1157 int is_mpeg1
= p
->video_encoding
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
;
1160 printk(KERN_INFO
"%s: Stream: %s",
1162 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_TYPE
));
1163 if (p
->stream_insert_nav_packets
)
1164 printk(" (with navigation packets)");
1166 printk(KERN_INFO
"%s: VBI Format: %s\n",
1168 cx2341x_menu_item(p
, V4L2_CID_MPEG_STREAM_VBI_FMT
));
1171 printk(KERN_INFO
"%s: Video: %dx%d, %d fps%s\n",
1173 p
->width
/ (is_mpeg1
? 2 : 1), p
->height
/ (is_mpeg1
? 2 : 1),
1174 p
->is_50hz
? 25 : 30,
1175 (p
->video_mute
) ? " (muted)" : "");
1176 printk(KERN_INFO
"%s: Video: %s, %s, %s, %d",
1178 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ENCODING
),
1179 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_ASPECT
),
1180 cx2341x_menu_item(p
, V4L2_CID_MPEG_VIDEO_BITRATE_MODE
),
1182 if (p
->video_bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
)
1183 printk(", Peak %d", p
->video_bitrate_peak
);
1186 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
1188 p
->video_gop_size
, p
->video_b_frames
,
1189 p
->video_gop_closure
? "" : "No ");
1190 if (p
->video_temporal_decimation
)
1191 printk(KERN_INFO
"%s: Video: Temporal Decimation %d\n",
1192 prefix
, p
->video_temporal_decimation
);
1195 printk(KERN_INFO
"%s: Audio: %s, %s, %s, %s%s",
1197 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
),
1198 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_ENCODING
),
1199 cx2341x_menu_item(p
,
1200 p
->audio_encoding
== V4L2_MPEG_AUDIO_ENCODING_AC3
1201 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1202 : V4L2_CID_MPEG_AUDIO_L2_BITRATE
),
1203 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_MODE
),
1204 p
->audio_mute
? " (muted)" : "");
1205 if (p
->audio_mode
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
)
1206 printk(", %s", cx2341x_menu_item(p
,
1207 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
));
1208 printk(", %s, %s\n",
1209 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_EMPHASIS
),
1210 cx2341x_menu_item(p
, V4L2_CID_MPEG_AUDIO_CRC
));
1212 /* Encoding filters */
1213 printk(KERN_INFO
"%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1215 cx2341x_menu_item(p
,
1216 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
),
1217 cx2341x_menu_item(p
,
1218 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
),
1219 cx2341x_menu_item(p
,
1220 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
),
1221 p
->video_spatial_filter
);
1223 printk(KERN_INFO
"%s: Temporal Filter: %s, %d\n",
1225 cx2341x_menu_item(p
,
1226 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
),
1227 p
->video_temporal_filter
);
1229 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1231 cx2341x_menu_item(p
,
1232 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
),
1233 p
->video_luma_median_filter_bottom
,
1234 p
->video_luma_median_filter_top
,
1235 p
->video_chroma_median_filter_bottom
,
1236 p
->video_chroma_median_filter_top
);
1238 EXPORT_SYMBOL(cx2341x_log_status
);
1242 /********************** NEW CODE *********************/
1244 static inline struct cx2341x_handler
*to_cxhdl(struct v4l2_ctrl
*ctrl
)
1246 return container_of(ctrl
->handler
, struct cx2341x_handler
, hdl
);
1249 static int cx2341x_hdl_api(struct cx2341x_handler
*hdl
,
1250 u32 cmd
, int args
, ...)
1252 u32 data
[CX2341X_MBOX_MAX_DATA
];
1256 va_start(vargs
, args
);
1258 for (i
= 0; i
< args
; i
++)
1259 data
[i
] = va_arg(vargs
, int);
1261 return hdl
->func(hdl
->priv
, cmd
, args
, 0, data
);
1264 /* ctrl->handler->lock is held, so it is safe to access cur.val */
1265 static inline int cx2341x_neq(struct v4l2_ctrl
*ctrl
)
1267 return ctrl
&& ctrl
->val
!= ctrl
->cur
.val
;
1270 static int cx2341x_try_ctrl(struct v4l2_ctrl
*ctrl
)
1272 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1273 s32 val
= ctrl
->val
;
1276 case V4L2_CID_MPEG_VIDEO_B_FRAMES
: {
1277 /* video gop cluster */
1279 int gop
= hdl
->video_gop_size
->val
;
1281 gop
= b
* ((gop
+ b
- 1) / b
);
1283 /* Max GOP size = 34 */
1286 hdl
->video_gop_size
->val
= gop
;
1290 case V4L2_CID_MPEG_STREAM_TYPE
:
1291 /* stream type cluster */
1292 hdl
->video_encoding
->val
=
1293 (hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_SS
||
1294 hdl
->stream_type
->val
== V4L2_MPEG_STREAM_TYPE_MPEG1_VCD
) ?
1295 V4L2_MPEG_VIDEO_ENCODING_MPEG_1
:
1296 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
;
1297 if (hdl
->video_encoding
->val
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
)
1298 /* MPEG-1 implies CBR */
1299 hdl
->video_bitrate_mode
->val
=
1300 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
;
1301 /* peak bitrate shall be >= normal bitrate */
1302 if (hdl
->video_bitrate_mode
->val
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
&&
1303 hdl
->video_bitrate_peak
->val
< hdl
->video_bitrate
->val
)
1304 hdl
->video_bitrate_peak
->val
= hdl
->video_bitrate
->val
;
1310 static int cx2341x_s_ctrl(struct v4l2_ctrl
*ctrl
)
1312 static const int mpeg_stream_type
[] = {
1320 struct cx2341x_handler
*hdl
= to_cxhdl(ctrl
);
1321 s32 val
= ctrl
->val
;
1326 case V4L2_CID_MPEG_STREAM_VBI_FMT
:
1327 if (hdl
->ops
&& hdl
->ops
->s_stream_vbi_fmt
)
1328 return hdl
->ops
->s_stream_vbi_fmt(hdl
, val
);
1331 case V4L2_CID_MPEG_VIDEO_ASPECT
:
1332 return cx2341x_hdl_api(hdl
,
1333 CX2341X_ENC_SET_ASPECT_RATIO
, 1, val
+ 1);
1335 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
:
1336 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_CLOSURE
, 1, val
);
1338 case V4L2_CID_MPEG_AUDIO_MUTE
:
1339 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_AUDIO
, 1, val
);
1341 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
:
1342 return cx2341x_hdl_api(hdl
,
1343 CX2341X_ENC_SET_FRAME_DROP_RATE
, 1, val
);
1345 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
:
1346 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MISC
, 2, 7, val
);
1348 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
:
1349 /* audio properties cluster */
1350 props
= (hdl
->audio_sampling_freq
->val
<< 0) |
1351 (hdl
->audio_mode
->val
<< 8) |
1352 (hdl
->audio_mode_extension
->val
<< 10) |
1353 (hdl
->audio_crc
->val
<< 14);
1354 if (hdl
->audio_emphasis
->val
== V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
)
1357 props
|= hdl
->audio_emphasis
->val
<< 12;
1359 if (hdl
->audio_encoding
->val
== V4L2_MPEG_AUDIO_ENCODING_AC3
) {
1362 /* Not sure if this MPEG Layer II setting is required */
1363 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2
) << 2) |
1365 (hdl
->audio_ac3_bitrate
->val
<< 4) |
1366 (CX2341X_AUDIO_ENCODING_METHOD_AC3
<< 28);
1368 /* Assuming MPEG Layer II */
1370 ((3 - hdl
->audio_encoding
->val
) << 2) |
1371 ((1 + hdl
->audio_l2_bitrate
->val
) << 4);
1373 err
= cx2341x_hdl_api(hdl
,
1374 CX2341X_ENC_SET_AUDIO_PROPERTIES
, 1, props
);
1378 hdl
->audio_properties
= props
;
1379 if (hdl
->audio_ac3_bitrate
) {
1380 int is_ac3
= hdl
->audio_encoding
->val
==
1381 V4L2_MPEG_AUDIO_ENCODING_AC3
;
1383 v4l2_ctrl_activate(hdl
->audio_ac3_bitrate
, is_ac3
);
1384 v4l2_ctrl_activate(hdl
->audio_l2_bitrate
, !is_ac3
);
1386 v4l2_ctrl_activate(hdl
->audio_mode_extension
,
1387 hdl
->audio_mode
->val
== V4L2_MPEG_AUDIO_MODE_JOINT_STEREO
);
1388 if (cx2341x_neq(hdl
->audio_sampling_freq
) &&
1389 hdl
->ops
&& hdl
->ops
->s_audio_sampling_freq
)
1390 return hdl
->ops
->s_audio_sampling_freq(hdl
, hdl
->audio_sampling_freq
->val
);
1391 if (cx2341x_neq(hdl
->audio_mode
) &&
1392 hdl
->ops
&& hdl
->ops
->s_audio_mode
)
1393 return hdl
->ops
->s_audio_mode(hdl
, hdl
->audio_mode
->val
);
1396 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
1397 /* video gop cluster */
1398 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_GOP_PROPERTIES
, 2,
1399 hdl
->video_gop_size
->val
,
1400 hdl
->video_b_frames
->val
+ 1);
1402 case V4L2_CID_MPEG_STREAM_TYPE
:
1403 /* stream type cluster */
1404 err
= cx2341x_hdl_api(hdl
,
1405 CX2341X_ENC_SET_STREAM_TYPE
, 1, mpeg_stream_type
[val
]);
1409 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_BIT_RATE
, 5,
1410 hdl
->video_bitrate_mode
->val
,
1411 hdl
->video_bitrate
->val
,
1412 hdl
->video_bitrate_peak
->val
/ 400, 0, 0);
1416 v4l2_ctrl_activate(hdl
->video_bitrate_mode
,
1417 hdl
->video_encoding
->val
!= V4L2_MPEG_VIDEO_ENCODING_MPEG_1
);
1418 v4l2_ctrl_activate(hdl
->video_bitrate_peak
,
1419 hdl
->video_bitrate_mode
->val
!= V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
);
1420 if (cx2341x_neq(hdl
->video_encoding
) &&
1421 hdl
->ops
&& hdl
->ops
->s_video_encoding
)
1422 return hdl
->ops
->s_video_encoding(hdl
, hdl
->video_encoding
->val
);
1425 case V4L2_CID_MPEG_VIDEO_MUTE
:
1426 /* video mute cluster */
1427 return cx2341x_hdl_api(hdl
, CX2341X_ENC_MUTE_VIDEO
, 1,
1428 hdl
->video_mute
->val
|
1429 (hdl
->video_mute_yuv
->val
<< 8));
1431 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
: {
1434 /* video filter mode */
1435 err
= cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_MODE
, 2,
1436 hdl
->video_spatial_filter_mode
->val
|
1437 (hdl
->video_temporal_filter_mode
->val
<< 1),
1438 hdl
->video_median_filter_type
->val
);
1442 active_filter
= hdl
->video_spatial_filter_mode
->val
!=
1443 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
;
1444 v4l2_ctrl_activate(hdl
->video_spatial_filter
, active_filter
);
1445 v4l2_ctrl_activate(hdl
->video_luma_spatial_filter_type
, active_filter
);
1446 v4l2_ctrl_activate(hdl
->video_chroma_spatial_filter_type
, active_filter
);
1447 active_filter
= hdl
->video_temporal_filter_mode
->val
!=
1448 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
;
1449 v4l2_ctrl_activate(hdl
->video_temporal_filter
, active_filter
);
1450 active_filter
= hdl
->video_median_filter_type
->val
!=
1451 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
;
1452 v4l2_ctrl_activate(hdl
->video_luma_median_filter_bottom
, active_filter
);
1453 v4l2_ctrl_activate(hdl
->video_luma_median_filter_top
, active_filter
);
1454 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_bottom
, active_filter
);
1455 v4l2_ctrl_activate(hdl
->video_chroma_median_filter_top
, active_filter
);
1459 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
:
1460 /* video filter type cluster */
1461 return cx2341x_hdl_api(hdl
,
1462 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
, 2,
1463 hdl
->video_luma_spatial_filter_type
->val
,
1464 hdl
->video_chroma_spatial_filter_type
->val
);
1466 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
:
1467 /* video filter cluster */
1468 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_DNR_FILTER_PROPS
, 2,
1469 hdl
->video_spatial_filter
->val
,
1470 hdl
->video_temporal_filter
->val
);
1472 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
:
1473 /* video median cluster */
1474 return cx2341x_hdl_api(hdl
, CX2341X_ENC_SET_CORING_LEVELS
, 4,
1475 hdl
->video_luma_median_filter_bottom
->val
,
1476 hdl
->video_luma_median_filter_top
->val
,
1477 hdl
->video_chroma_median_filter_bottom
->val
,
1478 hdl
->video_chroma_median_filter_top
->val
);
1483 static const struct v4l2_ctrl_ops cx2341x_ops
= {
1484 .try_ctrl
= cx2341x_try_ctrl
,
1485 .s_ctrl
= cx2341x_s_ctrl
,
1488 static struct v4l2_ctrl
*cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler
*hdl
,
1489 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1491 struct v4l2_ctrl_config cfg
;
1493 cx2341x_ctrl_fill(id
, &cfg
.name
, &cfg
.type
, &min
, &max
, &step
, &def
, &cfg
.flags
);
1494 cfg
.ops
= &cx2341x_ops
;
1499 if (cfg
.type
== V4L2_CTRL_TYPE_MENU
) {
1501 cfg
.menu_skip_mask
= step
;
1502 cfg
.qmenu
= cx2341x_get_menu(id
);
1505 cfg
.menu_skip_mask
= 0;
1507 return v4l2_ctrl_new_custom(hdl
, &cfg
, NULL
);
1510 static struct v4l2_ctrl
*cx2341x_ctrl_new_std(struct v4l2_ctrl_handler
*hdl
,
1511 u32 id
, s32 min
, s32 max
, s32 step
, s32 def
)
1513 return v4l2_ctrl_new_std(hdl
, &cx2341x_ops
, id
, min
, max
, step
, def
);
1516 static struct v4l2_ctrl
*cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler
*hdl
,
1517 u32 id
, s32 max
, s32 mask
, s32 def
)
1519 return v4l2_ctrl_new_std_menu(hdl
, &cx2341x_ops
, id
, max
, mask
, def
);
1522 int cx2341x_handler_init(struct cx2341x_handler
*cxhdl
,
1523 unsigned nr_of_controls_hint
)
1525 struct v4l2_ctrl_handler
*hdl
= &cxhdl
->hdl
;
1526 u32 caps
= cxhdl
->capabilities
;
1527 int has_sliced_vbi
= caps
& CX2341X_CAP_HAS_SLICED_VBI
;
1528 int has_ac3
= caps
& CX2341X_CAP_HAS_AC3
;
1529 int has_ts
= caps
& CX2341X_CAP_HAS_TS
;
1532 cxhdl
->height
= 480;
1534 v4l2_ctrl_handler_init(hdl
, nr_of_controls_hint
);
1536 /* Add controls in ascending control ID order for fastest
1538 cxhdl
->stream_type
= cx2341x_ctrl_new_menu(hdl
,
1539 V4L2_CID_MPEG_STREAM_TYPE
,
1540 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD
, has_ts
? 0 : 2,
1541 V4L2_MPEG_STREAM_TYPE_MPEG2_PS
);
1542 cxhdl
->stream_vbi_fmt
= cx2341x_ctrl_new_menu(hdl
,
1543 V4L2_CID_MPEG_STREAM_VBI_FMT
,
1544 V4L2_MPEG_STREAM_VBI_FMT_IVTV
, has_sliced_vbi
? 0 : 2,
1545 V4L2_MPEG_STREAM_VBI_FMT_NONE
);
1546 cxhdl
->audio_sampling_freq
= cx2341x_ctrl_new_menu(hdl
,
1547 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
,
1548 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000
, 0,
1549 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000
);
1550 cxhdl
->audio_encoding
= cx2341x_ctrl_new_menu(hdl
,
1551 V4L2_CID_MPEG_AUDIO_ENCODING
,
1552 V4L2_MPEG_AUDIO_ENCODING_AC3
, has_ac3
? ~0x12 : ~0x2,
1553 V4L2_MPEG_AUDIO_ENCODING_LAYER_2
);
1554 cxhdl
->audio_l2_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1555 V4L2_CID_MPEG_AUDIO_L2_BITRATE
,
1556 V4L2_MPEG_AUDIO_L2_BITRATE_384K
, 0x1ff,
1557 V4L2_MPEG_AUDIO_L2_BITRATE_224K
);
1558 cxhdl
->audio_mode
= cx2341x_ctrl_new_menu(hdl
,
1559 V4L2_CID_MPEG_AUDIO_MODE
,
1560 V4L2_MPEG_AUDIO_MODE_MONO
, 0,
1561 V4L2_MPEG_AUDIO_MODE_STEREO
);
1562 cxhdl
->audio_mode_extension
= cx2341x_ctrl_new_menu(hdl
,
1563 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
,
1564 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16
, 0,
1565 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4
);
1566 cxhdl
->audio_emphasis
= cx2341x_ctrl_new_menu(hdl
,
1567 V4L2_CID_MPEG_AUDIO_EMPHASIS
,
1568 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17
, 0,
1569 V4L2_MPEG_AUDIO_EMPHASIS_NONE
);
1570 cxhdl
->audio_crc
= cx2341x_ctrl_new_menu(hdl
,
1571 V4L2_CID_MPEG_AUDIO_CRC
,
1572 V4L2_MPEG_AUDIO_CRC_CRC16
, 0,
1573 V4L2_MPEG_AUDIO_CRC_NONE
);
1575 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_AUDIO_MUTE
, 0, 1, 1, 0);
1577 cxhdl
->audio_ac3_bitrate
= cx2341x_ctrl_new_menu(hdl
,
1578 V4L2_CID_MPEG_AUDIO_AC3_BITRATE
,
1579 V4L2_MPEG_AUDIO_AC3_BITRATE_448K
, 0x03,
1580 V4L2_MPEG_AUDIO_AC3_BITRATE_224K
);
1581 cxhdl
->video_encoding
= cx2341x_ctrl_new_menu(hdl
,
1582 V4L2_CID_MPEG_VIDEO_ENCODING
,
1583 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
, 0,
1584 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
);
1585 cx2341x_ctrl_new_menu(hdl
,
1586 V4L2_CID_MPEG_VIDEO_ASPECT
,
1587 V4L2_MPEG_VIDEO_ASPECT_221x100
, 0,
1588 V4L2_MPEG_VIDEO_ASPECT_4x3
);
1589 cxhdl
->video_b_frames
= cx2341x_ctrl_new_std(hdl
,
1590 V4L2_CID_MPEG_VIDEO_B_FRAMES
, 0, 33, 1, 2);
1591 cxhdl
->video_gop_size
= cx2341x_ctrl_new_std(hdl
,
1592 V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1593 1, 34, 1, cxhdl
->is_50hz
? 12 : 15);
1594 cx2341x_ctrl_new_std(hdl
, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
, 0, 1, 1, 1);
1595 cxhdl
->video_bitrate_mode
= cx2341x_ctrl_new_menu(hdl
,
1596 V4L2_CID_MPEG_VIDEO_BITRATE_MODE
,
1597 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
, 0,
1598 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
);
1599 cxhdl
->video_bitrate
= cx2341x_ctrl_new_std(hdl
,
1600 V4L2_CID_MPEG_VIDEO_BITRATE
,
1601 0, 27000000, 1, 6000000);
1602 cxhdl
->video_bitrate_peak
= cx2341x_ctrl_new_std(hdl
,
1603 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
,
1604 0, 27000000, 1, 8000000);
1605 cx2341x_ctrl_new_std(hdl
,
1606 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
, 0, 255, 1, 0);
1607 cxhdl
->video_mute
= cx2341x_ctrl_new_std(hdl
,
1608 V4L2_CID_MPEG_VIDEO_MUTE
, 0, 1, 1, 0);
1609 cxhdl
->video_mute_yuv
= cx2341x_ctrl_new_std(hdl
,
1610 V4L2_CID_MPEG_VIDEO_MUTE_YUV
, 0, 0xffffff, 1, 0x008080);
1612 /* CX23415/6 specific */
1613 cxhdl
->video_spatial_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1614 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
,
1615 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
,
1616 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO
, 0,
1617 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL
);
1618 cxhdl
->video_spatial_filter
= cx2341x_ctrl_new_custom(hdl
,
1619 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
,
1621 cxhdl
->video_luma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1622 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
,
1623 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF
,
1624 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE
,
1626 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1627 cxhdl
->video_chroma_spatial_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1628 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
,
1629 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF
,
1630 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
,
1632 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR
);
1633 cxhdl
->video_temporal_filter_mode
= cx2341x_ctrl_new_custom(hdl
,
1634 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
,
1635 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
,
1636 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO
,
1638 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL
);
1639 cxhdl
->video_temporal_filter
= cx2341x_ctrl_new_custom(hdl
,
1640 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
,
1642 cxhdl
->video_median_filter_type
= cx2341x_ctrl_new_custom(hdl
,
1643 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
,
1644 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
,
1645 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG
,
1647 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF
);
1648 cxhdl
->video_luma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1649 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
,
1651 cxhdl
->video_luma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1652 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
,
1654 cxhdl
->video_chroma_median_filter_bottom
= cx2341x_ctrl_new_custom(hdl
,
1655 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
,
1657 cxhdl
->video_chroma_median_filter_top
= cx2341x_ctrl_new_custom(hdl
,
1658 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
,
1660 cx2341x_ctrl_new_custom(hdl
, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
,
1664 int err
= hdl
->error
;
1666 v4l2_ctrl_handler_free(hdl
);
1670 v4l2_ctrl_cluster(8, &cxhdl
->audio_sampling_freq
);
1671 v4l2_ctrl_cluster(2, &cxhdl
->video_b_frames
);
1672 v4l2_ctrl_cluster(5, &cxhdl
->stream_type
);
1673 v4l2_ctrl_cluster(2, &cxhdl
->video_mute
);
1674 v4l2_ctrl_cluster(3, &cxhdl
->video_spatial_filter_mode
);
1675 v4l2_ctrl_cluster(2, &cxhdl
->video_luma_spatial_filter_type
);
1676 v4l2_ctrl_cluster(2, &cxhdl
->video_spatial_filter
);
1677 v4l2_ctrl_cluster(4, &cxhdl
->video_luma_median_filter_top
);
1681 EXPORT_SYMBOL(cx2341x_handler_init
);
1683 void cx2341x_handler_set_50hz(struct cx2341x_handler
*cxhdl
, int is_50hz
)
1685 cxhdl
->is_50hz
= is_50hz
;
1686 cxhdl
->video_gop_size
->default_value
= cxhdl
->is_50hz
? 12 : 15;
1688 EXPORT_SYMBOL(cx2341x_handler_set_50hz
);
1690 int cx2341x_handler_setup(struct cx2341x_handler
*cxhdl
)
1692 int h
= cxhdl
->height
;
1693 int w
= cxhdl
->width
;
1696 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_OUTPUT_PORT
, 2, cxhdl
->port
, 0);
1699 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_RATE
, 1, cxhdl
->is_50hz
);
1703 if (v4l2_ctrl_g_ctrl(cxhdl
->video_encoding
) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1
) {
1707 err
= cx2341x_hdl_api(cxhdl
, CX2341X_ENC_SET_FRAME_SIZE
, 2, h
, w
);
1710 return v4l2_ctrl_handler_setup(&cxhdl
->hdl
);
1712 EXPORT_SYMBOL(cx2341x_handler_setup
);
1714 void cx2341x_handler_set_busy(struct cx2341x_handler
*cxhdl
, int busy
)
1716 v4l2_ctrl_grab(cxhdl
->audio_sampling_freq
, busy
);
1717 v4l2_ctrl_grab(cxhdl
->audio_encoding
, busy
);
1718 v4l2_ctrl_grab(cxhdl
->audio_l2_bitrate
, busy
);
1719 v4l2_ctrl_grab(cxhdl
->audio_ac3_bitrate
, busy
);
1720 v4l2_ctrl_grab(cxhdl
->stream_vbi_fmt
, busy
);
1721 v4l2_ctrl_grab(cxhdl
->stream_type
, busy
);
1722 v4l2_ctrl_grab(cxhdl
->video_bitrate_mode
, busy
);
1723 v4l2_ctrl_grab(cxhdl
->video_bitrate
, busy
);
1724 v4l2_ctrl_grab(cxhdl
->video_bitrate_peak
, busy
);
1726 EXPORT_SYMBOL(cx2341x_handler_set_busy
);