[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1334735415.1693.9.camel@VPir>
Date: Wed, 18 Apr 2012 11:50:15 +0400
From: volokh <volokh@...ros.ru>
To: mchehab@...radead.org
Cc: gregkh@...uxfoundation.org, my84@...ru, volokh@...ros.ru,
dhowells@...hat.com, justinmattock@...il.com,
pradheep.sh@...il.com, linux-media@...r.kernel.org,
devel@...verdev.osuosl.org, linux-kernel@...r.kernel.org
Subject: [PATCH] Staging: go7007: detector features - add new tuning option
>From a600b33c0824bf1b5031f820f8afaefa9e51dc16 Mon Sep 17 00:00:00 2001
From: Volokh Konstantin <my84@...ru>
Date: Tue, 17 Apr 2012 21:39:15 +0400
Subject: [PATCH] Staging: go7007: detector features - 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
With Utility script for conversation to 'c' style based on checkpatch.pl
Signed-off-by: Volokh Konstantin <my84@...ru>
---
drivers/staging/media/go7007/go7007-priv.h | 3 +-
drivers/staging/media/go7007/go7007-v4l2.c | 988 ++++++++++++++++++----------
drivers/staging/media/go7007/go7007.h | 95 +---
drivers/staging/media/go7007/wis-tw2804.c | 414 +++++++-----
scripts/correctpatch.pl | 269 ++++++++
5 files changed, 1175 insertions(+), 594 deletions(-)
create mode 100755 scripts/correctpatch.pl
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b58c394..4e47f29 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -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 --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 3ef4cd8..88054f0 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -39,14 +39,6 @@
#include "go7007-priv.h"
#include "wis-i2c.h"
-/* Temporary defines until accepted in v4l-dvb */
-#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
-
#define call_all(dev, o, f, args...) \
v4l2_device_call_until_err(dev, 0, o, f, ##args)
@@ -136,6 +128,7 @@ static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
switch (format) {
case GO7007_FORMAT_MJPEG:
return V4L2_BUF_FLAG_KEYFRAME;
+ case GO7007_FORMAT_H263:
case GO7007_FORMAT_MPEG4:
switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
case 0:
@@ -159,6 +152,8 @@ static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
default:
return 0;
}
+ default:
+ break;
}
return 0;
@@ -171,7 +166,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
- fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_H263)
return -EINVAL;
switch (go->standard) {
@@ -303,11 +298,10 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
go->gop_header_enable = 1;
go->dvd_mode = 0;
break;
- /* Backwards compatibility only! */
- case V4L2_PIX_FMT_MPEG4:
- if (go->format == GO7007_FORMAT_MPEG4)
+ case V4L2_PIX_FMT_H263:
+ if (go->format == GO7007_FORMAT_H263)
break;
- go->format = GO7007_FORMAT_MPEG4;
+ go->format = GO7007_FORMAT_H263;
go->pali = 0xf5;
go->aspect_ratio = GO7007_RATIO_1_1;
go->gop_size = go->sensor_framerate / 1000;
@@ -334,112 +328,388 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
return 0;
}
-#if 0
-static int clip_to_modet_map(struct go7007 *go, int region,
- struct v4l2_clip *clip_list)
+static int md_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
{
- 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;
+ 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;
+}
- /* Clear old region macroblocks */
- for (mbnum = 0; mbnum < 1624; ++mbnum)
- if (go->modet_map[mbnum] == region)
+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;
+}
- /* 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;
+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_AVC:
+ strcpy(menuctrl->name, "MPEG4");
+ 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
+ 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
+ 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);
+ 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);
+ 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);
+ return v4l2_ctrl_query_fill(ctrl,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 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);
+ 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);
+ 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);
+ 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);
+ 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 -EINVAL;
}
return 0;
}
@@ -484,7 +754,7 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
else*/
go->pali = 0x48;
break;
- case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
+ case V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC:
go->format = GO7007_FORMAT_MPEG4;
/*if (mpeg->pali >> 24 == 4)
go->pali = mpeg->pali & 0xff;
@@ -537,8 +807,13 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
return -EINVAL;
go->bitrate = ctrl->value;
break;
+ 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 -EINVAL;
}
return 0;
}
@@ -561,7 +836,7 @@ static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
break;
case GO7007_FORMAT_MPEG4:
- ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
break;
default:
return -EINVAL;
@@ -591,8 +866,11 @@ static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
case V4L2_CID_MPEG_VIDEO_BITRATE:
ctrl->value = go->bitrate;
break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ ctrl->value = go->ipb ? 2 : 0;
+ break;
default:
- return -EINVAL;
+ return -EINVAL;
}
return 0;
}
@@ -604,9 +882,7 @@ static int vidioc_querycap(struct file *file, void *priv,
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);
@@ -633,6 +909,9 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
fmt->pixelformat = V4L2_PIX_FMT_MPEG;
desc = "MPEG1/MPEG2/MPEG4";
break;
+ case 2:
+ fmt->pixelformat = V4L2_PIX_FMT_H263;
+ desc = "Compressed H263";
default:
return -EINVAL;
}
@@ -652,8 +931,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt->fmt.pix.width = go->width;
fmt->fmt.pix.height = go->height;
- fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
- V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
+ fmt->fmt.pix.pixelformat = (
+ go->format == GO7007_FORMAT_MJPEG) ? V4L2_PIX_FMT_MJPEG : (
+ (
+ go->format == GO7007_FORMAT_H263) ? V4L2_PIX_FMT_H263 : V4L2_PIX_FMT_MPEG);
fmt->fmt.pix.field = V4L2_FIELD_NONE;
fmt->fmt.pix.bytesperline = 0;
fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
@@ -974,39 +1255,52 @@ static int vidioc_streamoff(struct file *file, void *priv,
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;
+ struct go7007 *go = ((struct go7007_file *)priv)->go;
int id = query->id;
if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
return 0;
query->id = id;
- return mpeg_query_ctrl(query);
+ 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;
- 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;
- 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,
@@ -1059,16 +1353,92 @@ static int vidioc_s_parm(struct file *filp, void *priv,
The two functions below implement the newer ioctls
*/
-static int vidioc_enum_framesizes(struct file *filp, void *priv,
- struct v4l2_frmsizeenum *fsize)
+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))
+ 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:
+ case V4L2_PIX_FMT_H263:
+ 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:
+ case V4L2_PIX_FMT_H263:
+ 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;
@@ -1079,16 +1449,140 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
return 0;
}
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *fival)
+static int vidioc_enum_frameintervals(
+ struct file *filp,
+ void *priv,
+ struct v4l2_frmivalenum *fival)
{
- 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) ||
- (go->board_info->sensor_flags & GO7007_SENSOR_TV))
+ /* 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:
+ case V4L2_PIX_FMT_H263:
+ 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;
@@ -1404,235 +1898,6 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
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)
{
@@ -1778,7 +2043,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.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 = {
@@ -1786,13 +2053,15 @@ static struct video_device go7007_template = {
.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)
@@ -1815,7 +2084,10 @@ 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));
-
+ 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;
}
diff --git a/drivers/staging/media/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
index 7399c91..39fd533 100644
--- a/drivers/staging/media/go7007/go7007.h
+++ b/drivers/staging/media/go7007/go7007.h
@@ -19,69 +19,11 @@
/* DEPRECATED -- use V4L2_PIX_FMT_MPEG and then call GO7007IOC_S_MPEG_PARAMS
* to select between MPEG1, MPEG2, and MPEG4 */
-#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
-/* 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 {
- GO7007_ASPECT_RATIO_1_1 = 0,
- GO7007_ASPECT_RATIO_4_3_NTSC = 1,
- GO7007_ASPECT_RATIO_4_3_PAL = 2,
- GO7007_ASPECT_RATIO_16_9_NTSC = 3,
- GO7007_ASPECT_RATIO_16_9_PAL = 4,
-};
-
-/* Used to set generic compression parameters */
-struct go7007_comp_params {
- __u32 gop_size;
- __u32 max_b_frames;
- enum go7007_aspect_ratio aspect_ratio;
- __u32 flags;
- __u32 reserved[8];
-};
-
-#define GO7007_COMP_CLOSED_GOP 0x00000001
-#define GO7007_COMP_OMIT_SEQ_HEADER 0x00000002
-
-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 {
- enum go7007_mpeg_video_standard mpeg_video_standard;
- __u32 flags;
- __u32 pali;
- __u32 reserved[8];
-};
-
-#define GO7007_MPEG_FORCE_DVD_MODE 0x00000001
-#define GO7007_MPEG_OMIT_GOP_HEADER 0x00000002
-#define GO7007_MPEG_REPEAT_SEQHEADER 0x00000004
-
-#define GO7007_MPEG_PROFILE(format, pali) (((format)<<24)|(pali))
-
-#define GO7007_MPEG2_PROFILE_MAIN_MAIN GO7007_MPEG_PROFILE(2, 0x48)
-
-#define GO7007_MPEG4_PROFILE_S_L0 GO7007_MPEG_PROFILE(4, 0x08)
-#define GO7007_MPEG4_PROFILE_S_L1 GO7007_MPEG_PROFILE(4, 0x01)
-#define GO7007_MPEG4_PROFILE_S_L2 GO7007_MPEG_PROFILE(4, 0x02)
-#define GO7007_MPEG4_PROFILE_S_L3 GO7007_MPEG_PROFILE(4, 0x03)
-#define GO7007_MPEG4_PROFILE_ARTS_L1 GO7007_MPEG_PROFILE(4, 0x91)
-#define GO7007_MPEG4_PROFILE_ARTS_L2 GO7007_MPEG_PROFILE(4, 0x92)
-#define GO7007_MPEG4_PROFILE_ARTS_L3 GO7007_MPEG_PROFILE(4, 0x93)
-#define GO7007_MPEG4_PROFILE_ARTS_L4 GO7007_MPEG_PROFILE(4, 0x94)
-#define GO7007_MPEG4_PROFILE_AS_L0 GO7007_MPEG_PROFILE(4, 0xf0)
-#define GO7007_MPEG4_PROFILE_AS_L1 GO7007_MPEG_PROFILE(4, 0xf1)
-#define GO7007_MPEG4_PROFILE_AS_L2 GO7007_MPEG_PROFILE(4, 0xf2)
-#define GO7007_MPEG4_PROFILE_AS_L3 GO7007_MPEG_PROFILE(4, 0xf3)
-#define GO7007_MPEG4_PROFILE_AS_L4 GO7007_MPEG_PROFILE(4, 0xf4)
-#define GO7007_MPEG4_PROFILE_AS_L5 GO7007_MPEG_PROFILE(4, 0xf5)
+/* 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
struct go7007_md_params {
__u16 region;
@@ -98,17 +40,18 @@ struct go7007_md_region {
__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, \
- struct go7007_mpeg_params)
-#define GO7007IOC_S_COMP_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 4, \
- struct go7007_comp_params)
-#define GO7007IOC_G_COMP_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 5, \
- struct go7007_comp_params)
-#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
- struct go7007_md_params)
-#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
- struct go7007_md_params)
-#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
- struct go7007_md_region)
+#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 --git a/drivers/staging/media/go7007/wis-tw2804.c b/drivers/staging/media/go7007/wis-tw2804.c
index 9134f03..5a39ce0 100644
--- a/drivers/staging/media/go7007/wis-tw2804.c
+++ b/drivers/staging/media/go7007/wis-tw2804.c
@@ -21,10 +21,13 @@
#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 v4l2_subdev sd;
int channel;
int norm;
int brightness;
@@ -33,6 +36,13 @@ struct wis_tw2804 {
int hue;
};
+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,
@@ -105,9 +115,23 @@ 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 +143,247 @@ static int write_regs(struct i2c_client *client, u8 *regs, int channel)
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) {
- int *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;
+ 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;
+ 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;
+ 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;
}
- 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;
+}
+
+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;
}
- 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;
+ 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;
}
- 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;
+ 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:
- break;
+ 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 +391,20 @@ static int wis_tw2804_probe(struct i2c_client *client,
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 +414,10 @@ static int wis_tw2804_probe(struct i2c_client *client,
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;
}
diff --git a/scripts/correctpatch.pl b/scripts/correctpatch.pl
new file mode 100755
index 0000000..2bcf5ea
--- /dev/null
+++ b/scripts/correctpatch.pl
@@ -0,0 +1,269 @@
+#!/usr/bin/perl
+#***************************************************************************
+#* Copyright (C) 2012 by volokh *
+#* my84@...ru *
+#* *
+#* This program is under GPL2 licence you may redistribute it and/or *
+#* modify *
+#* Ligovskii 203-207, StPetersburg, Home Work, Russia *
+#***************************************************************************
+
+#use strict;
+
+my $File=0;
+my $DirOut="";#The Same directory to output
+my $NoWarn=0;
+my $NoError=0;
+my $Debug=0;
+
+local $MaxWidht=80;
+
+use Getopt::Long;
+# qw(:config no_auto_abbrev);
+
+GetOptions
+(
+ 'dirout=s'=>\$DirOut
+ ,'nowarn'=>\$NoWarn
+ ,'noerror'=>\$NoError
+ ,'f|file'=>\$File
+ ,'debug'=>\$Debug
+);
+
+if($#ARGV<0)
+{
+ print "$0: no input files\n";
+ exit(1);
+}
+
+my $TmpFile=".corpach";
+
+if($ARGV[0]=~/([^\/]+)$/)
+{
+ $TmpFile.=".$1";
+}
+
+my $BaseDir;
+if($0=~/(.*)\/[^\/]+$/)
+{
+ $BaseDir=$1;
+}
+
+print "Try correct File Enter this file:$ARGV[0] file=$File to $TmpFile\n";
+print "\t\t\033[1;35mPlease, keep copy of your source.\n\tRun this script again while count of errors/warnings will be const.\033[0;39m\n";
+
+my @FileSource;
+if(ReadFile($ARGV[0],\@FileSource)==0)
+{
+ system("$BaseDir/checkpatch.pl ".($File ? "--file" : "")." --terse $ARGV[0] > $TmpFile");
+ my @ErrorsList;
+ if(ReadFile($TmpFile,\@ErrorsList)==0)
+ {
+ if($File)
+ {
+ CorrectSource($ARGV[0],\@ErrorsList,\@FileSource);
+ WriteFile($ARGV[0],\@FileSource);
+ }else
+ {
+ #todo Correct patch operations
+ }
+ }
+}
+
+unlink $TmpFile;
+
+exec("$BaseDir/checkpatch.pl ".($File ? "--file" : "")." $ARGV[0]");
+
+sub CorrectSource
+{
+ my ($File,$EList,$Source)=@_;
+ my $Offset=0;
+ foreach my $Item (@$EList)
+ {
+ my $FFile=$File;
+ $FFile=~s/(\W)/\\$1/g;
+ if($Item=~/$File:([0-9]+): (WARNING|ERROR): (.+)/)
+ {
+ my $Pos=int($1)+$Offset;
+ my $Type=$2;
+ my $Error=$3;
+ if($Debug!=0)
+ {
+ print "Find Error in File:".$File." in pos=".$1." with type ".$2.",with text=".$3."\n";
+ print "Source=".@...urce[$Pos-1]."\n";
+ }
+ if($Type eq "WARNING" && !$NoWarn)
+ {
+ ###############################################################
+ # It would be correctly if every error has its own error code #
+ ###############################################################
+ if($Error eq "please, no spaces at the start of a line")
+ {
+ if(@$Source[$Pos-1]=~/[^\s]/)
+ {
+ @$Source[$Pos-1]=~s/^\s*/\t/;
+ }
+ }elsif($Error eq "line over 80 characters")
+ {
+ my $Text=@...urce[$Pos-1];
+ #@...urce[$Pos-1]=~s#(\w+)|(//.+\s*)#defined $1 ? $1."\n\t" : $2#gse;
+ @$Source[$Pos-1]=~s#([,(])\s*|(//.+\s*)#defined $1 ? $1."\n\t" : $2#gse;
+ }elsif($Error=~/suspect code indent for conditional statements \(/)
+ {
+ my $BrOpen=0;
+ my $Text=@...urce[$Pos-1];
+ if($Text=~s/.*(if|for)//)
+ {
+ do
+ {
+ if($Text=~s/\(//)
+ {
+ $BrOpen++;
+ }elsif($Text=~s/\)//)
+ {
+ $BrOpen--;
+ }else
+ {
+ $Pos++;
+ $Text=@...urce[$Pos-1];
+ }
+ }while($BrOpen!=0);
+ if($BrOpen==0)
+ {
+ @$Source[$Pos]=~s/^(\t*)[ ]*/$1/;
+ @$Source[$Pos]="\t".@...urce[$Pos];
+# if(@$Source[$Pos]=~s/^(.)//)
+ # {
+ # }
+ }
+ }
+ }
+ }elsif($Type eq "ERROR" && !$NoError)
+ {
+ if($Error=~/space required after that '(.)'/)
+ {
+ my $That=$1;
+ my $TThat=$That;
+ $TThat=~s/(\W)/\\$1/g;
+ @$Source[$Pos-1]=~s/$TThat([^\s])/$That $1/;
+ }elsif($Error=~/spaces required around that '(.+)'/)
+ {
+ my $That=$1;
+ my $TThat=$That;
+ $TThat=~s/(\W)/\\$1/g;
+ if(@$Source[$Pos-1]!~s/([^ \-<>!=])$TThat([^ <>=])/$1 $That $2/)#@...urce[$Pos-1]!~s/([^ ->])$TThat([^ ])/$1 $That $2/)
+ {
+ print "Can`t replace [$1] in [$2] and[$3] on ".@...urce[$Pos-1]." with [$That] on [$TThat]\n";
+ }
+ }elsif($Error eq "trailing whitespace")
+ {
+ @$Source[$Pos-1]=~s/[ ]+$//;
+ }elsif($Error eq "do not use C99 // comments")
+ {
+ @$Source[$Pos-1]=~s/\/\/(.*)/\/*$1*\//;
+ }elsif(($Error eq "that open brace { should be on the previous line") || ($Error=~/open brace '{' following (\w+) go on the same line/))
+ {
+ if(@$Source[$Pos-1]!~s/^(\s*){(\s*)//)
+ {
+ #This bug found correct (point to prev line instead real line)
+ $Pos++;
+ if(@$Source[$Pos-1]!~s/^(\s*){(\s*)//)
+ {
+ next;
+ }
+ }
+ @$Source[$Pos-2]=~s/[ ]*([\s]+)$/ {$1/;
+ }elsif($Error eq "space required before the open parenthesis '('")
+ {
+ @$Source[$Pos-1]=~s/([^\s])\(/$1 \(/;
+ }elsif($Error eq "code indent should use tabs where possible")
+ {
+ @$Source[$Pos-1]=~s/ /\t/g;
+ }elsif($Error eq "switch and case should be at the same indent")
+ {
+ my $BrOpen=0;
+ my $InSwitch=0;
+ my $Text=@...urce[$Pos-1];
+ if($Text=~s/([^\s]*)(\s*)switch(.)*\(.+\)//)
+ {
+ my $Spaces=$2;
+ do
+ {
+ if($BrOpen==1)
+ {
+ if(@$Source[$Pos-1]=~s/([^{}\s]*)(\s*)(case|default)([^:]*):/$1$Spaces$3$4:/)
+ {
+ }
+ }
+ if($Text=~s/\{//)
+ {
+ $BrOpen++;
+ }elsif($Text=~s/\}//)
+ {
+ $BrOpen--;
+ }else
+ {
+ $Pos++;
+ $Text=@...urce[$Pos-1];
+ }
+ }while($BrOpen!=0);# && $Pos<length(@$Source));
+ }
+ }elsif($Error=~/space prohibited before that '(.+)'/)
+ {
+ my $That=$1;
+ my $TThat=$That;
+ $TThat=~s/(\W)/\\$1/g;
+ @$Source[$Pos-1]=~s/\s$TThat/$That/;
+ }
+ }else
+ {
+ print "Nothing to correct at $File in $Pos position\n";
+ }
+ }
+ }
+}
+
+sub ReadFile
+{
+ my ($File,$InArrayRef)=@_;
+ if(!open(SRC,'<',"$File"))
+ {
+ print("\033[1;41mfile: \'$File\' not found for read\033[0;39m\n");
+ #die("file: '.$File.' not found\n");
+ return -1;
+ }
+ @$InArrayRef=<SRC>;
+ close(SRC);
+ return 0;
+}
+
+sub WriteFile
+{
+ my ($File,$InArrayRef)=@_;
+ if(!open(DST,'>',"$File"))
+ {
+ print("\033[1;41mfile: \'$File\' not found for write\033[0;39m\n");
+ #die("file: '.$File.' not found\n");
+ return -1;
+ }
+ print DST @$InArrayRef;
+ close(DST);
+ return 0;
+}
+
+my $Version='20.12.04';
+
+sub Help
+{
+ print "
+ Usage: $0 [OPTION] FILE
+ Version: $Version
+
+ Options:
+todo --dirout=PATH Use this temp PATH instead of ./
+ --file Input is a source file, otherwise it`s a patch
+ --nowarn No need correct warnings
+ --noerror No need correct errors
+ --debug Show debug messages
+ ";
+}
--
1.7.7.6
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists