1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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>
28
29#include <media/tuner.h>
30#include <media/cx2341x.h>
31#include <media/v4l2-common.h>
32
33MODULE_DESCRIPTION("cx23415/6 driver");
34MODULE_AUTHOR("Hans Verkuil");
35MODULE_LICENSE("GPL");
36
37static int debug;
38module_param(debug, int, 0644);
39MODULE_PARM_DESC(debug, "Debug level (0-1)");
40
41const 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,
76 0
77};
78EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
79
80static const struct cx2341x_mpeg_params default_params = {
81
82 .capabilities = 0,
83 .port = CX2341X_PORT_MEMORY,
84 .width = 720,
85 .height = 480,
86 .is_50hz = 0,
87
88
89 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
90 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
91 .stream_insert_nav_packets = 0,
92
93
94 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
95 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
96 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
97 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
98 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
99 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
100 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
101 .audio_mute = 0,
102
103
104 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
105 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
106 .video_b_frames = 2,
107 .video_gop_size = 12,
108 .video_gop_closure = 1,
109 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
110 .video_bitrate = 6000000,
111 .video_bitrate_peak = 8000000,
112 .video_temporal_decimation = 0,
113 .video_mute = 0,
114 .video_mute_yuv = 0x008080,
115
116
117 .video_spatial_filter_mode =
118 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
119 .video_spatial_filter = 0,
120 .video_luma_spatial_filter_type =
121 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
122 .video_chroma_spatial_filter_type =
123 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
124 .video_temporal_filter_mode =
125 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
126 .video_temporal_filter = 8,
127 .video_median_filter_type =
128 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
129 .video_luma_median_filter_top = 255,
130 .video_luma_median_filter_bottom = 0,
131 .video_chroma_median_filter_top = 255,
132 .video_chroma_median_filter_bottom = 0,
133};
134
135
136
137
138static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
139 struct v4l2_ext_control *ctrl)
140{
141 switch (ctrl->id) {
142 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
143 ctrl->value = params->audio_sampling_freq;
144 break;
145 case V4L2_CID_MPEG_AUDIO_ENCODING:
146 ctrl->value = params->audio_encoding;
147 break;
148 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
149 ctrl->value = params->audio_l2_bitrate;
150 break;
151 case V4L2_CID_MPEG_AUDIO_MODE:
152 ctrl->value = params->audio_mode;
153 break;
154 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
155 ctrl->value = params->audio_mode_extension;
156 break;
157 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
158 ctrl->value = params->audio_emphasis;
159 break;
160 case V4L2_CID_MPEG_AUDIO_CRC:
161 ctrl->value = params->audio_crc;
162 break;
163 case V4L2_CID_MPEG_AUDIO_MUTE:
164 ctrl->value = params->audio_mute;
165 break;
166 case V4L2_CID_MPEG_VIDEO_ENCODING:
167 ctrl->value = params->video_encoding;
168 break;
169 case V4L2_CID_MPEG_VIDEO_ASPECT:
170 ctrl->value = params->video_aspect;
171 break;
172 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
173 ctrl->value = params->video_b_frames;
174 break;
175 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
176 ctrl->value = params->video_gop_size;
177 break;
178 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
179 ctrl->value = params->video_gop_closure;
180 break;
181 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
182 ctrl->value = params->video_bitrate_mode;
183 break;
184 case V4L2_CID_MPEG_VIDEO_BITRATE:
185 ctrl->value = params->video_bitrate;
186 break;
187 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
188 ctrl->value = params->video_bitrate_peak;
189 break;
190 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
191 ctrl->value = params->video_temporal_decimation;
192 break;
193 case V4L2_CID_MPEG_VIDEO_MUTE:
194 ctrl->value = params->video_mute;
195 break;
196 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
197 ctrl->value = params->video_mute_yuv;
198 break;
199 case V4L2_CID_MPEG_STREAM_TYPE:
200 ctrl->value = params->stream_type;
201 break;
202 case V4L2_CID_MPEG_STREAM_VBI_FMT:
203 ctrl->value = params->stream_vbi_fmt;
204 break;
205 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
206 ctrl->value = params->video_spatial_filter_mode;
207 break;
208 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
209 ctrl->value = params->video_spatial_filter;
210 break;
211 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
212 ctrl->value = params->video_luma_spatial_filter_type;
213 break;
214 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
215 ctrl->value = params->video_chroma_spatial_filter_type;
216 break;
217 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
218 ctrl->value = params->video_temporal_filter_mode;
219 break;
220 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
221 ctrl->value = params->video_temporal_filter;
222 break;
223 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
224 ctrl->value = params->video_median_filter_type;
225 break;
226 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
227 ctrl->value = params->video_luma_median_filter_top;
228 break;
229 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
230 ctrl->value = params->video_luma_median_filter_bottom;
231 break;
232 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
233 ctrl->value = params->video_chroma_median_filter_top;
234 break;
235 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
236 ctrl->value = params->video_chroma_median_filter_bottom;
237 break;
238 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
239 ctrl->value = params->stream_insert_nav_packets;
240 break;
241 default:
242 return -EINVAL;
243 }
244 return 0;
245}
246
247
248
249static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
250 struct v4l2_ext_control *ctrl)
251{
252 switch (ctrl->id) {
253 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
254 if (busy)
255 return -EBUSY;
256 params->audio_sampling_freq = ctrl->value;
257 break;
258 case V4L2_CID_MPEG_AUDIO_ENCODING:
259 params->audio_encoding = ctrl->value;
260 break;
261 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
262 if (busy)
263 return -EBUSY;
264 params->audio_l2_bitrate = ctrl->value;
265 break;
266 case V4L2_CID_MPEG_AUDIO_MODE:
267 params->audio_mode = ctrl->value;
268 break;
269 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
270 params->audio_mode_extension = ctrl->value;
271 break;
272 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
273 params->audio_emphasis = ctrl->value;
274 break;
275 case V4L2_CID_MPEG_AUDIO_CRC:
276 params->audio_crc = ctrl->value;
277 break;
278 case V4L2_CID_MPEG_AUDIO_MUTE:
279 params->audio_mute = ctrl->value;
280 break;
281 case V4L2_CID_MPEG_VIDEO_ASPECT:
282 params->video_aspect = ctrl->value;
283 break;
284 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
285 int b = ctrl->value + 1;
286 int gop = params->video_gop_size;
287 params->video_b_frames = ctrl->value;
288 params->video_gop_size = b * ((gop + b - 1) / b);
289
290 while (params->video_gop_size > 34)
291 params->video_gop_size -= b;
292 break;
293 }
294 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
295 int b = params->video_b_frames + 1;
296 int gop = ctrl->value;
297 params->video_gop_size = b * ((gop + b - 1) / b);
298
299 while (params->video_gop_size > 34)
300 params->video_gop_size -= b;
301 ctrl->value = params->video_gop_size;
302 break;
303 }
304 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
305 params->video_gop_closure = ctrl->value;
306 break;
307 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
308 if (busy)
309 return -EBUSY;
310
311 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
312 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
313 return -EINVAL;
314 params->video_bitrate_mode = ctrl->value;
315 break;
316 case V4L2_CID_MPEG_VIDEO_BITRATE:
317 if (busy)
318 return -EBUSY;
319 params->video_bitrate = ctrl->value;
320 break;
321 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
322 if (busy)
323 return -EBUSY;
324 params->video_bitrate_peak = ctrl->value;
325 break;
326 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
327 params->video_temporal_decimation = ctrl->value;
328 break;
329 case V4L2_CID_MPEG_VIDEO_MUTE:
330 params->video_mute = (ctrl->value != 0);
331 break;
332 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
333 params->video_mute_yuv = ctrl->value;
334 break;
335 case V4L2_CID_MPEG_STREAM_TYPE:
336 if (busy)
337 return -EBUSY;
338 params->stream_type = ctrl->value;
339 params->video_encoding =
340 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
341 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
342 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
343 V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
344 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
345
346 params->video_bitrate_mode =
347 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
348 break;
349 case V4L2_CID_MPEG_STREAM_VBI_FMT:
350 params->stream_vbi_fmt = ctrl->value;
351 break;
352 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
353 params->video_spatial_filter_mode = ctrl->value;
354 break;
355 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
356 params->video_spatial_filter = ctrl->value;
357 break;
358 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
359 params->video_luma_spatial_filter_type = ctrl->value;
360 break;
361 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
362 params->video_chroma_spatial_filter_type = ctrl->value;
363 break;
364 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
365 params->video_temporal_filter_mode = ctrl->value;
366 break;
367 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
368 params->video_temporal_filter = ctrl->value;
369 break;
370 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
371 params->video_median_filter_type = ctrl->value;
372 break;
373 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
374 params->video_luma_median_filter_top = ctrl->value;
375 break;
376 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
377 params->video_luma_median_filter_bottom = ctrl->value;
378 break;
379 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
380 params->video_chroma_median_filter_top = ctrl->value;
381 break;
382 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
383 params->video_chroma_median_filter_bottom = ctrl->value;
384 break;
385 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
386 params->stream_insert_nav_packets = ctrl->value;
387 break;
388 default:
389 return -EINVAL;
390 }
391 return 0;
392}
393
394static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
395 s32 min, s32 max, s32 step, s32 def)
396{
397 const char *name;
398
399 qctrl->flags = 0;
400 switch (qctrl->id) {
401
402 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
403 name = "Spatial Filter Mode";
404 break;
405 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
406 name = "Spatial Filter";
407 break;
408 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
409 name = "Spatial Luma Filter Type";
410 break;
411 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
412 name = "Spatial Chroma Filter Type";
413 break;
414 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
415 name = "Temporal Filter Mode";
416 break;
417 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
418 name = "Temporal Filter";
419 break;
420 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
421 name = "Median Filter Type";
422 break;
423 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
424 name = "Median Luma Filter Maximum";
425 break;
426 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
427 name = "Median Luma Filter Minimum";
428 break;
429 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
430 name = "Median Chroma Filter Maximum";
431 break;
432 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
433 name = "Median Chroma Filter Minimum";
434 break;
435 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
436 name = "Insert Navigation Packets";
437 break;
438
439 default:
440 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
441 }
442 switch (qctrl->id) {
443 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
444 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
445 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
446 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
447 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
448 qctrl->type = V4L2_CTRL_TYPE_MENU;
449 min = 0;
450 step = 1;
451 break;
452 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
453 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
454 min = 0;
455 max = 1;
456 step = 1;
457 break;
458 default:
459 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
460 break;
461 }
462 switch (qctrl->id) {
463 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
464 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
465 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
466 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
467 break;
468 }
469 qctrl->minimum = min;
470 qctrl->maximum = max;
471 qctrl->step = step;
472 qctrl->default_value = def;
473 qctrl->reserved[0] = qctrl->reserved[1] = 0;
474 snprintf(qctrl->name, sizeof(qctrl->name), name);
475 return 0;
476}
477
478int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
479 struct v4l2_queryctrl *qctrl)
480{
481 int err;
482
483 switch (qctrl->id) {
484 case V4L2_CID_MPEG_AUDIO_ENCODING:
485 return v4l2_ctrl_query_fill(qctrl,
486 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
487 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
488 default_params.audio_encoding);
489
490 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
491 return v4l2_ctrl_query_fill(qctrl,
492 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
493 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
494 default_params.audio_l2_bitrate);
495
496 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
497 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
498 return -EINVAL;
499
500 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
501 err = v4l2_ctrl_query_fill_std(qctrl);
502 if (err == 0 &&
503 params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
504 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
505 return err;
506
507 case V4L2_CID_MPEG_VIDEO_ENCODING:
508
509
510
511 err = v4l2_ctrl_query_fill_std(qctrl);
512 if (err == 0)
513 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
514 return err;
515
516 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
517 err = v4l2_ctrl_query_fill_std(qctrl);
518 if (err == 0 &&
519 params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
520 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
521 return err;
522
523 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
524 err = v4l2_ctrl_query_fill_std(qctrl);
525 if (err == 0 &&
526 params->video_bitrate_mode ==
527 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
528 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
529 return err;
530
531 case V4L2_CID_MPEG_STREAM_VBI_FMT:
532 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
533 return v4l2_ctrl_query_fill_std(qctrl);
534 return cx2341x_ctrl_query_fill(qctrl,
535 V4L2_MPEG_STREAM_VBI_FMT_NONE,
536 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
537 default_params.stream_vbi_fmt);
538
539 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
540 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
541 params->is_50hz ? 12 : 15);
542
543
544 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
545 return cx2341x_ctrl_query_fill(qctrl,
546 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
547 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
548 default_params.video_spatial_filter_mode);
549
550 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
551 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
552 default_params.video_spatial_filter);
553 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
554 if (params->video_spatial_filter_mode ==
555 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
556 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
557 return 0;
558
559 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
560 cx2341x_ctrl_query_fill(qctrl,
561 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
562 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
563 1,
564 default_params.video_luma_spatial_filter_type);
565 if (params->video_spatial_filter_mode ==
566 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
567 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
568 return 0;
569
570 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
571 cx2341x_ctrl_query_fill(qctrl,
572 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
573 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
574 1,
575 default_params.video_chroma_spatial_filter_type);
576 if (params->video_spatial_filter_mode ==
577 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
578 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
579 return 0;
580
581 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
582 return cx2341x_ctrl_query_fill(qctrl,
583 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
584 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
585 default_params.video_temporal_filter_mode);
586
587 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
588 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
589 default_params.video_temporal_filter);
590 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
591 if (params->video_temporal_filter_mode ==
592 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
593 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
594 return 0;
595
596 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
597 return cx2341x_ctrl_query_fill(qctrl,
598 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
599 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
600 default_params.video_median_filter_type);
601
602 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
603 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
604 default_params.video_luma_median_filter_top);
605 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
606 if (params->video_median_filter_type ==
607 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
608 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
609 return 0;
610
611 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
612 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
613 default_params.video_luma_median_filter_bottom);
614 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
615 if (params->video_median_filter_type ==
616 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
617 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
618 return 0;
619
620 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
621 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
622 default_params.video_chroma_median_filter_top);
623 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
624 if (params->video_median_filter_type ==
625 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
626 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
627 return 0;
628
629 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
630 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
631 default_params.video_chroma_median_filter_bottom);
632 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
633 if (params->video_median_filter_type ==
634 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
635 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
636 return 0;
637
638 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
639 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
640 default_params.stream_insert_nav_packets);
641
642 default:
643 return v4l2_ctrl_query_fill_std(qctrl);
644
645 }
646}
647EXPORT_SYMBOL(cx2341x_ctrl_query);
648
649const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
650{
651 static const char *mpeg_stream_type_without_ts[] = {
652 "MPEG-2 Program Stream",
653 "",
654 "MPEG-1 System Stream",
655 "MPEG-2 DVD-compatible Stream",
656 "MPEG-1 VCD-compatible Stream",
657 "MPEG-2 SVCD-compatible Stream",
658 NULL
659 };
660
661 static const char *mpeg_stream_type_with_ts[] = {
662 "MPEG-2 Program Stream",
663 "MPEG-2 Transport Stream",
664 "MPEG-1 System Stream",
665 "MPEG-2 DVD-compatible Stream",
666 "MPEG-1 VCD-compatible Stream",
667 "MPEG-2 SVCD-compatible Stream",
668 NULL
669 };
670
671 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
672 "Manual",
673 "Auto",
674 NULL
675 };
676
677 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
678 "Off",
679 "1D Horizontal",
680 "1D Vertical",
681 "2D H/V Separable",
682 "2D Symmetric non-separable",
683 NULL
684 };
685
686 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
687 "Off",
688 "1D Horizontal",
689 NULL
690 };
691
692 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
693 "Manual",
694 "Auto",
695 NULL
696 };
697
698 static const char *cx2341x_video_median_filter_type_menu[] = {
699 "Off",
700 "Horizontal",
701 "Vertical",
702 "Horizontal/Vertical",
703 "Diagonal",
704 NULL
705 };
706
707 switch (id) {
708 case V4L2_CID_MPEG_STREAM_TYPE:
709 return (p->capabilities & CX2341X_CAP_HAS_TS) ?
710 mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
711 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
712 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
713 return NULL;
714 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
715 return cx2341x_video_spatial_filter_mode_menu;
716 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
717 return cx2341x_video_luma_spatial_filter_type_menu;
718 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
719 return cx2341x_video_chroma_spatial_filter_type_menu;
720 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
721 return cx2341x_video_temporal_filter_mode_menu;
722 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
723 return cx2341x_video_median_filter_type_menu;
724 default:
725 return v4l2_ctrl_get_menu(id);
726 }
727}
728EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
729
730static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
731{
732 params->audio_properties = (params->audio_sampling_freq << 0) |
733 ((3 - params->audio_encoding) << 2) |
734 ((1 + params->audio_l2_bitrate) << 4) |
735 (params->audio_mode << 8) |
736 (params->audio_mode_extension << 10) |
737 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
738 ? 3 : params->audio_emphasis) << 12) |
739 (params->audio_crc << 14);
740}
741
742int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
743 struct v4l2_ext_controls *ctrls, unsigned int cmd)
744{
745 int err = 0;
746 int i;
747
748 if (cmd == VIDIOC_G_EXT_CTRLS) {
749 for (i = 0; i < ctrls->count; i++) {
750 struct v4l2_ext_control *ctrl = ctrls->controls + i;
751
752 err = cx2341x_get_ctrl(params, ctrl);
753 if (err) {
754 ctrls->error_idx = i;
755 break;
756 }
757 }
758 return err;
759 }
760 for (i = 0; i < ctrls->count; i++) {
761 struct v4l2_ext_control *ctrl = ctrls->controls + i;
762 struct v4l2_queryctrl qctrl;
763 const char **menu_items = NULL;
764
765 qctrl.id = ctrl->id;
766 err = cx2341x_ctrl_query(params, &qctrl);
767 if (err)
768 break;
769 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
770 menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
771 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
772 if (err)
773 break;
774 err = cx2341x_set_ctrl(params, busy, ctrl);
775 if (err)
776 break;
777 }
778 if (err == 0 &&
779 params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
780 params->video_bitrate_peak < params->video_bitrate) {
781 err = -ERANGE;
782 ctrls->error_idx = ctrls->count;
783 }
784 if (err)
785 ctrls->error_idx = i;
786 else
787 cx2341x_calc_audio_properties(params);
788 return err;
789}
790EXPORT_SYMBOL(cx2341x_ext_ctrls);
791
792void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
793{
794 *p = default_params;
795 cx2341x_calc_audio_properties(p);
796}
797EXPORT_SYMBOL(cx2341x_fill_defaults);
798
799static int cx2341x_api(void *priv, cx2341x_mbox_func func,
800 u32 cmd, int args, ...)
801{
802 u32 data[CX2341X_MBOX_MAX_DATA];
803 va_list vargs;
804 int i;
805
806 va_start(vargs, args);
807
808 for (i = 0; i < args; i++)
809 data[i] = va_arg(vargs, int);
810 va_end(vargs);
811 return func(priv, cmd, args, 0, data);
812}
813
814#define NEQ(field) (old->field != new->field)
815
816int cx2341x_update(void *priv, cx2341x_mbox_func func,
817 const struct cx2341x_mpeg_params *old,
818 const struct cx2341x_mpeg_params *new)
819{
820 static int mpeg_stream_type[] = {
821 0,
822 1,
823 2,
824 14,
825 11,
826 12,
827 };
828
829 int err = 0;
830 int force = (old == NULL);
831 u16 temporal = new->video_temporal_filter;
832
833 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
834
835 if (force || NEQ(is_50hz)) {
836 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
837 new->is_50hz);
838 if (err) return err;
839 }
840
841 if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
842 u16 w = new->width;
843 u16 h = new->height;
844
845 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
846 w /= 2;
847 h /= 2;
848 }
849 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
850 h, w);
851 if (err) return err;
852 }
853
854 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
855
856
857
858
859
860
861
862
863
864 temporal = 0;
865 }
866
867 if (force || NEQ(stream_type)) {
868 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
869 mpeg_stream_type[new->stream_type]);
870 if (err) return err;
871 }
872 if (force || NEQ(video_aspect)) {
873 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
874 1 + new->video_aspect);
875 if (err) return err;
876 }
877 if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
878 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
879 new->video_gop_size, new->video_b_frames + 1);
880 if (err) return err;
881 }
882 if (force || NEQ(video_gop_closure)) {
883 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
884 new->video_gop_closure);
885 if (err) return err;
886 }
887 if (force || NEQ(audio_properties)) {
888 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
889 1, new->audio_properties);
890 if (err) return err;
891 }
892 if (force || NEQ(audio_mute)) {
893 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
894 new->audio_mute);
895 if (err) return err;
896 }
897 if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
898 NEQ(video_bitrate_peak)) {
899 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
900 new->video_bitrate_mode, new->video_bitrate,
901 new->video_bitrate_peak / 400, 0, 0);
902 if (err) return err;
903 }
904 if (force || NEQ(video_spatial_filter_mode) ||
905 NEQ(video_temporal_filter_mode) ||
906 NEQ(video_median_filter_type)) {
907 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
908 2, new->video_spatial_filter_mode |
909 (new->video_temporal_filter_mode << 1),
910 new->video_median_filter_type);
911 if (err) return err;
912 }
913 if (force || NEQ(video_luma_median_filter_bottom) ||
914 NEQ(video_luma_median_filter_top) ||
915 NEQ(video_chroma_median_filter_bottom) ||
916 NEQ(video_chroma_median_filter_top)) {
917 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
918 new->video_luma_median_filter_bottom,
919 new->video_luma_median_filter_top,
920 new->video_chroma_median_filter_bottom,
921 new->video_chroma_median_filter_top);
922 if (err) return err;
923 }
924 if (force || NEQ(video_luma_spatial_filter_type) ||
925 NEQ(video_chroma_spatial_filter_type)) {
926 err = cx2341x_api(priv, func,
927 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
928 2, new->video_luma_spatial_filter_type,
929 new->video_chroma_spatial_filter_type);
930 if (err) return err;
931 }
932 if (force || NEQ(video_spatial_filter) ||
933 old->video_temporal_filter != temporal) {
934 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
935 2, new->video_spatial_filter, temporal);
936 if (err) return err;
937 }
938 if (force || NEQ(video_temporal_decimation)) {
939 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
940 1, new->video_temporal_decimation);
941 if (err) return err;
942 }
943 if (force || NEQ(video_mute) ||
944 (new->video_mute && NEQ(video_mute_yuv))) {
945 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
946 new->video_mute | (new->video_mute_yuv << 8));
947 if (err) return err;
948 }
949 if (force || NEQ(stream_insert_nav_packets)) {
950 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
951 7, new->stream_insert_nav_packets);
952 if (err) return err;
953 }
954 return 0;
955}
956EXPORT_SYMBOL(cx2341x_update);
957
958static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
959{
960 const char **menu = cx2341x_ctrl_get_menu(p, id);
961 struct v4l2_ext_control ctrl;
962
963 if (menu == NULL)
964 goto invalid;
965 ctrl.id = id;
966 if (cx2341x_get_ctrl(p, &ctrl))
967 goto invalid;
968 while (ctrl.value-- && *menu) menu++;
969 if (*menu == NULL)
970 goto invalid;
971 return *menu;
972
973invalid:
974 return "<invalid>";
975}
976
977void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
978{
979 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
980 int temporal = p->video_temporal_filter;
981
982
983 printk(KERN_INFO "%s: Stream: %s",
984 prefix,
985 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
986 if (p->stream_insert_nav_packets)
987 printk(" (with navigation packets)");
988 printk("\n");
989 printk(KERN_INFO "%s: VBI Format: %s\n",
990 prefix,
991 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
992
993
994 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
995 prefix,
996 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
997 p->is_50hz ? 25 : 30,
998 (p->video_mute) ? " (muted)" : "");
999 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
1000 prefix,
1001 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
1002 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
1003 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
1004 p->video_bitrate);
1005 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
1006 printk(", Peak %d", p->video_bitrate_peak);
1007 printk("\n");
1008 printk(KERN_INFO
1009 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
1010 prefix,
1011 p->video_gop_size, p->video_b_frames,
1012 p->video_gop_closure ? "" : "No ");
1013 if (p->video_temporal_decimation)
1014 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
1015 prefix, p->video_temporal_decimation);
1016
1017
1018 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
1019 prefix,
1020 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
1021 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
1022 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
1023 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1024 p->audio_mute ? " (muted)" : "");
1025 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1026 printk(", %s", cx2341x_menu_item(p,
1027 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
1028 printk(", %s, %s\n",
1029 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1030 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1031
1032
1033 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1034 prefix,
1035 cx2341x_menu_item(p,
1036 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1037 cx2341x_menu_item(p,
1038 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1039 cx2341x_menu_item(p,
1040 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
1041 p->video_spatial_filter);
1042
1043 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
1044 temporal = 0;
1045
1046 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1047 prefix,
1048 cx2341x_menu_item(p,
1049 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
1050 temporal);
1051 printk(KERN_INFO
1052 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1053 prefix,
1054 cx2341x_menu_item(p,
1055 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
1056 p->video_luma_median_filter_bottom,
1057 p->video_luma_median_filter_top,
1058 p->video_chroma_median_filter_bottom,
1059 p->video_chroma_median_filter_top);
1060}
1061EXPORT_SYMBOL(cx2341x_log_status);
1062
1063
1064
1065
1066
1067
1068
1069