Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / drivers / media / video / cx2341x.c
blobc592899a23175f8a75febad62b3e39b8e930f9cb
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;
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,
78 EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
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, int busy,
195 struct v4l2_ext_control *ctrl)
197 switch (ctrl->id) {
198 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
199 if (busy)
200 return -EBUSY;
201 params->audio_sampling_freq = ctrl->value;
202 break;
203 case V4L2_CID_MPEG_AUDIO_ENCODING:
204 params->audio_encoding = ctrl->value;
205 break;
206 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
207 if (busy)
208 return -EBUSY;
209 params->audio_l2_bitrate = ctrl->value;
210 break;
211 case V4L2_CID_MPEG_AUDIO_MODE:
212 params->audio_mode = ctrl->value;
213 break;
214 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
215 params->audio_mode_extension = ctrl->value;
216 break;
217 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
218 params->audio_emphasis = ctrl->value;
219 break;
220 case V4L2_CID_MPEG_AUDIO_CRC:
221 params->audio_crc = ctrl->value;
222 break;
223 case V4L2_CID_MPEG_AUDIO_MUTE:
224 params->audio_mute = ctrl->value;
225 break;
226 case V4L2_CID_MPEG_VIDEO_ASPECT:
227 params->video_aspect = ctrl->value;
228 break;
229 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
230 int b = ctrl->value + 1;
231 int gop = params->video_gop_size;
232 params->video_b_frames = ctrl->value;
233 params->video_gop_size = b * ((gop + b - 1) / b);
234 /* Max GOP size = 34 */
235 while (params->video_gop_size > 34)
236 params->video_gop_size -= b;
237 break;
239 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
240 int b = params->video_b_frames + 1;
241 int gop = ctrl->value;
242 params->video_gop_size = b * ((gop + b - 1) / b);
243 /* Max GOP size = 34 */
244 while (params->video_gop_size > 34)
245 params->video_gop_size -= b;
246 ctrl->value = params->video_gop_size;
247 break;
249 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
250 params->video_gop_closure = ctrl->value;
251 break;
252 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
253 if (busy)
254 return -EBUSY;
255 /* MPEG-1 only allows CBR */
256 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
257 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
258 return -EINVAL;
259 params->video_bitrate_mode = ctrl->value;
260 break;
261 case V4L2_CID_MPEG_VIDEO_BITRATE:
262 if (busy)
263 return -EBUSY;
264 params->video_bitrate = ctrl->value;
265 break;
266 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
267 if (busy)
268 return -EBUSY;
269 params->video_bitrate_peak = ctrl->value;
270 break;
271 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
272 params->video_temporal_decimation = ctrl->value;
273 break;
274 case V4L2_CID_MPEG_VIDEO_MUTE:
275 params->video_mute = (ctrl->value != 0);
276 break;
277 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
278 params->video_mute_yuv = ctrl->value;
279 break;
280 case V4L2_CID_MPEG_STREAM_TYPE:
281 if (busy)
282 return -EBUSY;
283 params->stream_type = ctrl->value;
284 params->video_encoding =
285 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
286 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
287 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
288 V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
289 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
290 /* MPEG-1 implies CBR */
291 params->video_bitrate_mode =
292 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
293 break;
294 case V4L2_CID_MPEG_STREAM_VBI_FMT:
295 params->stream_vbi_fmt = ctrl->value;
296 break;
297 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
298 params->video_spatial_filter_mode = ctrl->value;
299 break;
300 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
301 params->video_spatial_filter = ctrl->value;
302 break;
303 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
304 params->video_luma_spatial_filter_type = ctrl->value;
305 break;
306 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
307 params->video_chroma_spatial_filter_type = ctrl->value;
308 break;
309 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
310 params->video_temporal_filter_mode = ctrl->value;
311 break;
312 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
313 params->video_temporal_filter = ctrl->value;
314 break;
315 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
316 params->video_median_filter_type = ctrl->value;
317 break;
318 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
319 params->video_luma_median_filter_top = ctrl->value;
320 break;
321 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
322 params->video_luma_median_filter_bottom = ctrl->value;
323 break;
324 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
325 params->video_chroma_median_filter_top = ctrl->value;
326 break;
327 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
328 params->video_chroma_median_filter_bottom = ctrl->value;
329 break;
330 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
331 params->stream_insert_nav_packets = ctrl->value;
332 break;
333 default:
334 return -EINVAL;
336 return 0;
339 static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
340 s32 min, s32 max, s32 step, s32 def)
342 const char *name;
344 qctrl->flags = 0;
345 switch (qctrl->id) {
346 /* MPEG controls */
347 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
348 name = "Spatial Filter Mode";
349 break;
350 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
351 name = "Spatial Filter";
352 break;
353 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
354 name = "Spatial Luma Filter Type";
355 break;
356 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
357 name = "Spatial Chroma Filter Type";
358 break;
359 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
360 name = "Temporal Filter Mode";
361 break;
362 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
363 name = "Temporal Filter";
364 break;
365 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
366 name = "Median Filter Type";
367 break;
368 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
369 name = "Median Luma Filter Maximum";
370 break;
371 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
372 name = "Median Luma Filter Minimum";
373 break;
374 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
375 name = "Median Chroma Filter Maximum";
376 break;
377 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
378 name = "Median Chroma Filter Minimum";
379 break;
380 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
381 name = "Insert Navigation Packets";
382 break;
384 default:
385 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
387 switch (qctrl->id) {
388 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
389 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
390 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
391 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
392 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
393 qctrl->type = V4L2_CTRL_TYPE_MENU;
394 min = 0;
395 step = 1;
396 break;
397 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
398 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
399 min = 0;
400 max = 1;
401 step = 1;
402 break;
403 default:
404 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
405 break;
407 switch (qctrl->id) {
408 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
409 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
410 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
411 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
412 break;
414 qctrl->minimum = min;
415 qctrl->maximum = max;
416 qctrl->step = step;
417 qctrl->default_value = def;
418 qctrl->reserved[0] = qctrl->reserved[1] = 0;
419 snprintf(qctrl->name, sizeof(qctrl->name), name);
420 return 0;
423 int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
424 struct v4l2_queryctrl *qctrl)
426 int err;
428 switch (qctrl->id) {
429 case V4L2_CID_MPEG_AUDIO_ENCODING:
430 return v4l2_ctrl_query_fill(qctrl,
431 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
432 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
433 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
435 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
436 return v4l2_ctrl_query_fill(qctrl,
437 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
438 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
439 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
441 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
442 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
443 return -EINVAL;
445 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
446 err = v4l2_ctrl_query_fill_std(qctrl);
447 if (err == 0 &&
448 params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
449 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
450 return err;
452 case V4L2_CID_MPEG_VIDEO_ENCODING:
453 /* this setting is read-only for the cx2341x since the
454 V4L2_CID_MPEG_STREAM_TYPE really determines the
455 MPEG-1/2 setting */
456 err = v4l2_ctrl_query_fill_std(qctrl);
457 if (err == 0)
458 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
459 return err;
461 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
462 err = v4l2_ctrl_query_fill_std(qctrl);
463 if (err == 0 &&
464 params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
465 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
466 return err;
468 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
469 err = v4l2_ctrl_query_fill_std(qctrl);
470 if (err == 0 &&
471 params->video_bitrate_mode ==
472 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
473 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
474 return err;
476 case V4L2_CID_MPEG_STREAM_VBI_FMT:
477 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
478 return v4l2_ctrl_query_fill_std(qctrl);
479 return cx2341x_ctrl_query_fill(qctrl,
480 V4L2_MPEG_STREAM_VBI_FMT_NONE,
481 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
482 V4L2_MPEG_STREAM_VBI_FMT_NONE);
484 /* CX23415/6 specific */
485 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
486 return cx2341x_ctrl_query_fill(qctrl,
487 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
488 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
489 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
491 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
492 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
493 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
494 if (params->video_spatial_filter_mode ==
495 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_LUMA_SPATIAL_FILTER_TYPE:
500 cx2341x_ctrl_query_fill(qctrl,
501 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
502 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
504 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
505 if (params->video_spatial_filter_mode ==
506 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
507 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
508 return 0;
510 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
511 cx2341x_ctrl_query_fill(qctrl,
512 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
513 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
515 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
516 if (params->video_spatial_filter_mode ==
517 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
518 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
519 return 0;
521 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
522 return cx2341x_ctrl_query_fill(qctrl,
523 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
524 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
525 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
527 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
528 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
529 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
530 if (params->video_temporal_filter_mode ==
531 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
532 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
533 return 0;
535 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
536 return cx2341x_ctrl_query_fill(qctrl,
537 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
538 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
539 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
541 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_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 ==
545 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
546 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
547 return 0;
549 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
550 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
551 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
552 if (params->video_median_filter_type ==
553 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
554 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
555 return 0;
557 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
558 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
559 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
560 if (params->video_median_filter_type ==
561 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
562 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
563 return 0;
565 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
566 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
567 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
568 if (params->video_median_filter_type ==
569 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
570 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
571 return 0;
573 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
574 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
576 default:
577 return v4l2_ctrl_query_fill_std(qctrl);
581 EXPORT_SYMBOL(cx2341x_ctrl_query);
583 const char **cx2341x_ctrl_get_menu(u32 id)
585 static const char *mpeg_stream_type[] = {
586 "MPEG-2 Program Stream",
588 "MPEG-1 System Stream",
589 "MPEG-2 DVD-compatible Stream",
590 "MPEG-1 VCD-compatible Stream",
591 "MPEG-2 SVCD-compatible Stream",
592 NULL
595 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
596 "Manual",
597 "Auto",
598 NULL
601 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
602 "Off",
603 "1D Horizontal",
604 "1D Vertical",
605 "2D H/V Separable",
606 "2D Symmetric non-separable",
607 NULL
610 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
611 "Off",
612 "1D Horizontal",
613 NULL
616 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
617 "Manual",
618 "Auto",
619 NULL
622 static const char *cx2341x_video_median_filter_type_menu[] = {
623 "Off",
624 "Horizontal",
625 "Vertical",
626 "Horizontal/Vertical",
627 "Diagonal",
628 NULL
631 switch (id) {
632 case V4L2_CID_MPEG_STREAM_TYPE:
633 return mpeg_stream_type;
634 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
635 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
636 return NULL;
637 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
638 return cx2341x_video_spatial_filter_mode_menu;
639 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
640 return cx2341x_video_luma_spatial_filter_type_menu;
641 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
642 return cx2341x_video_chroma_spatial_filter_type_menu;
643 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
644 return cx2341x_video_temporal_filter_mode_menu;
645 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
646 return cx2341x_video_median_filter_type_menu;
647 default:
648 return v4l2_ctrl_get_menu(id);
651 EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
653 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
655 params->audio_properties = (params->audio_sampling_freq << 0) |
656 ((3 - params->audio_encoding) << 2) |
657 ((1 + params->audio_l2_bitrate) << 4) |
658 (params->audio_mode << 8) |
659 (params->audio_mode_extension << 10) |
660 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
661 ? 3 : params->audio_emphasis) << 12) |
662 (params->audio_crc << 14);
665 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
666 struct v4l2_ext_controls *ctrls, unsigned int cmd)
668 int err = 0;
669 int i;
671 if (cmd == VIDIOC_G_EXT_CTRLS) {
672 for (i = 0; i < ctrls->count; i++) {
673 struct v4l2_ext_control *ctrl = ctrls->controls + i;
675 err = cx2341x_get_ctrl(params, ctrl);
676 if (err) {
677 ctrls->error_idx = i;
678 break;
681 return err;
683 for (i = 0; i < ctrls->count; i++) {
684 struct v4l2_ext_control *ctrl = ctrls->controls + i;
685 struct v4l2_queryctrl qctrl;
686 const char **menu_items = NULL;
688 qctrl.id = ctrl->id;
689 err = cx2341x_ctrl_query(params, &qctrl);
690 if (err)
691 break;
692 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
693 menu_items = cx2341x_ctrl_get_menu(qctrl.id);
694 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
695 if (err)
696 break;
697 err = cx2341x_set_ctrl(params, busy, ctrl);
698 if (err)
699 break;
701 if (err == 0 &&
702 params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
703 params->video_bitrate_peak < params->video_bitrate) {
704 err = -ERANGE;
705 ctrls->error_idx = ctrls->count;
707 if (err)
708 ctrls->error_idx = i;
709 else
710 cx2341x_calc_audio_properties(params);
711 return err;
713 EXPORT_SYMBOL(cx2341x_ext_ctrls);
715 void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
717 static struct cx2341x_mpeg_params default_params = {
718 /* misc */
719 .capabilities = 0,
720 .port = CX2341X_PORT_MEMORY,
721 .width = 720,
722 .height = 480,
723 .is_50hz = 0,
725 /* stream */
726 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
727 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
728 .stream_insert_nav_packets = 0,
730 /* audio */
731 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
732 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
733 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
734 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
735 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
736 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
737 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
738 .audio_mute = 0,
740 /* video */
741 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
742 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
743 .video_b_frames = 2,
744 .video_gop_size = 12,
745 .video_gop_closure = 1,
746 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
747 .video_bitrate = 6000000,
748 .video_bitrate_peak = 8000000,
749 .video_temporal_decimation = 0,
750 .video_mute = 0,
751 .video_mute_yuv = 0x008080, /* YCbCr value for black */
753 /* encoding filters */
754 .video_spatial_filter_mode =
755 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
756 .video_spatial_filter = 0,
757 .video_luma_spatial_filter_type =
758 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
759 .video_chroma_spatial_filter_type =
760 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
761 .video_temporal_filter_mode =
762 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
763 .video_temporal_filter = 8,
764 .video_median_filter_type =
765 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
766 .video_luma_median_filter_top = 255,
767 .video_luma_median_filter_bottom = 0,
768 .video_chroma_median_filter_top = 255,
769 .video_chroma_median_filter_bottom = 0,
772 *p = default_params;
773 cx2341x_calc_audio_properties(p);
775 EXPORT_SYMBOL(cx2341x_fill_defaults);
777 static int cx2341x_api(void *priv, cx2341x_mbox_func func,
778 u32 cmd, int args, ...)
780 u32 data[CX2341X_MBOX_MAX_DATA];
781 va_list vargs;
782 int i;
784 va_start(vargs, args);
786 for (i = 0; i < args; i++)
787 data[i] = va_arg(vargs, int);
788 va_end(vargs);
789 return func(priv, cmd, args, 0, data);
792 #define NEQ(field) (old->field != new->field)
794 int cx2341x_update(void *priv, cx2341x_mbox_func func,
795 const struct cx2341x_mpeg_params *old,
796 const struct cx2341x_mpeg_params *new)
798 static int mpeg_stream_type[] = {
799 0, /* MPEG-2 PS */
800 1, /* MPEG-2 TS */
801 2, /* MPEG-1 SS */
802 14, /* DVD */
803 11, /* VCD */
804 12, /* SVCD */
807 int err = 0;
808 int force = (old == NULL);
809 u16 temporal = new->video_temporal_filter;
811 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
813 if (force || NEQ(is_50hz)) {
814 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
815 new->is_50hz);
816 if (err) return err;
819 if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
820 u16 w = new->width;
821 u16 h = new->height;
823 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
824 w /= 2;
825 h /= 2;
827 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
828 h, w);
829 if (err) return err;
832 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
833 /* Adjust temporal filter if necessary. The problem with the
834 temporal filter is that it works well with full resolution
835 capturing, but not when the capture window is scaled (the
836 filter introduces a ghosting effect). So if the capture
837 window is scaled, then force the filter to 0.
839 For full resolution the filter really improves the video
840 quality, especially if the original video quality is
841 suboptimal. */
842 temporal = 0;
845 if (force || NEQ(stream_type)) {
846 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
847 mpeg_stream_type[new->stream_type]);
848 if (err) return err;
850 if (force || NEQ(video_aspect)) {
851 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
852 1 + new->video_aspect);
853 if (err) return err;
855 if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
856 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
857 new->video_gop_size, new->video_b_frames + 1);
858 if (err) return err;
860 if (force || NEQ(video_gop_closure)) {
861 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
862 new->video_gop_closure);
863 if (err) return err;
865 if (force || NEQ(audio_properties)) {
866 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
867 1, new->audio_properties);
868 if (err) return err;
870 if (force || NEQ(audio_mute)) {
871 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
872 new->audio_mute);
873 if (err) return err;
875 if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
876 NEQ(video_bitrate_peak)) {
877 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
878 new->video_bitrate_mode, new->video_bitrate,
879 new->video_bitrate_peak / 400, 0, 0);
880 if (err) return err;
882 if (force || NEQ(video_spatial_filter_mode) ||
883 NEQ(video_temporal_filter_mode) ||
884 NEQ(video_median_filter_type)) {
885 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
886 2, new->video_spatial_filter_mode |
887 (new->video_temporal_filter_mode << 1),
888 new->video_median_filter_type);
889 if (err) return err;
891 if (force || NEQ(video_luma_median_filter_bottom) ||
892 NEQ(video_luma_median_filter_top) ||
893 NEQ(video_chroma_median_filter_bottom) ||
894 NEQ(video_chroma_median_filter_top)) {
895 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
896 new->video_luma_median_filter_bottom,
897 new->video_luma_median_filter_top,
898 new->video_chroma_median_filter_bottom,
899 new->video_chroma_median_filter_top);
900 if (err) return err;
902 if (force || NEQ(video_luma_spatial_filter_type) ||
903 NEQ(video_chroma_spatial_filter_type)) {
904 err = cx2341x_api(priv, func,
905 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
906 2, new->video_luma_spatial_filter_type,
907 new->video_chroma_spatial_filter_type);
908 if (err) return err;
910 if (force || NEQ(video_spatial_filter) ||
911 old->video_temporal_filter != temporal) {
912 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
913 2, new->video_spatial_filter, temporal);
914 if (err) return err;
916 if (force || NEQ(video_temporal_decimation)) {
917 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
918 1, new->video_temporal_decimation);
919 if (err) return err;
921 if (force || NEQ(video_mute) ||
922 (new->video_mute && NEQ(video_mute_yuv))) {
923 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
924 new->video_mute | (new->video_mute_yuv << 8));
925 if (err) return err;
927 if (force || NEQ(stream_insert_nav_packets)) {
928 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
929 7, new->stream_insert_nav_packets);
930 if (err) return err;
932 return 0;
934 EXPORT_SYMBOL(cx2341x_update);
936 static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
938 const char **menu = cx2341x_ctrl_get_menu(id);
939 struct v4l2_ext_control ctrl;
941 if (menu == NULL)
942 goto invalid;
943 ctrl.id = id;
944 if (cx2341x_get_ctrl(p, &ctrl))
945 goto invalid;
946 while (ctrl.value-- && *menu) menu++;
947 if (*menu == NULL)
948 goto invalid;
949 return *menu;
951 invalid:
952 return "<invalid>";
955 void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
957 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
958 int temporal = p->video_temporal_filter;
960 /* Stream */
961 printk(KERN_INFO "%s: Stream: %s",
962 prefix,
963 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
964 if (p->stream_insert_nav_packets)
965 printk(" (with navigation packets)");
966 printk("\n");
967 printk(KERN_INFO "%s: VBI Format: %s\n",
968 prefix,
969 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
971 /* Video */
972 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
973 prefix,
974 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
975 p->is_50hz ? 25 : 30,
976 (p->video_mute) ? " (muted)" : "");
977 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
978 prefix,
979 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
980 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
981 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
982 p->video_bitrate);
983 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
984 printk(", Peak %d", p->video_bitrate_peak);
985 printk("\n");
986 printk(KERN_INFO
987 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
988 prefix,
989 p->video_gop_size, p->video_b_frames,
990 p->video_gop_closure ? "" : "No ");
991 if (p->video_temporal_decimation)
992 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
993 prefix, p->video_temporal_decimation);
995 /* Audio */
996 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
997 prefix,
998 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
999 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
1000 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
1001 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1002 p->audio_mute ? " (muted)" : "");
1003 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1004 printk(", %s", cx2341x_menu_item(p,
1005 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
1006 printk(", %s, %s\n",
1007 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1008 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1010 /* Encoding filters */
1011 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1012 prefix,
1013 cx2341x_menu_item(p,
1014 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1015 cx2341x_menu_item(p,
1016 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1017 cx2341x_menu_item(p,
1018 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
1019 p->video_spatial_filter);
1021 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
1022 temporal = 0;
1024 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1025 prefix,
1026 cx2341x_menu_item(p,
1027 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
1028 temporal);
1029 printk(KERN_INFO
1030 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1031 prefix,
1032 cx2341x_menu_item(p,
1033 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
1034 p->video_luma_median_filter_bottom,
1035 p->video_luma_median_filter_top,
1036 p->video_chroma_median_filter_bottom,
1037 p->video_chroma_median_filter_top);
1039 EXPORT_SYMBOL(cx2341x_log_status);
1042 * Local variables:
1043 * c-basic-offset: 8
1044 * End: