blob: 4c8e95853fa3377b2fb53ace6659be808f04cbd2 [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) {
Hans Verkuilc6711c32009-06-14 05:20:21 -0300503 case V4L2_CID_MPEG_CLASS:
504 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
Hans Verkuil10afbef2009-02-21 18:47:24 -0300505 case V4L2_CID_MPEG_STREAM_TYPE:
506 return v4l2_ctrl_query_fill(qctrl,
507 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
508 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
509 V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
510
511 case V4L2_CID_MPEG_STREAM_VBI_FMT:
512 if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
513 return v4l2_ctrl_query_fill(qctrl,
514 V4L2_MPEG_STREAM_VBI_FMT_NONE,
515 V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
516 V4L2_MPEG_STREAM_VBI_FMT_NONE);
517 return cx2341x_ctrl_query_fill(qctrl,
518 V4L2_MPEG_STREAM_VBI_FMT_NONE,
519 V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
520 default_params.stream_vbi_fmt);
521
522 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
523 return v4l2_ctrl_query_fill(qctrl,
524 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
525 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
526 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
527
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300528 case V4L2_CID_MPEG_AUDIO_ENCODING:
Andy Walls31230c52009-01-03 14:21:30 -0300529 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
530 /*
531 * The state of L2 & AC3 bitrate controls can change
532 * when this control changes, but v4l2_ctrl_query_fill()
533 * already sets V4L2_CTRL_FLAG_UPDATE for
534 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
535 */
Andy Walls0d82fe82009-01-01 19:02:31 -0300536 return v4l2_ctrl_query_fill(qctrl,
537 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
538 V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
539 default_params.audio_encoding);
Andy Walls31230c52009-01-03 14:21:30 -0300540 }
Andy Walls0d82fe82009-01-01 19:02:31 -0300541
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300542 return v4l2_ctrl_query_fill(qctrl,
543 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
544 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300545 default_params.audio_encoding);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300546
547 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300548 err = v4l2_ctrl_query_fill(qctrl,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300549 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
550 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300551 default_params.audio_l2_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300552 if (err)
553 return err;
554 if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
555 params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
556 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
557 return 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300558
Hans Verkuil10afbef2009-02-21 18:47:24 -0300559 case V4L2_CID_MPEG_AUDIO_MODE:
560 return v4l2_ctrl_query_fill(qctrl,
561 V4L2_MPEG_AUDIO_MODE_STEREO,
562 V4L2_MPEG_AUDIO_MODE_MONO, 1,
563 V4L2_MPEG_AUDIO_MODE_STEREO);
564
565 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
566 err = v4l2_ctrl_query_fill(qctrl,
567 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
568 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
569 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
570 if (err == 0 &&
571 params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
572 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
573 return err;
574
575 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
576 return v4l2_ctrl_query_fill(qctrl,
577 V4L2_MPEG_AUDIO_EMPHASIS_NONE,
578 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
579 V4L2_MPEG_AUDIO_EMPHASIS_NONE);
580
581 case V4L2_CID_MPEG_AUDIO_CRC:
582 return v4l2_ctrl_query_fill(qctrl,
583 V4L2_MPEG_AUDIO_CRC_NONE,
584 V4L2_MPEG_AUDIO_CRC_CRC16, 1,
585 V4L2_MPEG_AUDIO_CRC_NONE);
586
587 case V4L2_CID_MPEG_AUDIO_MUTE:
588 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300589
Andy Walls0d82fe82009-01-01 19:02:31 -0300590 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
Andy Walls31230c52009-01-03 14:21:30 -0300591 err = v4l2_ctrl_query_fill(qctrl,
Andy Walls0d82fe82009-01-01 19:02:31 -0300592 V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
593 V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
594 default_params.audio_ac3_bitrate);
Andy Walls31230c52009-01-03 14:21:30 -0300595 if (err)
596 return err;
597 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
598 if (params->audio_encoding !=
599 V4L2_MPEG_AUDIO_ENCODING_AC3)
600 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
601 } else
602 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
603 return 0;
Andy Walls0d82fe82009-01-01 19:02:31 -0300604
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300605 case V4L2_CID_MPEG_VIDEO_ENCODING:
606 /* this setting is read-only for the cx2341x since the
607 V4L2_CID_MPEG_STREAM_TYPE really determines the
608 MPEG-1/2 setting */
Janne Grunau188919a2008-08-08 07:21:00 -0300609 err = v4l2_ctrl_query_fill(qctrl,
610 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
611 V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
612 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300613 if (err == 0)
614 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
615 return err;
616
Hans Verkuil10afbef2009-02-21 18:47:24 -0300617 case V4L2_CID_MPEG_VIDEO_ASPECT:
618 return v4l2_ctrl_query_fill(qctrl,
619 V4L2_MPEG_VIDEO_ASPECT_1x1,
620 V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
621 V4L2_MPEG_VIDEO_ASPECT_4x3);
622
623 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
624 return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
625
626 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
627 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
628 params->is_50hz ? 12 : 15);
629
630 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
631 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
632
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300633 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
Hans Verkuil10afbef2009-02-21 18:47:24 -0300634 err = v4l2_ctrl_query_fill(qctrl,
635 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
636 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
637 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
Hans Verkuil737bd412007-11-01 13:38:12 -0300638 if (err == 0 &&
639 params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
Hans Verkuil54aa9a22006-06-19 18:00:06 -0300640 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
641 return err;
642
Hans Verkuil10afbef2009-02-21 18:47:24 -0300643 case V4L2_CID_MPEG_VIDEO_BITRATE:
644 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
645
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300646 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
Hans Verkuil10afbef2009-02-21 18:47:24 -0300647 err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
Hans Verkuil737bd412007-11-01 13:38:12 -0300648 if (err == 0 &&
649 params->video_bitrate_mode ==
650 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300651 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
652 return err;
653
Hans Verkuil10afbef2009-02-21 18:47:24 -0300654 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
655 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
Hans Verkuilca130ee2008-07-17 12:26:45 -0300656
Hans Verkuil10afbef2009-02-21 18:47:24 -0300657 case V4L2_CID_MPEG_VIDEO_MUTE:
658 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
659
660 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
661 return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
Hans Verkuil8cbde942006-06-24 14:36:02 -0300662
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300663 /* CX23415/6 specific */
664 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
665 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300666 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
667 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300668 default_params.video_spatial_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300669
670 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300671 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
672 default_params.video_spatial_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300673 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300674 if (params->video_spatial_filter_mode ==
675 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
676 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300677 return 0;
678
679 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
680 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300681 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
682 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
683 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300684 default_params.video_luma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300685 if (params->video_spatial_filter_mode ==
686 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
687 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300688 return 0;
689
690 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
691 cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300692 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
693 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
694 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300695 default_params.video_chroma_spatial_filter_type);
Hans Verkuil737bd412007-11-01 13:38:12 -0300696 if (params->video_spatial_filter_mode ==
697 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
698 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300699 return 0;
700
701 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
702 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300703 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
704 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300705 default_params.video_temporal_filter_mode);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300706
707 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300708 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
709 default_params.video_temporal_filter);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300710 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300711 if (params->video_temporal_filter_mode ==
712 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
713 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300714 return 0;
715
716 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
717 return cx2341x_ctrl_query_fill(qctrl,
Hans Verkuil737bd412007-11-01 13:38:12 -0300718 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
719 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
Hans Verkuilca130ee2008-07-17 12:26:45 -0300720 default_params.video_median_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300721
722 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300723 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
724 default_params.video_luma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300725 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300726 if (params->video_median_filter_type ==
727 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
728 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300729 return 0;
730
731 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300732 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
733 default_params.video_luma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300734 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300735 if (params->video_median_filter_type ==
736 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
737 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300738 return 0;
739
740 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300741 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
742 default_params.video_chroma_median_filter_top);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300743 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300744 if (params->video_median_filter_type ==
745 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
746 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300747 return 0;
748
749 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300750 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
751 default_params.video_chroma_median_filter_bottom);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300752 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
Hans Verkuil737bd412007-11-01 13:38:12 -0300753 if (params->video_median_filter_type ==
754 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
755 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300756 return 0;
757
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300758 case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
Hans Verkuilca130ee2008-07-17 12:26:45 -0300759 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
760 default_params.stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300761
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300762 default:
Hans Verkuil10afbef2009-02-21 18:47:24 -0300763 return -EINVAL;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300764
765 }
766}
Hans Verkuil737bd412007-11-01 13:38:12 -0300767EXPORT_SYMBOL(cx2341x_ctrl_query);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300768
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300769const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300770{
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300771 static const char *mpeg_stream_type_without_ts[] = {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300772 "MPEG-2 Program Stream",
773 "",
774 "MPEG-1 System Stream",
775 "MPEG-2 DVD-compatible Stream",
776 "MPEG-1 VCD-compatible Stream",
777 "MPEG-2 SVCD-compatible Stream",
778 NULL
779 };
780
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300781 static const char *mpeg_stream_type_with_ts[] = {
782 "MPEG-2 Program Stream",
783 "MPEG-2 Transport Stream",
784 "MPEG-1 System Stream",
785 "MPEG-2 DVD-compatible Stream",
786 "MPEG-1 VCD-compatible Stream",
787 "MPEG-2 SVCD-compatible Stream",
788 NULL
789 };
790
Andy Walls0d82fe82009-01-01 19:02:31 -0300791 static const char *mpeg_audio_encoding_l2_ac3[] = {
792 "",
793 "MPEG-1/2 Layer II",
794 "",
795 "",
796 "AC-3",
797 NULL
798 };
799
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300800 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
801 "Manual",
802 "Auto",
803 NULL
804 };
805
806 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
807 "Off",
808 "1D Horizontal",
809 "1D Vertical",
810 "2D H/V Separable",
811 "2D Symmetric non-separable",
812 NULL
813 };
814
815 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
816 "Off",
817 "1D Horizontal",
818 NULL
819 };
820
821 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
822 "Manual",
823 "Auto",
824 NULL
825 };
826
827 static const char *cx2341x_video_median_filter_type_menu[] = {
828 "Off",
829 "Horizontal",
830 "Vertical",
831 "Horizontal/Vertical",
832 "Diagonal",
833 NULL
834 };
835
836 switch (id) {
837 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300838 return (p->capabilities & CX2341X_CAP_HAS_TS) ?
839 mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
Andy Walls0d82fe82009-01-01 19:02:31 -0300840 case V4L2_CID_MPEG_AUDIO_ENCODING:
841 return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
842 mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300843 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
844 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
845 return NULL;
846 case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
847 return cx2341x_video_spatial_filter_mode_menu;
848 case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
849 return cx2341x_video_luma_spatial_filter_type_menu;
850 case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
851 return cx2341x_video_chroma_spatial_filter_type_menu;
852 case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
853 return cx2341x_video_temporal_filter_mode_menu;
854 case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
855 return cx2341x_video_median_filter_type_menu;
856 default:
857 return v4l2_ctrl_get_menu(id);
858 }
859}
Hans Verkuil737bd412007-11-01 13:38:12 -0300860EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300861
Andy Walls0d82fe82009-01-01 19:02:31 -0300862/* definitions for audio properties bits 29-28 */
Andy Walls31230c52009-01-03 14:21:30 -0300863#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
864#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
865#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
Andy Walls0d82fe82009-01-01 19:02:31 -0300866
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300867static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
868{
Andy Walls0d82fe82009-01-01 19:02:31 -0300869 params->audio_properties =
870 (params->audio_sampling_freq << 0) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300871 (params->audio_mode << 8) |
872 (params->audio_mode_extension << 10) |
Hans Verkuil737bd412007-11-01 13:38:12 -0300873 (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
874 ? 3 : params->audio_emphasis) << 12) |
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300875 (params->audio_crc << 14);
Andy Walls0d82fe82009-01-01 19:02:31 -0300876
877 if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
878 params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
879 params->audio_properties |=
880 /* Not sure if this MPEG Layer II setting is required */
881 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
882 (params->audio_ac3_bitrate << 4) |
Andy Walls31230c52009-01-03 14:21:30 -0300883 (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
Andy Walls0d82fe82009-01-01 19:02:31 -0300884 } else {
885 /* Assuming MPEG Layer II */
886 params->audio_properties |=
887 ((3 - params->audio_encoding) << 2) |
888 ((1 + params->audio_l2_bitrate) << 4);
889 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300890}
891
Hans Verkuil01f1e442007-08-21 18:32:42 -0300892int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
Hans Verkuil4d6b5ae2006-06-26 09:31:18 -0300893 struct v4l2_ext_controls *ctrls, unsigned int cmd)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300894{
895 int err = 0;
896 int i;
897
898 if (cmd == VIDIOC_G_EXT_CTRLS) {
899 for (i = 0; i < ctrls->count; i++) {
900 struct v4l2_ext_control *ctrl = ctrls->controls + i;
901
902 err = cx2341x_get_ctrl(params, ctrl);
903 if (err) {
904 ctrls->error_idx = i;
905 break;
906 }
907 }
908 return err;
909 }
910 for (i = 0; i < ctrls->count; i++) {
911 struct v4l2_ext_control *ctrl = ctrls->controls + i;
912 struct v4l2_queryctrl qctrl;
913 const char **menu_items = NULL;
914
915 qctrl.id = ctrl->id;
916 err = cx2341x_ctrl_query(params, &qctrl);
917 if (err)
918 break;
919 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
Hans Verkuile0e31cd2008-06-22 12:03:28 -0300920 menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300921 err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
922 if (err)
923 break;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300924 err = cx2341x_set_ctrl(params, busy, ctrl);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300925 if (err)
926 break;
927 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300928 if (err == 0 &&
929 params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
930 params->video_bitrate_peak < params->video_bitrate) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300931 err = -ERANGE;
932 ctrls->error_idx = ctrls->count;
933 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300934 if (err)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300935 ctrls->error_idx = i;
Hans Verkuil737bd412007-11-01 13:38:12 -0300936 else
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300937 cx2341x_calc_audio_properties(params);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300938 return err;
939}
Hans Verkuil737bd412007-11-01 13:38:12 -0300940EXPORT_SYMBOL(cx2341x_ext_ctrls);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300941
942void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
943{
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300944 *p = default_params;
945 cx2341x_calc_audio_properties(p);
946}
Hans Verkuil737bd412007-11-01 13:38:12 -0300947EXPORT_SYMBOL(cx2341x_fill_defaults);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300948
Hans Verkuil737bd412007-11-01 13:38:12 -0300949static int cx2341x_api(void *priv, cx2341x_mbox_func func,
Hans Verkuilea48c132007-12-12 07:04:58 -0300950 u32 cmd, int args, ...)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300951{
952 u32 data[CX2341X_MBOX_MAX_DATA];
953 va_list vargs;
954 int i;
955
956 va_start(vargs, args);
957
Hans Verkuil737bd412007-11-01 13:38:12 -0300958 for (i = 0; i < args; i++)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300959 data[i] = va_arg(vargs, int);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300960 va_end(vargs);
961 return func(priv, cmd, args, 0, data);
962}
963
Hans Verkuil737bd412007-11-01 13:38:12 -0300964#define NEQ(field) (old->field != new->field)
965
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300966int cx2341x_update(void *priv, cx2341x_mbox_func func,
Hans Verkuil737bd412007-11-01 13:38:12 -0300967 const struct cx2341x_mpeg_params *old,
968 const struct cx2341x_mpeg_params *new)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300969{
970 static int mpeg_stream_type[] = {
971 0, /* MPEG-2 PS */
972 1, /* MPEG-2 TS */
973 2, /* MPEG-1 SS */
974 14, /* DVD */
975 11, /* VCD */
976 12, /* SVCD */
977 };
978
979 int err = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -0300980 int force = (old == NULL);
Hans Verkuil44b579d2006-08-27 19:22:15 -0300981 u16 temporal = new->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300982
Hans Verkuil45ad9f82006-06-21 17:04:13 -0300983 cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300984
Hans Verkuil737bd412007-11-01 13:38:12 -0300985 if (force || NEQ(is_50hz)) {
986 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
987 new->is_50hz);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300988 if (err) return err;
989 }
990
Hans Verkuil737bd412007-11-01 13:38:12 -0300991 if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -0300992 u16 w = new->width;
993 u16 h = new->height;
994
995 if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
996 w /= 2;
997 h /= 2;
998 }
Hans Verkuil737bd412007-11-01 13:38:12 -0300999 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
1000 h, w);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001001 if (err) return err;
Hans Verkuil12b896e2006-12-18 13:37:50 -03001002 }
Hans Verkuil44b579d2006-08-27 19:22:15 -03001003
Hans Verkuil12b896e2006-12-18 13:37:50 -03001004 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
Hans Verkuil737bd412007-11-01 13:38:12 -03001005 /* Adjust temporal filter if necessary. The problem with the
1006 temporal filter is that it works well with full resolution
1007 capturing, but not when the capture window is scaled (the
1008 filter introduces a ghosting effect). So if the capture
1009 window is scaled, then force the filter to 0.
Hans Verkuil44b579d2006-08-27 19:22:15 -03001010
Hans Verkuil12b896e2006-12-18 13:37:50 -03001011 For full resolution the filter really improves the video
Hans Verkuil737bd412007-11-01 13:38:12 -03001012 quality, especially if the original video quality is
1013 suboptimal. */
Hans Verkuil12b896e2006-12-18 13:37:50 -03001014 temporal = 0;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001015 }
1016
Hans Verkuil737bd412007-11-01 13:38:12 -03001017 if (force || NEQ(stream_type)) {
1018 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
1019 mpeg_stream_type[new->stream_type]);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001020 if (err) return err;
1021 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001022 if (force || NEQ(video_aspect)) {
1023 err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
1024 1 + new->video_aspect);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001025 if (err) return err;
1026 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001027 if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001028 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
1029 new->video_gop_size, new->video_b_frames + 1);
1030 if (err) return err;
1031 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001032 if (force || NEQ(video_gop_closure)) {
1033 err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
1034 new->video_gop_closure);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001035 if (err) return err;
1036 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001037 if (force || NEQ(audio_properties)) {
1038 err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
1039 1, new->audio_properties);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001040 if (err) return err;
1041 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001042 if (force || NEQ(audio_mute)) {
1043 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
1044 new->audio_mute);
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001045 if (err) return err;
1046 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001047 if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
1048 NEQ(video_bitrate_peak)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001049 err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
1050 new->video_bitrate_mode, new->video_bitrate,
1051 new->video_bitrate_peak / 400, 0, 0);
1052 if (err) return err;
1053 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001054 if (force || NEQ(video_spatial_filter_mode) ||
1055 NEQ(video_temporal_filter_mode) ||
1056 NEQ(video_median_filter_type)) {
1057 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
1058 2, new->video_spatial_filter_mode |
1059 (new->video_temporal_filter_mode << 1),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001060 new->video_median_filter_type);
1061 if (err) return err;
1062 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001063 if (force || NEQ(video_luma_median_filter_bottom) ||
1064 NEQ(video_luma_median_filter_top) ||
1065 NEQ(video_chroma_median_filter_bottom) ||
1066 NEQ(video_chroma_median_filter_top)) {
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001067 err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
1068 new->video_luma_median_filter_bottom,
1069 new->video_luma_median_filter_top,
1070 new->video_chroma_median_filter_bottom,
1071 new->video_chroma_median_filter_top);
1072 if (err) return err;
1073 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001074 if (force || NEQ(video_luma_spatial_filter_type) ||
1075 NEQ(video_chroma_spatial_filter_type)) {
1076 err = cx2341x_api(priv, func,
1077 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
1078 2, new->video_luma_spatial_filter_type,
1079 new->video_chroma_spatial_filter_type);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001080 if (err) return err;
1081 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001082 if (force || NEQ(video_spatial_filter) ||
1083 old->video_temporal_filter != temporal) {
1084 err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
1085 2, new->video_spatial_filter, temporal);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001086 if (err) return err;
1087 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001088 if (force || NEQ(video_temporal_decimation)) {
1089 err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
1090 1, new->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001091 if (err) return err;
1092 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001093 if (force || NEQ(video_mute) ||
1094 (new->video_mute && NEQ(video_mute_yuv))) {
1095 err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
1096 new->video_mute | (new->video_mute_yuv << 8));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001097 if (err) return err;
1098 }
Hans Verkuil737bd412007-11-01 13:38:12 -03001099 if (force || NEQ(stream_insert_nav_packets)) {
1100 err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
1101 7, new->stream_insert_nav_packets);
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001102 if (err) return err;
1103 }
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001104 return 0;
1105}
Hans Verkuil737bd412007-11-01 13:38:12 -03001106EXPORT_SYMBOL(cx2341x_update);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001107
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001108static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001109{
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001110 const char **menu = cx2341x_ctrl_get_menu(p, id);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001111 struct v4l2_ext_control ctrl;
1112
1113 if (menu == NULL)
1114 goto invalid;
1115 ctrl.id = id;
1116 if (cx2341x_get_ctrl(p, &ctrl))
1117 goto invalid;
1118 while (ctrl.value-- && *menu) menu++;
1119 if (*menu == NULL)
1120 goto invalid;
1121 return *menu;
1122
1123invalid:
1124 return "<invalid>";
1125}
1126
Hans Verkuile0e31cd2008-06-22 12:03:28 -03001127void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001128{
1129 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
Hans Verkuil83aaf132006-12-18 13:40:23 -03001130 int temporal = p->video_temporal_filter;
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001131
1132 /* Stream */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001133 printk(KERN_INFO "%s: Stream: %s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001134 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001135 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001136 if (p->stream_insert_nav_packets)
1137 printk(" (with navigation packets)");
1138 printk("\n");
Hans Verkuil44b579d2006-08-27 19:22:15 -03001139 printk(KERN_INFO "%s: VBI Format: %s\n",
1140 prefix,
1141 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001142
1143 /* Video */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001144 printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001145 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001146 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001147 p->is_50hz ? 25 : 30,
1148 (p->video_mute) ? " (muted)" : "");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001149 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
1150 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001151 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
1152 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
1153 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
1154 p->video_bitrate);
Hans Verkuil737bd412007-11-01 13:38:12 -03001155 if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001156 printk(", Peak %d", p->video_bitrate_peak);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001157 printk("\n");
Hans Verkuil737bd412007-11-01 13:38:12 -03001158 printk(KERN_INFO
1159 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001160 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001161 p->video_gop_size, p->video_b_frames,
Hans Verkuil75558ab2006-12-18 22:52:21 -03001162 p->video_gop_closure ? "" : "No ");
Hans Verkuil737bd412007-11-01 13:38:12 -03001163 if (p->video_temporal_decimation)
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001164 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
1165 prefix, p->video_temporal_decimation);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001166
1167 /* Audio */
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001168 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001169 prefix,
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001170 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
1171 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
Andy Walls0d82fe82009-01-01 19:02:31 -03001172 cx2341x_menu_item(p,
1173 p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
1174 ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
1175 : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
Hans Verkuil5eee72e2007-04-27 12:31:00 -03001176 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
1177 p->audio_mute ? " (muted)" : "");
Hans Verkuil737bd412007-11-01 13:38:12 -03001178 if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
1179 printk(", %s", cx2341x_menu_item(p,
1180 V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001181 printk(", %s, %s\n",
1182 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
1183 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
1184
1185 /* Encoding filters */
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001186 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
1187 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001188 cx2341x_menu_item(p,
1189 V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
1190 cx2341x_menu_item(p,
1191 V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
1192 cx2341x_menu_item(p,
1193 V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001194 p->video_spatial_filter);
Hans Verkuil737bd412007-11-01 13:38:12 -03001195
1196 if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
Hans Verkuil83aaf132006-12-18 13:40:23 -03001197 temporal = 0;
Hans Verkuil737bd412007-11-01 13:38:12 -03001198
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001199 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
1200 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001201 cx2341x_menu_item(p,
1202 V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
Hans Verkuil83aaf132006-12-18 13:40:23 -03001203 temporal);
Hans Verkuil737bd412007-11-01 13:38:12 -03001204 printk(KERN_INFO
1205 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
Hans Verkuil99eb44f2006-06-26 18:24:05 -03001206 prefix,
Hans Verkuil737bd412007-11-01 13:38:12 -03001207 cx2341x_menu_item(p,
1208 V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001209 p->video_luma_median_filter_bottom,
1210 p->video_luma_median_filter_top,
1211 p->video_chroma_median_filter_bottom,
1212 p->video_chroma_median_filter_top);
1213}
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001214EXPORT_SYMBOL(cx2341x_log_status);
Hans Verkuil5d1a9ae2006-06-18 14:40:30 -03001215
1216/*
1217 * Local variables:
1218 * c-basic-offset: 8
1219 * End:
1220 */
1221