blob: 6f4821616f753b534a46ef5869ce456a43f5113c [file] [log] [blame]
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001/*
Andy Walls0d82fe82009-01-01 19:02:31 -03002 * cx2341x - generic code for cx23415/6/8 based devices
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03003 *
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>
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -030023#include <linux/errno.h>
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/types.h>
27#include <linux/videodev2.h>
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -030028
29#include <media/tuner.h>
30#include <media/cx2341x.h>
31#include <media/v4l2-common.h>
32
Andy Walls0d82fe82009-01-01 19:02:31 -030033MODULE_DESCRIPTION("cx23415/6/8 driver");
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -030034MODULE_AUTHOR("Hans Verkuil");
35MODULE_LICENSE("GPL");
36
Hans Verkuil737bd412007-11-01 13:38:12 -030037static int debug;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -030038module_param(debug, int, 0644);
39MODULE_PARM_DESC(debug, "Debug level (0-1)");
40
Hans Verkuilcc7bc642006-06-19 17:53:08 -030041const u32 cx2341x_mpeg_ctrls[] = {
42 V4L2_CID_MPEG_CLASS,
43 V4L2_CID_MPEG_STREAM_TYPE,
Hans Verkuil8cbde942006-06-24 14:36:02 -030044 V4L2_CID_MPEG_STREAM_VBI_FMT,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030045 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
46 V4L2_CID_MPEG_AUDIO_ENCODING,
47 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
Andy Walls0d82fe82009-01-01 19:02:31 -030048 V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030049 V4L2_CID_MPEG_AUDIO_MODE,
50 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
51 V4L2_CID_MPEG_AUDIO_EMPHASIS,
52 V4L2_CID_MPEG_AUDIO_CRC,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030053 V4L2_CID_MPEG_AUDIO_MUTE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030054 V4L2_CID_MPEG_VIDEO_ENCODING,
55 V4L2_CID_MPEG_VIDEO_ASPECT,
56 V4L2_CID_MPEG_VIDEO_B_FRAMES,
57 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
58 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030059 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
60 V4L2_CID_MPEG_VIDEO_BITRATE,
61 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
62 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030063 V4L2_CID_MPEG_VIDEO_MUTE,
64 V4L2_CID_MPEG_VIDEO_MUTE_YUV,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030065 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
66 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
67 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
68 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
69 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
70 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
71 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
72 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
73 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
74 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
75 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030076 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030077 0
78};
Hans Verkuil737bd412007-11-01 13:38:12 -030079EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
Hans Verkuilcc7bc642006-06-19 17:53:08 -030080
Hans Verkuilca130ee2008-07-17 12:26:45 -030081static const struct cx2341x_mpeg_params default_params = {
82 /* misc */
83 .capabilities = 0,
84 .port = CX2341X_PORT_MEMORY,
85 .width = 720,
86 .height = 480,
87 .is_50hz = 0,
88
89 /* stream */
90 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
91 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
92 .stream_insert_nav_packets = 0,
93
94 /* audio */
95 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
96 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
97 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
Andy Walls0d82fe82009-01-01 19:02:31 -030098 .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
Hans Verkuilca130ee2008-07-17 12:26:45 -030099 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
100 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
101 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
102 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
103 .audio_mute = 0,
104
105 /* video */
106 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
107 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
108 .video_b_frames = 2,
109 .video_gop_size = 12,
110 .video_gop_closure = 1,
111 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
112 .video_bitrate = 6000000,
113 .video_bitrate_peak = 8000000,
114 .video_temporal_decimation = 0,
115 .video_mute = 0,
116 .video_mute_yuv = 0x008080, /* YCbCr value for black */
117
118 /* encoding filters */
119 .video_spatial_filter_mode =
120 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
121 .video_spatial_filter = 0,
122 .video_luma_spatial_filter_type =
123 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
124 .video_chroma_spatial_filter_type =
125 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
126 .video_temporal_filter_mode =
127 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
128 .video_temporal_filter = 8,
129 .video_median_filter_type =
130 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
131 .video_luma_median_filter_top = 255,
132 .video_luma_median_filter_bottom = 0,
133 .video_chroma_median_filter_top = 255,
134 .video_chroma_median_filter_bottom = 0,
135};
136
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300137
138/* Map the control ID to the correct field in the cx2341x_mpeg_params
139 struct. Return -EINVAL if the ID is unknown, else return 0. */
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300140static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300141 struct v4l2_ext_control *ctrl)
142{
143 switch (ctrl->id) {
144 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
145 ctrl->value = params->audio_sampling_freq;
146 break;
147 case V4L2_CID_MPEG_AUDIO_ENCODING:
148 ctrl->value = params->audio_encoding;
149 break;
150 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
151 ctrl->value = params->audio_l2_bitrate;
152 break;
Andy Walls0d82fe82009-01-01 19:02:31 -0300153 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
154 ctrl->value = params->audio_ac3_bitrate;
155 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300156 case V4L2_CID_MPEG_AUDIO_MODE:
157 ctrl->value = params->audio_mode;
158 break;
159 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
160 ctrl->value = params->audio_mode_extension;
161 break;
162 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
163 ctrl->value = params->audio_emphasis;
164 break;
165 case V4L2_CID_MPEG_AUDIO_CRC:
166 ctrl->value = params->audio_crc;
167 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300168 case V4L2_CID_MPEG_AUDIO_MUTE:
169 ctrl->value = params->audio_mute;
170 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300171 case V4L2_CID_MPEG_VIDEO_ENCODING:
172 ctrl->value = params->video_encoding;
173 break;
174 case V4L2_CID_MPEG_VIDEO_ASPECT:
175 ctrl->value = params->video_aspect;
176 break;
177 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
178 ctrl->value = params->video_b_frames;
179 break;
180 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
181 ctrl->value = params->video_gop_size;
182 break;
183 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
184 ctrl->value = params->video_gop_closure;
185 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300186 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
187 ctrl->value = params->video_bitrate_mode;
188 break;
189 case V4L2_CID_MPEG_VIDEO_BITRATE:
190 ctrl->value = params->video_bitrate;
191 break;
192 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
193 ctrl->value = params->video_bitrate_peak;
194 break;
195 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
196 ctrl->value = params->video_temporal_decimation;
197 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300198 case V4L2_CID_MPEG_VIDEO_MUTE:
199 ctrl->value = params->video_mute;
200 break;
201 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
202 ctrl->value = params->video_mute_yuv;
203 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300204 case V4L2_CID_MPEG_STREAM_TYPE:
205 ctrl->value = params->stream_type;
206 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300207 case V4L2_CID_MPEG_STREAM_VBI_FMT:
208 ctrl->value = params->stream_vbi_fmt;
209 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300210 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
211 ctrl->value = params->video_spatial_filter_mode;
212 break;
213 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
214 ctrl->value = params->video_spatial_filter;
215 break;
216 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
217 ctrl->value = params->video_luma_spatial_filter_type;
218 break;
219 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
220 ctrl->value = params->video_chroma_spatial_filter_type;
221 break;
222 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
223 ctrl->value = params->video_temporal_filter_mode;
224 break;
225 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
226 ctrl->value = params->video_temporal_filter;
227 break;
228 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
229 ctrl->value = params->video_median_filter_type;
230 break;
231 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
232 ctrl->value = params->video_luma_median_filter_top;
233 break;
234 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
235 ctrl->value = params->video_luma_median_filter_bottom;
236 break;
237 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
238 ctrl->value = params->video_chroma_median_filter_top;
239 break;
240 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
241 ctrl->value = params->video_chroma_median_filter_bottom;
242 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300243 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
244 ctrl->value = params->stream_insert_nav_packets;
245 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300246 default:
247 return -EINVAL;
248 }
249 return 0;
250}
251
252/* Map the control ID to the correct field in the cx2341x_mpeg_params
253 struct. Return -EINVAL if the ID is unknown, else return 0. */
Hans Verkuil01f1e442007-08-21 18:32:42 -0300254static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300255 struct v4l2_ext_control *ctrl)
256{
257 switch (ctrl->id) {
258 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300259 if (busy)
260 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300261 params->audio_sampling_freq = ctrl->value;
262 break;
263 case V4L2_CID_MPEG_AUDIO_ENCODING:
Andy Walls0d82fe82009-01-01 19:02:31 -0300264 if (busy)
265 return -EBUSY;
Andy Walls31230c52009-01-03 14:21:30 -0300266 if (params->capabilities & CX2341X_CAP_HAS_AC3)
267 if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
268 ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
269 return -ERANGE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300270 params->audio_encoding = ctrl->value;
271 break;
272 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300273 if (busy)
274 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300275 params->audio_l2_bitrate = ctrl->value;
276 break;
Andy Walls0d82fe82009-01-01 19:02:31 -0300277 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
278 if (busy)
279 return -EBUSY;
Andy Walls31230c52009-01-03 14:21:30 -0300280 if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
281 return -EINVAL;
Andy Walls0d82fe82009-01-01 19:02:31 -0300282 params->audio_ac3_bitrate = ctrl->value;
283 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300284 case V4L2_CID_MPEG_AUDIO_MODE:
285 params->audio_mode = ctrl->value;
286 break;
287 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
288 params->audio_mode_extension = ctrl->value;
289 break;
290 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
291 params->audio_emphasis = ctrl->value;
292 break;
293 case V4L2_CID_MPEG_AUDIO_CRC:
294 params->audio_crc = ctrl->value;
295 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300296 case V4L2_CID_MPEG_AUDIO_MUTE:
297 params->audio_mute = ctrl->value;
298 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300299 case V4L2_CID_MPEG_VIDEO_ASPECT:
300 params->video_aspect = ctrl->value;
301 break;
302 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
303 int b = ctrl->value + 1;
304 int gop = params->video_gop_size;
305 params->video_b_frames = ctrl->value;
306 params->video_gop_size = b * ((gop + b - 1) / b);
307 /* Max GOP size = 34 */
308 while (params->video_gop_size > 34)
309 params->video_gop_size -= b;
310 break;
311 }
312 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
313 int b = params->video_b_frames + 1;
314 int gop = ctrl->value;
315 params->video_gop_size = b * ((gop + b - 1) / b);
316 /* Max GOP size = 34 */
317 while (params->video_gop_size > 34)
318 params->video_gop_size -= b;
319 ctrl->value = params->video_gop_size;
320 break;
321 }
322 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
323 params->video_gop_closure = ctrl->value;
324 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300325 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300326 if (busy)
327 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300328 /* MPEG-1 only allows CBR */
329 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
330 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
331 return -EINVAL;
332 params->video_bitrate_mode = ctrl->value;
333 break;
334 case V4L2_CID_MPEG_VIDEO_BITRATE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300335 if (busy)
336 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300337 params->video_bitrate = ctrl->value;
338 break;
339 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300340 if (busy)
341 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300342 params->video_bitrate_peak = ctrl->value;
343 break;
344 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
345 params->video_temporal_decimation = ctrl->value;
346 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300347 case V4L2_CID_MPEG_VIDEO_MUTE:
348 params->video_mute = (ctrl->value != 0);
349 break;
350 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
351 params->video_mute_yuv = ctrl->value;
352 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300353 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300354 if (busy)
355 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300356 params->stream_type = ctrl->value;
357 params->video_encoding =
Hans Verkuil737bd412007-11-01 13:38:12 -0300358 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
359 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
360 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
361 V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
362 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300363 /* MPEG-1 implies CBR */
Hans Verkuil737bd412007-11-01 13:38:12 -0300364 params->video_bitrate_mode =
365 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300366 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300367 case V4L2_CID_MPEG_STREAM_VBI_FMT:
368 params->stream_vbi_fmt = ctrl->value;
369 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300370 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
371 params->video_spatial_filter_mode = ctrl->value;
372 break;
373 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
374 params->video_spatial_filter = ctrl->value;
375 break;
376 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
377 params->video_luma_spatial_filter_type = ctrl->value;
378 break;
379 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
380 params->video_chroma_spatial_filter_type = ctrl->value;
381 break;
382 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
383 params->video_temporal_filter_mode = ctrl->value;
384 break;
385 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
386 params->video_temporal_filter = ctrl->value;
387 break;
388 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
389 params->video_median_filter_type = ctrl->value;
390 break;
391 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
392 params->video_luma_median_filter_top = ctrl->value;
393 break;
394 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
395 params->video_luma_median_filter_bottom = ctrl->value;
396 break;
397 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
398 params->video_chroma_median_filter_top = ctrl->value;
399 break;
400 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
401 params->video_chroma_median_filter_bottom = ctrl->value;
402 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300403 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
404 params->stream_insert_nav_packets = ctrl->value;
405 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300406 default:
407 return -EINVAL;
408 }
409 return 0;
410}
411
Hans Verkuil737bd412007-11-01 13:38:12 -0300412static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
413 s32 min, s32 max, s32 step, s32 def)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300414{
415 const char *name;
416
417 qctrl->flags = 0;
418 switch (qctrl->id) {
419 /* MPEG controls */
420 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
421 name = "Spatial Filter Mode";
422 break;
423 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
424 name = "Spatial Filter";
425 break;
426 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
427 name = "Spatial Luma Filter Type";
428 break;
429 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
430 name = "Spatial Chroma Filter Type";
431 break;
432 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
433 name = "Temporal Filter Mode";
434 break;
435 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
436 name = "Temporal Filter";
437 break;
438 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
439 name = "Median Filter Type";
440 break;
441 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
442 name = "Median Luma Filter Maximum";
443 break;
444 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
445 name = "Median Luma Filter Minimum";
446 break;
447 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
448 name = "Median Chroma Filter Maximum";
449 break;
450 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
451 name = "Median Chroma Filter Minimum";
452 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300453 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
454 name = "Insert Navigation Packets";
455 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300456
457 default:
458 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
459 }
460 switch (qctrl->id) {
461 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
462 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
463 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
464 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
465 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
466 qctrl->type = V4L2_CTRL_TYPE_MENU;
467 min = 0;
468 step = 1;
469 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300470 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
471 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
472 min = 0;
473 max = 1;
474 step = 1;
475 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300476 default:
477 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
478 break;
479 }
480 switch (qctrl->id) {
481 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
482 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
483 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
484 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
485 break;
486 }
487 qctrl->minimum = min;
488 qctrl->maximum = max;
489 qctrl->step = step;
490 qctrl->default_value = def;
491 qctrl->reserved[0] = qctrl->reserved[1] = 0;
492 snprintf(qctrl->name, sizeof(qctrl->name), name);
493 return 0;
494}
495
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300496int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
Hans Verkuil737bd412007-11-01 13:38:12 -0300497 struct v4l2_queryctrl *qctrl)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300498{
499 int err;
500
501 switch (qctrl->id) {
502 case V4L2_CID_MPEG_AUDIO_ENCODING:
Andy Walls31230c52009-01-03 14:21:30 -0300503 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
504 /*
505 * The state of L2 & AC3 bitrate controls can change
506 * when this control changes, but v4l2_ctrl_query_fill()
507 * already sets V4L2_CTRL_FLAG_UPDATE for
508 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
509 */
Andy Walls0d82fe82009-01-01 19:02:31 -0300510 return v4l2_ctrl_query_fill(qctrl,
511 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
512 V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
513 default_params.audio_encoding);
Andy Walls31230c52009-01-03 14:21:30 -0300514 }
Andy Walls0d82fe82009-01-01 19:02:31 -0300515
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300516 return v4l2_ctrl_query_fill(qctrl,
517 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
518 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300519 default_params.audio_encoding);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300520
521 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300522 err = v4l2_ctrl_query_fill(qctrl,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300523 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
524 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300525 default_params.audio_l2_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300526 if (err)
527 return err;
528 if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
529 params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
530 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
531 return 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300532
533 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
534 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
535 return -EINVAL;
536
Andy Walls0d82fe82009-01-01 19:02:31 -0300537 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300538 err = v4l2_ctrl_query_fill(qctrl,
Andy Walls0d82fe82009-01-01 19:02:31 -0300539 V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
540 V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
541 default_params.audio_ac3_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300542 if (err)
543 return err;
544 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
545 if (params->audio_encoding !=
546 V4L2_MPEG_AUDIO_ENCODING_AC3)
547 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
548 } else
549 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
550 return 0;
Andy Walls0d82fe82009-01-01 19:02:31 -0300551
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300552 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
553 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300554 if (err == 0 &&
555 params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300556 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
557 return err;
558
559 case V4L2_CID_MPEG_VIDEO_ENCODING:
560 /* this setting is read-only for the cx2341x since the
561 V4L2_CID_MPEG_STREAM_TYPE really determines the
562 MPEG-1/2 setting */
Janne Grunau188919a2008-08-08 07:21:00 -0300563 err = v4l2_ctrl_query_fill(qctrl,
564 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
565 V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
566 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300567 if (err == 0)
568 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
569 return err;
570
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300571 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
572 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300573 if (err == 0 &&
574 params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300575 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
576 return err;
577
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300578 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
579 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300580 if (err == 0 &&
581 params->video_bitrate_mode ==
582 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300583 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
584 return err;
585
Hans Verkuil8cbde942006-06-24 14:36:02 -0300586 case V4L2_CID_MPEG_STREAM_VBI_FMT:
587 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
588 return v4l2_ctrl_query_fill_std(qctrl);
589 return cx2341x_ctrl_query_fill(qctrl,
590 V4L2_MPEG_STREAM_VBI_FMT_NONE,
591 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300592 default_params.stream_vbi_fmt);
593
594 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
595 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
596 params->is_50hz ? 12 : 15);
Hans Verkuil8cbde942006-06-24 14:36:02 -0300597
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300598 /* CX23415/6 specific */
599 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
600 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300601 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
602 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300603 default_params.video_spatial_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300604
605 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300606 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
607 default_params.video_spatial_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300608 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300609 if (params->video_spatial_filter_mode ==
610 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
611 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300612 return 0;
613
614 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
615 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300616 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
617 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
618 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300619 default_params.video_luma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300620 if (params->video_spatial_filter_mode ==
621 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
622 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300623 return 0;
624
625 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
626 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300627 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
628 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
629 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300630 default_params.video_chroma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300631 if (params->video_spatial_filter_mode ==
632 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
633 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300634 return 0;
635
636 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
637 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300638 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
639 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300640 default_params.video_temporal_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300641
642 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300643 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
644 default_params.video_temporal_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300645 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300646 if (params->video_temporal_filter_mode ==
647 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
648 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300649 return 0;
650
651 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
652 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300653 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
654 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300655 default_params.video_median_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300656
657 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300658 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
659 default_params.video_luma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300660 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300661 if (params->video_median_filter_type ==
662 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
663 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300664 return 0;
665
666 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300667 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
668 default_params.video_luma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300669 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300670 if (params->video_median_filter_type ==
671 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
672 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300673 return 0;
674
675 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300676 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
677 default_params.video_chroma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300678 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300679 if (params->video_median_filter_type ==
680 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
681 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300682 return 0;
683
684 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300685 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
686 default_params.video_chroma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300687 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300688 if (params->video_median_filter_type ==
689 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
690 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300691 return 0;
692
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300693 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300694 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
695 default_params.stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300696
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300697 default:
698 return v4l2_ctrl_query_fill_std(qctrl);
699
700 }
701}
Hans Verkuil737bd412007-11-01 13:38:12 -0300702EXPORT_SYMBOL(cx2341x_ctrl_query);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300703
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300704const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300705{
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300706 static const char *mpeg_stream_type_without_ts[] = {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300707 "MPEG-2 Program Stream",
708 "",
709 "MPEG-1 System Stream",
710 "MPEG-2 DVD-compatible Stream",
711 "MPEG-1 VCD-compatible Stream",
712 "MPEG-2 SVCD-compatible Stream",
713 NULL
714 };
715
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300716 static const char *mpeg_stream_type_with_ts[] = {
717 "MPEG-2 Program Stream",
718 "MPEG-2 Transport Stream",
719 "MPEG-1 System Stream",
720 "MPEG-2 DVD-compatible Stream",
721 "MPEG-1 VCD-compatible Stream",
722 "MPEG-2 SVCD-compatible Stream",
723 NULL
724 };
725
Andy Walls0d82fe82009-01-01 19:02:31 -0300726 static const char *mpeg_audio_encoding_l2_ac3[] = {
727 "",
728 "MPEG-1/2 Layer II",
729 "",
730 "",
731 "AC-3",
732 NULL
733 };
734
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300735 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
736 "Manual",
737 "Auto",
738 NULL
739 };
740
741 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
742 "Off",
743 "1D Horizontal",
744 "1D Vertical",
745 "2D H/V Separable",
746 "2D Symmetric non-separable",
747 NULL
748 };
749
750 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
751 "Off",
752 "1D Horizontal",
753 NULL
754 };
755
756 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
757 "Manual",
758 "Auto",
759 NULL
760 };
761
762 static const char *cx2341x_video_median_filter_type_menu[] = {
763 "Off",
764 "Horizontal",
765 "Vertical",
766 "Horizontal/Vertical",
767 "Diagonal",
768 NULL
769 };
770
771 switch (id) {
772 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300773 return (p->capabilities & CX2341X_CAP_HAS_TS) ?
774 mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
Andy Walls0d82fe82009-01-01 19:02:31 -0300775 case V4L2_CID_MPEG_AUDIO_ENCODING:
776 return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
777 mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300778 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
779 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
780 return NULL;
781 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
782 return cx2341x_video_spatial_filter_mode_menu;
783 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
784 return cx2341x_video_luma_spatial_filter_type_menu;
785 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
786 return cx2341x_video_chroma_spatial_filter_type_menu;
787 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
788 return cx2341x_video_temporal_filter_mode_menu;
789 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
790 return cx2341x_video_median_filter_type_menu;
791 default:
792 return v4l2_ctrl_get_menu(id);
793 }
794}
Hans Verkuil737bd412007-11-01 13:38:12 -0300795EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300796
Andy Walls0d82fe82009-01-01 19:02:31 -0300797/* definitions for audio properties bits 29-28 */
Andy Walls31230c52009-01-03 14:21:30 -0300798#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
799#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
800#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
Andy Walls0d82fe82009-01-01 19:02:31 -0300801
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300802static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
803{
Andy Walls0d82fe82009-01-01 19:02:31 -0300804 params->audio_properties =
805 (params->audio_sampling_freq << 0) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300806 (params->audio_mode << 8) |
807 (params->audio_mode_extension << 10) |
Hans Verkuil737bd412007-11-01 13:38:12 -0300808 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
809 ? 3 : params->audio_emphasis) << 12) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300810 (params->audio_crc << 14);
Andy Walls0d82fe82009-01-01 19:02:31 -0300811
812 if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
813 params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
814 params->audio_properties |=
815 /* Not sure if this MPEG Layer II setting is required */
816 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
817 (params->audio_ac3_bitrate << 4) |
Andy Walls31230c52009-01-03 14:21:30 -0300818 (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
Andy Walls0d82fe82009-01-01 19:02:31 -0300819 } else {
820 /* Assuming MPEG Layer II */
821 params->audio_properties |=
822 ((3 - params->audio_encoding) << 2) |
823 ((1 + params->audio_l2_bitrate) << 4);
824 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300825}
826
Hans Verkuil01f1e442007-08-21 18:32:42 -0300827int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
Hans Verkuil4d6b5ae2006-06-26 09:31:18 -0300828 struct v4l2_ext_controls *ctrls, unsigned int cmd)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300829{
830 int err = 0;
831 int i;
832
833 if (cmd == VIDIOC_G_EXT_CTRLS) {
834 for (i = 0; i < ctrls->count; i++) {
835 struct v4l2_ext_control *ctrl = ctrls->controls + i;
836
837 err = cx2341x_get_ctrl(params, ctrl);
838 if (err) {
839 ctrls->error_idx = i;
840 break;
841 }
842 }
843 return err;
844 }
845 for (i = 0; i < ctrls->count; i++) {
846 struct v4l2_ext_control *ctrl = ctrls->controls + i;
847 struct v4l2_queryctrl qctrl;
848 const char **menu_items = NULL;
849
850 qctrl.id = ctrl->id;
851 err = cx2341x_ctrl_query(params, &qctrl);
852 if (err)
853 break;
854 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300855 menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300856 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
857 if (err)
858 break;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300859 err = cx2341x_set_ctrl(params, busy, ctrl);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300860 if (err)
861 break;
862 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300863 if (err == 0 &&
864 params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
865 params->video_bitrate_peak < params->video_bitrate) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300866 err = -ERANGE;
867 ctrls->error_idx = ctrls->count;
868 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300869 if (err)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300870 ctrls->error_idx = i;
Hans Verkuil737bd412007-11-01 13:38:12 -0300871 else
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300872 cx2341x_calc_audio_properties(params);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300873 return err;
874}
Hans Verkuil737bd412007-11-01 13:38:12 -0300875EXPORT_SYMBOL(cx2341x_ext_ctrls);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300876
877void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
878{
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300879 *p = default_params;
880 cx2341x_calc_audio_properties(p);
881}
Hans Verkuil737bd412007-11-01 13:38:12 -0300882EXPORT_SYMBOL(cx2341x_fill_defaults);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300883
Hans Verkuil737bd412007-11-01 13:38:12 -0300884static int cx2341x_api(void *priv, cx2341x_mbox_func func,
Hans Verkuilea48c132007-12-12 07:04:58 -0300885 u32 cmd, int args, ...)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300886{
887 u32 data[CX2341X_MBOX_MAX_DATA];
888 va_list vargs;
889 int i;
890
891 va_start(vargs, args);
892
Hans Verkuil737bd412007-11-01 13:38:12 -0300893 for (i = 0; i < args; i++)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300894 data[i] = va_arg(vargs, int);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300895 va_end(vargs);
896 return func(priv, cmd, args, 0, data);
897}
898
Hans Verkuil737bd412007-11-01 13:38:12 -0300899#define NEQ(field) (old->field != new->field)
900
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300901int cx2341x_update(void *priv, cx2341x_mbox_func func,
Hans Verkuil737bd412007-11-01 13:38:12 -0300902 const struct cx2341x_mpeg_params *old,
903 const struct cx2341x_mpeg_params *new)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300904{
905 static int mpeg_stream_type[] = {
906 0, /* MPEG-2 PS */
907 1, /* MPEG-2 TS */
908 2, /* MPEG-1 SS */
909 14, /* DVD */
910 11, /* VCD */
911 12, /* SVCD */
912 };
913
914 int err = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -0300915 int force = (old == NULL);
Hans Verkuil44b579d2006-08-27 19:22:15 -0300916 u16 temporal = new->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300917
Hans Verkuil45ad9f82006-06-21 17:04:13 -0300918 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300919
Hans Verkuil737bd412007-11-01 13:38:12 -0300920 if (force || NEQ(is_50hz)) {
921 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
922 new->is_50hz);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300923 if (err) return err;
924 }
925
Hans Verkuil737bd412007-11-01 13:38:12 -0300926 if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300927 u16 w = new->width;
928 u16 h = new->height;
929
930 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
931 w /= 2;
932 h /= 2;
933 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300934 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
935 h, w);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300936 if (err) return err;
Hans Verkuil12b896e2006-12-18 13:37:50 -0300937 }
Hans Verkuil44b579d2006-08-27 19:22:15 -0300938
Hans Verkuil12b896e2006-12-18 13:37:50 -0300939 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
Hans Verkuil737bd412007-11-01 13:38:12 -0300940 /* Adjust temporal filter if necessary. The problem with the
941 temporal filter is that it works well with full resolution
942 capturing, but not when the capture window is scaled (the
943 filter introduces a ghosting effect). So if the capture
944 window is scaled, then force the filter to 0.
Hans Verkuil44b579d2006-08-27 19:22:15 -0300945
Hans Verkuil12b896e2006-12-18 13:37:50 -0300946 For full resolution the filter really improves the video
Hans Verkuil737bd412007-11-01 13:38:12 -0300947 quality, especially if the original video quality is
948 suboptimal. */
Hans Verkuil12b896e2006-12-18 13:37:50 -0300949 temporal = 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300950 }
951
Hans Verkuil737bd412007-11-01 13:38:12 -0300952 if (force || NEQ(stream_type)) {
953 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
954 mpeg_stream_type[new->stream_type]);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300955 if (err) return err;
956 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300957 if (force || NEQ(video_aspect)) {
958 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
959 1 + new->video_aspect);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300960 if (err) return err;
961 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300962 if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300963 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
964 new->video_gop_size, new->video_b_frames + 1);
965 if (err) return err;
966 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300967 if (force || NEQ(video_gop_closure)) {
968 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
969 new->video_gop_closure);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300970 if (err) return err;
971 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300972 if (force || NEQ(audio_properties)) {
973 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
974 1, new->audio_properties);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300975 if (err) return err;
976 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300977 if (force || NEQ(audio_mute)) {
978 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
979 new->audio_mute);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300980 if (err) return err;
981 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300982 if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
983 NEQ(video_bitrate_peak)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300984 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
985 new->video_bitrate_mode, new->video_bitrate,
986 new->video_bitrate_peak / 400, 0, 0);
987 if (err) return err;
988 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300989 if (force || NEQ(video_spatial_filter_mode) ||
990 NEQ(video_temporal_filter_mode) ||
991 NEQ(video_median_filter_type)) {
992 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
993 2, new->video_spatial_filter_mode |
994 (new->video_temporal_filter_mode << 1),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300995 new->video_median_filter_type);
996 if (err) return err;
997 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300998 if (force || NEQ(video_luma_median_filter_bottom) ||
999 NEQ(video_luma_median_filter_top) ||
1000 NEQ(video_chroma_median_filter_bottom) ||
1001 NEQ(video_chroma_median_filter_top)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001002 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
1003 new->video_luma_median_filter_bottom,
1004 new->video_luma_median_filter_top,
1005 new->video_chroma_median_filter_bottom,
1006 new->video_chroma_median_filter_top);
1007 if (err) return err;
1008 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001009 if (force || NEQ(video_luma_spatial_filter_type) ||
1010 NEQ(video_chroma_spatial_filter_type)) {
1011 err = cx2341x_api(priv, func,
1012 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
1013 2, new->video_luma_spatial_filter_type,
1014 new->video_chroma_spatial_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001015 if (err) return err;
1016 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001017 if (force || NEQ(video_spatial_filter) ||
1018 old->video_temporal_filter != temporal) {
1019 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
1020 2, new->video_spatial_filter, temporal);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001021 if (err) return err;
1022 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001023 if (force || NEQ(video_temporal_decimation)) {
1024 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
1025 1, new->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001026 if (err) return err;
1027 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001028 if (force || NEQ(video_mute) ||
1029 (new->video_mute && NEQ(video_mute_yuv))) {
1030 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
1031 new->video_mute | (new->video_mute_yuv << 8));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001032 if (err) return err;
1033 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001034 if (force || NEQ(stream_insert_nav_packets)) {
1035 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
1036 7, new->stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001037 if (err) return err;
1038 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001039 return 0;
1040}
Hans Verkuil737bd412007-11-01 13:38:12 -03001041EXPORT_SYMBOL(cx2341x_update);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001042
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001043static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001044{
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001045 const char **menu = cx2341x_ctrl_get_menu(p, id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001046 struct v4l2_ext_control ctrl;
1047
1048 if (menu == NULL)
1049 goto invalid;
1050 ctrl.id = id;
1051 if (cx2341x_get_ctrl(p, &ctrl))
1052 goto invalid;
1053 while (ctrl.value-- && *menu) menu++;
1054 if (*menu == NULL)
1055 goto invalid;
1056 return *menu;
1057
1058invalid:
1059 return "<invalid>";
1060}
1061
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001062void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001063{
1064 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
Hans Verkuil83aaf132006-12-18 13:40:23 -03001065 int temporal = p->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001066
1067 /* Stream */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001068 printk(KERN_INFO "%s: Stream: %s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001069 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001070 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001071 if (p->stream_insert_nav_packets)
1072 printk(" (with navigation packets)");
1073 printk("\n");
Hans Verkuil44b579d2006-08-27 19:22:15 -03001074 printk(KERN_INFO "%s: VBI Format: %s\n",
1075 prefix,
1076 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001077
1078 /* Video */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001079 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001080 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001081 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001082 p->is_50hz ? 25 : 30,
1083 (p->video_mute) ? " (muted)" : "");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001084 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
1085 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001086 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
1087 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
1088 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
1089 p->video_bitrate);
Hans Verkuil737bd412007-11-01 13:38:12 -03001090 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001091 printk(", Peak %d", p->video_bitrate_peak);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001092 printk("\n");
Hans Verkuil737bd412007-11-01 13:38:12 -03001093 printk(KERN_INFO
1094 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001095 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001096 p->video_gop_size, p->video_b_frames,
Hans Verkuil75558ab2006-12-18 22:52:21 -03001097 p->video_gop_closure ? "" : "No ");
Hans Verkuil737bd412007-11-01 13:38:12 -03001098 if (p->video_temporal_decimation)
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001099 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
1100 prefix, p->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001101
1102 /* Audio */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001103 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001104 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001105 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
1106 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
Andy Walls0d82fe82009-01-01 19:02:31 -03001107 cx2341x_menu_item(p,
1108 p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
1109 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1110 : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001111 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1112 p->audio_mute ? " (muted)" : "");
Hans Verkuil737bd412007-11-01 13:38:12 -03001113 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1114 printk(", %s", cx2341x_menu_item(p,
1115 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001116 printk(", %s, %s\n",
1117 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1118 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1119
1120 /* Encoding filters */
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001121 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1122 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001123 cx2341x_menu_item(p,
1124 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1125 cx2341x_menu_item(p,
1126 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1127 cx2341x_menu_item(p,
1128 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001129 p->video_spatial_filter);
Hans Verkuil737bd412007-11-01 13:38:12 -03001130
1131 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
Hans Verkuil83aaf132006-12-18 13:40:23 -03001132 temporal = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -03001133
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001134 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1135 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001136 cx2341x_menu_item(p,
1137 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
Hans Verkuil83aaf132006-12-18 13:40:23 -03001138 temporal);
Hans Verkuil737bd412007-11-01 13:38:12 -03001139 printk(KERN_INFO
1140 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001141 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001142 cx2341x_menu_item(p,
1143 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001144 p->video_luma_median_filter_bottom,
1145 p->video_luma_median_filter_top,
1146 p->video_chroma_median_filter_bottom,
1147 p->video_chroma_median_filter_top);
1148}
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001149EXPORT_SYMBOL(cx2341x_log_status);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001150
1151/*
1152 * Local variables:
1153 * c-basic-offset: 8
1154 * End:
1155 */
1156