V4L/DVB (6395): cafe_ccic: Add a pointer to the data sheet
[linux-2.6/linux-2.6-openrd.git] / drivers / media / video / cx2341x.c
blob62304255dcae120cbf669f451942003227f4330e
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/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 driver");
34 MODULE_AUTHOR("Hans Verkuil");
35 MODULE_LICENSE("GPL");
37 static int debug = 0;
38 module_param(debug, int, 0644);
39 MODULE_PARM_DESC(debug, "Debug level (0-1)");
41 const u32 cx2341x_mpeg_ctrls[] = {
42 V4L2_CID_MPEG_CLASS,
43 V4L2_CID_MPEG_STREAM_TYPE,
44 V4L2_CID_MPEG_STREAM_VBI_FMT,
45 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
46 V4L2_CID_MPEG_AUDIO_ENCODING,
47 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
48 V4L2_CID_MPEG_AUDIO_MODE,
49 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
50 V4L2_CID_MPEG_AUDIO_EMPHASIS,
51 V4L2_CID_MPEG_AUDIO_CRC,
52 V4L2_CID_MPEG_AUDIO_MUTE,
53 V4L2_CID_MPEG_VIDEO_ENCODING,
54 V4L2_CID_MPEG_VIDEO_ASPECT,
55 V4L2_CID_MPEG_VIDEO_B_FRAMES,
56 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
57 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
58 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
59 V4L2_CID_MPEG_VIDEO_BITRATE,
60 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
61 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
62 V4L2_CID_MPEG_VIDEO_MUTE,
63 V4L2_CID_MPEG_VIDEO_MUTE_YUV,
64 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
65 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
66 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
67 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
68 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
69 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
70 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
71 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
72 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
73 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
74 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
75 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
80 /* Map the control ID to the correct field in the cx2341x_mpeg_params
81 struct. Return -EINVAL if the ID is unknown, else return 0. */
82 static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
83 struct v4l2_ext_control *ctrl)
85 switch (ctrl->id) {
86 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
87 ctrl->value = params->audio_sampling_freq;
88 break;
89 case V4L2_CID_MPEG_AUDIO_ENCODING:
90 ctrl->value = params->audio_encoding;
91 break;
92 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
93 ctrl->value = params->audio_l2_bitrate;
94 break;
95 case V4L2_CID_MPEG_AUDIO_MODE:
96 ctrl->value = params->audio_mode;
97 break;
98 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
99 ctrl->value = params->audio_mode_extension;
100 break;
101 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
102 ctrl->value = params->audio_emphasis;
103 break;
104 case V4L2_CID_MPEG_AUDIO_CRC:
105 ctrl->value = params->audio_crc;
106 break;
107 case V4L2_CID_MPEG_AUDIO_MUTE:
108 ctrl->value = params->audio_mute;
109 break;
110 case V4L2_CID_MPEG_VIDEO_ENCODING:
111 ctrl->value = params->video_encoding;
112 break;
113 case V4L2_CID_MPEG_VIDEO_ASPECT:
114 ctrl->value = params->video_aspect;
115 break;
116 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
117 ctrl->value = params->video_b_frames;
118 break;
119 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
120 ctrl->value = params->video_gop_size;
121 break;
122 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
123 ctrl->value = params->video_gop_closure;
124 break;
125 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
126 ctrl->value = params->video_bitrate_mode;
127 break;
128 case V4L2_CID_MPEG_VIDEO_BITRATE:
129 ctrl->value = params->video_bitrate;
130 break;
131 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
132 ctrl->value = params->video_bitrate_peak;
133 break;
134 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
135 ctrl->value = params->video_temporal_decimation;
136 break;
137 case V4L2_CID_MPEG_VIDEO_MUTE:
138 ctrl->value = params->video_mute;
139 break;
140 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
141 ctrl->value = params->video_mute_yuv;
142 break;
143 case V4L2_CID_MPEG_STREAM_TYPE:
144 ctrl->value = params->stream_type;
145 break;
146 case V4L2_CID_MPEG_STREAM_VBI_FMT:
147 ctrl->value = params->stream_vbi_fmt;
148 break;
149 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
150 ctrl->value = params->video_spatial_filter_mode;
151 break;
152 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
153 ctrl->value = params->video_spatial_filter;
154 break;
155 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
156 ctrl->value = params->video_luma_spatial_filter_type;
157 break;
158 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
159 ctrl->value = params->video_chroma_spatial_filter_type;
160 break;
161 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
162 ctrl->value = params->video_temporal_filter_mode;
163 break;
164 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
165 ctrl->value = params->video_temporal_filter;
166 break;
167 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
168 ctrl->value = params->video_median_filter_type;
169 break;
170 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
171 ctrl->value = params->video_luma_median_filter_top;
172 break;
173 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
174 ctrl->value = params->video_luma_median_filter_bottom;
175 break;
176 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
177 ctrl->value = params->video_chroma_median_filter_top;
178 break;
179 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
180 ctrl->value = params->video_chroma_median_filter_bottom;
181 break;
182 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
183 ctrl->value = params->stream_insert_nav_packets;
184 break;
185 default:
186 return -EINVAL;
188 return 0;
191 /* Map the control ID to the correct field in the cx2341x_mpeg_params
192 struct. Return -EINVAL if the ID is unknown, else return 0. */
193 static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
194 struct v4l2_ext_control *ctrl)
196 switch (ctrl->id) {
197 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
198 if (busy)
199 return -EBUSY;
200 params->audio_sampling_freq = ctrl->value;
201 break;
202 case V4L2_CID_MPEG_AUDIO_ENCODING:
203 params->audio_encoding = ctrl->value;
204 break;
205 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
206 if (busy)
207 return -EBUSY;
208 params->audio_l2_bitrate = ctrl->value;
209 break;
210 case V4L2_CID_MPEG_AUDIO_MODE:
211 params->audio_mode = ctrl->value;
212 break;
213 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
214 params->audio_mode_extension = ctrl->value;
215 break;
216 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
217 params->audio_emphasis = ctrl->value;
218 break;
219 case V4L2_CID_MPEG_AUDIO_CRC:
220 params->audio_crc = ctrl->value;
221 break;
222 case V4L2_CID_MPEG_AUDIO_MUTE:
223 params->audio_mute = ctrl->value;
224 break;
225 case V4L2_CID_MPEG_VIDEO_ASPECT:
226 params->video_aspect = ctrl->value;
227 break;
228 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
229 int b = ctrl->value + 1;
230 int gop = params->video_gop_size;
231 params->video_b_frames = ctrl->value;
232 params->video_gop_size = b * ((gop + b - 1) / b);
233 /* Max GOP size = 34 */
234 while (params->video_gop_size > 34)
235 params->video_gop_size -= b;
236 break;
238 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
239 int b = params->video_b_frames + 1;
240 int gop = ctrl->value;
241 params->video_gop_size = b * ((gop + b - 1) / b);
242 /* Max GOP size = 34 */
243 while (params->video_gop_size > 34)
244 params->video_gop_size -= b;
245 ctrl->value = params->video_gop_size;
246 break;
248 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
249 params->video_gop_closure = ctrl->value;
250 break;
251 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
252 if (busy)
253 return -EBUSY;
254 /* MPEG-1 only allows CBR */
255 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
256 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
257 return -EINVAL;
258 params->video_bitrate_mode = ctrl->value;
259 break;
260 case V4L2_CID_MPEG_VIDEO_BITRATE:
261 if (busy)
262 return -EBUSY;
263 params->video_bitrate = ctrl->value;
264 break;
265 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
266 if (busy)
267 return -EBUSY;
268 params->video_bitrate_peak = ctrl->value;
269 break;
270 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
271 params->video_temporal_decimation = ctrl->value;
272 break;
273 case V4L2_CID_MPEG_VIDEO_MUTE:
274 params->video_mute = (ctrl->value != 0);
275 break;
276 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
277 params->video_mute_yuv = ctrl->value;
278 break;
279 case V4L2_CID_MPEG_STREAM_TYPE:
280 if (busy)
281 return -EBUSY;
282 params->stream_type = ctrl->value;
283 params->video_encoding =
284 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
285 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
286 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
287 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
288 /* MPEG-1 implies CBR */
289 params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
291 break;
292 case V4L2_CID_MPEG_STREAM_VBI_FMT:
293 params->stream_vbi_fmt = ctrl->value;
294 break;
295 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
296 params->video_spatial_filter_mode = ctrl->value;
297 break;
298 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
299 params->video_spatial_filter = ctrl->value;
300 break;
301 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
302 params->video_luma_spatial_filter_type = ctrl->value;
303 break;
304 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
305 params->video_chroma_spatial_filter_type = ctrl->value;
306 break;
307 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
308 params->video_temporal_filter_mode = ctrl->value;
309 break;
310 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
311 params->video_temporal_filter = ctrl->value;
312 break;
313 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
314 params->video_median_filter_type = ctrl->value;
315 break;
316 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
317 params->video_luma_median_filter_top = ctrl->value;
318 break;
319 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
320 params->video_luma_median_filter_bottom = ctrl->value;
321 break;
322 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
323 params->video_chroma_median_filter_top = ctrl->value;
324 break;
325 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
326 params->video_chroma_median_filter_bottom = ctrl->value;
327 break;
328 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
329 params->stream_insert_nav_packets = ctrl->value;
330 break;
331 default:
332 return -EINVAL;
334 return 0;
337 static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
339 const char *name;
341 qctrl->flags = 0;
342 switch (qctrl->id) {
343 /* MPEG controls */
344 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
345 name = "Spatial Filter Mode";
346 break;
347 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
348 name = "Spatial Filter";
349 break;
350 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
351 name = "Spatial Luma Filter Type";
352 break;
353 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
354 name = "Spatial Chroma Filter Type";
355 break;
356 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
357 name = "Temporal Filter Mode";
358 break;
359 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
360 name = "Temporal Filter";
361 break;
362 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
363 name = "Median Filter Type";
364 break;
365 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
366 name = "Median Luma Filter Maximum";
367 break;
368 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
369 name = "Median Luma Filter Minimum";
370 break;
371 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
372 name = "Median Chroma Filter Maximum";
373 break;
374 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
375 name = "Median Chroma Filter Minimum";
376 break;
377 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
378 name = "Insert Navigation Packets";
379 break;
381 default:
382 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
384 switch (qctrl->id) {
385 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
386 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
387 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
388 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
389 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
390 qctrl->type = V4L2_CTRL_TYPE_MENU;
391 min = 0;
392 step = 1;
393 break;
394 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
395 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
396 min = 0;
397 max = 1;
398 step = 1;
399 break;
400 default:
401 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
402 break;
404 switch (qctrl->id) {
405 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
406 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
407 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
408 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
409 break;
411 qctrl->minimum = min;
412 qctrl->maximum = max;
413 qctrl->step = step;
414 qctrl->default_value = def;
415 qctrl->reserved[0] = qctrl->reserved[1] = 0;
416 snprintf(qctrl->name, sizeof(qctrl->name), name);
417 return 0;
420 int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
422 int err;
424 switch (qctrl->id) {
425 case V4L2_CID_MPEG_AUDIO_ENCODING:
426 return v4l2_ctrl_query_fill(qctrl,
427 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
428 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
429 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
431 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
432 return v4l2_ctrl_query_fill(qctrl,
433 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
434 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
435 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
437 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
438 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
439 return -EINVAL;
441 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
442 err = v4l2_ctrl_query_fill_std(qctrl);
443 if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
444 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
445 return err;
447 case V4L2_CID_MPEG_VIDEO_ENCODING:
448 /* this setting is read-only for the cx2341x since the
449 V4L2_CID_MPEG_STREAM_TYPE really determines the
450 MPEG-1/2 setting */
451 err = v4l2_ctrl_query_fill_std(qctrl);
452 if (err == 0)
453 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
454 return err;
456 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
457 err = v4l2_ctrl_query_fill_std(qctrl);
458 if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
459 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
460 return err;
462 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
463 err = v4l2_ctrl_query_fill_std(qctrl);
464 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
465 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
466 return err;
468 case V4L2_CID_MPEG_STREAM_VBI_FMT:
469 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
470 return v4l2_ctrl_query_fill_std(qctrl);
471 return cx2341x_ctrl_query_fill(qctrl,
472 V4L2_MPEG_STREAM_VBI_FMT_NONE,
473 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
474 V4L2_MPEG_STREAM_VBI_FMT_NONE);
476 /* CX23415/6 specific */
477 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
478 return cx2341x_ctrl_query_fill(qctrl,
479 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
480 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
481 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
483 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
484 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
485 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
486 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
487 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
488 return 0;
490 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
491 cx2341x_ctrl_query_fill(qctrl,
492 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
493 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
494 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
495 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
496 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
497 return 0;
499 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
500 cx2341x_ctrl_query_fill(qctrl,
501 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
502 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
503 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
504 if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
505 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
506 return 0;
508 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
509 return cx2341x_ctrl_query_fill(qctrl,
510 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
511 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
512 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
514 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
515 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
516 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
517 if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
518 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
519 return 0;
521 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
522 return cx2341x_ctrl_query_fill(qctrl,
523 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
524 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
525 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
527 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
528 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
529 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
530 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
531 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
532 return 0;
534 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
535 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
536 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
537 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
538 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
539 return 0;
541 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
542 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
543 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
544 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
545 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
546 return 0;
548 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
549 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
550 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
551 if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
552 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
553 return 0;
555 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
556 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
558 default:
559 return v4l2_ctrl_query_fill_std(qctrl);
564 const char **cx2341x_ctrl_get_menu(u32 id)
566 static const char *mpeg_stream_type[] = {
567 "MPEG-2 Program Stream",
569 "MPEG-1 System Stream",
570 "MPEG-2 DVD-compatible Stream",
571 "MPEG-1 VCD-compatible Stream",
572 "MPEG-2 SVCD-compatible Stream",
573 NULL
576 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
577 "Manual",
578 "Auto",
579 NULL
582 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
583 "Off",
584 "1D Horizontal",
585 "1D Vertical",
586 "2D H/V Separable",
587 "2D Symmetric non-separable",
588 NULL
591 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
592 "Off",
593 "1D Horizontal",
594 NULL
597 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
598 "Manual",
599 "Auto",
600 NULL
603 static const char *cx2341x_video_median_filter_type_menu[] = {
604 "Off",
605 "Horizontal",
606 "Vertical",
607 "Horizontal/Vertical",
608 "Diagonal",
609 NULL
612 switch (id) {
613 case V4L2_CID_MPEG_STREAM_TYPE:
614 return mpeg_stream_type;
615 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
616 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
617 return NULL;
618 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
619 return cx2341x_video_spatial_filter_mode_menu;
620 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
621 return cx2341x_video_luma_spatial_filter_type_menu;
622 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
623 return cx2341x_video_chroma_spatial_filter_type_menu;
624 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
625 return cx2341x_video_temporal_filter_mode_menu;
626 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
627 return cx2341x_video_median_filter_type_menu;
628 default:
629 return v4l2_ctrl_get_menu(id);
633 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
635 params->audio_properties = (params->audio_sampling_freq << 0) |
636 ((3 - params->audio_encoding) << 2) |
637 ((1 + params->audio_l2_bitrate) << 4) |
638 (params->audio_mode << 8) |
639 (params->audio_mode_extension << 10) |
640 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
642 params->audio_emphasis) << 12) |
643 (params->audio_crc << 14);
646 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
647 struct v4l2_ext_controls *ctrls, unsigned int cmd)
649 int err = 0;
650 int i;
652 if (cmd == VIDIOC_G_EXT_CTRLS) {
653 for (i = 0; i < ctrls->count; i++) {
654 struct v4l2_ext_control *ctrl = ctrls->controls + i;
656 err = cx2341x_get_ctrl(params, ctrl);
657 if (err) {
658 ctrls->error_idx = i;
659 break;
662 return err;
664 for (i = 0; i < ctrls->count; i++) {
665 struct v4l2_ext_control *ctrl = ctrls->controls + i;
666 struct v4l2_queryctrl qctrl;
667 const char **menu_items = NULL;
669 qctrl.id = ctrl->id;
670 err = cx2341x_ctrl_query(params, &qctrl);
671 if (err)
672 break;
673 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
674 menu_items = cx2341x_ctrl_get_menu(qctrl.id);
675 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
676 if (err)
677 break;
678 err = cx2341x_set_ctrl(params, busy, ctrl);
679 if (err)
680 break;
682 if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
683 params->video_bitrate_peak < params->video_bitrate) {
684 err = -ERANGE;
685 ctrls->error_idx = ctrls->count;
687 if (err) {
688 ctrls->error_idx = i;
690 else {
691 cx2341x_calc_audio_properties(params);
693 return err;
696 void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
698 static struct cx2341x_mpeg_params default_params = {
699 /* misc */
700 .capabilities = 0,
701 .port = CX2341X_PORT_MEMORY,
702 .width = 720,
703 .height = 480,
704 .is_50hz = 0,
706 /* stream */
707 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
708 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
709 .stream_insert_nav_packets = 0,
711 /* audio */
712 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
713 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
714 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
715 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
716 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
717 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
718 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
719 .audio_mute = 0,
721 /* video */
722 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
723 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
724 .video_b_frames = 2,
725 .video_gop_size = 12,
726 .video_gop_closure = 1,
727 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
728 .video_bitrate = 6000000,
729 .video_bitrate_peak = 8000000,
730 .video_temporal_decimation = 0,
731 .video_mute = 0,
732 .video_mute_yuv = 0x008080, /* YCbCr value for black */
734 /* encoding filters */
735 .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
736 .video_spatial_filter = 0,
737 .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
738 .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
739 .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
740 .video_temporal_filter = 8,
741 .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
742 .video_luma_median_filter_top = 255,
743 .video_luma_median_filter_bottom = 0,
744 .video_chroma_median_filter_top = 255,
745 .video_chroma_median_filter_bottom = 0,
748 *p = default_params;
749 cx2341x_calc_audio_properties(p);
752 static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
754 u32 data[CX2341X_MBOX_MAX_DATA];
755 va_list vargs;
756 int i;
758 va_start(vargs, args);
760 for (i = 0; i < args; i++) {
761 data[i] = va_arg(vargs, int);
763 va_end(vargs);
764 return func(priv, cmd, args, 0, data);
767 int cx2341x_update(void *priv, cx2341x_mbox_func func,
768 const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
770 static int mpeg_stream_type[] = {
771 0, /* MPEG-2 PS */
772 1, /* MPEG-2 TS */
773 2, /* MPEG-1 SS */
774 14, /* DVD */
775 11, /* VCD */
776 12, /* SVCD */
779 int err = 0;
780 u16 temporal = new->video_temporal_filter;
782 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
784 if (old == NULL || old->is_50hz != new->is_50hz) {
785 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
786 if (err) return err;
789 if (old == NULL || old->width != new->width || old->height != new->height ||
790 old->video_encoding != new->video_encoding) {
791 u16 w = new->width;
792 u16 h = new->height;
794 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
795 w /= 2;
796 h /= 2;
798 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
799 if (err) return err;
802 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
803 /* Adjust temporal filter if necessary. The problem with the temporal
804 filter is that it works well with full resolution capturing, but
805 not when the capture window is scaled (the filter introduces
806 a ghosting effect). So if the capture window is scaled, then
807 force the filter to 0.
809 For full resolution the filter really improves the video
810 quality, especially if the original video quality is suboptimal. */
811 temporal = 0;
814 if (old == NULL || old->stream_type != new->stream_type) {
815 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
816 if (err) return err;
818 if (old == NULL || old->video_aspect != new->video_aspect) {
819 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
820 if (err) return err;
822 if (old == NULL || old->video_b_frames != new->video_b_frames ||
823 old->video_gop_size != new->video_gop_size) {
824 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
825 new->video_gop_size, new->video_b_frames + 1);
826 if (err) return err;
828 if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
829 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
830 if (err) return err;
832 if (old == NULL || old->audio_properties != new->audio_properties) {
833 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
834 if (err) return err;
836 if (old == NULL || old->audio_mute != new->audio_mute) {
837 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, new->audio_mute);
838 if (err) return err;
840 if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
841 old->video_bitrate != new->video_bitrate ||
842 old->video_bitrate_peak != new->video_bitrate_peak) {
843 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
844 new->video_bitrate_mode, new->video_bitrate,
845 new->video_bitrate_peak / 400, 0, 0);
846 if (err) return err;
848 if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
849 old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
850 old->video_median_filter_type != new->video_median_filter_type) {
851 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
852 new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
853 new->video_median_filter_type);
854 if (err) return err;
856 if (old == NULL ||
857 old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
858 old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
859 old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
860 old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
861 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
862 new->video_luma_median_filter_bottom,
863 new->video_luma_median_filter_top,
864 new->video_chroma_median_filter_bottom,
865 new->video_chroma_median_filter_top);
866 if (err) return err;
868 if (old == NULL ||
869 old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
870 old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
871 err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
872 new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
873 if (err) return err;
875 if (old == NULL ||
876 old->video_spatial_filter != new->video_spatial_filter ||
877 old->video_temporal_filter != temporal) {
878 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
879 new->video_spatial_filter, temporal);
880 if (err) return err;
882 if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
883 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
884 new->video_temporal_decimation);
885 if (err) return err;
887 if (old == NULL || old->video_mute != new->video_mute ||
888 (new->video_mute && old->video_mute_yuv != new->video_mute_yuv)) {
889 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, new->video_mute | (new->video_mute_yuv << 8));
890 if (err) return err;
892 if (old == NULL || old->stream_insert_nav_packets != new->stream_insert_nav_packets) {
893 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, 7, new->stream_insert_nav_packets);
894 if (err) return err;
896 return 0;
899 static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
901 const char **menu = cx2341x_ctrl_get_menu(id);
902 struct v4l2_ext_control ctrl;
904 if (menu == NULL)
905 goto invalid;
906 ctrl.id = id;
907 if (cx2341x_get_ctrl(p, &ctrl))
908 goto invalid;
909 while (ctrl.value-- && *menu) menu++;
910 if (*menu == NULL)
911 goto invalid;
912 return *menu;
914 invalid:
915 return "<invalid>";
918 void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
920 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
921 int temporal = p->video_temporal_filter;
923 /* Stream */
924 printk(KERN_INFO "%s: Stream: %s",
925 prefix,
926 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
927 if (p->stream_insert_nav_packets)
928 printk(" (with navigation packets)");
929 printk("\n");
930 printk(KERN_INFO "%s: VBI Format: %s\n",
931 prefix,
932 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
934 /* Video */
935 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
936 prefix,
937 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
938 p->is_50hz ? 25 : 30,
939 (p->video_mute) ? " (muted)" : "");
940 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
941 prefix,
942 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
943 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
944 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
945 p->video_bitrate);
946 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
947 printk(", Peak %d", p->video_bitrate_peak);
949 printk("\n");
950 printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
951 prefix,
952 p->video_gop_size, p->video_b_frames,
953 p->video_gop_closure ? "" : "No ");
954 if (p->video_temporal_decimation) {
955 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
956 prefix, p->video_temporal_decimation);
959 /* Audio */
960 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
961 prefix,
962 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
963 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
964 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
965 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
966 p->audio_mute ? " (muted)" : "");
967 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
968 printk(", %s",
969 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
971 printk(", %s, %s\n",
972 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
973 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
975 /* Encoding filters */
976 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
977 prefix,
978 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
979 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
980 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
981 p->video_spatial_filter);
982 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
983 temporal = 0;
985 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
986 prefix,
987 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
988 temporal);
989 printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
990 prefix,
991 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
992 p->video_luma_median_filter_bottom,
993 p->video_luma_median_filter_top,
994 p->video_chroma_median_filter_bottom,
995 p->video_chroma_median_filter_top);
998 EXPORT_SYMBOL(cx2341x_fill_defaults);
999 EXPORT_SYMBOL(cx2341x_ctrl_query);
1000 EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
1001 EXPORT_SYMBOL(cx2341x_ext_ctrls);
1002 EXPORT_SYMBOL(cx2341x_update);
1003 EXPORT_SYMBOL(cx2341x_log_status);
1004 EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
1007 * Local variables:
1008 * c-basic-offset: 8
1009 * End: