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