Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux...
[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(qctrl,
512                                            V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
513                                            V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
514                                            V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
515                 if (err == 0)
516                         qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
517                 return err;
518
519         case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
520                 err = v4l2_ctrl_query_fill_std(qctrl);
521                 if (err == 0 &&
522                     params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
523                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
524                 return err;
525
526         case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
527                 err = v4l2_ctrl_query_fill_std(qctrl);
528                 if (err == 0 &&
529                     params->video_bitrate_mode ==
530                                 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
531                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
532                 return err;
533
534         case V4L2_CID_MPEG_STREAM_VBI_FMT:
535                 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
536                         return v4l2_ctrl_query_fill_std(qctrl);
537                 return cx2341x_ctrl_query_fill(qctrl,
538                                 V4L2_MPEG_STREAM_VBI_FMT_NONE,
539                                 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
540                                 default_params.stream_vbi_fmt);
541
542         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
543                 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
544                                 params->is_50hz ? 12 : 15);
545
546         /* CX23415/6 specific */
547         case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
548                 return cx2341x_ctrl_query_fill(qctrl,
549                         V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
550                         V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
551                         default_params.video_spatial_filter_mode);
552
553         case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
554                 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
555                                 default_params.video_spatial_filter);
556                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
557                 if (params->video_spatial_filter_mode ==
558                             V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
559                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
560                 return 0;
561
562         case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
563                 cx2341x_ctrl_query_fill(qctrl,
564                         V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
565                         V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
566                         1,
567                         default_params.video_luma_spatial_filter_type);
568                 if (params->video_spatial_filter_mode ==
569                             V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
570                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
571                 return 0;
572
573         case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
574                 cx2341x_ctrl_query_fill(qctrl,
575                     V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
576                     V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
577                     1,
578                     default_params.video_chroma_spatial_filter_type);
579                 if (params->video_spatial_filter_mode ==
580                         V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
581                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
582                 return 0;
583
584         case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
585                 return cx2341x_ctrl_query_fill(qctrl,
586                         V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
587                         V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
588                         default_params.video_temporal_filter_mode);
589
590         case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
591                 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
592                                 default_params.video_temporal_filter);
593                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
594                 if (params->video_temporal_filter_mode ==
595                         V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
596                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
597                 return 0;
598
599         case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
600                 return cx2341x_ctrl_query_fill(qctrl,
601                         V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
602                         V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
603                         default_params.video_median_filter_type);
604
605         case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
606                 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
607                                 default_params.video_luma_median_filter_top);
608                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
609                 if (params->video_median_filter_type ==
610                                 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
611                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
612                 return 0;
613
614         case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
615                 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
616                                 default_params.video_luma_median_filter_bottom);
617                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
618                 if (params->video_median_filter_type ==
619                                 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
620                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
621                 return 0;
622
623         case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
624                 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
625                                 default_params.video_chroma_median_filter_top);
626                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
627                 if (params->video_median_filter_type ==
628                                 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
629                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
630                 return 0;
631
632         case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
633                 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
634                         default_params.video_chroma_median_filter_bottom);
635                 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
636                 if (params->video_median_filter_type ==
637                                 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
638                         qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
639                 return 0;
640
641         case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
642                 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
643                                 default_params.stream_insert_nav_packets);
644
645         default:
646                 return v4l2_ctrl_query_fill_std(qctrl);
647
648         }
649 }
650 EXPORT_SYMBOL(cx2341x_ctrl_query);
651
652 const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
653 {
654         static const char *mpeg_stream_type_without_ts[] = {
655                 "MPEG-2 Program Stream",
656                 "",
657                 "MPEG-1 System Stream",
658                 "MPEG-2 DVD-compatible Stream",
659                 "MPEG-1 VCD-compatible Stream",
660                 "MPEG-2 SVCD-compatible Stream",
661                 NULL
662         };
663
664         static const char *mpeg_stream_type_with_ts[] = {
665                 "MPEG-2 Program Stream",
666                 "MPEG-2 Transport Stream",
667                 "MPEG-1 System Stream",
668                 "MPEG-2 DVD-compatible Stream",
669                 "MPEG-1 VCD-compatible Stream",
670                 "MPEG-2 SVCD-compatible Stream",
671                 NULL
672         };
673
674         static const char *cx2341x_video_spatial_filter_mode_menu[] = {
675                 "Manual",
676                 "Auto",
677                 NULL
678         };
679
680         static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
681                 "Off",
682                 "1D Horizontal",
683                 "1D Vertical",
684                 "2D H/V Separable",
685                 "2D Symmetric non-separable",
686                 NULL
687         };
688
689         static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
690                 "Off",
691                 "1D Horizontal",
692                 NULL
693         };
694
695         static const char *cx2341x_video_temporal_filter_mode_menu[] = {
696                 "Manual",
697                 "Auto",
698                 NULL
699         };
700
701         static const char *cx2341x_video_median_filter_type_menu[] = {
702                 "Off",
703                 "Horizontal",
704                 "Vertical",
705                 "Horizontal/Vertical",
706                 "Diagonal",
707                 NULL
708         };
709
710         switch (id) {
711         case V4L2_CID_MPEG_STREAM_TYPE:
712                 return (p->capabilities & CX2341X_CAP_HAS_TS) ?
713                         mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
714         case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
715         case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
716                 return NULL;
717         case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
718                 return cx2341x_video_spatial_filter_mode_menu;
719         case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
720                 return cx2341x_video_luma_spatial_filter_type_menu;
721         case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
722                 return cx2341x_video_chroma_spatial_filter_type_menu;
723         case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
724                 return cx2341x_video_temporal_filter_mode_menu;
725         case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
726                 return cx2341x_video_median_filter_type_menu;
727         default:
728                 return v4l2_ctrl_get_menu(id);
729         }
730 }
731 EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
732
733 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
734 {
735         params->audio_properties = (params->audio_sampling_freq << 0) |
736                 ((3 - params->audio_encoding) << 2) |
737                 ((1 + params->audio_l2_bitrate) << 4) |
738                 (params->audio_mode << 8) |
739                 (params->audio_mode_extension << 10) |
740                 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
741                   ? 3 : params->audio_emphasis) << 12) |
742                 (params->audio_crc << 14);
743 }
744
745 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
746                   struct v4l2_ext_controls *ctrls, unsigned int cmd)
747 {
748         int err = 0;
749         int i;
750
751         if (cmd == VIDIOC_G_EXT_CTRLS) {
752                 for (i = 0; i < ctrls->count; i++) {
753                         struct v4l2_ext_control *ctrl = ctrls->controls + i;
754
755                         err = cx2341x_get_ctrl(params, ctrl);
756                         if (err) {
757                                 ctrls->error_idx = i;
758                                 break;
759                         }
760                 }
761                 return err;
762         }
763         for (i = 0; i < ctrls->count; i++) {
764                 struct v4l2_ext_control *ctrl = ctrls->controls + i;
765                 struct v4l2_queryctrl qctrl;
766                 const char **menu_items = NULL;
767
768                 qctrl.id = ctrl->id;
769                 err = cx2341x_ctrl_query(params, &qctrl);
770                 if (err)
771                         break;
772                 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
773                         menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
774                 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
775                 if (err)
776                         break;
777                 err = cx2341x_set_ctrl(params, busy, ctrl);
778                 if (err)
779                         break;
780         }
781         if (err == 0 &&
782             params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
783             params->video_bitrate_peak < params->video_bitrate) {
784                 err = -ERANGE;
785                 ctrls->error_idx = ctrls->count;
786         }
787         if (err)
788                 ctrls->error_idx = i;
789         else
790                 cx2341x_calc_audio_properties(params);
791         return err;
792 }
793 EXPORT_SYMBOL(cx2341x_ext_ctrls);
794
795 void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
796 {
797         *p = default_params;
798         cx2341x_calc_audio_properties(p);
799 }
800 EXPORT_SYMBOL(cx2341x_fill_defaults);
801
802 static int cx2341x_api(void *priv, cx2341x_mbox_func func,
803                        u32 cmd, int args, ...)
804 {
805         u32 data[CX2341X_MBOX_MAX_DATA];
806         va_list vargs;
807         int i;
808
809         va_start(vargs, args);
810
811         for (i = 0; i < args; i++)
812                 data[i] = va_arg(vargs, int);
813         va_end(vargs);
814         return func(priv, cmd, args, 0, data);
815 }
816
817 #define NEQ(field) (old->field != new->field)
818
819 int cx2341x_update(void *priv, cx2341x_mbox_func func,
820                    const struct cx2341x_mpeg_params *old,
821                    const struct cx2341x_mpeg_params *new)
822 {
823         static int mpeg_stream_type[] = {
824                 0,      /* MPEG-2 PS */
825                 1,      /* MPEG-2 TS */
826                 2,      /* MPEG-1 SS */
827                 14,     /* DVD */
828                 11,     /* VCD */
829                 12,     /* SVCD */
830         };
831
832         int err = 0;
833         int force = (old == NULL);
834         u16 temporal = new->video_temporal_filter;
835
836         cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
837
838         if (force || NEQ(is_50hz)) {
839                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
840                                   new->is_50hz);
841                 if (err) return err;
842         }
843
844         if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
845                 u16 w = new->width;
846                 u16 h = new->height;
847
848                 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
849                         w /= 2;
850                         h /= 2;
851                 }
852                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
853                                   h, w);
854                 if (err) return err;
855         }
856
857         if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
858                 /* Adjust temporal filter if necessary. The problem with the
859                    temporal filter is that it works well with full resolution
860                    capturing, but not when the capture window is scaled (the
861                    filter introduces a ghosting effect). So if the capture
862                    window is scaled, then force the filter to 0.
863
864                    For full resolution the filter really improves the video
865                    quality, especially if the original video quality is
866                    suboptimal. */
867                 temporal = 0;
868         }
869
870         if (force || NEQ(stream_type)) {
871                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
872                                   mpeg_stream_type[new->stream_type]);
873                 if (err) return err;
874         }
875         if (force || NEQ(video_aspect)) {
876                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
877                                   1 + new->video_aspect);
878                 if (err) return err;
879         }
880         if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
881                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
882                                 new->video_gop_size, new->video_b_frames + 1);
883                 if (err) return err;
884         }
885         if (force || NEQ(video_gop_closure)) {
886                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
887                                   new->video_gop_closure);
888                 if (err) return err;
889         }
890         if (force || NEQ(audio_properties)) {
891                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
892                                   1, new->audio_properties);
893                 if (err) return err;
894         }
895         if (force || NEQ(audio_mute)) {
896                 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
897                                   new->audio_mute);
898                 if (err) return err;
899         }
900         if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
901                                                 NEQ(video_bitrate_peak)) {
902                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
903                                 new->video_bitrate_mode, new->video_bitrate,
904                                 new->video_bitrate_peak / 400, 0, 0);
905                 if (err) return err;
906         }
907         if (force || NEQ(video_spatial_filter_mode) ||
908                      NEQ(video_temporal_filter_mode) ||
909                      NEQ(video_median_filter_type)) {
910                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
911                                   2, new->video_spatial_filter_mode |
912                                         (new->video_temporal_filter_mode << 1),
913                                 new->video_median_filter_type);
914                 if (err) return err;
915         }
916         if (force || NEQ(video_luma_median_filter_bottom) ||
917                      NEQ(video_luma_median_filter_top) ||
918                      NEQ(video_chroma_median_filter_bottom) ||
919                      NEQ(video_chroma_median_filter_top)) {
920                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
921                                 new->video_luma_median_filter_bottom,
922                                 new->video_luma_median_filter_top,
923                                 new->video_chroma_median_filter_bottom,
924                                 new->video_chroma_median_filter_top);
925                 if (err) return err;
926         }
927         if (force || NEQ(video_luma_spatial_filter_type) ||
928                      NEQ(video_chroma_spatial_filter_type)) {
929                 err = cx2341x_api(priv, func,
930                                   CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
931                                   2, new->video_luma_spatial_filter_type,
932                                   new->video_chroma_spatial_filter_type);
933                 if (err) return err;
934         }
935         if (force || NEQ(video_spatial_filter) ||
936                      old->video_temporal_filter != temporal) {
937                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
938                                   2, new->video_spatial_filter, temporal);
939                 if (err) return err;
940         }
941         if (force || NEQ(video_temporal_decimation)) {
942                 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
943                                   1, new->video_temporal_decimation);
944                 if (err) return err;
945         }
946         if (force || NEQ(video_mute) ||
947                 (new->video_mute && NEQ(video_mute_yuv))) {
948                 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
949                                 new->video_mute | (new->video_mute_yuv << 8));
950                 if (err) return err;
951         }
952         if (force || NEQ(stream_insert_nav_packets)) {
953                 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
954                                 7, new->stream_insert_nav_packets);
955                 if (err) return err;
956         }
957         return 0;
958 }
959 EXPORT_SYMBOL(cx2341x_update);
960
961 static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
962 {
963         const char **menu = cx2341x_ctrl_get_menu(p, id);
964         struct v4l2_ext_control ctrl;
965
966         if (menu == NULL)
967                 goto invalid;
968         ctrl.id = id;
969         if (cx2341x_get_ctrl(p, &ctrl))
970                 goto invalid;
971         while (ctrl.value-- && *menu) menu++;
972         if (*menu == NULL)
973                 goto invalid;
974         return *menu;
975
976 invalid:
977         return "<invalid>";
978 }
979
980 void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
981 {
982         int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
983         int temporal = p->video_temporal_filter;
984
985         /* Stream */
986         printk(KERN_INFO "%s: Stream: %s",
987                 prefix,
988                 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
989         if (p->stream_insert_nav_packets)
990                 printk(" (with navigation packets)");
991         printk("\n");
992         printk(KERN_INFO "%s: VBI Format: %s\n",
993                 prefix,
994                 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
995
996         /* Video */
997         printk(KERN_INFO "%s: Video:  %dx%d, %d fps%s\n",
998                 prefix,
999                 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
1000                 p->is_50hz ? 25 : 30,
1001                 (p->video_mute) ? " (muted)" : "");
1002         printk(KERN_INFO "%s: Video:  %s, %s, %s, %d",
1003                 prefix,
1004                 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
1005                 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
1006                 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
1007                 p->video_bitrate);
1008         if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
1009                 printk(", Peak %d", p->video_bitrate_peak);
1010         printk("\n");
1011         printk(KERN_INFO
1012                 "%s: Video:  GOP Size %d, %d B-Frames, %sGOP Closure\n",
1013                 prefix,
1014                 p->video_gop_size, p->video_b_frames,
1015                 p->video_gop_closure ? "" : "No ");
1016         if (p->video_temporal_decimation)
1017                 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
1018                         prefix, p->video_temporal_decimation);
1019
1020         /* Audio */
1021         printk(KERN_INFO "%s: Audio:  %s, %s, %s, %s%s",
1022                 prefix,
1023                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
1024                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
1025                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
1026                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1027                 p->audio_mute ? " (muted)" : "");
1028         if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1029                 printk(", %s", cx2341x_menu_item(p,
1030                                 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
1031         printk(", %s, %s\n",
1032                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1033                 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1034
1035         /* Encoding filters */
1036         printk(KERN_INFO "%s: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
1037                 prefix,
1038                 cx2341x_menu_item(p,
1039                     V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1040                 cx2341x_menu_item(p,
1041                     V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1042                 cx2341x_menu_item(p,
1043                     V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
1044                 p->video_spatial_filter);
1045
1046         if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
1047                 temporal = 0;
1048
1049         printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1050                 prefix,
1051                 cx2341x_menu_item(p,
1052                         V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
1053                 temporal);
1054         printk(KERN_INFO
1055                 "%s: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
1056                 prefix,
1057                 cx2341x_menu_item(p,
1058                         V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
1059                 p->video_luma_median_filter_bottom,
1060                 p->video_luma_median_filter_top,
1061                 p->video_chroma_median_filter_bottom,
1062                 p->video_chroma_median_filter_top);
1063 }
1064 EXPORT_SYMBOL(cx2341x_log_status);
1065
1066 /*
1067  * Local variables:
1068  * c-basic-offset: 8
1069  * End:
1070  */
1071