blob: b36f522d2c5575a6c62ba11b529dcb61f857ca88 [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 Verkuil2ba58892009-02-13 10:57:48 -030041/* Must be sorted from low to high control ID! */
Hans Verkuilcc7bc642006-06-19 17:53:08 -030042const u32 cx2341x_mpeg_ctrls[] = {
43 V4L2_CID_MPEG_CLASS,
44 V4L2_CID_MPEG_STREAM_TYPE,
Hans Verkuil8cbde942006-06-24 14:36:02 -030045 V4L2_CID_MPEG_STREAM_VBI_FMT,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030046 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
47 V4L2_CID_MPEG_AUDIO_ENCODING,
48 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
49 V4L2_CID_MPEG_AUDIO_MODE,
50 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
51 V4L2_CID_MPEG_AUDIO_EMPHASIS,
52 V4L2_CID_MPEG_AUDIO_CRC,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030053 V4L2_CID_MPEG_AUDIO_MUTE,
Hans Verkuilee6f78c2009-02-13 05:12:02 -030054 V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030055 V4L2_CID_MPEG_VIDEO_ENCODING,
56 V4L2_CID_MPEG_VIDEO_ASPECT,
57 V4L2_CID_MPEG_VIDEO_B_FRAMES,
58 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
59 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030060 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
61 V4L2_CID_MPEG_VIDEO_BITRATE,
62 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
63 V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030064 V4L2_CID_MPEG_VIDEO_MUTE,
65 V4L2_CID_MPEG_VIDEO_MUTE_YUV,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030066 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
67 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
68 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
69 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
70 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
71 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
72 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
73 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
74 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
75 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
76 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
Hans Verkuil5eee72e2007-04-27 12:31:00 -030077 V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
Hans Verkuilcc7bc642006-06-19 17:53:08 -030078 0
79};
Hans Verkuil737bd412007-11-01 13:38:12 -030080EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
Hans Verkuilcc7bc642006-06-19 17:53:08 -030081
Hans Verkuilca130ee2008-07-17 12:26:45 -030082static const struct cx2341x_mpeg_params default_params = {
83 /* misc */
84 .capabilities = 0,
85 .port = CX2341X_PORT_MEMORY,
86 .width = 720,
87 .height = 480,
88 .is_50hz = 0,
89
90 /* stream */
91 .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
92 .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
93 .stream_insert_nav_packets = 0,
94
95 /* audio */
96 .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
97 .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
98 .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
Andy Walls0d82fe82009-01-01 19:02:31 -030099 .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300100 .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
101 .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
102 .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
103 .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
104 .audio_mute = 0,
105
106 /* video */
107 .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
108 .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
109 .video_b_frames = 2,
110 .video_gop_size = 12,
111 .video_gop_closure = 1,
112 .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
113 .video_bitrate = 6000000,
114 .video_bitrate_peak = 8000000,
115 .video_temporal_decimation = 0,
116 .video_mute = 0,
117 .video_mute_yuv = 0x008080, /* YCbCr value for black */
118
119 /* encoding filters */
120 .video_spatial_filter_mode =
121 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
122 .video_spatial_filter = 0,
123 .video_luma_spatial_filter_type =
124 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
125 .video_chroma_spatial_filter_type =
126 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
127 .video_temporal_filter_mode =
128 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
129 .video_temporal_filter = 8,
130 .video_median_filter_type =
131 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
132 .video_luma_median_filter_top = 255,
133 .video_luma_median_filter_bottom = 0,
134 .video_chroma_median_filter_top = 255,
135 .video_chroma_median_filter_bottom = 0,
136};
137
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300138
139/* Map the control ID to the correct field in the cx2341x_mpeg_params
140 struct. Return -EINVAL if the ID is unknown, else return 0. */
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300141static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300142 struct v4l2_ext_control *ctrl)
143{
144 switch (ctrl->id) {
145 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
146 ctrl->value = params->audio_sampling_freq;
147 break;
148 case V4L2_CID_MPEG_AUDIO_ENCODING:
149 ctrl->value = params->audio_encoding;
150 break;
151 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
152 ctrl->value = params->audio_l2_bitrate;
153 break;
Andy Walls0d82fe82009-01-01 19:02:31 -0300154 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
155 ctrl->value = params->audio_ac3_bitrate;
156 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300157 case V4L2_CID_MPEG_AUDIO_MODE:
158 ctrl->value = params->audio_mode;
159 break;
160 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
161 ctrl->value = params->audio_mode_extension;
162 break;
163 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
164 ctrl->value = params->audio_emphasis;
165 break;
166 case V4L2_CID_MPEG_AUDIO_CRC:
167 ctrl->value = params->audio_crc;
168 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300169 case V4L2_CID_MPEG_AUDIO_MUTE:
170 ctrl->value = params->audio_mute;
171 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300172 case V4L2_CID_MPEG_VIDEO_ENCODING:
173 ctrl->value = params->video_encoding;
174 break;
175 case V4L2_CID_MPEG_VIDEO_ASPECT:
176 ctrl->value = params->video_aspect;
177 break;
178 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
179 ctrl->value = params->video_b_frames;
180 break;
181 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
182 ctrl->value = params->video_gop_size;
183 break;
184 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
185 ctrl->value = params->video_gop_closure;
186 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300187 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
188 ctrl->value = params->video_bitrate_mode;
189 break;
190 case V4L2_CID_MPEG_VIDEO_BITRATE:
191 ctrl->value = params->video_bitrate;
192 break;
193 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
194 ctrl->value = params->video_bitrate_peak;
195 break;
196 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
197 ctrl->value = params->video_temporal_decimation;
198 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300199 case V4L2_CID_MPEG_VIDEO_MUTE:
200 ctrl->value = params->video_mute;
201 break;
202 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
203 ctrl->value = params->video_mute_yuv;
204 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300205 case V4L2_CID_MPEG_STREAM_TYPE:
206 ctrl->value = params->stream_type;
207 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300208 case V4L2_CID_MPEG_STREAM_VBI_FMT:
209 ctrl->value = params->stream_vbi_fmt;
210 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300211 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
212 ctrl->value = params->video_spatial_filter_mode;
213 break;
214 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
215 ctrl->value = params->video_spatial_filter;
216 break;
217 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
218 ctrl->value = params->video_luma_spatial_filter_type;
219 break;
220 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
221 ctrl->value = params->video_chroma_spatial_filter_type;
222 break;
223 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
224 ctrl->value = params->video_temporal_filter_mode;
225 break;
226 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
227 ctrl->value = params->video_temporal_filter;
228 break;
229 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
230 ctrl->value = params->video_median_filter_type;
231 break;
232 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
233 ctrl->value = params->video_luma_median_filter_top;
234 break;
235 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
236 ctrl->value = params->video_luma_median_filter_bottom;
237 break;
238 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
239 ctrl->value = params->video_chroma_median_filter_top;
240 break;
241 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
242 ctrl->value = params->video_chroma_median_filter_bottom;
243 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300244 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
245 ctrl->value = params->stream_insert_nav_packets;
246 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300247 default:
248 return -EINVAL;
249 }
250 return 0;
251}
252
253/* Map the control ID to the correct field in the cx2341x_mpeg_params
254 struct. Return -EINVAL if the ID is unknown, else return 0. */
Hans Verkuil01f1e442007-08-21 18:32:42 -0300255static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300256 struct v4l2_ext_control *ctrl)
257{
258 switch (ctrl->id) {
259 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300260 if (busy)
261 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300262 params->audio_sampling_freq = ctrl->value;
263 break;
264 case V4L2_CID_MPEG_AUDIO_ENCODING:
Andy Walls0d82fe82009-01-01 19:02:31 -0300265 if (busy)
266 return -EBUSY;
Andy Walls31230c52009-01-03 14:21:30 -0300267 if (params->capabilities & CX2341X_CAP_HAS_AC3)
268 if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
269 ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
270 return -ERANGE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300271 params->audio_encoding = ctrl->value;
272 break;
273 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300274 if (busy)
275 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300276 params->audio_l2_bitrate = ctrl->value;
277 break;
Andy Walls0d82fe82009-01-01 19:02:31 -0300278 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
279 if (busy)
280 return -EBUSY;
Andy Walls31230c52009-01-03 14:21:30 -0300281 if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
282 return -EINVAL;
Andy Walls0d82fe82009-01-01 19:02:31 -0300283 params->audio_ac3_bitrate = ctrl->value;
284 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300285 case V4L2_CID_MPEG_AUDIO_MODE:
286 params->audio_mode = ctrl->value;
287 break;
288 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
289 params->audio_mode_extension = ctrl->value;
290 break;
291 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
292 params->audio_emphasis = ctrl->value;
293 break;
294 case V4L2_CID_MPEG_AUDIO_CRC:
295 params->audio_crc = ctrl->value;
296 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300297 case V4L2_CID_MPEG_AUDIO_MUTE:
298 params->audio_mute = ctrl->value;
299 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300300 case V4L2_CID_MPEG_VIDEO_ASPECT:
301 params->video_aspect = ctrl->value;
302 break;
303 case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
304 int b = ctrl->value + 1;
305 int gop = params->video_gop_size;
306 params->video_b_frames = ctrl->value;
307 params->video_gop_size = b * ((gop + b - 1) / b);
308 /* Max GOP size = 34 */
309 while (params->video_gop_size > 34)
310 params->video_gop_size -= b;
311 break;
312 }
313 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
314 int b = params->video_b_frames + 1;
315 int gop = ctrl->value;
316 params->video_gop_size = b * ((gop + b - 1) / b);
317 /* Max GOP size = 34 */
318 while (params->video_gop_size > 34)
319 params->video_gop_size -= b;
320 ctrl->value = params->video_gop_size;
321 break;
322 }
323 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
324 params->video_gop_closure = ctrl->value;
325 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300326 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300327 if (busy)
328 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300329 /* MPEG-1 only allows CBR */
330 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
331 ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
332 return -EINVAL;
333 params->video_bitrate_mode = ctrl->value;
334 break;
335 case V4L2_CID_MPEG_VIDEO_BITRATE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300336 if (busy)
337 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300338 params->video_bitrate = ctrl->value;
339 break;
340 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300341 if (busy)
342 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300343 params->video_bitrate_peak = ctrl->value;
344 break;
345 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
346 params->video_temporal_decimation = ctrl->value;
347 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300348 case V4L2_CID_MPEG_VIDEO_MUTE:
349 params->video_mute = (ctrl->value != 0);
350 break;
351 case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
352 params->video_mute_yuv = ctrl->value;
353 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300354 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300355 if (busy)
356 return -EBUSY;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300357 params->stream_type = ctrl->value;
358 params->video_encoding =
Hans Verkuil737bd412007-11-01 13:38:12 -0300359 (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
360 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
361 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
362 V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
363 if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300364 /* MPEG-1 implies CBR */
Hans Verkuil737bd412007-11-01 13:38:12 -0300365 params->video_bitrate_mode =
366 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300367 break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300368 case V4L2_CID_MPEG_STREAM_VBI_FMT:
369 params->stream_vbi_fmt = ctrl->value;
370 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300371 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
372 params->video_spatial_filter_mode = ctrl->value;
373 break;
374 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
375 params->video_spatial_filter = ctrl->value;
376 break;
377 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
378 params->video_luma_spatial_filter_type = ctrl->value;
379 break;
380 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
381 params->video_chroma_spatial_filter_type = ctrl->value;
382 break;
383 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
384 params->video_temporal_filter_mode = ctrl->value;
385 break;
386 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
387 params->video_temporal_filter = ctrl->value;
388 break;
389 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
390 params->video_median_filter_type = ctrl->value;
391 break;
392 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
393 params->video_luma_median_filter_top = ctrl->value;
394 break;
395 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
396 params->video_luma_median_filter_bottom = ctrl->value;
397 break;
398 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
399 params->video_chroma_median_filter_top = ctrl->value;
400 break;
401 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
402 params->video_chroma_median_filter_bottom = ctrl->value;
403 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300404 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
405 params->stream_insert_nav_packets = ctrl->value;
406 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300407 default:
408 return -EINVAL;
409 }
410 return 0;
411}
412
Hans Verkuil737bd412007-11-01 13:38:12 -0300413static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
414 s32 min, s32 max, s32 step, s32 def)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300415{
416 const char *name;
417
418 qctrl->flags = 0;
419 switch (qctrl->id) {
420 /* MPEG controls */
421 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
422 name = "Spatial Filter Mode";
423 break;
424 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
425 name = "Spatial Filter";
426 break;
427 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
428 name = "Spatial Luma Filter Type";
429 break;
430 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
431 name = "Spatial Chroma Filter Type";
432 break;
433 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
434 name = "Temporal Filter Mode";
435 break;
436 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
437 name = "Temporal Filter";
438 break;
439 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
440 name = "Median Filter Type";
441 break;
442 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
443 name = "Median Luma Filter Maximum";
444 break;
445 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
446 name = "Median Luma Filter Minimum";
447 break;
448 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
449 name = "Median Chroma Filter Maximum";
450 break;
451 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
452 name = "Median Chroma Filter Minimum";
453 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300454 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
455 name = "Insert Navigation Packets";
456 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300457
458 default:
459 return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
460 }
461 switch (qctrl->id) {
462 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
463 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
464 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
465 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
466 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
467 qctrl->type = V4L2_CTRL_TYPE_MENU;
468 min = 0;
469 step = 1;
470 break;
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300471 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
472 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
473 min = 0;
474 max = 1;
475 step = 1;
476 break;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300477 default:
478 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
479 break;
480 }
481 switch (qctrl->id) {
482 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
483 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
484 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
485 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
486 break;
487 }
488 qctrl->minimum = min;
489 qctrl->maximum = max;
490 qctrl->step = step;
491 qctrl->default_value = def;
492 qctrl->reserved[0] = qctrl->reserved[1] = 0;
493 snprintf(qctrl->name, sizeof(qctrl->name), name);
494 return 0;
495}
496
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300497int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
Hans Verkuil737bd412007-11-01 13:38:12 -0300498 struct v4l2_queryctrl *qctrl)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300499{
500 int err;
501
502 switch (qctrl->id) {
503 case V4L2_CID_MPEG_AUDIO_ENCODING:
Andy Walls31230c52009-01-03 14:21:30 -0300504 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
505 /*
506 * The state of L2 & AC3 bitrate controls can change
507 * when this control changes, but v4l2_ctrl_query_fill()
508 * already sets V4L2_CTRL_FLAG_UPDATE for
509 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
510 */
Andy Walls0d82fe82009-01-01 19:02:31 -0300511 return v4l2_ctrl_query_fill(qctrl,
512 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
513 V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
514 default_params.audio_encoding);
Andy Walls31230c52009-01-03 14:21:30 -0300515 }
Andy Walls0d82fe82009-01-01 19:02:31 -0300516
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300517 return v4l2_ctrl_query_fill(qctrl,
518 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
519 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300520 default_params.audio_encoding);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300521
522 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300523 err = v4l2_ctrl_query_fill(qctrl,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300524 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
525 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300526 default_params.audio_l2_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300527 if (err)
528 return err;
529 if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
530 params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
531 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
532 return 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300533
534 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
535 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
536 return -EINVAL;
537
Andy Walls0d82fe82009-01-01 19:02:31 -0300538 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300539 err = v4l2_ctrl_query_fill(qctrl,
Andy Walls0d82fe82009-01-01 19:02:31 -0300540 V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
541 V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
542 default_params.audio_ac3_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300543 if (err)
544 return err;
545 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
546 if (params->audio_encoding !=
547 V4L2_MPEG_AUDIO_ENCODING_AC3)
548 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
549 } else
550 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
551 return 0;
Andy Walls0d82fe82009-01-01 19:02:31 -0300552
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300553 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
554 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300555 if (err == 0 &&
556 params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300557 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
558 return err;
559
560 case V4L2_CID_MPEG_VIDEO_ENCODING:
561 /* this setting is read-only for the cx2341x since the
562 V4L2_CID_MPEG_STREAM_TYPE really determines the
563 MPEG-1/2 setting */
Janne Grunau188919a2008-08-08 07:21:00 -0300564 err = v4l2_ctrl_query_fill(qctrl,
565 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
566 V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
567 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300568 if (err == 0)
569 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
570 return err;
571
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300572 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
573 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300574 if (err == 0 &&
575 params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300576 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
577 return err;
578
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300579 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
580 err = v4l2_ctrl_query_fill_std(qctrl);
Hans Verkuil737bd412007-11-01 13:38:12 -0300581 if (err == 0 &&
582 params->video_bitrate_mode ==
583 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300584 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
585 return err;
586
Hans Verkuil8cbde942006-06-24 14:36:02 -0300587 case V4L2_CID_MPEG_STREAM_VBI_FMT:
588 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
589 return v4l2_ctrl_query_fill_std(qctrl);
590 return cx2341x_ctrl_query_fill(qctrl,
591 V4L2_MPEG_STREAM_VBI_FMT_NONE,
592 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300593 default_params.stream_vbi_fmt);
594
595 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
596 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
597 params->is_50hz ? 12 : 15);
Hans Verkuil8cbde942006-06-24 14:36:02 -0300598
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300599 /* CX23415/6 specific */
600 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
601 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300602 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
603 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300604 default_params.video_spatial_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300605
606 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300607 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
608 default_params.video_spatial_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300609 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300610 if (params->video_spatial_filter_mode ==
611 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
612 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300613 return 0;
614
615 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
616 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300617 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
618 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
619 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300620 default_params.video_luma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300621 if (params->video_spatial_filter_mode ==
622 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
623 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300624 return 0;
625
626 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
627 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300628 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
629 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
630 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300631 default_params.video_chroma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300632 if (params->video_spatial_filter_mode ==
633 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
634 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300635 return 0;
636
637 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
638 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300639 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
640 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300641 default_params.video_temporal_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300642
643 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300644 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
645 default_params.video_temporal_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300646 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300647 if (params->video_temporal_filter_mode ==
648 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
649 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300650 return 0;
651
652 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
653 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300654 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
655 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300656 default_params.video_median_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300657
658 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300659 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
660 default_params.video_luma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300661 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300662 if (params->video_median_filter_type ==
663 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
664 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300665 return 0;
666
667 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300668 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
669 default_params.video_luma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300670 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300671 if (params->video_median_filter_type ==
672 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
673 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300674 return 0;
675
676 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300677 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
678 default_params.video_chroma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300679 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300680 if (params->video_median_filter_type ==
681 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
682 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300683 return 0;
684
685 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300686 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
687 default_params.video_chroma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300688 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300689 if (params->video_median_filter_type ==
690 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
691 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300692 return 0;
693
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300694 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300695 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
696 default_params.stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300697
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300698 default:
699 return v4l2_ctrl_query_fill_std(qctrl);
700
701 }
702}
Hans Verkuil737bd412007-11-01 13:38:12 -0300703EXPORT_SYMBOL(cx2341x_ctrl_query);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300704
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300705const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300706{
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300707 static const char *mpeg_stream_type_without_ts[] = {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300708 "MPEG-2 Program Stream",
709 "",
710 "MPEG-1 System Stream",
711 "MPEG-2 DVD-compatible Stream",
712 "MPEG-1 VCD-compatible Stream",
713 "MPEG-2 SVCD-compatible Stream",
714 NULL
715 };
716
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300717 static const char *mpeg_stream_type_with_ts[] = {
718 "MPEG-2 Program Stream",
719 "MPEG-2 Transport Stream",
720 "MPEG-1 System Stream",
721 "MPEG-2 DVD-compatible Stream",
722 "MPEG-1 VCD-compatible Stream",
723 "MPEG-2 SVCD-compatible Stream",
724 NULL
725 };
726
Andy Walls0d82fe82009-01-01 19:02:31 -0300727 static const char *mpeg_audio_encoding_l2_ac3[] = {
728 "",
729 "MPEG-1/2 Layer II",
730 "",
731 "",
732 "AC-3",
733 NULL
734 };
735
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300736 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
737 "Manual",
738 "Auto",
739 NULL
740 };
741
742 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
743 "Off",
744 "1D Horizontal",
745 "1D Vertical",
746 "2D H/V Separable",
747 "2D Symmetric non-separable",
748 NULL
749 };
750
751 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
752 "Off",
753 "1D Horizontal",
754 NULL
755 };
756
757 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
758 "Manual",
759 "Auto",
760 NULL
761 };
762
763 static const char *cx2341x_video_median_filter_type_menu[] = {
764 "Off",
765 "Horizontal",
766 "Vertical",
767 "Horizontal/Vertical",
768 "Diagonal",
769 NULL
770 };
771
772 switch (id) {
773 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300774 return (p->capabilities & CX2341X_CAP_HAS_TS) ?
775 mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
Andy Walls0d82fe82009-01-01 19:02:31 -0300776 case V4L2_CID_MPEG_AUDIO_ENCODING:
777 return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
778 mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300779 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
780 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
781 return NULL;
782 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
783 return cx2341x_video_spatial_filter_mode_menu;
784 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
785 return cx2341x_video_luma_spatial_filter_type_menu;
786 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
787 return cx2341x_video_chroma_spatial_filter_type_menu;
788 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
789 return cx2341x_video_temporal_filter_mode_menu;
790 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
791 return cx2341x_video_median_filter_type_menu;
792 default:
793 return v4l2_ctrl_get_menu(id);
794 }
795}
Hans Verkuil737bd412007-11-01 13:38:12 -0300796EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300797
Andy Walls0d82fe82009-01-01 19:02:31 -0300798/* definitions for audio properties bits 29-28 */
Andy Walls31230c52009-01-03 14:21:30 -0300799#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
800#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
801#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
Andy Walls0d82fe82009-01-01 19:02:31 -0300802
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300803static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
804{
Andy Walls0d82fe82009-01-01 19:02:31 -0300805 params->audio_properties =
806 (params->audio_sampling_freq << 0) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300807 (params->audio_mode << 8) |
808 (params->audio_mode_extension << 10) |
Hans Verkuil737bd412007-11-01 13:38:12 -0300809 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
810 ? 3 : params->audio_emphasis) << 12) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300811 (params->audio_crc << 14);
Andy Walls0d82fe82009-01-01 19:02:31 -0300812
813 if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
814 params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
815 params->audio_properties |=
816 /* Not sure if this MPEG Layer II setting is required */
817 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
818 (params->audio_ac3_bitrate << 4) |
Andy Walls31230c52009-01-03 14:21:30 -0300819 (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
Andy Walls0d82fe82009-01-01 19:02:31 -0300820 } else {
821 /* Assuming MPEG Layer II */
822 params->audio_properties |=
823 ((3 - params->audio_encoding) << 2) |
824 ((1 + params->audio_l2_bitrate) << 4);
825 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300826}
827
Hans Verkuil01f1e442007-08-21 18:32:42 -0300828int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
Hans Verkuil4d6b5ae2006-06-26 09:31:18 -0300829 struct v4l2_ext_controls *ctrls, unsigned int cmd)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300830{
831 int err = 0;
832 int i;
833
834 if (cmd == VIDIOC_G_EXT_CTRLS) {
835 for (i = 0; i < ctrls->count; i++) {
836 struct v4l2_ext_control *ctrl = ctrls->controls + i;
837
838 err = cx2341x_get_ctrl(params, ctrl);
839 if (err) {
840 ctrls->error_idx = i;
841 break;
842 }
843 }
844 return err;
845 }
846 for (i = 0; i < ctrls->count; i++) {
847 struct v4l2_ext_control *ctrl = ctrls->controls + i;
848 struct v4l2_queryctrl qctrl;
849 const char **menu_items = NULL;
850
851 qctrl.id = ctrl->id;
852 err = cx2341x_ctrl_query(params, &qctrl);
853 if (err)
854 break;
855 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300856 menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300857 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
858 if (err)
859 break;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300860 err = cx2341x_set_ctrl(params, busy, ctrl);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300861 if (err)
862 break;
863 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300864 if (err == 0 &&
865 params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
866 params->video_bitrate_peak < params->video_bitrate) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300867 err = -ERANGE;
868 ctrls->error_idx = ctrls->count;
869 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300870 if (err)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300871 ctrls->error_idx = i;
Hans Verkuil737bd412007-11-01 13:38:12 -0300872 else
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300873 cx2341x_calc_audio_properties(params);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300874 return err;
875}
Hans Verkuil737bd412007-11-01 13:38:12 -0300876EXPORT_SYMBOL(cx2341x_ext_ctrls);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300877
878void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
879{
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300880 *p = default_params;
881 cx2341x_calc_audio_properties(p);
882}
Hans Verkuil737bd412007-11-01 13:38:12 -0300883EXPORT_SYMBOL(cx2341x_fill_defaults);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300884
Hans Verkuil737bd412007-11-01 13:38:12 -0300885static int cx2341x_api(void *priv, cx2341x_mbox_func func,
Hans Verkuilea48c132007-12-12 07:04:58 -0300886 u32 cmd, int args, ...)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300887{
888 u32 data[CX2341X_MBOX_MAX_DATA];
889 va_list vargs;
890 int i;
891
892 va_start(vargs, args);
893
Hans Verkuil737bd412007-11-01 13:38:12 -0300894 for (i = 0; i < args; i++)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300895 data[i] = va_arg(vargs, int);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300896 va_end(vargs);
897 return func(priv, cmd, args, 0, data);
898}
899
Hans Verkuil737bd412007-11-01 13:38:12 -0300900#define NEQ(field) (old->field != new->field)
901
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300902int cx2341x_update(void *priv, cx2341x_mbox_func func,
Hans Verkuil737bd412007-11-01 13:38:12 -0300903 const struct cx2341x_mpeg_params *old,
904 const struct cx2341x_mpeg_params *new)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300905{
906 static int mpeg_stream_type[] = {
907 0, /* MPEG-2 PS */
908 1, /* MPEG-2 TS */
909 2, /* MPEG-1 SS */
910 14, /* DVD */
911 11, /* VCD */
912 12, /* SVCD */
913 };
914
915 int err = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -0300916 int force = (old == NULL);
Hans Verkuil44b579d2006-08-27 19:22:15 -0300917 u16 temporal = new->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300918
Hans Verkuil45ad9f82006-06-21 17:04:13 -0300919 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300920
Hans Verkuil737bd412007-11-01 13:38:12 -0300921 if (force || NEQ(is_50hz)) {
922 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
923 new->is_50hz);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300924 if (err) return err;
925 }
926
Hans Verkuil737bd412007-11-01 13:38:12 -0300927 if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300928 u16 w = new->width;
929 u16 h = new->height;
930
931 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
932 w /= 2;
933 h /= 2;
934 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300935 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
936 h, w);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300937 if (err) return err;
Hans Verkuil12b896e2006-12-18 13:37:50 -0300938 }
Hans Verkuil44b579d2006-08-27 19:22:15 -0300939
Hans Verkuil12b896e2006-12-18 13:37:50 -0300940 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
Hans Verkuil737bd412007-11-01 13:38:12 -0300941 /* Adjust temporal filter if necessary. The problem with the
942 temporal filter is that it works well with full resolution
943 capturing, but not when the capture window is scaled (the
944 filter introduces a ghosting effect). So if the capture
945 window is scaled, then force the filter to 0.
Hans Verkuil44b579d2006-08-27 19:22:15 -0300946
Hans Verkuil12b896e2006-12-18 13:37:50 -0300947 For full resolution the filter really improves the video
Hans Verkuil737bd412007-11-01 13:38:12 -0300948 quality, especially if the original video quality is
949 suboptimal. */
Hans Verkuil12b896e2006-12-18 13:37:50 -0300950 temporal = 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300951 }
952
Hans Verkuil737bd412007-11-01 13:38:12 -0300953 if (force || NEQ(stream_type)) {
954 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
955 mpeg_stream_type[new->stream_type]);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300956 if (err) return err;
957 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300958 if (force || NEQ(video_aspect)) {
959 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
960 1 + new->video_aspect);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300961 if (err) return err;
962 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300963 if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300964 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
965 new->video_gop_size, new->video_b_frames + 1);
966 if (err) return err;
967 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300968 if (force || NEQ(video_gop_closure)) {
969 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
970 new->video_gop_closure);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300971 if (err) return err;
972 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300973 if (force || NEQ(audio_properties)) {
974 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
975 1, new->audio_properties);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300976 if (err) return err;
977 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300978 if (force || NEQ(audio_mute)) {
979 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
980 new->audio_mute);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300981 if (err) return err;
982 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300983 if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
984 NEQ(video_bitrate_peak)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300985 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
986 new->video_bitrate_mode, new->video_bitrate,
987 new->video_bitrate_peak / 400, 0, 0);
988 if (err) return err;
989 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300990 if (force || NEQ(video_spatial_filter_mode) ||
991 NEQ(video_temporal_filter_mode) ||
992 NEQ(video_median_filter_type)) {
993 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
994 2, new->video_spatial_filter_mode |
995 (new->video_temporal_filter_mode << 1),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300996 new->video_median_filter_type);
997 if (err) return err;
998 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300999 if (force || NEQ(video_luma_median_filter_bottom) ||
1000 NEQ(video_luma_median_filter_top) ||
1001 NEQ(video_chroma_median_filter_bottom) ||
1002 NEQ(video_chroma_median_filter_top)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001003 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
1004 new->video_luma_median_filter_bottom,
1005 new->video_luma_median_filter_top,
1006 new->video_chroma_median_filter_bottom,
1007 new->video_chroma_median_filter_top);
1008 if (err) return err;
1009 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001010 if (force || NEQ(video_luma_spatial_filter_type) ||
1011 NEQ(video_chroma_spatial_filter_type)) {
1012 err = cx2341x_api(priv, func,
1013 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
1014 2, new->video_luma_spatial_filter_type,
1015 new->video_chroma_spatial_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001016 if (err) return err;
1017 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001018 if (force || NEQ(video_spatial_filter) ||
1019 old->video_temporal_filter != temporal) {
1020 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
1021 2, new->video_spatial_filter, temporal);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001022 if (err) return err;
1023 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001024 if (force || NEQ(video_temporal_decimation)) {
1025 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
1026 1, new->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001027 if (err) return err;
1028 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001029 if (force || NEQ(video_mute) ||
1030 (new->video_mute && NEQ(video_mute_yuv))) {
1031 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
1032 new->video_mute | (new->video_mute_yuv << 8));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001033 if (err) return err;
1034 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001035 if (force || NEQ(stream_insert_nav_packets)) {
1036 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
1037 7, new->stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001038 if (err) return err;
1039 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001040 return 0;
1041}
Hans Verkuil737bd412007-11-01 13:38:12 -03001042EXPORT_SYMBOL(cx2341x_update);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001043
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001044static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001045{
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001046 const char **menu = cx2341x_ctrl_get_menu(p, id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001047 struct v4l2_ext_control ctrl;
1048
1049 if (menu == NULL)
1050 goto invalid;
1051 ctrl.id = id;
1052 if (cx2341x_get_ctrl(p, &ctrl))
1053 goto invalid;
1054 while (ctrl.value-- && *menu) menu++;
1055 if (*menu == NULL)
1056 goto invalid;
1057 return *menu;
1058
1059invalid:
1060 return "<invalid>";
1061}
1062
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001063void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001064{
1065 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
Hans Verkuil83aaf132006-12-18 13:40:23 -03001066 int temporal = p->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001067
1068 /* Stream */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001069 printk(KERN_INFO "%s: Stream: %s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001070 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001071 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001072 if (p->stream_insert_nav_packets)
1073 printk(" (with navigation packets)");
1074 printk("\n");
Hans Verkuil44b579d2006-08-27 19:22:15 -03001075 printk(KERN_INFO "%s: VBI Format: %s\n",
1076 prefix,
1077 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001078
1079 /* Video */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001080 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001081 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001082 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001083 p->is_50hz ? 25 : 30,
1084 (p->video_mute) ? " (muted)" : "");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001085 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
1086 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001087 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
1088 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
1089 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
1090 p->video_bitrate);
Hans Verkuil737bd412007-11-01 13:38:12 -03001091 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001092 printk(", Peak %d", p->video_bitrate_peak);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001093 printk("\n");
Hans Verkuil737bd412007-11-01 13:38:12 -03001094 printk(KERN_INFO
1095 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001096 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001097 p->video_gop_size, p->video_b_frames,
Hans Verkuil75558ab2006-12-18 22:52:21 -03001098 p->video_gop_closure ? "" : "No ");
Hans Verkuil737bd412007-11-01 13:38:12 -03001099 if (p->video_temporal_decimation)
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001100 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
1101 prefix, p->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001102
1103 /* Audio */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001104 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001105 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001106 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
1107 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
Andy Walls0d82fe82009-01-01 19:02:31 -03001108 cx2341x_menu_item(p,
1109 p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
1110 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1111 : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001112 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1113 p->audio_mute ? " (muted)" : "");
Hans Verkuil737bd412007-11-01 13:38:12 -03001114 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1115 printk(", %s", cx2341x_menu_item(p,
1116 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001117 printk(", %s, %s\n",
1118 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1119 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1120
1121 /* Encoding filters */
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001122 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1123 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001124 cx2341x_menu_item(p,
1125 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1126 cx2341x_menu_item(p,
1127 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1128 cx2341x_menu_item(p,
1129 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001130 p->video_spatial_filter);
Hans Verkuil737bd412007-11-01 13:38:12 -03001131
1132 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
Hans Verkuil83aaf132006-12-18 13:40:23 -03001133 temporal = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -03001134
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001135 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1136 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001137 cx2341x_menu_item(p,
1138 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
Hans Verkuil83aaf132006-12-18 13:40:23 -03001139 temporal);
Hans Verkuil737bd412007-11-01 13:38:12 -03001140 printk(KERN_INFO
1141 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001142 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001143 cx2341x_menu_item(p,
1144 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001145 p->video_luma_median_filter_bottom,
1146 p->video_luma_median_filter_top,
1147 p->video_chroma_median_filter_bottom,
1148 p->video_chroma_median_filter_top);
1149}
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001150EXPORT_SYMBOL(cx2341x_log_status);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001151
1152/*
1153 * Local variables:
1154 * c-basic-offset: 8
1155 * End:
1156 */
1157