mm/slab.c: proper prototypes
[wrt350n-kernel.git] / drivers / media / video / cx2341x.c
blobd73c86aeeaacb9a13e5f190492cb8ad31f419882
1 /*
2 * cx2341x - generic code for cx23415/6 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/moduleparam.h>
24 #include <linux/errno.h>
25 #include <linux/kernel.h>
26 #include <linux/init.h>
27 #include <linux/types.h>
28 #include <linux/videodev2.h>
30 #include <media/tuner.h>
31 #include <media/cx2341x.h>
32 #include <media/v4l2-common.h>
34 MODULE_DESCRIPTION("cx23415/6 driver");
35 MODULE_AUTHOR("Hans Verkuil");
36 MODULE_LICENSE("GPL");
38 static int debug = 0;
39 module_param(debug, int, 0644);
40 MODULE_PARM_DESC(debug, "Debug level (0-1)");
42 const u32 cx2341x_mpeg_ctrls[] = {
43 V4L2_CID_MPEG_CLASS,
44 V4L2_CID_MPEG_STREAM_TYPE,
45 V4L2_CID_MPEG_STREAM_VBI_FMT,
46 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
47 V4L2_CID_MPEG_AUDIO_ENCODING,
48 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
49 V4L2_CID_MPEG_AUDIO_MODE,
50 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
51 V4L2_CID_MPEG_AUDIO_EMPHASIS,
52 V4L2_CID_MPEG_AUDIO_CRC,
53 V4L2_CID_MPEG_AUDIO_MUTE,
54 V4L2_CID_MPEG_VIDEO_ENCODING,
55 V4L2_CID_MPEG_VIDEO_ASPECT,
56 V4L2_CID_MPEG_VIDEO_B_FRAMES,
57 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
58 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
59 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
60 V4L2_CID_MPEG_VIDEO_BITRATE,
61 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
62 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
63 V4L2_CID_MPEG_VIDEO_MUTE,
64 V4L2_CID_MPEG_VIDEO_MUTE_YUV,
65 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
66 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
67 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
68 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
69 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
70 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
71 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
72 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
73 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
74 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
75 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
76 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
81 /* Map the control ID to the correct field in the cx2341x_mpeg_params
82 struct. Return -EINVAL if the ID is unknown, else return 0. */
83 static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
84 struct v4l2_ext_control *ctrl)
86 switch (ctrl->id) {
87 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
88 ctrl->value = params->audio_sampling_freq;
89 break;
90 case V4L2_CID_MPEG_AUDIO_ENCODING:
91 ctrl->value = params->audio_encoding;
92 break;
93 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
94 ctrl->value = params->audio_l2_bitrate;
95 break;
96 case V4L2_CID_MPEG_AUDIO_MODE:
97 ctrl->value = params->audio_mode;
98 break;
99 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
100 ctrl->value = params->audio_mode_extension;
101 break;
102 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
103 ctrl->value = params->audio_emphasis;
104 break;
105 case V4L2_CID_MPEG_AUDIO_CRC:
106 ctrl->value = params->audio_crc;
107 break;
108 case V4L2_CID_MPEG_AUDIO_MUTE:
109 ctrl->value = params->audio_mute;
110 break;
111 case V4L2_CID_MPEG_VIDEO_ENCODING:
112 ctrl->value = params->video_encoding;
113 break;
114 case V4L2_CID_MPEG_VIDEO_ASPECT:
115 ctrl->value = params->video_aspect;
116 break;
117 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
118 ctrl->value = params->video_b_frames;
119 break;
120 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
121 ctrl->value = params->video_gop_size;
122 break;
123 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
124 ctrl->value = params->video_gop_closure;
125 break;
126 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
127 ctrl->value = params->video_bitrate_mode;
128 break;
129 case V4L2_CID_MPEG_VIDEO_BITRATE:
130 ctrl->value = params->video_bitrate;
131 break;
132 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
133 ctrl->value = params->video_bitrate_peak;
134 break;
135 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
136 ctrl->value = params->video_temporal_decimation;
137 break;
138 case V4L2_CID_MPEG_VIDEO_MUTE:
139 ctrl->value = params->video_mute;
140 break;
141 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
142 ctrl->value = params->video_mute_yuv;
143 break;
144 case V4L2_CID_MPEG_STREAM_TYPE:
145 ctrl->value = params->stream_type;
146 break;
147 case V4L2_CID_MPEG_STREAM_VBI_FMT:
148 ctrl->value = params->stream_vbi_fmt;
149 break;
150 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
151 ctrl->value = params->video_spatial_filter_mode;
152 break;
153 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
154 ctrl->value = params->video_spatial_filter;
155 break;
156 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
157 ctrl->value = params->video_luma_spatial_filter_type;
158 break;
159 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
160 ctrl->value = params->video_chroma_spatial_filter_type;
161 break;
162 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
163 ctrl->value = params->video_temporal_filter_mode;
164 break;
165 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
166 ctrl->value = params->video_temporal_filter;
167 break;
168 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
169 ctrl->value = params->video_median_filter_type;
170 break;
171 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
172 ctrl->value = params->video_luma_median_filter_top;
173 break;
174 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
175 ctrl->value = params->video_luma_median_filter_bottom;
176 break;
177 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
178 ctrl->value = params->video_chroma_median_filter_top;
179 break;
180 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
181 ctrl->value = params->video_chroma_median_filter_bottom;
182 break;
183 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
184 ctrl->value = params->stream_insert_nav_packets;
185 break;
186 default:
187 return -EINVAL;
189 return 0;
192 /* Map the control ID to the correct field in the cx2341x_mpeg_params
193 struct. Return -EINVAL if the ID is unknown, else return 0. */
194 static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
195 struct v4l2_ext_control *ctrl)
197 switch (ctrl->id) {
198 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
199 params->audio_sampling_freq = ctrl->value;
200 break;
201 case V4L2_CID_MPEG_AUDIO_ENCODING:
202 params->audio_encoding = ctrl->value;
203 break;
204 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
205 params->audio_l2_bitrate = ctrl->value;
206 break;
207 case V4L2_CID_MPEG_AUDIO_MODE:
208 params->audio_mode = ctrl->value;
209 break;
210 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
211 params->audio_mode_extension = ctrl->value;
212 break;
213 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
214 params->audio_emphasis = ctrl->value;
215 break;
216 case V4L2_CID_MPEG_AUDIO_CRC:
217 params->audio_crc = ctrl->value;
218 break;
219 case V4L2_CID_MPEG_AUDIO_MUTE:
220 params->audio_mute = ctrl->value;
221 break;
222 case V4L2_CID_MPEG_VIDEO_ASPECT:
223 params->video_aspect = ctrl->value;
224 break;
225 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
226 int b = ctrl->value + 1;
227 int gop = params->video_gop_size;
228 params->video_b_frames = ctrl->value;
229 params->video_gop_size = b * ((gop + b - 1) / b);
230 /* Max GOP size = 34 */
231 while (params->video_gop_size > 34)
232 params->video_gop_size -= b;
233 break;
235 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
236 int b = params->video_b_frames + 1;
237 int gop = ctrl->value;
238 params->video_gop_size = b * ((gop + b - 1) / b);
239 /* Max GOP size = 34 */
240 while (params->video_gop_size > 34)
241 params->video_gop_size -= b;
242 ctrl->value = params->video_gop_size;
243 break;
245 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
246 params->video_gop_closure = ctrl->value;
247 break;
248 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
249 /* MPEG-1 only allows CBR */
250 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
251 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
252 return -EINVAL;
253 params->video_bitrate_mode = ctrl->value;
254 break;
255 case V4L2_CID_MPEG_VIDEO_BITRATE:
256 params->video_bitrate = ctrl->value;
257 break;
258 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
259 params->video_bitrate_peak = ctrl->value;
260 break;
261 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
262 params->video_temporal_decimation = ctrl->value;
263 break;
264 case V4L2_CID_MPEG_VIDEO_MUTE:
265 params->video_mute = (ctrl->value != 0);
266 break;
267 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
268 params->video_mute_yuv = ctrl->value;
269 break;
270 case V4L2_CID_MPEG_STREAM_TYPE:
271 params->stream_type = ctrl->value;
272 params->video_encoding =
273 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
274 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
275 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
276 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
277 /* MPEG-1 implies CBR */
278 params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
280 break;
281 case V4L2_CID_MPEG_STREAM_VBI_FMT:
282 params->stream_vbi_fmt = ctrl->value;
283 break;
284 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
285 params->video_spatial_filter_mode = ctrl->value;
286 break;
287 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
288 params->video_spatial_filter = ctrl->value;
289 break;
290 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
291 params->video_luma_spatial_filter_type = ctrl->value;
292 break;
293 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
294 params->video_chroma_spatial_filter_type = ctrl->value;
295 break;
296 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
297 params->video_temporal_filter_mode = ctrl->value;
298 break;
299 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
300 params->video_temporal_filter = ctrl->value;
301 break;
302 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
303 params->video_median_filter_type = ctrl->value;
304 break;
305 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
306 params->video_luma_median_filter_top = ctrl->value;
307 break;
308 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
309 params->video_luma_median_filter_bottom = ctrl->value;
310 break;
311 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
312 params->video_chroma_median_filter_top = ctrl->value;
313 break;
314 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
315 params->video_chroma_median_filter_bottom = ctrl->value;
316 break;
317 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
318 params->stream_insert_nav_packets = ctrl->value;
319 break;
320 default:
321 return -EINVAL;
323 return 0;
326 static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
328 const char *name;
330 qctrl->flags = 0;
331 switch (qctrl->id) {
332 /* MPEG controls */
333 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
334 name = "Spatial Filter Mode";
335 break;
336 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
337 name = "Spatial Filter";
338 break;
339 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
340 name = "Spatial Luma Filter Type";
341 break;
342 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
343 name = "Spatial Chroma Filter Type";
344 break;
345 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
346 name = "Temporal Filter Mode";
347 break;
348 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
349 name = "Temporal Filter";
350 break;
351 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
352 name = "Median Filter Type";
353 break;
354 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
355 name = "Median Luma Filter Maximum";
356 break;
357 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
358 name = "Median Luma Filter Minimum";
359 break;
360 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
361 name = "Median Chroma Filter Maximum";
362 break;
363 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
364 name = "Median Chroma Filter Minimum";
365 break;
366 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
367 name = "Insert Navigation Packets";
368 break;
370 default:
371 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
373 switch (qctrl->id) {
374 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
375 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
376 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
377 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
378 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
379 qctrl->type = V4L2_CTRL_TYPE_MENU;
380 min = 0;
381 step = 1;
382 break;
383 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
384 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
385 min = 0;
386 max = 1;
387 step = 1;
388 break;
389 default:
390 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
391 break;
393 switch (qctrl->id) {
394 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
395 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
396 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
397 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
398 break;
400 qctrl->minimum = min;
401 qctrl->maximum = max;
402 qctrl->step = step;
403 qctrl->default_value = def;
404 qctrl->reserved[0] = qctrl->reserved[1] = 0;
405 snprintf(qctrl->name, sizeof(qctrl->name), name);
406 return 0;
409 int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
411 int err;
413 switch (qctrl->id) {
414 case V4L2_CID_MPEG_AUDIO_ENCODING:
415 return v4l2_ctrl_query_fill(qctrl,
416 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
417 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
418 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
420 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
421 return v4l2_ctrl_query_fill(qctrl,
422 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
423 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
424 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
426 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
427 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
428 return -EINVAL;
430 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
431 err = v4l2_ctrl_query_fill_std(qctrl);
432 if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
433 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
434 return err;
436 case V4L2_CID_MPEG_VIDEO_ENCODING:
437 /* this setting is read-only for the cx2341x since the
438 V4L2_CID_MPEG_STREAM_TYPE really determines the
439 MPEG-1/2 setting */
440 err = v4l2_ctrl_query_fill_std(qctrl);
441 if (err == 0)
442 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
443 return err;
445 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
446 err = v4l2_ctrl_query_fill_std(qctrl);
447 if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
448 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
449 return err;
451 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
452 err = v4l2_ctrl_query_fill_std(qctrl);
453 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
454 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
455 return err;
457 case V4L2_CID_MPEG_STREAM_VBI_FMT:
458 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
459 return v4l2_ctrl_query_fill_std(qctrl);
460 return cx2341x_ctrl_query_fill(qctrl,
461 V4L2_MPEG_STREAM_VBI_FMT_NONE,
462 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
463 V4L2_MPEG_STREAM_VBI_FMT_NONE);
465 /* CX23415/6 specific */
466 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
467 return cx2341x_ctrl_query_fill(qctrl,
468 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
469 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
470 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
472 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
473 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
474 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
475 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
476 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
477 return 0;
479 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
480 cx2341x_ctrl_query_fill(qctrl,
481 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
482 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
483 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
484 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
485 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
486 return 0;
488 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
489 cx2341x_ctrl_query_fill(qctrl,
490 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
491 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
492 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
493 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
494 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
495 return 0;
497 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
498 return cx2341x_ctrl_query_fill(qctrl,
499 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
500 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
501 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
503 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
504 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
505 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
506 if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
507 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
508 return 0;
510 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
511 return cx2341x_ctrl_query_fill(qctrl,
512 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
513 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
514 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
516 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
517 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
518 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
519 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
520 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
521 return 0;
523 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
524 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
525 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
526 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
527 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
528 return 0;
530 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
531 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
532 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
533 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
534 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
535 return 0;
537 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
538 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
539 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
540 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
541 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
542 return 0;
544 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
545 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
547 default:
548 return v4l2_ctrl_query_fill_std(qctrl);
553 const char **cx2341x_ctrl_get_menu(u32 id)
555 static const char *mpeg_stream_type[] = {
556 "MPEG-2 Program Stream",
558 "MPEG-1 System Stream",
559 "MPEG-2 DVD-compatible Stream",
560 "MPEG-1 VCD-compatible Stream",
561 "MPEG-2 SVCD-compatible Stream",
562 NULL
565 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
566 "Manual",
567 "Auto",
568 NULL
571 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
572 "Off",
573 "1D Horizontal",
574 "1D Vertical",
575 "2D H/V Separable",
576 "2D Symmetric non-separable",
577 NULL
580 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
581 "Off",
582 "1D Horizontal",
583 NULL
586 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
587 "Manual",
588 "Auto",
589 NULL
592 static const char *cx2341x_video_median_filter_type_menu[] = {
593 "Off",
594 "Horizontal",
595 "Vertical",
596 "Horizontal/Vertical",
597 "Diagonal",
598 NULL
601 switch (id) {
602 case V4L2_CID_MPEG_STREAM_TYPE:
603 return mpeg_stream_type;
604 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
605 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
606 return NULL;
607 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
608 return cx2341x_video_spatial_filter_mode_menu;
609 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
610 return cx2341x_video_luma_spatial_filter_type_menu;
611 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
612 return cx2341x_video_chroma_spatial_filter_type_menu;
613 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
614 return cx2341x_video_temporal_filter_mode_menu;
615 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
616 return cx2341x_video_median_filter_type_menu;
617 default:
618 return v4l2_ctrl_get_menu(id);
622 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
624 params->audio_properties = (params->audio_sampling_freq << 0) |
625 ((3 - params->audio_encoding) << 2) |
626 ((1 + params->audio_l2_bitrate) << 4) |
627 (params->audio_mode << 8) |
628 (params->audio_mode_extension << 10) |
629 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
631 params->audio_emphasis) << 12) |
632 (params->audio_crc << 14);
635 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
636 struct v4l2_ext_controls *ctrls, unsigned int cmd)
638 int err = 0;
639 int i;
641 if (cmd == VIDIOC_G_EXT_CTRLS) {
642 for (i = 0; i < ctrls->count; i++) {
643 struct v4l2_ext_control *ctrl = ctrls->controls + i;
645 err = cx2341x_get_ctrl(params, ctrl);
646 if (err) {
647 ctrls->error_idx = i;
648 break;
651 return err;
653 for (i = 0; i < ctrls->count; i++) {
654 struct v4l2_ext_control *ctrl = ctrls->controls + i;
655 struct v4l2_queryctrl qctrl;
656 const char **menu_items = NULL;
658 qctrl.id = ctrl->id;
659 err = cx2341x_ctrl_query(params, &qctrl);
660 if (err)
661 break;
662 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
663 menu_items = cx2341x_ctrl_get_menu(qctrl.id);
664 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
665 if (err)
666 break;
667 err = cx2341x_set_ctrl(params, ctrl);
668 if (err)
669 break;
671 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
672 params->video_bitrate_peak < params->video_bitrate) {
673 err = -ERANGE;
674 ctrls->error_idx = ctrls->count;
676 if (err) {
677 ctrls->error_idx = i;
679 else {
680 cx2341x_calc_audio_properties(params);
682 return err;
685 void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
687 static struct cx2341x_mpeg_params default_params = {
688 /* misc */
689 .capabilities = 0,
690 .port = CX2341X_PORT_MEMORY,
691 .width = 720,
692 .height = 480,
693 .is_50hz = 0,
695 /* stream */
696 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
697 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
698 .stream_insert_nav_packets = 0,
700 /* audio */
701 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
702 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
703 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
704 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
705 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
706 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
707 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
708 .audio_mute = 0,
710 /* video */
711 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
712 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
713 .video_b_frames = 2,
714 .video_gop_size = 12,
715 .video_gop_closure = 1,
716 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
717 .video_bitrate = 6000000,
718 .video_bitrate_peak = 8000000,
719 .video_temporal_decimation = 0,
720 .video_mute = 0,
721 .video_mute_yuv = 0x008080, /* YCbCr value for black */
723 /* encoding filters */
724 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
725 .video_spatial_filter = 0,
726 .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
727 .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
728 .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
729 .video_temporal_filter = 8,
730 .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
731 .video_luma_median_filter_top = 255,
732 .video_luma_median_filter_bottom = 0,
733 .video_chroma_median_filter_top = 255,
734 .video_chroma_median_filter_bottom = 0,
737 *p = default_params;
738 cx2341x_calc_audio_properties(p);
741 static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
743 u32 data[CX2341X_MBOX_MAX_DATA];
744 va_list vargs;
745 int i;
747 va_start(vargs, args);
749 for (i = 0; i < args; i++) {
750 data[i] = va_arg(vargs, int);
752 va_end(vargs);
753 return func(priv, cmd, args, 0, data);
756 int cx2341x_update(void *priv, cx2341x_mbox_func func,
757 const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
759 static int mpeg_stream_type[] = {
760 0, /* MPEG-2 PS */
761 1, /* MPEG-2 TS */
762 2, /* MPEG-1 SS */
763 14, /* DVD */
764 11, /* VCD */
765 12, /* SVCD */
768 int err = 0;
769 u16 temporal = new->video_temporal_filter;
771 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
773 if (old == NULL || old->is_50hz != new->is_50hz) {
774 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
775 if (err) return err;
778 if (old == NULL || old->width != new->width || old->height != new->height ||
779 old->video_encoding != new->video_encoding) {
780 u16 w = new->width;
781 u16 h = new->height;
783 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
784 w /= 2;
785 h /= 2;
787 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
788 if (err) return err;
791 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
792 /* Adjust temporal filter if necessary. The problem with the temporal
793 filter is that it works well with full resolution capturing, but
794 not when the capture window is scaled (the filter introduces
795 a ghosting effect). So if the capture window is scaled, then
796 force the filter to 0.
798 For full resolution the filter really improves the video
799 quality, especially if the original video quality is suboptimal. */
800 temporal = 0;
803 if (old == NULL || old->stream_type != new->stream_type) {
804 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
805 if (err) return err;
807 if (old == NULL || old->video_aspect != new->video_aspect) {
808 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
809 if (err) return err;
811 if (old == NULL || old->video_b_frames != new->video_b_frames ||
812 old->video_gop_size != new->video_gop_size) {
813 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
814 new->video_gop_size, new->video_b_frames + 1);
815 if (err) return err;
817 if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
818 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
819 if (err) return err;
821 if (old == NULL || old->audio_properties != new->audio_properties) {
822 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
823 if (err) return err;
825 if (old == NULL || old->audio_mute != new->audio_mute) {
826 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, new->audio_mute);
827 if (err) return err;
829 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
830 old->video_bitrate != new->video_bitrate ||
831 old->video_bitrate_peak != new->video_bitrate_peak) {
832 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
833 new->video_bitrate_mode, new->video_bitrate,
834 new->video_bitrate_peak / 400, 0, 0);
835 if (err) return err;
837 if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
838 old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
839 old->video_median_filter_type != new->video_median_filter_type) {
840 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
841 new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
842 new->video_median_filter_type);
843 if (err) return err;
845 if (old == NULL ||
846 old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
847 old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
848 old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
849 old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
850 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
851 new->video_luma_median_filter_bottom,
852 new->video_luma_median_filter_top,
853 new->video_chroma_median_filter_bottom,
854 new->video_chroma_median_filter_top);
855 if (err) return err;
857 if (old == NULL ||
858 old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
859 old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
860 err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
861 new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
862 if (err) return err;
864 if (old == NULL ||
865 old->video_spatial_filter != new->video_spatial_filter ||
866 old->video_temporal_filter != temporal) {
867 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
868 new->video_spatial_filter, temporal);
869 if (err) return err;
871 if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
872 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
873 new->video_temporal_decimation);
874 if (err) return err;
876 if (old == NULL || old->video_mute != new->video_mute ||
877 (new->video_mute && old->video_mute_yuv != new->video_mute_yuv)) {
878 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, new->video_mute | (new->video_mute_yuv << 8));
879 if (err) return err;
881 if (old == NULL || old->stream_insert_nav_packets != new->stream_insert_nav_packets) {
882 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, 7, new->stream_insert_nav_packets);
883 if (err) return err;
885 return 0;
888 static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
890 const char **menu = cx2341x_ctrl_get_menu(id);
891 struct v4l2_ext_control ctrl;
893 if (menu == NULL)
894 goto invalid;
895 ctrl.id = id;
896 if (cx2341x_get_ctrl(p, &ctrl))
897 goto invalid;
898 while (ctrl.value-- && *menu) menu++;
899 if (*menu == NULL)
900 goto invalid;
901 return *menu;
903 invalid:
904 return "<invalid>";
907 void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
909 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
910 int temporal = p->video_temporal_filter;
912 /* Stream */
913 printk(KERN_INFO "%s: Stream: %s",
914 prefix,
915 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
916 if (p->stream_insert_nav_packets)
917 printk(" (with navigation packets)");
918 printk("\n");
919 printk(KERN_INFO "%s: VBI Format: %s\n",
920 prefix,
921 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
923 /* Video */
924 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
925 prefix,
926 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
927 p->is_50hz ? 25 : 30,
928 (p->video_mute) ? " (muted)" : "");
929 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
930 prefix,
931 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
932 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
933 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
934 p->video_bitrate);
935 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
936 printk(", Peak %d", p->video_bitrate_peak);
938 printk("\n");
939 printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
940 prefix,
941 p->video_gop_size, p->video_b_frames,
942 p->video_gop_closure ? "" : "No ");
943 if (p->video_temporal_decimation) {
944 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
945 prefix, p->video_temporal_decimation);
948 /* Audio */
949 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
950 prefix,
951 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
952 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
953 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
954 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
955 p->audio_mute ? " (muted)" : "");
956 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
957 printk(", %s",
958 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
960 printk(", %s, %s\n",
961 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
962 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
964 /* Encoding filters */
965 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
966 prefix,
967 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
968 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
969 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
970 p->video_spatial_filter);
971 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
972 temporal = 0;
974 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
975 prefix,
976 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
977 temporal);
978 printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
979 prefix,
980 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
981 p->video_luma_median_filter_bottom,
982 p->video_luma_median_filter_top,
983 p->video_chroma_median_filter_bottom,
984 p->video_chroma_median_filter_top);
987 EXPORT_SYMBOL(cx2341x_fill_defaults);
988 EXPORT_SYMBOL(cx2341x_ctrl_query);
989 EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
990 EXPORT_SYMBOL(cx2341x_ext_ctrls);
991 EXPORT_SYMBOL(cx2341x_update);
992 EXPORT_SYMBOL(cx2341x_log_status);
993 EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
996 * Local variables:
997 * c-basic-offset: 8
998 * End: