22 #include <linux/module.h>
23 #include <linux/errno.h>
24 #include <linux/kernel.h>
26 #include <linux/types.h>
27 #include <linux/videodev2.h>
44 #define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
45 #define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
46 #define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
48 static const char *cx2341x_get_name(
u32 id)
52 return "Spatial Filter Mode";
54 return "Spatial Filter";
56 return "Spatial Luma Filter Type";
58 return "Spatial Chroma Filter Type";
60 return "Temporal Filter Mode";
62 return "Temporal Filter";
64 return "Median Filter Type";
66 return "Median Luma Filter Maximum";
68 return "Median Luma Filter Minimum";
70 return "Median Chroma Filter Maximum";
72 return "Median Chroma Filter Minimum";
74 return "Insert Navigation Packets";
79 static const char **cx2341x_get_menu(
u32 id)
81 static const char *cx2341x_video_spatial_filter_mode_menu[] = {
87 static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
92 "2D Symmetric non-separable",
96 static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
102 static const char *cx2341x_video_temporal_filter_mode_menu[] = {
108 static const char *cx2341x_video_median_filter_type_menu[] = {
112 "Horizontal/Vertical",
119 return cx2341x_video_spatial_filter_mode_menu;
121 return cx2341x_video_luma_spatial_filter_type_menu;
123 return cx2341x_video_chroma_spatial_filter_type_menu;
125 return cx2341x_video_temporal_filter_mode_menu;
127 return cx2341x_video_median_filter_type_menu;
135 *name = cx2341x_get_name(
id);
232 .stream_insert_nav_packets = 0,
249 .video_gop_size = 12,
250 .video_gop_closure = 1,
252 .video_bitrate = 6000000,
253 .video_bitrate_peak = 8000000,
254 .video_temporal_decimation = 0,
256 .video_mute_yuv = 0x008080,
259 .video_spatial_filter_mode =
261 .video_spatial_filter = 0,
262 .video_luma_spatial_filter_type =
264 .video_chroma_spatial_filter_type =
266 .video_temporal_filter_mode =
268 .video_temporal_filter = 8,
269 .video_median_filter_type =
271 .video_luma_median_filter_top = 255,
272 .video_luma_median_filter_bottom = 0,
273 .video_chroma_median_filter_top = 255,
274 .video_chroma_median_filter_bottom = 0,
452 int gop = ctrl->
value;
569 cx2341x_ctrl_fill(qctrl->
id, &name, &qctrl->
type,
570 &min, &max, &step, &def, &qctrl->
flags);
604 return cx2341x_ctrl_query_fill(qctrl,
752 return cx2341x_ctrl_query_fill(qctrl,
758 cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
767 cx2341x_ctrl_query_fill(qctrl,
778 cx2341x_ctrl_query_fill(qctrl,
789 return cx2341x_ctrl_query_fill(qctrl,
795 cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
804 return cx2341x_ctrl_query_fill(qctrl,
810 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
819 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
828 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
837 cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
846 return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
858 static const char *
const mpeg_stream_type_without_ts[] = {
859 "MPEG-2 Program Stream",
861 "MPEG-1 System Stream",
862 "MPEG-2 DVD-compatible Stream",
863 "MPEG-1 VCD-compatible Stream",
864 "MPEG-2 SVCD-compatible Stream",
868 static const char *mpeg_stream_type_with_ts[] = {
869 "MPEG-2 Program Stream",
870 "MPEG-2 Transport Stream",
871 "MPEG-1 System Stream",
872 "MPEG-2 DVD-compatible Stream",
873 "MPEG-1 VCD-compatible Stream",
874 "MPEG-2 SVCD-compatible Stream",
878 static const char *mpeg_audio_encoding_l2_ac3[] = {
890 mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
902 return cx2341x_get_menu(
id);
941 for (i = 0; i < ctrls->
count; i++) {
944 err = cx2341x_get_ctrl(params, ctrl);
952 for (i = 0; i < ctrls->
count; i++) {
955 const char *
const *menu_items =
NULL;
966 err = cx2341x_set_ctrl(params, busy, ctrl);
979 cx2341x_calc_audio_properties(params);
987 cx2341x_calc_audio_properties(p);
1000 for (i = 0; i < args; i++)
1001 data[i] =
va_arg(vargs,
int);
1003 return func(priv, cmd, args, 0, data);
1006 #define NEQ(field) (old->field != new->field)
1012 static int mpeg_stream_type[] = {
1023 u16 temporal =
new->video_temporal_filter;
1027 if (force ||
NEQ(is_50hz)) {
1030 if (err)
return err;
1035 u16 h =
new->height;
1043 if (err)
return err;
1047 mpeg_stream_type[new->stream_type]);
1048 if (err)
return err;
1050 if (force ||
NEQ(video_aspect)) {
1052 1 + new->video_aspect);
1053 if (err)
return err;
1055 if (force ||
NEQ(video_b_frames) ||
NEQ(video_gop_size)) {
1057 new->video_gop_size, new->video_b_frames + 1);
1058 if (err)
return err;
1060 if (force ||
NEQ(video_gop_closure)) {
1062 new->video_gop_closure);
1063 if (err)
return err;
1065 if (force ||
NEQ(audio_properties)) {
1067 1, new->audio_properties);
1068 if (err)
return err;
1070 if (force ||
NEQ(audio_mute)) {
1073 if (err)
return err;
1075 if (force ||
NEQ(video_bitrate_mode) ||
NEQ(video_bitrate) ||
1076 NEQ(video_bitrate_peak)) {
1078 new->video_bitrate_mode, new->video_bitrate,
1079 new->video_bitrate_peak / 400, 0, 0);
1080 if (err)
return err;
1082 if (force ||
NEQ(video_spatial_filter_mode) ||
1083 NEQ(video_temporal_filter_mode) ||
1084 NEQ(video_median_filter_type)) {
1086 2, new->video_spatial_filter_mode |
1087 (new->video_temporal_filter_mode << 1),
1088 new->video_median_filter_type);
1089 if (err)
return err;
1091 if (force ||
NEQ(video_luma_median_filter_bottom) ||
1092 NEQ(video_luma_median_filter_top) ||
1093 NEQ(video_chroma_median_filter_bottom) ||
1094 NEQ(video_chroma_median_filter_top)) {
1096 new->video_luma_median_filter_bottom,
1097 new->video_luma_median_filter_top,
1098 new->video_chroma_median_filter_bottom,
1099 new->video_chroma_median_filter_top);
1100 if (err)
return err;
1102 if (force ||
NEQ(video_luma_spatial_filter_type) ||
1103 NEQ(video_chroma_spatial_filter_type)) {
1104 err = cx2341x_api(priv, func,
1106 2, new->video_luma_spatial_filter_type,
1107 new->video_chroma_spatial_filter_type);
1108 if (err)
return err;
1110 if (force ||
NEQ(video_spatial_filter) ||
1113 2, new->video_spatial_filter, temporal);
1114 if (err)
return err;
1116 if (force ||
NEQ(video_temporal_decimation)) {
1118 1, new->video_temporal_decimation);
1119 if (err)
return err;
1121 if (force ||
NEQ(video_mute) ||
1122 (new->video_mute &&
NEQ(video_mute_yuv))) {
1124 new->video_mute | (new->video_mute_yuv << 8));
1125 if (err)
return err;
1127 if (force ||
NEQ(stream_insert_nav_packets)) {
1129 7, new->stream_insert_nav_packets);
1130 if (err)
return err;
1144 if (cx2341x_get_ctrl(p, &ctrl))
1146 while (ctrl.
value-- && *menu) menu++;
1164 printk(
" (with navigation packets)");
1173 p->
width / (is_mpeg1 ? 2 : 1), p->
height / (is_mpeg1 ? 2 : 1),
1186 "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
1199 cx2341x_menu_item(p,
1206 printk(
", %s", cx2341x_menu_item(p,
1215 cx2341x_menu_item(p,
1217 cx2341x_menu_item(p,
1219 cx2341x_menu_item(p,
1225 cx2341x_menu_item(p,
1229 "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
1231 cx2341x_menu_item(p,
1250 u32 cmd,
int args, ...)
1258 for (i = 0; i < args; i++)
1259 data[i] =
va_arg(vargs,
int);
1261 return hdl->
func(hdl->
priv, cmd, args, 0, data);
1265 static inline int cx2341x_neq(
struct v4l2_ctrl *ctrl)
1267 return ctrl && ctrl->
val != ctrl->
cur.
val;
1270 static int cx2341x_try_ctrl(
struct v4l2_ctrl *ctrl)
1281 gop = b * ((gop + b - 1) / b);
1310 static int cx2341x_s_ctrl(
struct v4l2_ctrl *ctrl)
1312 static const int mpeg_stream_type[] = {
1327 if (hdl->
ops && hdl->
ops->s_stream_vbi_fmt)
1328 return hdl->
ops->s_stream_vbi_fmt(hdl, val);
1332 return cx2341x_hdl_api(hdl,
1342 return cx2341x_hdl_api(hdl,
1373 err = cx2341x_hdl_api(hdl,
1389 hdl->
ops && hdl->
ops->s_audio_sampling_freq)
1392 hdl->
ops && hdl->
ops->s_audio_mode)
1404 err = cx2341x_hdl_api(hdl,
1421 hdl->
ops && hdl->
ops->s_video_encoding)
1461 return cx2341x_hdl_api(hdl,
1484 .try_ctrl = cx2341x_try_ctrl,
1485 .s_ctrl = cx2341x_s_ctrl,
1493 cx2341x_ctrl_fill(
id, &
cfg.name, &
cfg.type, &min, &max, &step, &def, &
cfg.flags);
1494 cfg.ops = &cx2341x_ops;
1502 cfg.qmenu = cx2341x_get_menu(
id);
1505 cfg.menu_skip_mask = 0;
1523 unsigned nr_of_controls_hint)
1558 cxhdl->
audio_mode = cx2341x_ctrl_new_menu(hdl,
1570 cxhdl->
audio_crc = cx2341x_ctrl_new_menu(hdl,
1585 cx2341x_ctrl_new_menu(hdl,
1593 1, 34, 1, cxhdl->
is_50hz ? 12 : 15);
1601 0, 27000000, 1, 6000000);
1604 0, 27000000, 1, 8000000);
1605 cx2341x_ctrl_new_std(hdl,
1607 cxhdl->
video_mute = cx2341x_ctrl_new_std(hdl,
1664 int err = hdl->
error;