From: volokh <volokh@telros.ru>
To: linux-media@vger.kernel.org, volokh@telros.ru,
devel@linuxdriverproject.org
Subject: [PATCH] go7007 patch for 3.2.x
Date: Tue, 20 Mar 2012 19:30:51 +0400 [thread overview]
Message-ID: <1332257451.6182.60.camel@VPir> (raw)
please reply this at linux-media@vger.kernel.org I`ve some trouble
- add new tuning option for card(
V4L2_MPEG_VIDEO_ENCODING_H263
,V4L2_CID_MPEG_VIDEO_B_FRAMES)
- add framesizes&frameintervals control
- tested&realize motion detector control(
GO7007IOC_REGION_NUMBER
,GO7007IOC_PIXEL_THRESOLD
,GO7007IOC_MOTION_THRESOLD
,GO7007IOC_TRIGGER
,GO7007IOC_REGION_CONTROL
,GO7007IOC_CLIP_LEFT
,GO7007IOC_CLIP_TOP
,GO7007IOC_CLIP_WIDTH
,GO7007IOC_CLIP_HEIGHT)
Tested with Angelo PCI-MPG24(Adlink) with go7007&tw2804 onboard
Regards Volokh
diff -uprN -X linux-3.2.11-vanilla/Documentation/dontdiff linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007.h linux-3.2.11/drivers/staging/media/go7007/go7007.h
--- linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007.h 2012-03-13 21:05:09.000000000 +0400
+++ linux-3.2.11/drivers/staging/media/go7007/go7007.h 2012-03-20 16:17:26.095901486 +0400
@@ -21,12 +21,27 @@
* to select between MPEG1, MPEG2, and MPEG4 */
#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
+/* Temporary defines until accepted in v4l2-api (videodev2.h) */
+#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
+ #define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */
+#endif
+#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
+ #define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
+#endif
+
+#ifndef V4L2_MPEG_VIDEO_ENCODING_H263
+ #define V4L2_MPEG_VIDEO_ENCODING_H263 4
+#endif
+
+///deprecated defs
+#if 0
/* These will be replaced with a better interface
* soon, so don't get too attached to them */
#define GO7007IOC_S_BITRATE _IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
#define GO7007IOC_G_BITRATE _IOR('V', BASE_VIDIOC_PRIVATE + 1, int)
-enum go7007_aspect_ratio {
+enum go7007_aspect_ratio
+{
GO7007_ASPECT_RATIO_1_1 = 0,
GO7007_ASPECT_RATIO_4_3_NTSC = 1,
GO7007_ASPECT_RATIO_4_3_PAL = 2,
@@ -35,7 +50,8 @@ enum go7007_aspect_ratio {
};
/* Used to set generic compression parameters */
-struct go7007_comp_params {
+struct go7007_comp_params
+{
__u32 gop_size;
__u32 max_b_frames;
enum go7007_aspect_ratio aspect_ratio;
@@ -46,14 +62,16 @@ struct go7007_comp_params {
#define GO7007_COMP_CLOSED_GOP 0x00000001
#define GO7007_COMP_OMIT_SEQ_HEADER 0x00000002
-enum go7007_mpeg_video_standard {
+enum go7007_mpeg_video_standard
+{
GO7007_MPEG_VIDEO_MPEG1 = 0,
GO7007_MPEG_VIDEO_MPEG2 = 1,
GO7007_MPEG_VIDEO_MPEG4 = 2,
};
/* Used to set parameters for V4L2_PIX_FMT_MPEG format */
-struct go7007_mpeg_params {
+struct go7007_mpeg_params
+{
enum go7007_mpeg_video_standard mpeg_video_standard;
__u32 flags;
__u32 pali;
@@ -83,21 +101,6 @@ struct go7007_mpeg_params {
#define GO7007_MPEG4_PROFILE_AS_L4 GO7007_MPEG_PROFILE(4, 0xf4)
#define GO7007_MPEG4_PROFILE_AS_L5 GO7007_MPEG_PROFILE(4, 0xf5)
-struct go7007_md_params {
- __u16 region;
- __u16 trigger;
- __u16 pixel_threshold;
- __u16 motion_threshold;
- __u32 reserved[8];
-};
-
-struct go7007_md_region {
- __u16 region;
- __u16 flags;
- struct v4l2_clip *clips;
- __u32 reserved[8];
-};
-
#define GO7007IOC_S_MPEG_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 2, \
struct go7007_mpeg_params)
#define GO7007IOC_G_MPEG_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 3, \
@@ -112,3 +115,38 @@ struct go7007_md_region {
struct go7007_md_params)
#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
struct go7007_md_region)
+#endif
+
+struct go7007_md_params
+{
+ __u16 region;
+ __u16 trigger;
+ __u16 pixel_threshold;
+ __u16 motion_threshold;
+ __u32 reserved[8];
+};
+
+struct go7007_md_region
+{
+ __u16 region;
+ __u16 flags;
+ struct v4l2_clip *clips;
+ __u32 reserved[8];
+};
+
+#define GO7007IOC_REGION_NUMBER V4L2_CID_PRIVATE_BASE
+#define GO7007IOC_PIXEL_THRESOLD V4L2_CID_PRIVATE_BASE+1
+#define GO7007IOC_MOTION_THRESOLD V4L2_CID_PRIVATE_BASE+2
+#define GO7007IOC_TRIGGER V4L2_CID_PRIVATE_BASE+3
+#define GO7007IOC_REGION_CONTROL V4L2_CID_PRIVATE_BASE+4
+#define GO7007IOC_CLIP_LEFT V4L2_CID_PRIVATE_BASE+5
+#define GO7007IOC_CLIP_TOP V4L2_CID_PRIVATE_BASE+6
+#define GO7007IOC_CLIP_WIDTH V4L2_CID_PRIVATE_BASE+7
+#define GO7007IOC_CLIP_HEIGHT V4L2_CID_PRIVATE_BASE+8
+
+enum RegionControl
+{
+ rcAdd=0
+ ,rcDelete=1
+ ,rcClear=2
+};
diff -uprN -X linux-3.2.11-vanilla/Documentation/dontdiff linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007-priv.h linux-3.2.11/drivers/staging/media/go7007/go7007-priv.h
--- linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007-priv.h 2012-03-13 21:05:09.000000000 +0400
+++ linux-3.2.11/drivers/staging/media/go7007/go7007-priv.h 2012-03-20 16:17:58.246497298 +0400
@@ -215,7 +215,8 @@ struct go7007 {
} modet[4];
unsigned char modet_map[1624];
unsigned char active_map[216];
-
+ struct v4l2_rect fClipRegion;
+ unsigned char fCurrentRegion:2;
/* Video streaming */
struct go7007_buffer *active_buf;
enum go7007_parser_state state;
diff -uprN -X linux-3.2.11-vanilla/Documentation/dontdiff linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007-v4l2.c linux-3.2.11/drivers/staging/media/go7007/go7007-v4l2.c
--- linux-3.2.11-vanilla/drivers/staging/media/go7007/go7007-v4l2.c 2012-03-13 21:05:09.000000000 +0400
+++ linux-3.2.11/drivers/staging/media/go7007/go7007-v4l2.c 2012-03-20 16:17:51.181586119 +0400
@@ -335,114 +335,390 @@ static int set_capture_size(struct go700
return 0;
}
-#if 0
-static int clip_to_modet_map(struct go7007 *go, int region,
- struct v4l2_clip *clip_list)
-{
- struct v4l2_clip clip, *clip_ptr;
- int x, y, mbnum;
-
- /* Check if coordinates are OK and if any macroblocks are already
- * used by other regions (besides 0) */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- if (clip.c.left < 0 || (clip.c.left & 0xF) ||
- clip.c.width <= 0 || (clip.c.width & 0xF))
- return -EINVAL;
- if (clip.c.left + clip.c.width > go->width)
- return -EINVAL;
- if (clip.c.top < 0 || (clip.c.top & 0xF) ||
- clip.c.height <= 0 || (clip.c.height & 0xF))
- return -EINVAL;
- if (clip.c.top + clip.c.height > go->height)
- return -EINVAL;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- if (go->modet_map[mbnum] != 0 &&
- go->modet_map[mbnum] != region)
- return -EBUSY;
- }
- clip_ptr = clip.next;
- }
-
- /* Clear old region macroblocks */
- for (mbnum = 0; mbnum < 1624; ++mbnum)
- if (go->modet_map[mbnum] == region)
- go->modet_map[mbnum] = 0;
-
- /* Claim macroblocks in this list */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- go->modet_map[mbnum] = region;
- }
- clip_ptr = clip.next;
- }
- return 0;
+static int md_g_ctrl(struct v4l2_control *ctrl,struct go7007 *go)
+{
+ switch(ctrl->id)
+ {
+ case GO7007IOC_REGION_NUMBER:
+ ctrl->value=go->fCurrentRegion;
+ break;
+ case GO7007IOC_PIXEL_THRESOLD:
+ ctrl->value=(go->modet[go->fCurrentRegion].pixel_threshold<<1)+1;
+ break;
+ case GO7007IOC_MOTION_THRESOLD:
+ ctrl->value=(go->modet[go->fCurrentRegion].motion_threshold<<1)+1;
+ break;
+ case GO7007IOC_TRIGGER:
+ ctrl->value=(go->modet[go->fCurrentRegion].mb_threshold<<1)+1;
+ break;
+ case GO7007IOC_CLIP_LEFT:
+ ctrl->value=go->fClipRegion.left;
+ break;
+ case GO7007IOC_CLIP_TOP:
+ ctrl->value=go->fClipRegion.top;
+ break;
+ case GO7007IOC_CLIP_WIDTH:
+ ctrl->value=go->fClipRegion.width;
+ break;
+ case GO7007IOC_CLIP_HEIGHT:
+ ctrl->value=go->fClipRegion.height;
+ break;
+ case GO7007IOC_REGION_CONTROL:
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void ClearModetMap(struct go7007 *go,char Region)
+{
+ /* Clear old region macroblocks */
+ int mbnum;
+ for(mbnum=0;mbnum<sizeof(go->modet_map);++mbnum)
+ if(go->modet_map[mbnum]==Region)
+ go->modet_map[mbnum]=0;
+}
+
+static int RectToModetMap(struct go7007 *go,char Region,struct v4l2_rect *Rect,int Delete)
+{
+ register int x,y,mbnum;
+ /* Check if coordinates are OK and if any macroblocks are already
+ * used by other regions (besides 0) */
+// if(Rect)
+ if(Rect->left<0 || (Rect->left & 0xF) || Rect->width<=0 || (Rect->width & 0xF))
+ return -EINVAL;
+ if(Rect->left+Rect->width>go->width)
+ return -EINVAL;
+ if(Rect->top<0 || (Rect->top & 0xF) || Rect->height<=0 || (Rect->height & 0xF))
+ return -EINVAL;
+ if(Rect->top+Rect->height>go->height)
+ return -EINVAL;
+ for(y=0;y<Rect->height;y+=16)
+ for(x=0;x<Rect->width;x+=16)
+ {
+ mbnum=(go->width>>4)*((Rect->top+y)>>4)+((Rect->left+x)>>4);
+ if(go->modet_map[mbnum]!=0 && go->modet_map[mbnum]!=Region)
+ return -EBUSY;
+ else
+ go->modet_map[mbnum]=Delete ? 0 : Region;
+ }
+ return 0;
+}
+
+static int md_s_ctrl(struct v4l2_control *ctrl,struct go7007 *go)
+{
+ switch(ctrl->id)
+ {
+ case GO7007IOC_REGION_NUMBER:
+ if(ctrl->value<0 || ctrl->value>3)
+ return -EINVAL;
+ go->fCurrentRegion=ctrl->value;
+ break;
+ case GO7007IOC_PIXEL_THRESOLD:
+ if(ctrl->value<0 || ctrl->value>65535)
+ return -EINVAL;
+ go->modet[go->fCurrentRegion].pixel_threshold=ctrl->value>>1;
+ break;
+ case GO7007IOC_MOTION_THRESOLD:
+ if(ctrl->value<0 || ctrl->value>65535)
+ return -EINVAL;
+ go->modet[go->fCurrentRegion].motion_threshold=ctrl->value>>1;
+ break;
+ case GO7007IOC_TRIGGER:
+ if(ctrl->value<0 || ctrl->value>65535)
+ return -EINVAL;
+ go->modet[go->fCurrentRegion].mb_threshold=ctrl->value>>1;
+ go->modet[go->fCurrentRegion].enable=ctrl->value>0;
+ break;
+ case GO7007IOC_REGION_CONTROL:
+ if(go->fCurrentRegion<1 || go->fCurrentRegion>3)
+ return -EINVAL;
+ switch(ctrl->value)
+ {
+ case rcAdd:
+ RectToModetMap(go,go->fCurrentRegion,&go->fClipRegion,0);
+ break;
+ case rcDelete:
+ RectToModetMap(go,go->fCurrentRegion,&go->fClipRegion,1);
+ break;
+ case rcClear:
+ ClearModetMap(go,go->fCurrentRegion);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case GO7007IOC_CLIP_LEFT:
+ go->fClipRegion.top=ctrl->value;
+ break;
+ case GO7007IOC_CLIP_TOP:
+ go->fClipRegion.left=ctrl->value;
+ break;
+ case GO7007IOC_CLIP_WIDTH:
+ go->fClipRegion.width=ctrl->value;
+ break;
+ case GO7007IOC_CLIP_HEIGHT:
+ go->fClipRegion.height=ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_querymenu(struct file *file,void *fh,struct v4l2_querymenu *menuctrl)
+{
+ switch(menuctrl->id)
+ {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ switch(menuctrl->index)
+ {
+ case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
+ strcpy(menuctrl->name,"MPEG2 DVD");
+ break;
+ case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
+ strcpy(menuctrl->name,"MPEG ELEM");
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ switch(menuctrl->index)
+ {
+ case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
+ strcpy(menuctrl->name,"MPEG1");
+ break;
+ case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
+ strcpy(menuctrl->name,"MPEG2");
+ break;
+ case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
+ strcpy(menuctrl->name,"MPEG4");
+ break;
+ case V4L2_MPEG_VIDEO_ENCODING_H263:
+ strcpy(menuctrl->name,"H263");
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ switch(menuctrl->index)
+ {
+ case V4L2_MPEG_VIDEO_ASPECT_1x1:
+ strcpy(menuctrl->name,"1x1");
+ break;
+ case V4L2_MPEG_VIDEO_ASPECT_4x3:
+ strcpy(menuctrl->name,"4x3");
+ break;
+ case V4L2_MPEG_VIDEO_ASPECT_16x9:
+ strcpy(menuctrl->name,"16x9");
+ break;
+ case V4L2_MPEG_VIDEO_ASPECT_221x100:
+ strcpy(menuctrl->name,"221x100");
+// break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case GO7007IOC_REGION_CONTROL:
+ switch(menuctrl->index)
+ {
+ case rcAdd:
+ strcpy(menuctrl->name,"Add");
+ break;
+ case rcDelete:
+ strcpy(menuctrl->name,"Delete");
+ break;
+ case rcClear:
+ strcpy(menuctrl->name,"Clear");
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int md_query_ctrl(struct v4l2_queryctrl *ctrl,struct go7007 *go)
+{
+ static const u32 md_ctrls[]=
+ {
+ GO7007IOC_REGION_NUMBER
+ ,GO7007IOC_PIXEL_THRESOLD
+ ,GO7007IOC_MOTION_THRESOLD
+ ,GO7007IOC_TRIGGER
+ ,GO7007IOC_REGION_CONTROL
+ ,GO7007IOC_CLIP_LEFT
+ ,GO7007IOC_CLIP_TOP
+ ,GO7007IOC_CLIP_WIDTH
+ ,GO7007IOC_CLIP_HEIGHT
+ ,0
+ };
+
+ static const u32 *ctrl_classes[]=
+ {
+ md_ctrls
+ ,NULL
+ };
+
+ printk(KERN_INFO"Before Try md query ctrl %d",ctrl->id);
+
+ ctrl->id=v4l2_ctrl_next(ctrl_classes,ctrl->id);
+
+ printk(KERN_INFO"Try md query ctrl %d",ctrl->id);
+ switch(ctrl->id)
+ {
+ case GO7007IOC_REGION_NUMBER:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Region MD",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=3;
+ ctrl->step=1;
+ ctrl->default_value=0;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_PIXEL_THRESOLD:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Pixel Thresold",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=65535;
+ ctrl->step=1;
+ ctrl->default_value=32767;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_MOTION_THRESOLD:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Motion Thresold",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=65535;
+ ctrl->step=1;
+ ctrl->default_value=32767;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_TRIGGER:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Trigger",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=65535;
+ ctrl->step=1;
+ ctrl->default_value=32767;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_REGION_CONTROL:
+ ctrl->type=V4L2_CTRL_TYPE_MENU;//V4L2_CTRL_TYPE_BUTTON;
+ strncpy(ctrl->name,"Region Control",sizeof(ctrl->name));
+ ctrl->minimum=rcAdd;
+ ctrl->maximum=rcClear;
+ ctrl->step=1;
+ ctrl->default_value=rcAdd;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_CLIP_LEFT:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Left of Region",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=go->width-1;
+ ctrl->step=1;
+ ctrl->default_value=0;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_CLIP_TOP:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Top of Region",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=go->height-1;
+ ctrl->step=1;
+ ctrl->default_value=0;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_CLIP_WIDTH:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Width of Region",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=go->width;
+ ctrl->step=1;
+ ctrl->default_value=0;
+ ctrl->flags=0;
+ break;
+ case GO7007IOC_CLIP_HEIGHT:
+ ctrl->type=V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name,"Height of Region",sizeof(ctrl->name));
+ ctrl->minimum=0;
+ ctrl->maximum=go->height;
+ ctrl->step=1;
+ ctrl->default_value=0;
+ ctrl->flags=0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
-#endif
static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
{
- static const u32 mpeg_ctrls[] = {
- V4L2_CID_MPEG_CLASS,
- V4L2_CID_MPEG_STREAM_TYPE,
- V4L2_CID_MPEG_VIDEO_ENCODING,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- 0
- };
- static const u32 *ctrl_classes[] = {
- mpeg_ctrls,
- NULL
- };
-
- ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_CLASS:
- return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(ctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
- V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(ctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(ctrl,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
- V4L2_MPEG_VIDEO_ASPECT_1x1);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(ctrl,
- 64000,
- 10000000, 1,
- 1500000);
- default:
- return -EINVAL;
- }
- return 0;
+ static const u32 mpeg_ctrls[]=
+ {
+ V4L2_CID_MPEG_CLASS
+ ,V4L2_CID_MPEG_STREAM_TYPE
+ ,V4L2_CID_MPEG_VIDEO_ENCODING
+ ,V4L2_CID_MPEG_VIDEO_ASPECT
+ ,V4L2_CID_MPEG_VIDEO_B_FRAMES
+ ,V4L2_CID_MPEG_VIDEO_GOP_SIZE
+ ,V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
+ ,V4L2_CID_MPEG_VIDEO_BITRATE
+//GO7007_COMP_OMIT_SEQ_HEADER,
+//GO7007_MPEG_REPEAT_SEQHEADER
+//GO7007_MPEG_OMIT_GOP_HEADER
+ ,0
+ };
+
+ static const u32 *ctrl_classes[]=
+ {
+ mpeg_ctrls
+ ,NULL
+ };
+
+ ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
+
+ switch(ctrl->id)
+ {
+ case V4L2_CID_MPEG_CLASS:
+ return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return v4l2_ctrl_query_fill(ctrl,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
+ V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ return v4l2_ctrl_query_fill(ctrl,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4/*V4L2_MPEG_VIDEO_ENCODING_H263*/,1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return v4l2_ctrl_query_fill(ctrl,
+ V4L2_MPEG_VIDEO_ASPECT_1x1,
+ V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
+ V4L2_MPEG_VIDEO_ASPECT_1x1);
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(ctrl,
+ 64000,
+ 10000000, 1,
+ 1500000);
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ return v4l2_ctrl_query_fill(ctrl,0,2,1,0);
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
@@ -492,6 +768,9 @@ static int mpeg_s_ctrl(struct v4l2_contr
else*/
go->pali = 0xf5;
break;
+ case V4L2_MPEG_VIDEO_ENCODING_H263:
+ go->format=GO7007_FORMAT_H263;
+ break;
default:
return -EINVAL;
}
@@ -538,10 +817,15 @@ static int mpeg_s_ctrl(struct v4l2_contr
return -EINVAL;
go->bitrate = ctrl->value;
break;
- default:
- return -EINVAL;
- }
- return 0;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ if(ctrl->value<0 || ctrl->value>2)///checking
+ return -EINVAL;
+ go->ipb=ctrl->value>0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
@@ -564,6 +848,9 @@ static int mpeg_g_ctrl(struct v4l2_contr
case GO7007_FORMAT_MPEG4:
ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
break;
+ case GO7007_FORMAT_H263:
+ ctrl->value=V4L2_MPEG_VIDEO_ENCODING_H263;
+ break;
default:
return -EINVAL;
}
@@ -592,10 +879,13 @@ static int mpeg_g_ctrl(struct v4l2_contr
case V4L2_CID_MPEG_VIDEO_BITRATE:
ctrl->value = go->bitrate;
break;
- default:
- return -EINVAL;
- }
- return 0;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ ctrl->value=go->ipb ? 2 : 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
static int vidioc_querycap(struct file *file, void *priv,
@@ -605,9 +895,7 @@ static int vidioc_querycap(struct file *
strlcpy(cap->driver, "go7007", sizeof(cap->driver));
strlcpy(cap->card, go->name, sizeof(cap->card));
-#if 0
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
-#endif
+ strlcpy(cap->bus_info,dev_name(go->dev),sizeof(cap->bus_info));
cap->version = KERNEL_VERSION(0, 9, 8);
@@ -975,39 +1263,43 @@ static int vidioc_streamoff(struct file
return 0;
}
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *query)
+static int vidioc_queryctrl(struct file *file,void *priv,struct v4l2_queryctrl *query)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
- int id = query->id;
+ struct go7007 *go=((struct go7007_file *)priv)->go;
+ int id=query->id;
- if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
- return 0;
+ if(0==call_all(&go->v4l2_dev,core,queryctrl,query))
+ return 0;
- query->id = id;
- return mpeg_query_ctrl(query);
+ query->id=id;
+ if(mpeg_query_ctrl(query)==0)
+ return 0;
+ query->id=id;
+ return md_query_ctrl(query,go);
}
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_g_ctrl(struct file *file,void *priv,struct v4l2_control *ctrl)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go=((struct go7007_file *)priv)->go;
- if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
- return 0;
+ if(0==call_all(&go->v4l2_dev,core,g_ctrl,ctrl))
+ return 0;
- return mpeg_g_ctrl(ctrl, go);
+ if(mpeg_g_ctrl(ctrl,go)==0)
+ return 0;
+ return md_g_ctrl(ctrl,go);
}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_s_ctrl(struct file *file,void *priv,struct v4l2_control *ctrl)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go=((struct go7007_file *)priv)->go;
- if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
- return 0;
+ if(0==call_all(&go->v4l2_dev,core,s_ctrl,ctrl))
+ return 0;
- return mpeg_s_ctrl(ctrl, go);
+ if(mpeg_s_ctrl(ctrl,go)==0)
+ return 0;
+ return md_s_ctrl(ctrl,go);
}
static int vidioc_g_parm(struct file *filp, void *priv,
@@ -1060,44 +1352,246 @@ static int vidioc_s_parm(struct file *fi
The two functions bellow implements the newer ioctls
*/
-static int vidioc_enum_framesizes(struct file *filp, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
-
- /* Return -EINVAL, if it is a TV board */
- if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
- (go->board_info->sensor_flags & GO7007_SENSOR_TV))
- return -EINVAL;
-
- if (fsize->index > 0)
- return -EINVAL;
-
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = go->board_info->sensor_width;
- fsize->discrete.height = go->board_info->sensor_height;
-
- return 0;
-}
-
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *fival)
+static int vidioc_enum_framesizes(struct file *filp,void *priv,struct v4l2_frmsizeenum *fsize)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go=((struct go7007_file *)priv)->go;
+ /* Return -EINVAL, if it is a TV board */
+ if(go->board_info->flags & GO7007_BOARD_HAS_TUNER)
+ return -EINVAL;
+
+ if(go->board_info->sensor_flags & GO7007_SENSOR_TV)
+ {
+ switch(go->standard)
+ {
+ case GO7007_STD_NTSC:
+ switch(fsize->pixel_format)
+ {
+ case V4L2_PIX_FMT_MJPEG:
+ case V4L2_PIX_FMT_MPEG:
+ switch(fsize->index)
+ {
+ case 0:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=720;
+ fsize->discrete.height=480;
+ break;
+ case 1:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=640;
+ fsize->discrete.height=480;
+ break;
+ case 2:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=352;
+ fsize->discrete.height=240;
+ break;
+ case 3:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=320;
+ fsize->discrete.height=240;
+ break;
+ case 4:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=176;
+ fsize->discrete.height=112;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case GO7007_STD_PAL:
+ switch(fsize->pixel_format)
+ {
+ case V4L2_PIX_FMT_MJPEG:
+ case V4L2_PIX_FMT_MPEG:
+ switch(fsize->index)
+ {
+ case 0:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=720;
+ fsize->discrete.height=576;
+ break;
+ case 1:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=352;
+ fsize->discrete.height=288;
+ break;
+ case 2:
+ fsize->type=V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width=176;
+ fsize->discrete.height=144;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ if (fsize->index > 0)
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = go->board_info->sensor_width;
+ fsize->discrete.height = go->board_info->sensor_height;
+
+ return 0;
+}
+
+static int vidioc_enum_frameintervals(struct file *filp,void *priv,struct v4l2_frmivalenum *fival)
+{
+ struct go7007 *go=((struct go7007_file *)priv)->go;
+
+ /* Return -EINVAL, if it is a TV board */
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+ return -EINVAL;
+
+ if(go->board_info->sensor_flags & GO7007_SENSOR_TV)
+ {
+ switch(fival->pixel_format)
+ {
+ case V4L2_PIX_FMT_MJPEG:
+ case V4L2_PIX_FMT_MPEG:
+ switch(go->standard)
+ {
+ case GO7007_STD_NTSC:
+ switch(fival->index)
+ {
+ case 0:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*1;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 1:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*2;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 2:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*3;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 3:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*4;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 4:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*5;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 5:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*6;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 6:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*7;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 7:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*10;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 8:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*15;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 9:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*30;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case GO7007_STD_PAL:
+ switch(fival->index)
+ {
+ case 0:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*1;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 1:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*2;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 2:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*3;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 3:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*4;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 4:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*5;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 5:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*6;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 6:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*8;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 7:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*13;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ case 8:
+ fival->type=V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator=1001*25;
+ fival->discrete.denominator=go->sensor_framerate;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ if (fival->index > 0)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1001;
+ fival->discrete.denominator = go->board_info->sensor_framerate;
- /* Return -EINVAL, if it is a TV board */
- if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
- (go->board_info->sensor_flags & GO7007_SENSOR_TV))
- return -EINVAL;
-
- if (fival->index > 0)
- return -EINVAL;
-
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete.numerator = 1001;
- fival->discrete.denominator = go->board_info->sensor_framerate;
-
- return 0;
+ return 0;
}
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
@@ -1405,235 +1899,6 @@ static int vidioc_s_jpegcomp(struct file
return 0;
}
-/* FIXME:
- Those ioctls are private, and not needed, since several standard
- extended controls already provide streaming control.
- So, those ioctls should be converted into vidioc_g_ext_ctrls()
- and vidioc_s_ext_ctrls()
- */
-
-#if 0
- /* Temporary ioctls for controlling compression characteristics */
- case GO7007IOC_S_BITRATE:
- {
- int *bitrate = arg;
-
- if (go->streaming)
- return -EINVAL;
- /* Upper bound is kind of arbitrary here */
- if (*bitrate < 64000 || *bitrate > 10000000)
- return -EINVAL;
- go->bitrate = *bitrate;
- return 0;
- }
- case GO7007IOC_G_BITRATE:
- {
- int *bitrate = arg;
-
- *bitrate = go->bitrate;
- return 0;
- }
- case GO7007IOC_S_COMP_PARAMS:
- {
- struct go7007_comp_params *comp = arg;
-
- if (go->format == GO7007_FORMAT_MJPEG)
- return -EINVAL;
- if (comp->gop_size > 0)
- go->gop_size = comp->gop_size;
- else
- go->gop_size = go->sensor_framerate / 1000;
- if (go->gop_size != 15)
- go->dvd_mode = 0;
- /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
- if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
- switch (comp->aspect_ratio) {
- case GO7007_ASPECT_RATIO_4_3_NTSC:
- case GO7007_ASPECT_RATIO_4_3_PAL:
- go->aspect_ratio = GO7007_RATIO_4_3;
- break;
- case GO7007_ASPECT_RATIO_16_9_NTSC:
- case GO7007_ASPECT_RATIO_16_9_PAL:
- go->aspect_ratio = GO7007_RATIO_16_9;
- break;
- default:
- go->aspect_ratio = GO7007_RATIO_1_1;
- break;
- }
- }
- if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
- go->dvd_mode = 0;
- go->seq_header_enable = 0;
- } else {
- go->seq_header_enable = 1;
- }
- /* fall-through */
- }
- case GO7007IOC_G_COMP_PARAMS:
- {
- struct go7007_comp_params *comp = arg;
-
- if (go->format == GO7007_FORMAT_MJPEG)
- return -EINVAL;
- memset(comp, 0, sizeof(*comp));
- comp->gop_size = go->gop_size;
- comp->max_b_frames = go->ipb ? 2 : 0;
- switch (go->aspect_ratio) {
- case GO7007_RATIO_4_3:
- if (go->standard == GO7007_STD_NTSC)
- comp->aspect_ratio =
- GO7007_ASPECT_RATIO_4_3_NTSC;
- else
- comp->aspect_ratio =
- GO7007_ASPECT_RATIO_4_3_PAL;
- break;
- case GO7007_RATIO_16_9:
- if (go->standard == GO7007_STD_NTSC)
- comp->aspect_ratio =
- GO7007_ASPECT_RATIO_16_9_NTSC;
- else
- comp->aspect_ratio =
- GO7007_ASPECT_RATIO_16_9_PAL;
- break;
- default:
- comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
- break;
- }
- if (go->closed_gop)
- comp->flags |= GO7007_COMP_CLOSED_GOP;
- if (!go->seq_header_enable)
- comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
- return 0;
- }
- case GO7007IOC_S_MPEG_PARAMS:
- {
- struct go7007_mpeg_params *mpeg = arg;
-
- if (go->format != GO7007_FORMAT_MPEG1 &&
- go->format != GO7007_FORMAT_MPEG2 &&
- go->format != GO7007_FORMAT_MPEG4)
- return -EINVAL;
-
- if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
- go->format = GO7007_FORMAT_MPEG2;
- go->bitrate = 9800000;
- go->gop_size = 15;
- go->pali = 0x48;
- go->closed_gop = 1;
- go->repeat_seqhead = 0;
- go->seq_header_enable = 1;
- go->gop_header_enable = 1;
- go->dvd_mode = 1;
- } else {
- switch (mpeg->mpeg_video_standard) {
- case GO7007_MPEG_VIDEO_MPEG1:
- go->format = GO7007_FORMAT_MPEG1;
- go->pali = 0;
- break;
- case GO7007_MPEG_VIDEO_MPEG2:
- go->format = GO7007_FORMAT_MPEG2;
- if (mpeg->pali >> 24 == 2)
- go->pali = mpeg->pali & 0xff;
- else
- go->pali = 0x48;
- break;
- case GO7007_MPEG_VIDEO_MPEG4:
- go->format = GO7007_FORMAT_MPEG4;
- if (mpeg->pali >> 24 == 4)
- go->pali = mpeg->pali & 0xff;
- else
- go->pali = 0xf5;
- break;
- default:
- return -EINVAL;
- }
- go->gop_header_enable =
- mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
- ? 0 : 1;
- if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
- go->repeat_seqhead = 1;
- else
- go->repeat_seqhead = 0;
- go->dvd_mode = 0;
- }
- /* fall-through */
- }
- case GO7007IOC_G_MPEG_PARAMS:
- {
- struct go7007_mpeg_params *mpeg = arg;
-
- memset(mpeg, 0, sizeof(*mpeg));
- switch (go->format) {
- case GO7007_FORMAT_MPEG1:
- mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
- mpeg->pali = 0;
- break;
- case GO7007_FORMAT_MPEG2:
- mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
- mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
- break;
- case GO7007_FORMAT_MPEG4:
- mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
- mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
- break;
- default:
- return -EINVAL;
- }
- if (!go->gop_header_enable)
- mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
- if (go->repeat_seqhead)
- mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
- if (go->dvd_mode)
- mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
- return 0;
- }
- case GO7007IOC_S_MD_PARAMS:
- {
- struct go7007_md_params *mdp = arg;
-
- if (mdp->region > 3)
- return -EINVAL;
- if (mdp->trigger > 0) {
- go->modet[mdp->region].pixel_threshold =
- mdp->pixel_threshold >> 1;
- go->modet[mdp->region].motion_threshold =
- mdp->motion_threshold >> 1;
- go->modet[mdp->region].mb_threshold =
- mdp->trigger >> 1;
- go->modet[mdp->region].enable = 1;
- } else
- go->modet[mdp->region].enable = 0;
- /* fall-through */
- }
- case GO7007IOC_G_MD_PARAMS:
- {
- struct go7007_md_params *mdp = arg;
- int region = mdp->region;
-
- if (mdp->region > 3)
- return -EINVAL;
- memset(mdp, 0, sizeof(struct go7007_md_params));
- mdp->region = region;
- if (!go->modet[region].enable)
- return 0;
- mdp->pixel_threshold =
- (go->modet[region].pixel_threshold << 1) + 1;
- mdp->motion_threshold =
- (go->modet[region].motion_threshold << 1) + 1;
- mdp->trigger =
- (go->modet[region].mb_threshold << 1) + 1;
- return 0;
- }
- case GO7007IOC_S_MD_REGION:
- {
- struct go7007_md_region *region = arg;
-
- if (region->region < 1 || region->region > 3)
- return -EINVAL;
- return clip_to_modet_map(go, region->region, region->clips);
- }
-#endif
-
static ssize_t go7007_read(struct file *file, char __user *data,
size_t count, loff_t *ppos)
{
@@ -1779,7 +2044,9 @@ static const struct v4l2_ioctl_ops video
.vidioc_g_crop = vidioc_g_crop,
.vidioc_s_crop = vidioc_s_crop,
.vidioc_g_jpegcomp = vidioc_g_jpegcomp,
- .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
+ .vidioc_s_jpegcomp = vidioc_s_jpegcomp
+ ,.vidioc_querymenu=vidioc_querymenu
+ ,
};
static struct video_device go7007_template = {
@@ -1787,13 +2054,14 @@ static struct video_device go7007_templa
.fops = &go7007_fops,
.release = go7007_vfl_release,
.ioctl_ops = &video_ioctl_ops,
- .tvnorms = V4L2_STD_ALL,
+ .tvnorms = V4L2_STD_SECAM | V4L2_STD_NTSC | V4L2_STD_PAL,///V4L2_STD_ALL,
.current_norm = V4L2_STD_NTSC,
};
int go7007_v4l2_init(struct go7007 *go)
{
int rv;
+ register int i;
go->video_dev = video_device_alloc();
if (go->video_dev == NULL)
@@ -1816,8 +2084,11 @@ int go7007_v4l2_init(struct go7007 *go)
++go->ref_count;
printk(KERN_INFO "%s: registered device %s [v4l2]\n",
go->video_dev->name, video_device_node_name(go->video_dev));
-
- return 0;
+ memset(&go->fClipRegion,0,sizeof(go->fClipRegion));
+ go->fCurrentRegion=0;
+ for(i=0;i<4;i++)
+ memset(&go->modet[i],0,sizeof(go->modet[i]));
+ return 0;
}
void go7007_v4l2_remove(struct go7007 *go)
diff -uprN -X linux-3.2.11-vanilla/Documentation/dontdiff linux-3.2.11-vanilla/drivers/staging/media/go7007/wis-tw2804.c linux-3.2.11/drivers/staging/media/go7007/wis-tw2804.c
--- linux-3.2.11-vanilla/drivers/staging/media/go7007/wis-tw2804.c 2012-03-13 21:05:09.000000000 +0400
+++ linux-3.2.11/drivers/staging/media/go7007/wis-tw2804.c 2012-03-20 16:17:38.452746142 +0400
@@ -21,10 +21,14 @@
#include <linux/videodev2.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
#include "wis-i2c.h"
-struct wis_tw2804 {
+struct wis_tw2804
+{
+ struct v4l2_subdev sd;
int channel;
int norm;
int brightness;
@@ -33,7 +37,15 @@ struct wis_tw2804 {
int hue;
};
-static u8 global_registers[] = {
+static inline struct wis_tw2804 *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd,struct wis_tw2804,sd);
+}
+
+static int tw2804_log_status(struct v4l2_subdev *sd);
+
+static u8 global_registers[]=
+{
0x39, 0x00,
0x3a, 0xff,
0x3b, 0x84,
@@ -44,7 +56,8 @@ static u8 global_registers[] = {
0xff, 0xff, /* Terminator (reg 0xff does not exist) */
};
-static u8 channel_registers[] = {
+static u8 channel_registers[]=
+{
0x01, 0xc4,
0x02, 0xa5,
0x03, 0x20,
@@ -105,9 +118,18 @@ static u8 channel_registers[] = {
static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
{
- return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
+ int i;
+ for(i=0;i<10;i++)
+ /*return */if(i2c_smbus_write_byte_data(client,reg|(channel<<6),value)<0)
+ return -1;
+ return 0;
}
+/**static u8 read_reg(struct i2c_client *client, u8 reg, int channel)
+{
+ return i2c_smbus_read_byte_data(client,reg|(channel<<6));
+}*/
+
static int write_regs(struct i2c_client *client, u8 *regs, int channel)
{
int i;
@@ -119,183 +141,228 @@ static int write_regs(struct i2c_client
return 0;
}
-static int wis_tw2804_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
+static int wis_tw2804_command(struct i2c_client *client,unsigned int cmd,void *arg)
{
- struct wis_tw2804 *dec = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd=i2c_get_clientdata(client);
+ struct wis_tw2804 *dec=to_state(sd);
+ int *input;
+
+ printk(KERN_INFO"wis-tw2804: call command %d\n",cmd);
+ if(cmd==DECODER_SET_CHANNEL)
+ {
+ printk(KERN_INFO"wis-tw2804: DecoderSetChannel call command %d\n",cmd);
+
+ input=arg;
+
+ if(*input<0 || *input>3)
+ {
+ printk(KERN_ERR"wis-tw2804: channel %d is not between 0 and 3!\n",*input);
+ return 0;
+ }
+ dec->channel=*input;
+ printk(KERN_DEBUG"wis-tw2804: initializing TW2804 channel %d\n",dec->channel);
+ if(dec->channel==0 && write_regs(client,global_registers,0)<0)
+ {
+ printk(KERN_ERR"wis-tw2804: error initializing TW2804 global registers\n");
+ return 0;
+ }
+ if(write_regs(client,channel_registers,dec->channel)<0)
+ {
+ printk(KERN_ERR"wis-tw2804: error initializing TW2804 channel %d\n",dec->channel);
+ return 0;
+ }
+ return 0;
+ }
+
+ if(dec->channel<0)
+ {
+ printk(KERN_DEBUG"wis-tw2804: ignoring command %08x until channel number is set\n",cmd);
+ return 0;
+ }
- if (cmd == DECODER_SET_CHANNEL) {
- int *input = arg;
+ return 0;
+}
- if (*input < 0 || *input > 3) {
- printk(KERN_ERR "wis-tw2804: channel %d is not "
- "between 0 and 3!\n", *input);
- return 0;
- }
- dec->channel = *input;
- printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
- "channel %d\n", dec->channel);
- if (dec->channel == 0 &&
- write_regs(client, global_registers, 0) < 0) {
- printk(KERN_ERR "wis-tw2804: error initializing "
- "TW2804 global registers\n");
- return 0;
- }
- if (write_regs(client, channel_registers, dec->channel) < 0) {
- printk(KERN_ERR "wis-tw2804: error initializing "
- "TW2804 channel %d\n", dec->channel);
- return 0;
- }
- return 0;
- }
-
- if (dec->channel < 0) {
- printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
- "channel number is set\n", cmd);
- return 0;
- }
-
- switch (cmd) {
- case VIDIOC_S_STD:
- {
- v4l2_std_id *input = arg;
- u8 regs[] = {
- 0x01, *input & V4L2_STD_NTSC ? 0xc4 : 0x84,
- 0x09, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
- 0x0a, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
- 0x0b, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
- 0x0c, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
- 0x0d, *input & V4L2_STD_NTSC ? 0x40 : 0x4a,
- 0x16, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
- 0x17, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
- 0x20, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
- 0x21, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
- 0xff, 0xff,
- };
- write_regs(client, regs, dec->channel);
- dec->norm = *input;
- break;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *ctrl = arg;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
- strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
- ctrl->minimum = 0;
- ctrl->maximum = 255;
- ctrl->step = 1;
- ctrl->default_value = 128;
- ctrl->flags = 0;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
- strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
- ctrl->minimum = 0;
- ctrl->maximum = 255;
- ctrl->step = 1;
- ctrl->default_value = 128;
- ctrl->flags = 0;
- break;
- case V4L2_CID_SATURATION:
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
- strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
- ctrl->minimum = 0;
- ctrl->maximum = 255;
- ctrl->step = 1;
- ctrl->default_value = 128;
- ctrl->flags = 0;
- break;
- case V4L2_CID_HUE:
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
- strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
- ctrl->minimum = 0;
- ctrl->maximum = 255;
- ctrl->step = 1;
- ctrl->default_value = 128;
- ctrl->flags = 0;
- break;
- }
- break;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl = arg;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- if (ctrl->value > 255)
- dec->brightness = 255;
- else if (ctrl->value < 0)
- dec->brightness = 0;
- else
- dec->brightness = ctrl->value;
- write_reg(client, 0x12, dec->brightness, dec->channel);
- break;
- case V4L2_CID_CONTRAST:
- if (ctrl->value > 255)
- dec->contrast = 255;
- else if (ctrl->value < 0)
- dec->contrast = 0;
- else
- dec->contrast = ctrl->value;
- write_reg(client, 0x11, dec->contrast, dec->channel);
- break;
- case V4L2_CID_SATURATION:
- if (ctrl->value > 255)
- dec->saturation = 255;
- else if (ctrl->value < 0)
- dec->saturation = 0;
- else
- dec->saturation = ctrl->value;
- write_reg(client, 0x10, dec->saturation, dec->channel);
- break;
- case V4L2_CID_HUE:
- if (ctrl->value > 255)
- dec->hue = 255;
- else if (ctrl->value < 0)
- dec->hue = 0;
- else
- dec->hue = ctrl->value;
- write_reg(client, 0x0f, dec->hue, dec->channel);
- break;
- }
- break;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl = arg;
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = dec->brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = dec->contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = dec->saturation;
- break;
- case V4L2_CID_HUE:
- ctrl->value = dec->hue;
- break;
- }
- break;
- }
- default:
- break;
- }
- return 0;
+static int tw2804_log_status(struct v4l2_subdev *sd)
+{
+ struct wis_tw2804 *state=to_state(sd);
+ v4l2_info(sd, "Standard: %s\n",state->norm==V4L2_STD_NTSC ? "NTSC" : state->norm==V4L2_STD_PAL ? "PAL" : state->norm==V4L2_STD_SECAM ? "SECAM" : "unknown");
+ v4l2_info(sd,"Input: %d\n",state->channel);
+ v4l2_info(sd,"Brightness: %d\n",state->brightness);
+ v4l2_info(sd,"Contrast: %d\n",state->contrast);
+ v4l2_info(sd,"Saturation: %d\n",state->saturation);
+ v4l2_info(sd,"Hue: %d\n",state->hue);
+ return 0;
}
+static int tw2804_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
+{
+ static const u32 user_ctrls[]=
+ {
+ V4L2_CID_USER_CLASS,
+ V4L2_CID_BRIGHTNESS,
+ V4L2_CID_CONTRAST,
+ V4L2_CID_SATURATION,
+ V4L2_CID_HUE,
+ 0
+ };
+
+ static const u32 *ctrl_classes[]=
+ {
+ user_ctrls,
+ NULL
+ };
+
+ query->id=v4l2_ctrl_next(ctrl_classes,query->id);
+
+ switch (query->id)
+ {
+ case V4L2_CID_USER_CLASS:
+ return v4l2_ctrl_query_fill(query, 0, 0, 0, 0);
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(query, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(query, 0, 255, 1, 128);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(query, 0, 255, 1, 128);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(query, 0, 255, 1, 128);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int tw2804_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct wis_tw2804 *dec=to_state(sd);
+ struct i2c_client *client=v4l2_get_subdevdata(sd);
+
+ int Addr=0x00;
+ switch(ctrl->id)
+ {
+ case V4L2_CID_BRIGHTNESS:
+ Addr=0x12;
+ break;
+ case V4L2_CID_CONTRAST:
+ Addr=0x11;
+ break;
+ case V4L2_CID_SATURATION:
+ Addr=0x10;
+ break;
+ case V4L2_CID_HUE:
+ Addr=0x0f;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ctrl->value=ctrl->value>255 ? 255 : (ctrl->value<0 ? 0 : ctrl->value);
+ Addr=write_reg(client,Addr,ctrl->value,dec->channel);
+ if(Addr<0)
+ {
+ printk(KERN_INFO"wis_tw2804: can`t set_ctrl value:id=%d;value=%d",ctrl->id,ctrl->value);
+ return Addr;
+ }
+ printk(KERN_INFO"wis_tw2804: set_ctrl value:id=%d;value=%d",ctrl->id,ctrl->value);
+ switch(ctrl->id)
+ {
+ case V4L2_CID_BRIGHTNESS:
+ dec->brightness=ctrl->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ dec->contrast=ctrl->value;
+ break;
+ case V4L2_CID_SATURATION:
+ dec->saturation=ctrl->value;
+ break;
+ case V4L2_CID_HUE:
+ dec->hue=ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int tw2804_g_ctrl(struct v4l2_subdev *sd,struct v4l2_control *ctrl)
+{
+ struct wis_tw2804 *state=to_state(sd);
+ /// struct i2c_client *client=v4l2_get_subdevdata(sd);
+
+ switch(ctrl->id)
+ {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value=state->brightness;//=read_reg(client,0x12,state->channel);
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value=state->contrast;//=read_reg(client,0x11,state->channel);
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value=state->saturation;//=read_reg(client,0x10,state->channel);
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value=state->hue;//=read_reg(client,0x0f,state->channel);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int tw2804_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ struct wis_tw2804 *dec=to_state(sd);
+ struct i2c_client *client=v4l2_get_subdevdata(sd);
+
+/// v4l2_std_id *input=arg;
+ u8 regs[]=
+ {
+ 0x01,norm&V4L2_STD_NTSC ? 0xc4 : 0x84,
+ 0x09,norm&V4L2_STD_NTSC ? 0x07 : 0x04,
+ 0x0a,norm&V4L2_STD_NTSC ? 0xf0 : 0x20,
+ 0x0b,norm&V4L2_STD_NTSC ? 0x07 : 0x04,
+ 0x0c,norm&V4L2_STD_NTSC ? 0xf0 : 0x20,
+ 0x0d,norm&V4L2_STD_NTSC ? 0x40 : 0x4a,
+ 0x16,norm&V4L2_STD_NTSC ? 0x00 : 0x40,
+ 0x17,norm&V4L2_STD_NTSC ? 0x00 : 0x40,
+ 0x20,norm&V4L2_STD_NTSC ? 0x07 : 0x0f,
+ 0x21,norm&V4L2_STD_NTSC ? 0x07 : 0x0f,
+ 0xff,0xff,
+ };
+ write_regs(client,regs,dec->channel);
+ dec->norm=norm;
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops tw2804_core_ops=
+{
+ .log_status=tw2804_log_status,
+ .g_ctrl=tw2804_g_ctrl,
+ .s_ctrl=tw2804_s_ctrl,
+ .queryctrl=tw2804_queryctrl,
+ .s_std=tw2804_s_std,
+};
+
+/*
+static const struct v4l2_subdev_video_ops tw2804_video_ops = {
+ .s_routing = tw2804_s_video_routing,
+ .s_fmt = tw2804_s_fmt,
+};*/
+
+static const struct v4l2_subdev_ops tw2804_ops=
+{
+ .core=&tw2804_core_ops,
+/// .audio = &s2250_audio_ops,
+/// .video = &s2250_video_ops,
+};
+
static int wis_tw2804_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct wis_tw2804 *dec;
+ struct v4l2_subdev *sd;
+ printk(KERN_DEBUG "wis_tw2804 :probing %s adapter %s",id->name,client->adapter->name);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
@@ -303,13 +370,15 @@ static int wis_tw2804_probe(struct i2c_c
if (dec == NULL)
return -ENOMEM;
+ sd=&dec->sd;
dec->channel = -1;
dec->norm = V4L2_STD_NTSC;
dec->brightness = 128;
dec->contrast = 128;
dec->saturation = 128;
dec->hue = 128;
- i2c_set_clientdata(client, dec);
+ v4l2_i2c_subdev_init(sd,client,&tw2804_ops);
+ v4l2_info(sd,"initializing %s at address 0x%x on %s\n","tw 2804", client->addr, client->adapter->name);
printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
client->addr, adapter->name);
@@ -319,9 +388,10 @@ static int wis_tw2804_probe(struct i2c_c
static int wis_tw2804_remove(struct i2c_client *client)
{
- struct wis_tw2804 *dec = i2c_get_clientdata(client);
-
- kfree(dec);
+ struct v4l2_subdev *sd=i2c_get_clientdata(client);
+ printk(KERN_INFO"wis_tw2804: remove");
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
return 0;
}
next reply other threads:[~2012-03-20 15:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-20 15:30 volokh [this message]
2012-03-20 15:37 ` [PATCH] go7007 patch for 3.2.x Greg KH
2012-03-20 16:00 ` Ezequiel García
-- strict thread matches above, loose matches on Subject: below --
2012-03-20 15:21 volokh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1332257451.6182.60.camel@VPir \
--to=volokh@telros.ru \
--cc=devel@linuxdriverproject.org \
--cc=linux-media@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.