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