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