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