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