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