cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cx2341x.c (57219B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * cx2341x - generic code for cx23415/6/8 based devices
      4 *
      5 * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
      6 */
      7
      8
      9#include <linux/module.h>
     10#include <linux/errno.h>
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/types.h>
     14#include <linux/videodev2.h>
     15
     16#include <media/tuner.h>
     17#include <media/drv-intf/cx2341x.h>
     18#include <media/v4l2-common.h>
     19
     20MODULE_DESCRIPTION("cx23415/6/8 driver");
     21MODULE_AUTHOR("Hans Verkuil");
     22MODULE_LICENSE("GPL");
     23
     24static int debug;
     25module_param(debug, int, 0644);
     26MODULE_PARM_DESC(debug, "Debug level (0-1)");
     27
     28/********************** COMMON CODE *********************/
     29
     30/* definitions for audio properties bits 29-28 */
     31#define CX2341X_AUDIO_ENCODING_METHOD_MPEG	0
     32#define CX2341X_AUDIO_ENCODING_METHOD_AC3	1
     33#define CX2341X_AUDIO_ENCODING_METHOD_LPCM	2
     34
     35static const char *cx2341x_get_name(u32 id)
     36{
     37	switch (id) {
     38	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
     39		return "Spatial Filter Mode";
     40	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
     41		return "Spatial Filter";
     42	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
     43		return "Spatial Luma Filter Type";
     44	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
     45		return "Spatial Chroma Filter Type";
     46	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
     47		return "Temporal Filter Mode";
     48	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
     49		return "Temporal Filter";
     50	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
     51		return "Median Filter Type";
     52	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
     53		return "Median Luma Filter Maximum";
     54	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
     55		return "Median Luma Filter Minimum";
     56	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
     57		return "Median Chroma Filter Maximum";
     58	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
     59		return "Median Chroma Filter Minimum";
     60	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
     61		return "Insert Navigation Packets";
     62	}
     63	return NULL;
     64}
     65
     66static const char **cx2341x_get_menu(u32 id)
     67{
     68	static const char *cx2341x_video_spatial_filter_mode_menu[] = {
     69		"Manual",
     70		"Auto",
     71		NULL
     72	};
     73
     74	static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
     75		"Off",
     76		"1D Horizontal",
     77		"1D Vertical",
     78		"2D H/V Separable",
     79		"2D Symmetric non-separable",
     80		NULL
     81	};
     82
     83	static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
     84		"Off",
     85		"1D Horizontal",
     86		NULL
     87	};
     88
     89	static const char *cx2341x_video_temporal_filter_mode_menu[] = {
     90		"Manual",
     91		"Auto",
     92		NULL
     93	};
     94
     95	static const char *cx2341x_video_median_filter_type_menu[] = {
     96		"Off",
     97		"Horizontal",
     98		"Vertical",
     99		"Horizontal/Vertical",
    100		"Diagonal",
    101		NULL
    102	};
    103
    104	switch (id) {
    105	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    106		return cx2341x_video_spatial_filter_mode_menu;
    107	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    108		return cx2341x_video_luma_spatial_filter_type_menu;
    109	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    110		return cx2341x_video_chroma_spatial_filter_type_menu;
    111	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    112		return cx2341x_video_temporal_filter_mode_menu;
    113	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    114		return cx2341x_video_median_filter_type_menu;
    115	}
    116	return NULL;
    117}
    118
    119static void cx2341x_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
    120		    s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags)
    121{
    122	*name = cx2341x_get_name(id);
    123	*flags = 0;
    124
    125	switch (id) {
    126	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    127	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    128	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    129	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    130	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    131		*type = V4L2_CTRL_TYPE_MENU;
    132		*min = 0;
    133		*step = 0;
    134		break;
    135	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
    136		*type = V4L2_CTRL_TYPE_BOOLEAN;
    137		*min = 0;
    138		*max = *step = 1;
    139		break;
    140	default:
    141		*type = V4L2_CTRL_TYPE_INTEGER;
    142		break;
    143	}
    144	switch (id) {
    145	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    146	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    147	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    148		*flags |= V4L2_CTRL_FLAG_UPDATE;
    149		break;
    150	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
    151	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
    152	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
    153	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
    154	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
    155	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
    156		*flags |= V4L2_CTRL_FLAG_SLIDER;
    157		break;
    158	case V4L2_CID_MPEG_VIDEO_ENCODING:
    159		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
    160		break;
    161	}
    162}
    163
    164
    165/********************** OLD CODE *********************/
    166
    167/* Must be sorted from low to high control ID! */
    168const u32 cx2341x_mpeg_ctrls[] = {
    169	V4L2_CID_CODEC_CLASS,
    170	V4L2_CID_MPEG_STREAM_TYPE,
    171	V4L2_CID_MPEG_STREAM_VBI_FMT,
    172	V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
    173	V4L2_CID_MPEG_AUDIO_ENCODING,
    174	V4L2_CID_MPEG_AUDIO_L2_BITRATE,
    175	V4L2_CID_MPEG_AUDIO_MODE,
    176	V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
    177	V4L2_CID_MPEG_AUDIO_EMPHASIS,
    178	V4L2_CID_MPEG_AUDIO_CRC,
    179	V4L2_CID_MPEG_AUDIO_MUTE,
    180	V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
    181	V4L2_CID_MPEG_VIDEO_ENCODING,
    182	V4L2_CID_MPEG_VIDEO_ASPECT,
    183	V4L2_CID_MPEG_VIDEO_B_FRAMES,
    184	V4L2_CID_MPEG_VIDEO_GOP_SIZE,
    185	V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
    186	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
    187	V4L2_CID_MPEG_VIDEO_BITRATE,
    188	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
    189	V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
    190	V4L2_CID_MPEG_VIDEO_MUTE,
    191	V4L2_CID_MPEG_VIDEO_MUTE_YUV,
    192	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
    193	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
    194	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
    195	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
    196	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
    197	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
    198	V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
    199	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
    200	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
    201	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
    202	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
    203	V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
    204	0
    205};
    206EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
    207
    208static const struct cx2341x_mpeg_params default_params = {
    209	/* misc */
    210	.capabilities = 0,
    211	.port = CX2341X_PORT_MEMORY,
    212	.width = 720,
    213	.height = 480,
    214	.is_50hz = 0,
    215
    216	/* stream */
    217	.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
    218	.stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
    219	.stream_insert_nav_packets = 0,
    220
    221	/* audio */
    222	.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
    223	.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
    224	.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
    225	.audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
    226	.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
    227	.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
    228	.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
    229	.audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
    230	.audio_mute = 0,
    231
    232	/* video */
    233	.video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
    234	.video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
    235	.video_b_frames = 2,
    236	.video_gop_size = 12,
    237	.video_gop_closure = 1,
    238	.video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
    239	.video_bitrate = 6000000,
    240	.video_bitrate_peak = 8000000,
    241	.video_temporal_decimation = 0,
    242	.video_mute = 0,
    243	.video_mute_yuv = 0x008080,  /* YCbCr value for black */
    244
    245	/* encoding filters */
    246	.video_spatial_filter_mode =
    247		V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
    248	.video_spatial_filter = 0,
    249	.video_luma_spatial_filter_type =
    250		V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
    251	.video_chroma_spatial_filter_type =
    252		V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
    253	.video_temporal_filter_mode =
    254		V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
    255	.video_temporal_filter = 8,
    256	.video_median_filter_type =
    257		V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
    258	.video_luma_median_filter_top = 255,
    259	.video_luma_median_filter_bottom = 0,
    260	.video_chroma_median_filter_top = 255,
    261	.video_chroma_median_filter_bottom = 0,
    262};
    263/* Map the control ID to the correct field in the cx2341x_mpeg_params
    264   struct. Return -EINVAL if the ID is unknown, else return 0. */
    265static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
    266		struct v4l2_ext_control *ctrl)
    267{
    268	switch (ctrl->id) {
    269	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
    270		ctrl->value = params->audio_sampling_freq;
    271		break;
    272	case V4L2_CID_MPEG_AUDIO_ENCODING:
    273		ctrl->value = params->audio_encoding;
    274		break;
    275	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
    276		ctrl->value = params->audio_l2_bitrate;
    277		break;
    278	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
    279		ctrl->value = params->audio_ac3_bitrate;
    280		break;
    281	case V4L2_CID_MPEG_AUDIO_MODE:
    282		ctrl->value = params->audio_mode;
    283		break;
    284	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
    285		ctrl->value = params->audio_mode_extension;
    286		break;
    287	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
    288		ctrl->value = params->audio_emphasis;
    289		break;
    290	case V4L2_CID_MPEG_AUDIO_CRC:
    291		ctrl->value = params->audio_crc;
    292		break;
    293	case V4L2_CID_MPEG_AUDIO_MUTE:
    294		ctrl->value = params->audio_mute;
    295		break;
    296	case V4L2_CID_MPEG_VIDEO_ENCODING:
    297		ctrl->value = params->video_encoding;
    298		break;
    299	case V4L2_CID_MPEG_VIDEO_ASPECT:
    300		ctrl->value = params->video_aspect;
    301		break;
    302	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
    303		ctrl->value = params->video_b_frames;
    304		break;
    305	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
    306		ctrl->value = params->video_gop_size;
    307		break;
    308	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
    309		ctrl->value = params->video_gop_closure;
    310		break;
    311	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
    312		ctrl->value = params->video_bitrate_mode;
    313		break;
    314	case V4L2_CID_MPEG_VIDEO_BITRATE:
    315		ctrl->value = params->video_bitrate;
    316		break;
    317	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
    318		ctrl->value = params->video_bitrate_peak;
    319		break;
    320	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
    321		ctrl->value = params->video_temporal_decimation;
    322		break;
    323	case V4L2_CID_MPEG_VIDEO_MUTE:
    324		ctrl->value = params->video_mute;
    325		break;
    326	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
    327		ctrl->value = params->video_mute_yuv;
    328		break;
    329	case V4L2_CID_MPEG_STREAM_TYPE:
    330		ctrl->value = params->stream_type;
    331		break;
    332	case V4L2_CID_MPEG_STREAM_VBI_FMT:
    333		ctrl->value = params->stream_vbi_fmt;
    334		break;
    335	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    336		ctrl->value = params->video_spatial_filter_mode;
    337		break;
    338	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
    339		ctrl->value = params->video_spatial_filter;
    340		break;
    341	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    342		ctrl->value = params->video_luma_spatial_filter_type;
    343		break;
    344	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    345		ctrl->value = params->video_chroma_spatial_filter_type;
    346		break;
    347	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    348		ctrl->value = params->video_temporal_filter_mode;
    349		break;
    350	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
    351		ctrl->value = params->video_temporal_filter;
    352		break;
    353	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    354		ctrl->value = params->video_median_filter_type;
    355		break;
    356	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
    357		ctrl->value = params->video_luma_median_filter_top;
    358		break;
    359	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
    360		ctrl->value = params->video_luma_median_filter_bottom;
    361		break;
    362	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
    363		ctrl->value = params->video_chroma_median_filter_top;
    364		break;
    365	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
    366		ctrl->value = params->video_chroma_median_filter_bottom;
    367		break;
    368	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
    369		ctrl->value = params->stream_insert_nav_packets;
    370		break;
    371	default:
    372		return -EINVAL;
    373	}
    374	return 0;
    375}
    376
    377/* Map the control ID to the correct field in the cx2341x_mpeg_params
    378   struct. Return -EINVAL if the ID is unknown, else return 0. */
    379static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
    380		struct v4l2_ext_control *ctrl)
    381{
    382	switch (ctrl->id) {
    383	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
    384		if (busy)
    385			return -EBUSY;
    386		params->audio_sampling_freq = ctrl->value;
    387		break;
    388	case V4L2_CID_MPEG_AUDIO_ENCODING:
    389		if (busy)
    390			return -EBUSY;
    391		if (params->capabilities & CX2341X_CAP_HAS_AC3)
    392			if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
    393			    ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
    394				return -ERANGE;
    395		params->audio_encoding = ctrl->value;
    396		break;
    397	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
    398		if (busy)
    399			return -EBUSY;
    400		params->audio_l2_bitrate = ctrl->value;
    401		break;
    402	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
    403		if (busy)
    404			return -EBUSY;
    405		if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
    406			return -EINVAL;
    407		params->audio_ac3_bitrate = ctrl->value;
    408		break;
    409	case V4L2_CID_MPEG_AUDIO_MODE:
    410		params->audio_mode = ctrl->value;
    411		break;
    412	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
    413		params->audio_mode_extension = ctrl->value;
    414		break;
    415	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
    416		params->audio_emphasis = ctrl->value;
    417		break;
    418	case V4L2_CID_MPEG_AUDIO_CRC:
    419		params->audio_crc = ctrl->value;
    420		break;
    421	case V4L2_CID_MPEG_AUDIO_MUTE:
    422		params->audio_mute = ctrl->value;
    423		break;
    424	case V4L2_CID_MPEG_VIDEO_ASPECT:
    425		params->video_aspect = ctrl->value;
    426		break;
    427	case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
    428		int b = ctrl->value + 1;
    429		int gop = params->video_gop_size;
    430		params->video_b_frames = ctrl->value;
    431		params->video_gop_size = b * ((gop + b - 1) / b);
    432		/* Max GOP size = 34 */
    433		while (params->video_gop_size > 34)
    434			params->video_gop_size -= b;
    435		break;
    436	}
    437	case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
    438		int b = params->video_b_frames + 1;
    439		int gop = ctrl->value;
    440		params->video_gop_size = b * ((gop + b - 1) / b);
    441		/* Max GOP size = 34 */
    442		while (params->video_gop_size > 34)
    443			params->video_gop_size -= b;
    444		ctrl->value = params->video_gop_size;
    445		break;
    446	}
    447	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
    448		params->video_gop_closure = ctrl->value;
    449		break;
    450	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
    451		if (busy)
    452			return -EBUSY;
    453		/* MPEG-1 only allows CBR */
    454		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
    455		    ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
    456			return -EINVAL;
    457		params->video_bitrate_mode = ctrl->value;
    458		break;
    459	case V4L2_CID_MPEG_VIDEO_BITRATE:
    460		if (busy)
    461			return -EBUSY;
    462		params->video_bitrate = ctrl->value;
    463		break;
    464	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
    465		if (busy)
    466			return -EBUSY;
    467		params->video_bitrate_peak = ctrl->value;
    468		break;
    469	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
    470		params->video_temporal_decimation = ctrl->value;
    471		break;
    472	case V4L2_CID_MPEG_VIDEO_MUTE:
    473		params->video_mute = (ctrl->value != 0);
    474		break;
    475	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
    476		params->video_mute_yuv = ctrl->value;
    477		break;
    478	case V4L2_CID_MPEG_STREAM_TYPE:
    479		if (busy)
    480			return -EBUSY;
    481		params->stream_type = ctrl->value;
    482		params->video_encoding =
    483		    (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
    484		     params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
    485			V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
    486			V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
    487		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
    488			/* MPEG-1 implies CBR */
    489			params->video_bitrate_mode =
    490				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
    491		break;
    492	case V4L2_CID_MPEG_STREAM_VBI_FMT:
    493		params->stream_vbi_fmt = ctrl->value;
    494		break;
    495	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    496		params->video_spatial_filter_mode = ctrl->value;
    497		break;
    498	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
    499		params->video_spatial_filter = ctrl->value;
    500		break;
    501	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    502		params->video_luma_spatial_filter_type = ctrl->value;
    503		break;
    504	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    505		params->video_chroma_spatial_filter_type = ctrl->value;
    506		break;
    507	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    508		params->video_temporal_filter_mode = ctrl->value;
    509		break;
    510	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
    511		params->video_temporal_filter = ctrl->value;
    512		break;
    513	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    514		params->video_median_filter_type = ctrl->value;
    515		break;
    516	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
    517		params->video_luma_median_filter_top = ctrl->value;
    518		break;
    519	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
    520		params->video_luma_median_filter_bottom = ctrl->value;
    521		break;
    522	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
    523		params->video_chroma_median_filter_top = ctrl->value;
    524		break;
    525	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
    526		params->video_chroma_median_filter_bottom = ctrl->value;
    527		break;
    528	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
    529		params->stream_insert_nav_packets = ctrl->value;
    530		break;
    531	default:
    532		return -EINVAL;
    533	}
    534	return 0;
    535}
    536
    537static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
    538				   s32 min, s32 max, s32 step, s32 def)
    539{
    540	const char *name;
    541
    542	switch (qctrl->id) {
    543	/* MPEG controls */
    544	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    545	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
    546	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    547	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    548	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    549	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
    550	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    551	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
    552	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
    553	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
    554	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
    555	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
    556		cx2341x_ctrl_fill(qctrl->id, &name, &qctrl->type,
    557				&min, &max, &step, &def, &qctrl->flags);
    558		qctrl->minimum = min;
    559		qctrl->maximum = max;
    560		qctrl->step = step;
    561		qctrl->default_value = def;
    562		qctrl->reserved[0] = qctrl->reserved[1] = 0;
    563		strscpy(qctrl->name, name, sizeof(qctrl->name));
    564		return 0;
    565
    566	default:
    567		return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
    568	}
    569}
    570
    571int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
    572		       struct v4l2_queryctrl *qctrl)
    573{
    574	int err;
    575
    576	switch (qctrl->id) {
    577	case V4L2_CID_CODEC_CLASS:
    578		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
    579	case V4L2_CID_MPEG_STREAM_TYPE:
    580		return v4l2_ctrl_query_fill(qctrl,
    581				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
    582				V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
    583				V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
    584
    585	case V4L2_CID_MPEG_STREAM_VBI_FMT:
    586		if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
    587			return v4l2_ctrl_query_fill(qctrl,
    588					V4L2_MPEG_STREAM_VBI_FMT_NONE,
    589					V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
    590					V4L2_MPEG_STREAM_VBI_FMT_NONE);
    591		return cx2341x_ctrl_query_fill(qctrl,
    592				V4L2_MPEG_STREAM_VBI_FMT_NONE,
    593				V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
    594				default_params.stream_vbi_fmt);
    595
    596	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
    597		return v4l2_ctrl_query_fill(qctrl,
    598				V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
    599				V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
    600				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
    601
    602	case V4L2_CID_MPEG_AUDIO_ENCODING:
    603		if (params->capabilities & CX2341X_CAP_HAS_AC3) {
    604			/*
    605			 * The state of L2 & AC3 bitrate controls can change
    606			 * when this control changes, but v4l2_ctrl_query_fill()
    607			 * already sets V4L2_CTRL_FLAG_UPDATE for
    608			 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
    609			 */
    610			return v4l2_ctrl_query_fill(qctrl,
    611					V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
    612					V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
    613					default_params.audio_encoding);
    614		}
    615
    616		return v4l2_ctrl_query_fill(qctrl,
    617				V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
    618				V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
    619				default_params.audio_encoding);
    620
    621	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
    622		err = v4l2_ctrl_query_fill(qctrl,
    623				V4L2_MPEG_AUDIO_L2_BITRATE_192K,
    624				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
    625				default_params.audio_l2_bitrate);
    626		if (err)
    627			return err;
    628		if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
    629		    params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
    630			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    631		return 0;
    632
    633	case V4L2_CID_MPEG_AUDIO_MODE:
    634		return v4l2_ctrl_query_fill(qctrl,
    635				V4L2_MPEG_AUDIO_MODE_STEREO,
    636				V4L2_MPEG_AUDIO_MODE_MONO, 1,
    637				V4L2_MPEG_AUDIO_MODE_STEREO);
    638
    639	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
    640		err = v4l2_ctrl_query_fill(qctrl,
    641				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
    642				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
    643				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
    644		if (err == 0 &&
    645		    params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
    646			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    647		return err;
    648
    649	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
    650		return v4l2_ctrl_query_fill(qctrl,
    651				V4L2_MPEG_AUDIO_EMPHASIS_NONE,
    652				V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
    653				V4L2_MPEG_AUDIO_EMPHASIS_NONE);
    654
    655	case V4L2_CID_MPEG_AUDIO_CRC:
    656		return v4l2_ctrl_query_fill(qctrl,
    657				V4L2_MPEG_AUDIO_CRC_NONE,
    658				V4L2_MPEG_AUDIO_CRC_CRC16, 1,
    659				V4L2_MPEG_AUDIO_CRC_NONE);
    660
    661	case V4L2_CID_MPEG_AUDIO_MUTE:
    662		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
    663
    664	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
    665		err = v4l2_ctrl_query_fill(qctrl,
    666				V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
    667				V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
    668				default_params.audio_ac3_bitrate);
    669		if (err)
    670			return err;
    671		if (params->capabilities & CX2341X_CAP_HAS_AC3) {
    672			if (params->audio_encoding !=
    673						   V4L2_MPEG_AUDIO_ENCODING_AC3)
    674				qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    675		} else
    676			qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
    677		return 0;
    678
    679	case V4L2_CID_MPEG_VIDEO_ENCODING:
    680		/* this setting is read-only for the cx2341x since the
    681		   V4L2_CID_MPEG_STREAM_TYPE really determines the
    682		   MPEG-1/2 setting */
    683		err = v4l2_ctrl_query_fill(qctrl,
    684					   V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
    685					   V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
    686					   V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
    687		if (err == 0)
    688			qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
    689		return err;
    690
    691	case V4L2_CID_MPEG_VIDEO_ASPECT:
    692		return v4l2_ctrl_query_fill(qctrl,
    693				V4L2_MPEG_VIDEO_ASPECT_1x1,
    694				V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
    695				V4L2_MPEG_VIDEO_ASPECT_4x3);
    696
    697	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
    698		return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
    699
    700	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
    701		return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
    702				params->is_50hz ? 12 : 15);
    703
    704	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
    705		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
    706
    707	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
    708		err = v4l2_ctrl_query_fill(qctrl,
    709				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
    710				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
    711				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
    712		if (err == 0 &&
    713		    params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
    714			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    715		return err;
    716
    717	case V4L2_CID_MPEG_VIDEO_BITRATE:
    718		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
    719
    720	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
    721		err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
    722		if (err == 0 &&
    723		    params->video_bitrate_mode ==
    724				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
    725			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    726		return err;
    727
    728	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
    729		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
    730
    731	case V4L2_CID_MPEG_VIDEO_MUTE:
    732		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
    733
    734	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:  /* Init YUV (really YCbCr) to black */
    735		return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
    736
    737	/* CX23415/6 specific */
    738	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    739		return cx2341x_ctrl_query_fill(qctrl,
    740			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
    741			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
    742			default_params.video_spatial_filter_mode);
    743
    744	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
    745		cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
    746				default_params.video_spatial_filter);
    747		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    748		if (params->video_spatial_filter_mode ==
    749			    V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
    750			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    751		return 0;
    752
    753	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    754		cx2341x_ctrl_query_fill(qctrl,
    755			V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
    756			V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
    757			1,
    758			default_params.video_luma_spatial_filter_type);
    759		if (params->video_spatial_filter_mode ==
    760			    V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
    761			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    762		return 0;
    763
    764	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    765		cx2341x_ctrl_query_fill(qctrl,
    766		    V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
    767		    V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
    768		    1,
    769		    default_params.video_chroma_spatial_filter_type);
    770		if (params->video_spatial_filter_mode ==
    771			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
    772			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    773		return 0;
    774
    775	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    776		return cx2341x_ctrl_query_fill(qctrl,
    777			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
    778			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
    779			default_params.video_temporal_filter_mode);
    780
    781	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
    782		cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
    783				default_params.video_temporal_filter);
    784		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    785		if (params->video_temporal_filter_mode ==
    786			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
    787			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    788		return 0;
    789
    790	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    791		return cx2341x_ctrl_query_fill(qctrl,
    792			V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
    793			V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
    794			default_params.video_median_filter_type);
    795
    796	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
    797		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
    798				default_params.video_luma_median_filter_top);
    799		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    800		if (params->video_median_filter_type ==
    801				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
    802			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    803		return 0;
    804
    805	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
    806		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
    807				default_params.video_luma_median_filter_bottom);
    808		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    809		if (params->video_median_filter_type ==
    810				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
    811			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    812		return 0;
    813
    814	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
    815		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
    816				default_params.video_chroma_median_filter_top);
    817		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    818		if (params->video_median_filter_type ==
    819				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
    820			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    821		return 0;
    822
    823	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
    824		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
    825			default_params.video_chroma_median_filter_bottom);
    826		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
    827		if (params->video_median_filter_type ==
    828				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
    829			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
    830		return 0;
    831
    832	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
    833		return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
    834				default_params.stream_insert_nav_packets);
    835
    836	default:
    837		return -EINVAL;
    838
    839	}
    840}
    841EXPORT_SYMBOL(cx2341x_ctrl_query);
    842
    843const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
    844{
    845	static const char * const mpeg_stream_type_without_ts[] = {
    846		"MPEG-2 Program Stream",
    847		"",
    848		"MPEG-1 System Stream",
    849		"MPEG-2 DVD-compatible Stream",
    850		"MPEG-1 VCD-compatible Stream",
    851		"MPEG-2 SVCD-compatible Stream",
    852		NULL
    853	};
    854
    855	static const char *mpeg_stream_type_with_ts[] = {
    856		"MPEG-2 Program Stream",
    857		"MPEG-2 Transport Stream",
    858		"MPEG-1 System Stream",
    859		"MPEG-2 DVD-compatible Stream",
    860		"MPEG-1 VCD-compatible Stream",
    861		"MPEG-2 SVCD-compatible Stream",
    862		NULL
    863	};
    864
    865	static const char *mpeg_audio_encoding_l2_ac3[] = {
    866		"",
    867		"MPEG-1/2 Layer II",
    868		"",
    869		"",
    870		"AC-3",
    871		NULL
    872	};
    873
    874	switch (id) {
    875	case V4L2_CID_MPEG_STREAM_TYPE:
    876		return (p->capabilities & CX2341X_CAP_HAS_TS) ?
    877			mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
    878	case V4L2_CID_MPEG_AUDIO_ENCODING:
    879		return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
    880			mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
    881	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
    882	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
    883		return NULL;
    884	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
    885	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
    886	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
    887	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
    888	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
    889		return cx2341x_get_menu(id);
    890	default:
    891		return v4l2_ctrl_get_menu(id);
    892	}
    893}
    894EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
    895
    896static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
    897{
    898	params->audio_properties =
    899		(params->audio_sampling_freq << 0) |
    900		(params->audio_mode << 8) |
    901		(params->audio_mode_extension << 10) |
    902		(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
    903		  ? 3 : params->audio_emphasis) << 12) |
    904		(params->audio_crc << 14);
    905
    906	if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
    907	    params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
    908		params->audio_properties |=
    909			/* Not sure if this MPEG Layer II setting is required */
    910			((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
    911			(params->audio_ac3_bitrate << 4) |
    912			(CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
    913	} else {
    914		/* Assuming MPEG Layer II */
    915		params->audio_properties |=
    916			((3 - params->audio_encoding) << 2) |
    917			((1 + params->audio_l2_bitrate) << 4);
    918	}
    919}
    920
    921/* Check for correctness of the ctrl's value based on the data from
    922   struct v4l2_queryctrl and the available menu items. Note that
    923   menu_items may be NULL, in that case it is ignored. */
    924static int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
    925		const char * const *menu_items)
    926{
    927	if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
    928		return -EINVAL;
    929	if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
    930		return -EBUSY;
    931	if (qctrl->type == V4L2_CTRL_TYPE_STRING)
    932		return 0;
    933	if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
    934	    qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
    935	    qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
    936		return 0;
    937	if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
    938		return -ERANGE;
    939	if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
    940		if (menu_items[ctrl->value] == NULL ||
    941		    menu_items[ctrl->value][0] == '\0')
    942			return -EINVAL;
    943	}
    944	if (qctrl->type == V4L2_CTRL_TYPE_BITMASK &&
    945			(ctrl->value & ~qctrl->maximum))
    946		return -ERANGE;
    947	return 0;
    948}
    949
    950int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
    951		  struct v4l2_ext_controls *ctrls, unsigned int cmd)
    952{
    953	int err = 0;
    954	int i;
    955
    956	if (cmd == VIDIOC_G_EXT_CTRLS) {
    957		for (i = 0; i < ctrls->count; i++) {
    958			struct v4l2_ext_control *ctrl = ctrls->controls + i;
    959
    960			err = cx2341x_get_ctrl(params, ctrl);
    961			if (err) {
    962				ctrls->error_idx = i;
    963				break;
    964			}
    965		}
    966		return err;
    967	}
    968	for (i = 0; i < ctrls->count; i++) {
    969		struct v4l2_ext_control *ctrl = ctrls->controls + i;
    970		struct v4l2_queryctrl qctrl;
    971		const char * const *menu_items = NULL;
    972
    973		qctrl.id = ctrl->id;
    974		err = cx2341x_ctrl_query(params, &qctrl);
    975		if (err)
    976			break;
    977		if (qctrl.type == V4L2_CTRL_TYPE_MENU)
    978			menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
    979		err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
    980		if (err)
    981			break;
    982		err = cx2341x_set_ctrl(params, busy, ctrl);
    983		if (err)
    984			break;
    985	}
    986	if (err == 0 &&
    987	    params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
    988	    params->video_bitrate_peak < params->video_bitrate) {
    989		err = -ERANGE;
    990		ctrls->error_idx = ctrls->count;
    991	}
    992	if (err)
    993		ctrls->error_idx = i;
    994	else
    995		cx2341x_calc_audio_properties(params);
    996	return err;
    997}
    998EXPORT_SYMBOL(cx2341x_ext_ctrls);
    999
   1000void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
   1001{
   1002	*p = default_params;
   1003	cx2341x_calc_audio_properties(p);
   1004}
   1005EXPORT_SYMBOL(cx2341x_fill_defaults);
   1006
   1007static int cx2341x_api(void *priv, cx2341x_mbox_func func,
   1008		       u32 cmd, int args, ...)
   1009{
   1010	u32 data[CX2341X_MBOX_MAX_DATA];
   1011	va_list vargs;
   1012	int i;
   1013
   1014	va_start(vargs, args);
   1015
   1016	for (i = 0; i < args; i++)
   1017		data[i] = va_arg(vargs, int);
   1018	va_end(vargs);
   1019	return func(priv, cmd, args, 0, data);
   1020}
   1021
   1022#define CMP_FIELD(__old, __new, __field) (__old->__field != __new->__field)
   1023
   1024int cx2341x_update(void *priv, cx2341x_mbox_func func,
   1025		   const struct cx2341x_mpeg_params *old,
   1026		   const struct cx2341x_mpeg_params *new)
   1027{
   1028	static int mpeg_stream_type[] = {
   1029		0,	/* MPEG-2 PS */
   1030		1,	/* MPEG-2 TS */
   1031		2,	/* MPEG-1 SS */
   1032		14,	/* DVD */
   1033		11,	/* VCD */
   1034		12,	/* SVCD */
   1035	};
   1036	int err;
   1037
   1038	cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
   1039
   1040	if (!old ||
   1041	    CMP_FIELD(old, new, is_50hz)) {
   1042		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
   1043				  new->is_50hz);
   1044		if (err)
   1045			return err;
   1046	}
   1047
   1048	if (!old ||
   1049	    CMP_FIELD(old, new, width) ||
   1050	    CMP_FIELD(old, new, height) ||
   1051	    CMP_FIELD(old, new, video_encoding)) {
   1052		u16 w = new->width;
   1053		u16 h = new->height;
   1054
   1055		if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
   1056			w /= 2;
   1057			h /= 2;
   1058		}
   1059		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
   1060				  h, w);
   1061		if (err)
   1062			return err;
   1063	}
   1064	if (!old ||
   1065	    CMP_FIELD(old, new, stream_type)) {
   1066		err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
   1067				  mpeg_stream_type[new->stream_type]);
   1068		if (err)
   1069			return err;
   1070	}
   1071	if (!old ||
   1072	    CMP_FIELD(old, new, video_aspect)) {
   1073		err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
   1074				  1 + new->video_aspect);
   1075		if (err)
   1076			return err;
   1077	}
   1078	if (!old ||
   1079	    CMP_FIELD(old, new, video_b_frames) ||
   1080	    CMP_FIELD(old, new, video_gop_size)) {
   1081		err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
   1082				  new->video_gop_size, new->video_b_frames + 1);
   1083		if (err)
   1084			return err;
   1085	}
   1086	if (!old ||
   1087	    CMP_FIELD(old, new, video_gop_closure)) {
   1088		err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
   1089				  new->video_gop_closure);
   1090		if (err)
   1091			return err;
   1092	}
   1093	if (!old ||
   1094	    CMP_FIELD(old, new, audio_properties)) {
   1095		err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
   1096				  1, new->audio_properties);
   1097		if (err)
   1098			return err;
   1099	}
   1100	if (!old ||
   1101	    CMP_FIELD(old, new, audio_mute)) {
   1102		err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
   1103				  new->audio_mute);
   1104		if (err)
   1105			return err;
   1106	}
   1107	if (!old ||
   1108	    CMP_FIELD(old, new, video_bitrate_mode) ||
   1109	    CMP_FIELD(old, new, video_bitrate) ||
   1110	    CMP_FIELD(old, new, video_bitrate_peak)) {
   1111		err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
   1112				  new->video_bitrate_mode, new->video_bitrate,
   1113				  new->video_bitrate_peak / 400, 0, 0);
   1114		if (err)
   1115			return err;
   1116	}
   1117	if (!old ||
   1118	    CMP_FIELD(old, new, video_spatial_filter_mode) ||
   1119	    CMP_FIELD(old, new, video_temporal_filter_mode) ||
   1120	    CMP_FIELD(old, new, video_median_filter_type)) {
   1121		err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
   1122				  2,
   1123				  new->video_spatial_filter_mode |
   1124					(new->video_temporal_filter_mode << 1),
   1125				  new->video_median_filter_type);
   1126		if (err)
   1127			return err;
   1128	}
   1129	if (!old ||
   1130	    CMP_FIELD(old, new, video_luma_median_filter_bottom) ||
   1131	    CMP_FIELD(old, new, video_luma_median_filter_top) ||
   1132	    CMP_FIELD(old, new, video_chroma_median_filter_bottom) ||
   1133	    CMP_FIELD(old, new, video_chroma_median_filter_top)) {
   1134		err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
   1135				  new->video_luma_median_filter_bottom,
   1136				  new->video_luma_median_filter_top,
   1137				  new->video_chroma_median_filter_bottom,
   1138				  new->video_chroma_median_filter_top);
   1139		if (err)
   1140			return err;
   1141	}
   1142	if (!old ||
   1143	    CMP_FIELD(old, new, video_luma_spatial_filter_type) ||
   1144	    CMP_FIELD(old, new, video_chroma_spatial_filter_type)) {
   1145		err = cx2341x_api(priv, func,
   1146				  CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
   1147				  2, new->video_luma_spatial_filter_type,
   1148				  new->video_chroma_spatial_filter_type);
   1149		if (err)
   1150			return err;
   1151	}
   1152	if (!old ||
   1153	    CMP_FIELD(old, new, video_spatial_filter) ||
   1154	    CMP_FIELD(old, new, video_temporal_filter)) {
   1155		err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
   1156				  2, new->video_spatial_filter,
   1157				  new->video_temporal_filter);
   1158		if (err)
   1159			return err;
   1160	}
   1161	if (!old ||
   1162	    CMP_FIELD(old, new, video_temporal_decimation)) {
   1163		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
   1164				  1, new->video_temporal_decimation);
   1165		if (err)
   1166			return err;
   1167	}
   1168	if (!old ||
   1169	    CMP_FIELD(old, new, video_mute) ||
   1170	    (new->video_mute && CMP_FIELD(old, new, video_mute_yuv))) {
   1171		err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
   1172				  new->video_mute | (new->video_mute_yuv << 8));
   1173		if (err)
   1174			return err;
   1175	}
   1176	if (!old ||
   1177	    CMP_FIELD(old, new, stream_insert_nav_packets)) {
   1178		err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
   1179				  7, new->stream_insert_nav_packets);
   1180		if (err)
   1181			return err;
   1182	}
   1183	return 0;
   1184}
   1185EXPORT_SYMBOL(cx2341x_update);
   1186
   1187static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
   1188{
   1189	const char * const *menu = cx2341x_ctrl_get_menu(p, id);
   1190	struct v4l2_ext_control ctrl;
   1191
   1192	if (menu == NULL)
   1193		goto invalid;
   1194	ctrl.id = id;
   1195	if (cx2341x_get_ctrl(p, &ctrl))
   1196		goto invalid;
   1197	while (ctrl.value-- && *menu) menu++;
   1198	if (*menu == NULL)
   1199		goto invalid;
   1200	return *menu;
   1201
   1202invalid:
   1203	return "<invalid>";
   1204}
   1205
   1206void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
   1207{
   1208	int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
   1209
   1210	/* Stream */
   1211	printk(KERN_INFO "%s: Stream: %s",
   1212		prefix,
   1213		cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
   1214	if (p->stream_insert_nav_packets)
   1215		printk(KERN_CONT " (with navigation packets)");
   1216	printk(KERN_CONT "\n");
   1217	printk(KERN_INFO "%s: VBI Format: %s\n",
   1218		prefix,
   1219		cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
   1220
   1221	/* Video */
   1222	printk(KERN_INFO "%s: Video:  %dx%d, %d fps%s\n",
   1223		prefix,
   1224		p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
   1225		p->is_50hz ? 25 : 30,
   1226		(p->video_mute) ? " (muted)" : "");
   1227	printk(KERN_INFO "%s: Video:  %s, %s, %s, %d",
   1228		prefix,
   1229		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
   1230		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
   1231		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
   1232		p->video_bitrate);
   1233	if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
   1234		printk(KERN_CONT ", Peak %d", p->video_bitrate_peak);
   1235	printk(KERN_CONT "\n");
   1236	printk(KERN_INFO
   1237		"%s: Video:  GOP Size %d, %d B-Frames, %sGOP Closure\n",
   1238		prefix,
   1239		p->video_gop_size, p->video_b_frames,
   1240		p->video_gop_closure ? "" : "No ");
   1241	if (p->video_temporal_decimation)
   1242		printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
   1243			prefix, p->video_temporal_decimation);
   1244
   1245	/* Audio */
   1246	printk(KERN_INFO "%s: Audio:  %s, %s, %s, %s%s",
   1247		prefix,
   1248		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
   1249		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
   1250		cx2341x_menu_item(p,
   1251			   p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
   1252					      ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
   1253					      : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
   1254		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
   1255		p->audio_mute ? " (muted)" : "");
   1256	if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
   1257		printk(KERN_CONT ", %s", cx2341x_menu_item(p,
   1258				V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
   1259	printk(KERN_CONT ", %s, %s\n",
   1260		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
   1261		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
   1262
   1263	/* Encoding filters */
   1264	printk(KERN_INFO "%s: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
   1265		prefix,
   1266		cx2341x_menu_item(p,
   1267		    V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
   1268		cx2341x_menu_item(p,
   1269		    V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
   1270		cx2341x_menu_item(p,
   1271		    V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
   1272		p->video_spatial_filter);
   1273
   1274	printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
   1275		prefix,
   1276		cx2341x_menu_item(p,
   1277			V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
   1278		p->video_temporal_filter);
   1279	printk(KERN_INFO
   1280		"%s: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
   1281		prefix,
   1282		cx2341x_menu_item(p,
   1283			V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
   1284		p->video_luma_median_filter_bottom,
   1285		p->video_luma_median_filter_top,
   1286		p->video_chroma_median_filter_bottom,
   1287		p->video_chroma_median_filter_top);
   1288}
   1289EXPORT_SYMBOL(cx2341x_log_status);
   1290
   1291
   1292
   1293/********************** NEW CODE *********************/
   1294
   1295static inline struct cx2341x_handler *to_cxhdl(struct v4l2_ctrl *ctrl)
   1296{
   1297	return container_of(ctrl->handler, struct cx2341x_handler, hdl);
   1298}
   1299
   1300static int cx2341x_hdl_api(struct cx2341x_handler *hdl,
   1301		       u32 cmd, int args, ...)
   1302{
   1303	u32 data[CX2341X_MBOX_MAX_DATA];
   1304	va_list vargs;
   1305	int i;
   1306
   1307	va_start(vargs, args);
   1308
   1309	for (i = 0; i < args; i++)
   1310		data[i] = va_arg(vargs, int);
   1311	va_end(vargs);
   1312	return hdl->func(hdl->priv, cmd, args, 0, data);
   1313}
   1314
   1315/* ctrl->handler->lock is held, so it is safe to access cur.val */
   1316static inline int cx2341x_neq(struct v4l2_ctrl *ctrl)
   1317{
   1318	return ctrl && ctrl->val != ctrl->cur.val;
   1319}
   1320
   1321static int cx2341x_try_ctrl(struct v4l2_ctrl *ctrl)
   1322{
   1323	struct cx2341x_handler *hdl = to_cxhdl(ctrl);
   1324	s32 val = ctrl->val;
   1325
   1326	switch (ctrl->id) {
   1327	case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
   1328		/* video gop cluster */
   1329		int b = val + 1;
   1330		int gop = hdl->video_gop_size->val;
   1331
   1332		gop = b * ((gop + b - 1) / b);
   1333
   1334		/* Max GOP size = 34 */
   1335		while (gop > 34)
   1336			gop -= b;
   1337		hdl->video_gop_size->val = gop;
   1338		break;
   1339	}
   1340
   1341	case V4L2_CID_MPEG_STREAM_TYPE:
   1342		/* stream type cluster */
   1343		hdl->video_encoding->val =
   1344		    (hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
   1345		     hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
   1346			V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
   1347			V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
   1348		if (hdl->video_encoding->val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
   1349			/* MPEG-1 implies CBR */
   1350			hdl->video_bitrate_mode->val =
   1351				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
   1352		/* peak bitrate shall be >= normal bitrate */
   1353		if (hdl->video_bitrate_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
   1354		    hdl->video_bitrate_peak->val < hdl->video_bitrate->val)
   1355			hdl->video_bitrate_peak->val = hdl->video_bitrate->val;
   1356		break;
   1357	}
   1358	return 0;
   1359}
   1360
   1361static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
   1362{
   1363	static const int mpeg_stream_type[] = {
   1364		0,	/* MPEG-2 PS */
   1365		1,	/* MPEG-2 TS */
   1366		2,	/* MPEG-1 SS */
   1367		14,	/* DVD */
   1368		11,	/* VCD */
   1369		12,	/* SVCD */
   1370	};
   1371	struct cx2341x_handler *hdl = to_cxhdl(ctrl);
   1372	s32 val = ctrl->val;
   1373	u32 props;
   1374	int err;
   1375
   1376	switch (ctrl->id) {
   1377	case V4L2_CID_MPEG_STREAM_VBI_FMT:
   1378		if (hdl->ops && hdl->ops->s_stream_vbi_fmt)
   1379			return hdl->ops->s_stream_vbi_fmt(hdl, val);
   1380		return 0;
   1381
   1382	case V4L2_CID_MPEG_VIDEO_ASPECT:
   1383		return cx2341x_hdl_api(hdl,
   1384			CX2341X_ENC_SET_ASPECT_RATIO, 1, val + 1);
   1385
   1386	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
   1387		return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_CLOSURE, 1, val);
   1388
   1389	case V4L2_CID_MPEG_AUDIO_MUTE:
   1390		return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_AUDIO, 1, val);
   1391
   1392	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
   1393		return cx2341x_hdl_api(hdl,
   1394			CX2341X_ENC_SET_FRAME_DROP_RATE, 1, val);
   1395
   1396	case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
   1397		return cx2341x_hdl_api(hdl, CX2341X_ENC_MISC, 2, 7, val);
   1398
   1399	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
   1400		/* audio properties cluster */
   1401		props = (hdl->audio_sampling_freq->val << 0) |
   1402			(hdl->audio_mode->val << 8) |
   1403			(hdl->audio_mode_extension->val << 10) |
   1404			(hdl->audio_crc->val << 14);
   1405		if (hdl->audio_emphasis->val == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
   1406			props |= 3 << 12;
   1407		else
   1408			props |= hdl->audio_emphasis->val << 12;
   1409
   1410		if (hdl->audio_encoding->val == V4L2_MPEG_AUDIO_ENCODING_AC3) {
   1411			props |=
   1412#if 1
   1413				/* Not sure if this MPEG Layer II setting is required */
   1414				((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
   1415#endif
   1416				(hdl->audio_ac3_bitrate->val << 4) |
   1417				(CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
   1418		} else {
   1419			/* Assuming MPEG Layer II */
   1420			props |=
   1421				((3 - hdl->audio_encoding->val) << 2) |
   1422				((1 + hdl->audio_l2_bitrate->val) << 4);
   1423		}
   1424		err = cx2341x_hdl_api(hdl,
   1425				CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, props);
   1426		if (err)
   1427			return err;
   1428
   1429		hdl->audio_properties = props;
   1430		if (hdl->audio_ac3_bitrate) {
   1431			int is_ac3 = hdl->audio_encoding->val ==
   1432						V4L2_MPEG_AUDIO_ENCODING_AC3;
   1433
   1434			v4l2_ctrl_activate(hdl->audio_ac3_bitrate, is_ac3);
   1435			v4l2_ctrl_activate(hdl->audio_l2_bitrate, !is_ac3);
   1436		}
   1437		v4l2_ctrl_activate(hdl->audio_mode_extension,
   1438			hdl->audio_mode->val == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO);
   1439		if (cx2341x_neq(hdl->audio_sampling_freq) &&
   1440		    hdl->ops && hdl->ops->s_audio_sampling_freq)
   1441			return hdl->ops->s_audio_sampling_freq(hdl, hdl->audio_sampling_freq->val);
   1442		if (cx2341x_neq(hdl->audio_mode) &&
   1443		    hdl->ops && hdl->ops->s_audio_mode)
   1444			return hdl->ops->s_audio_mode(hdl, hdl->audio_mode->val);
   1445		return 0;
   1446
   1447	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
   1448		/* video gop cluster */
   1449		return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
   1450				hdl->video_gop_size->val,
   1451				hdl->video_b_frames->val + 1);
   1452
   1453	case V4L2_CID_MPEG_STREAM_TYPE:
   1454		/* stream type cluster */
   1455		err = cx2341x_hdl_api(hdl,
   1456			CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[val]);
   1457		if (err)
   1458			return err;
   1459
   1460		err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_BIT_RATE, 5,
   1461				hdl->video_bitrate_mode->val,
   1462				hdl->video_bitrate->val,
   1463				hdl->video_bitrate_peak->val / 400, 0, 0);
   1464		if (err)
   1465			return err;
   1466
   1467		v4l2_ctrl_activate(hdl->video_bitrate_mode,
   1468			hdl->video_encoding->val != V4L2_MPEG_VIDEO_ENCODING_MPEG_1);
   1469		v4l2_ctrl_activate(hdl->video_bitrate_peak,
   1470			hdl->video_bitrate_mode->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
   1471		if (cx2341x_neq(hdl->video_encoding) &&
   1472		    hdl->ops && hdl->ops->s_video_encoding)
   1473			return hdl->ops->s_video_encoding(hdl, hdl->video_encoding->val);
   1474		return 0;
   1475
   1476	case V4L2_CID_MPEG_VIDEO_MUTE:
   1477		/* video mute cluster */
   1478		return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_VIDEO, 1,
   1479				hdl->video_mute->val |
   1480					(hdl->video_mute_yuv->val << 8));
   1481
   1482	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: {
   1483		int active_filter;
   1484
   1485		/* video filter mode */
   1486		err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
   1487				hdl->video_spatial_filter_mode->val |
   1488					(hdl->video_temporal_filter_mode->val << 1),
   1489				hdl->video_median_filter_type->val);
   1490		if (err)
   1491			return err;
   1492
   1493		active_filter = hdl->video_spatial_filter_mode->val !=
   1494				V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO;
   1495		v4l2_ctrl_activate(hdl->video_spatial_filter, active_filter);
   1496		v4l2_ctrl_activate(hdl->video_luma_spatial_filter_type, active_filter);
   1497		v4l2_ctrl_activate(hdl->video_chroma_spatial_filter_type, active_filter);
   1498		active_filter = hdl->video_temporal_filter_mode->val !=
   1499				V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO;
   1500		v4l2_ctrl_activate(hdl->video_temporal_filter, active_filter);
   1501		active_filter = hdl->video_median_filter_type->val !=
   1502				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF;
   1503		v4l2_ctrl_activate(hdl->video_luma_median_filter_bottom, active_filter);
   1504		v4l2_ctrl_activate(hdl->video_luma_median_filter_top, active_filter);
   1505		v4l2_ctrl_activate(hdl->video_chroma_median_filter_bottom, active_filter);
   1506		v4l2_ctrl_activate(hdl->video_chroma_median_filter_top, active_filter);
   1507		return 0;
   1508	}
   1509
   1510	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
   1511		/* video filter type cluster */
   1512		return cx2341x_hdl_api(hdl,
   1513				CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
   1514				hdl->video_luma_spatial_filter_type->val,
   1515				hdl->video_chroma_spatial_filter_type->val);
   1516
   1517	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
   1518		/* video filter cluster */
   1519		return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
   1520				hdl->video_spatial_filter->val,
   1521				hdl->video_temporal_filter->val);
   1522
   1523	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
   1524		/* video median cluster */
   1525		return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_CORING_LEVELS, 4,
   1526				hdl->video_luma_median_filter_bottom->val,
   1527				hdl->video_luma_median_filter_top->val,
   1528				hdl->video_chroma_median_filter_bottom->val,
   1529				hdl->video_chroma_median_filter_top->val);
   1530	}
   1531	return -EINVAL;
   1532}
   1533
   1534static const struct v4l2_ctrl_ops cx2341x_ops = {
   1535	.try_ctrl = cx2341x_try_ctrl,
   1536	.s_ctrl = cx2341x_s_ctrl,
   1537};
   1538
   1539static struct v4l2_ctrl *cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
   1540			u32 id, s32 min, s32 max, s32 step, s32 def)
   1541{
   1542	struct v4l2_ctrl_config cfg;
   1543
   1544	memset(&cfg, 0, sizeof(cfg));
   1545	cx2341x_ctrl_fill(id, &cfg.name, &cfg.type, &min, &max, &step, &def, &cfg.flags);
   1546	cfg.ops = &cx2341x_ops;
   1547	cfg.id = id;
   1548	cfg.min = min;
   1549	cfg.max = max;
   1550	cfg.def = def;
   1551	if (cfg.type == V4L2_CTRL_TYPE_MENU) {
   1552		cfg.step = 0;
   1553		cfg.menu_skip_mask = step;
   1554		cfg.qmenu = cx2341x_get_menu(id);
   1555	} else {
   1556		cfg.step = step;
   1557		cfg.menu_skip_mask = 0;
   1558	}
   1559	return v4l2_ctrl_new_custom(hdl, &cfg, NULL);
   1560}
   1561
   1562static struct v4l2_ctrl *cx2341x_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
   1563			u32 id, s32 min, s32 max, s32 step, s32 def)
   1564{
   1565	return v4l2_ctrl_new_std(hdl, &cx2341x_ops, id, min, max, step, def);
   1566}
   1567
   1568static struct v4l2_ctrl *cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler *hdl,
   1569			u32 id, s32 max, s32 mask, s32 def)
   1570{
   1571	return v4l2_ctrl_new_std_menu(hdl, &cx2341x_ops, id, max, mask, def);
   1572}
   1573
   1574int cx2341x_handler_init(struct cx2341x_handler *cxhdl,
   1575			 unsigned nr_of_controls_hint)
   1576{
   1577	struct v4l2_ctrl_handler *hdl = &cxhdl->hdl;
   1578	u32 caps = cxhdl->capabilities;
   1579	int has_sliced_vbi = caps & CX2341X_CAP_HAS_SLICED_VBI;
   1580	int has_ac3 = caps & CX2341X_CAP_HAS_AC3;
   1581	int has_ts = caps & CX2341X_CAP_HAS_TS;
   1582
   1583	cxhdl->width = 720;
   1584	cxhdl->height = 480;
   1585
   1586	v4l2_ctrl_handler_init(hdl, nr_of_controls_hint);
   1587
   1588	/* Add controls in ascending control ID order for fastest
   1589	   insertion time. */
   1590	cxhdl->stream_type = cx2341x_ctrl_new_menu(hdl,
   1591			V4L2_CID_MPEG_STREAM_TYPE,
   1592			V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, has_ts ? 0 : 2,
   1593			V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
   1594	cxhdl->stream_vbi_fmt = cx2341x_ctrl_new_menu(hdl,
   1595			V4L2_CID_MPEG_STREAM_VBI_FMT,
   1596			V4L2_MPEG_STREAM_VBI_FMT_IVTV, has_sliced_vbi ? 0 : 2,
   1597			V4L2_MPEG_STREAM_VBI_FMT_NONE);
   1598	cxhdl->audio_sampling_freq = cx2341x_ctrl_new_menu(hdl,
   1599			V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
   1600			V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 0,
   1601			V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
   1602	cxhdl->audio_encoding = cx2341x_ctrl_new_menu(hdl,
   1603			V4L2_CID_MPEG_AUDIO_ENCODING,
   1604			V4L2_MPEG_AUDIO_ENCODING_AC3, has_ac3 ? ~0x12 : ~0x2,
   1605			V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
   1606	cxhdl->audio_l2_bitrate = cx2341x_ctrl_new_menu(hdl,
   1607			V4L2_CID_MPEG_AUDIO_L2_BITRATE,
   1608			V4L2_MPEG_AUDIO_L2_BITRATE_384K, 0x1ff,
   1609			V4L2_MPEG_AUDIO_L2_BITRATE_224K);
   1610	cxhdl->audio_mode = cx2341x_ctrl_new_menu(hdl,
   1611			V4L2_CID_MPEG_AUDIO_MODE,
   1612			V4L2_MPEG_AUDIO_MODE_MONO, 0,
   1613			V4L2_MPEG_AUDIO_MODE_STEREO);
   1614	cxhdl->audio_mode_extension = cx2341x_ctrl_new_menu(hdl,
   1615			V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
   1616			V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 0,
   1617			V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
   1618	cxhdl->audio_emphasis = cx2341x_ctrl_new_menu(hdl,
   1619			V4L2_CID_MPEG_AUDIO_EMPHASIS,
   1620			V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 0,
   1621			V4L2_MPEG_AUDIO_EMPHASIS_NONE);
   1622	cxhdl->audio_crc = cx2341x_ctrl_new_menu(hdl,
   1623			V4L2_CID_MPEG_AUDIO_CRC,
   1624			V4L2_MPEG_AUDIO_CRC_CRC16, 0,
   1625			V4L2_MPEG_AUDIO_CRC_NONE);
   1626
   1627	cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_AUDIO_MUTE, 0, 1, 1, 0);
   1628	if (has_ac3)
   1629		cxhdl->audio_ac3_bitrate = cx2341x_ctrl_new_menu(hdl,
   1630				V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
   1631				V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 0x03,
   1632				V4L2_MPEG_AUDIO_AC3_BITRATE_224K);
   1633	cxhdl->video_encoding = cx2341x_ctrl_new_menu(hdl,
   1634			V4L2_CID_MPEG_VIDEO_ENCODING,
   1635			V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 0,
   1636			V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
   1637	cx2341x_ctrl_new_menu(hdl,
   1638			V4L2_CID_MPEG_VIDEO_ASPECT,
   1639			V4L2_MPEG_VIDEO_ASPECT_221x100, 0,
   1640			V4L2_MPEG_VIDEO_ASPECT_4x3);
   1641	cxhdl->video_b_frames = cx2341x_ctrl_new_std(hdl,
   1642			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 33, 1, 2);
   1643	cxhdl->video_gop_size = cx2341x_ctrl_new_std(hdl,
   1644			V4L2_CID_MPEG_VIDEO_GOP_SIZE,
   1645			1, 34, 1, cxhdl->is_50hz ? 12 : 15);
   1646	cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
   1647	cxhdl->video_bitrate_mode = cx2341x_ctrl_new_menu(hdl,
   1648			V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
   1649			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
   1650			V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
   1651	cxhdl->video_bitrate = cx2341x_ctrl_new_std(hdl,
   1652			V4L2_CID_MPEG_VIDEO_BITRATE,
   1653			0, 27000000, 1, 6000000);
   1654	cxhdl->video_bitrate_peak = cx2341x_ctrl_new_std(hdl,
   1655			V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
   1656			0, 27000000, 1, 8000000);
   1657	cx2341x_ctrl_new_std(hdl,
   1658			V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, 0, 255, 1, 0);
   1659	cxhdl->video_mute = cx2341x_ctrl_new_std(hdl,
   1660			V4L2_CID_MPEG_VIDEO_MUTE, 0, 1, 1, 0);
   1661	cxhdl->video_mute_yuv = cx2341x_ctrl_new_std(hdl,
   1662			V4L2_CID_MPEG_VIDEO_MUTE_YUV, 0, 0xffffff, 1, 0x008080);
   1663
   1664	/* CX23415/6 specific */
   1665	cxhdl->video_spatial_filter_mode = cx2341x_ctrl_new_custom(hdl,
   1666			V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
   1667			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
   1668			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 0,
   1669			V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
   1670	cxhdl->video_spatial_filter = cx2341x_ctrl_new_custom(hdl,
   1671			V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
   1672			0, 15, 1, 0);
   1673	cxhdl->video_luma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
   1674			V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
   1675			V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
   1676			V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
   1677			0,
   1678			V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR);
   1679	cxhdl->video_chroma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
   1680			V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
   1681			V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
   1682			V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
   1683			0,
   1684			V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR);
   1685	cxhdl->video_temporal_filter_mode = cx2341x_ctrl_new_custom(hdl,
   1686			V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
   1687			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
   1688			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO,
   1689			0,
   1690			V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
   1691	cxhdl->video_temporal_filter = cx2341x_ctrl_new_custom(hdl,
   1692			V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
   1693			0, 31, 1, 8);
   1694	cxhdl->video_median_filter_type = cx2341x_ctrl_new_custom(hdl,
   1695			V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
   1696			V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
   1697			V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG,
   1698			0,
   1699			V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
   1700	cxhdl->video_luma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
   1701			V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
   1702			0, 255, 1, 0);
   1703	cxhdl->video_luma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
   1704			V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
   1705			0, 255, 1, 255);
   1706	cxhdl->video_chroma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
   1707			V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
   1708			0, 255, 1, 0);
   1709	cxhdl->video_chroma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
   1710			V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
   1711			0, 255, 1, 255);
   1712	cx2341x_ctrl_new_custom(hdl, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
   1713			0, 1, 1, 0);
   1714
   1715	if (hdl->error) {
   1716		int err = hdl->error;
   1717
   1718		v4l2_ctrl_handler_free(hdl);
   1719		return err;
   1720	}
   1721
   1722	v4l2_ctrl_cluster(8, &cxhdl->audio_sampling_freq);
   1723	v4l2_ctrl_cluster(2, &cxhdl->video_b_frames);
   1724	v4l2_ctrl_cluster(5, &cxhdl->stream_type);
   1725	v4l2_ctrl_cluster(2, &cxhdl->video_mute);
   1726	v4l2_ctrl_cluster(3, &cxhdl->video_spatial_filter_mode);
   1727	v4l2_ctrl_cluster(2, &cxhdl->video_luma_spatial_filter_type);
   1728	v4l2_ctrl_cluster(2, &cxhdl->video_spatial_filter);
   1729	v4l2_ctrl_cluster(4, &cxhdl->video_luma_median_filter_top);
   1730
   1731	return 0;
   1732}
   1733EXPORT_SYMBOL(cx2341x_handler_init);
   1734
   1735void cx2341x_handler_set_50hz(struct cx2341x_handler *cxhdl, int is_50hz)
   1736{
   1737	cxhdl->is_50hz = is_50hz;
   1738	cxhdl->video_gop_size->default_value = cxhdl->is_50hz ? 12 : 15;
   1739}
   1740EXPORT_SYMBOL(cx2341x_handler_set_50hz);
   1741
   1742int cx2341x_handler_setup(struct cx2341x_handler *cxhdl)
   1743{
   1744	int h = cxhdl->height;
   1745	int w = cxhdl->width;
   1746	int err;
   1747
   1748	err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_OUTPUT_PORT, 2, cxhdl->port, 0);
   1749	if (err)
   1750		return err;
   1751	err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_RATE, 1, cxhdl->is_50hz);
   1752	if (err)
   1753		return err;
   1754
   1755	if (v4l2_ctrl_g_ctrl(cxhdl->video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
   1756		w /= 2;
   1757		h /= 2;
   1758	}
   1759	err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
   1760	if (err)
   1761		return err;
   1762	return v4l2_ctrl_handler_setup(&cxhdl->hdl);
   1763}
   1764EXPORT_SYMBOL(cx2341x_handler_setup);
   1765
   1766void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy)
   1767{
   1768	v4l2_ctrl_grab(cxhdl->audio_sampling_freq, busy);
   1769	v4l2_ctrl_grab(cxhdl->audio_encoding, busy);
   1770	v4l2_ctrl_grab(cxhdl->audio_l2_bitrate, busy);
   1771	v4l2_ctrl_grab(cxhdl->audio_ac3_bitrate, busy);
   1772	v4l2_ctrl_grab(cxhdl->stream_vbi_fmt, busy);
   1773	v4l2_ctrl_grab(cxhdl->stream_type, busy);
   1774	v4l2_ctrl_grab(cxhdl->video_bitrate_mode, busy);
   1775	v4l2_ctrl_grab(cxhdl->video_bitrate, busy);
   1776	v4l2_ctrl_grab(cxhdl->video_bitrate_peak, busy);
   1777}
   1778EXPORT_SYMBOL(cx2341x_handler_set_busy);