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