Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
d7b09335
Commit
d7b09335
authored
Mar 04, 2002
by
Mark W. McClelland
Committed by
Linus Torvalds
Mar 04, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update USB ov511 driver to version 1.53
parent
cf16aaca
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1015 additions
and
1064 deletions
+1015
-1064
Documentation/usb/ov511.txt
Documentation/usb/ov511.txt
+3
-3
drivers/usb/ov511.c
drivers/usb/ov511.c
+960
-1031
drivers/usb/ov511.h
drivers/usb/ov511.h
+52
-30
No files found.
Documentation/usb/ov511.txt
View file @
d7b09335
...
@@ -182,9 +182,9 @@ MODULE PARAMETERS:
...
@@ -182,9 +182,9 @@ MODULE PARAMETERS:
DEFAULT: 1 (Always on)
DEFAULT: 1 (Always on)
DESC: Controls whether the LED (the little light) on the front of the camera
DESC: Controls whether the LED (the little light) on the front of the camera
is always off (0), always on (1), or only on when driver is open (2).
is always off (0), always on (1), or only on when driver is open (2).
This is
only supported with the OV511+ chipset, and even then only o
n
This is
not supported with the OV511, and might only work with certai
n
some cameras (ones that actually have the LED wired to the control pin,
cameras (ones that actually have the LED wired to the control pin, and
and not just hard
wired to be on all the time).
not just hard-
wired to be on all the time).
NAME: dump_bridge
NAME: dump_bridge
TYPE: integer (Boolean)
TYPE: integer (Boolean)
...
...
drivers/usb/ov511.c
View file @
d7b09335
/*
/*
* OmniVision OV511 Camera-to-USB Bridge Driver
* OmniVision OV511 Camera-to-USB Bridge Driver
*
*
* Copyright (c) 1999-200
1
Mark W. McClelland
* Copyright (c) 1999-200
2
Mark W. McClelland
* Original decompression code Copyright 1998-2000 OmniVision Technologies
* Original decompression code Copyright 1998-2000 OmniVision Technologies
* Many improvements by Bret Wallach <bwallac1@san.rr.com>
* Many improvements by Bret Wallach <bwallac1@san.rr.com>
* Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
* Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
* Changes by Claudio Matsuoka <claudio@conectiva.com>
* Changes by Claudio Matsuoka <claudio@conectiva.com>
* Original SAA7111A code by Dave Perks <dperks@ibm.net>
* Original SAA7111A code by Dave Perks <dperks@ibm.net>
* Kernel I2C interface adapted from nt1003 driver
* Kernel I2C interface adapted from nt1003 driver
* URB error messages from pwc driver by Nemosoft
* generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox
*
*
* Based on the Linux CPiA driver written by Peter Pregler,
* Based on the Linux CPiA driver written by Peter Pregler,
* Scott J. Bertin and Johannes Erdfelt.
* Scott J. Bertin and Johannes Erdfelt.
...
@@ -53,22 +55,35 @@
...
@@ -53,22 +55,35 @@
#include <asm/cpufeature.h>
#include <asm/cpufeature.h>
#endif
#endif
/* A new implementation of the V4L 1 API exists that gives drivers direct
* access to file_operations. The old API is compatible with all 2.2 and 2.4
* kernels, and all 2.5 kernels through 2.5.5 (at least).
*
* Remove this #define to enable the new API
*
* Note: This has nothing to do with the V4L 2 API.
*/
#define OV511_OLD_V4L
#include "ov511.h"
#include "ov511.h"
/*
/*
* Version Information
* Version Information
*/
*/
#define DRIVER_VERSION "v1.
49
for Linux 2.5"
#define DRIVER_VERSION "v1.
53
for Linux 2.5"
#define EMAIL "mmcclell@bigfoot.com"
#define EMAIL "mmcclell@bigfoot.com"
#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
<cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
<cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
#define DRIVER_DESC "
OV
511 USB Camera Driver"
#define DRIVER_DESC "
ov
511 USB Camera Driver"
#define OV511_I2C_RETRIES 3
#define OV511_I2C_RETRIES 3
#define ENABLE_Y_QUANTABLE 1
#define ENABLE_Y_QUANTABLE 1
#define ENABLE_UV_QUANTABLE 1
#define ENABLE_UV_QUANTABLE 1
/* If you change this, you must also change the MODULE_PARM definition */
#define OV511_MAX_UNIT_VIDEO 16
/* Pixel count * 3 bytes for RGB */
/* Pixel count * 3 bytes for RGB */
#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3)
#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3)
#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
...
@@ -78,128 +93,55 @@
...
@@ -78,128 +93,55 @@
#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
/* PARAMETER VARIABLES: */
/**********************************************************************
/* (See ov511.txt for detailed descriptions of these.) */
* Module Parameters
* (See ov511.txt for detailed descriptions of these)
/* Sensor automatically changes brightness */
**********************************************************************/
static
int
autobright
=
1
;
/* Sensor automatically changes gain */
static
int
autogain
=
1
;
/* Sensor automatically changes exposure */
static
int
autoexp
=
1
;
/* 0=no debug messages
* 1=init/detection/unload and other significant messages,
* 2=some warning messages
* 3=config/control function calls
* 4=most function calls and data parsing messages
* 5=highly repetitive mesgs
* NOTE: This should be changed to 0, 1, or 2 for production kernels
*/
static
int
debug
;
/* = 0 */
/* Fix vertical misalignment of red and blue at 640x480 */
static
int
fix_rgb_offset
;
/* = 0 */
/* Snapshot mode enabled flag */
static
int
snapshot
;
/* = 0 */
/* Force image to be read in RGB instead of BGR. This option allow
* programs that expect RGB data (e.g. gqcam) to work with this driver. */
static
int
force_rgb
;
/* = 0 */
/* Number of seconds before inactive buffers are deallocated */
static
int
buf_timeout
=
5
;
/* Number of cameras to stream from simultaneously */
static
int
cams
=
1
;
/* Enable compression. Needs a fast (>300 MHz) CPU. */
static
int
compress
;
/* = 0 */
/* Display test pattern - doesn't work yet either */
static
int
testpat
;
/* = 0 */
/* Setting this to 1 will make the sensor output GBR422 instead of YUV420. Only
* affects RGB24 mode. */
static
int
sensor_gbr
;
/* = 0 */
/* Dump raw pixel data. */
static
int
dumppix
;
/* = 0 */
/* LED policy. Only works on some OV511+ cameras. 0=off, 1=on (default), 2=auto
* (on when open) */
static
int
led
=
1
;
/* Set this to 1 to dump the bridge register contents after initialization */
static
int
dump_bridge
;
/* = 0 */
/* Set this to 1 to dump the sensor register contents after initialization */
static
int
dump_sensor
;
/* = 0 */
/* Temporary option for debugging "works, but no image" problem. Prints the
* first 12 bytes of data (potentially a packet header) in each isochronous
* data frame. */
static
int
printph
;
/* = 0 */
/* Compression parameters - I'm not exactly sure what these do yet */
static
int
phy
=
0x1f
;
static
int
phuv
=
0x05
;
static
int
pvy
=
0x06
;
static
int
pvuv
=
0x06
;
static
int
qhy
=
0x14
;
static
int
qhuv
=
0x03
;
static
int
qvy
=
0x04
;
static
int
qvuv
=
0x04
;
/* Light frequency. Set to 50 or 60 (Hz), or zero for default settings */
static
int
lightfreq
;
/* = 0 */
/* Set this to 1 to enable banding filter by default. Compensates for
/* These variables (and all static globals) default to zero */
* alternating horizontal light/dark bands caused by (usually fluorescent)
static
int
autobright
=
1
;
* lights */
static
int
autogain
=
1
;
static
int
bandingfilter
;
/* = 0 */
static
int
autoexp
=
1
;
static
int
debug
;
static
int
fix_rgb_offset
;
static
int
snapshot
;
static
int
force_rgb
;
static
int
buf_timeout
=
5
;
static
int
cams
=
1
;
static
int
compress
;
static
int
testpat
;
static
int
sensor_gbr
;
static
int
dumppix
;
static
int
led
=
1
;
static
int
dump_bridge
;
static
int
dump_sensor
;
static
int
printph
;
static
int
phy
=
0x1f
;
static
int
phuv
=
0x05
;
static
int
pvy
=
0x06
;
static
int
pvuv
=
0x06
;
static
int
qhy
=
0x14
;
static
int
qhuv
=
0x03
;
static
int
qvy
=
0x04
;
static
int
qvuv
=
0x04
;
static
int
lightfreq
;
static
int
bandingfilter
;
/* Pixel clock divisor */
/* Pixel clock divisor */
static
int
clockdiv
=
-
1
;
static
int
clockdiv
=
-
1
;
/* Isoc packet size */
/* Isoc packet size */
static
int
packetsize
=
-
1
;
static
int
packetsize
=
-
1
;
/* Frame drop register (16h) */
/* Frame drop register (16h) */
static
int
framedrop
=
-
1
;
static
int
framedrop
=
-
1
;
/* Allows picture settings (brightness, hue, etc...) to take effect immediately,
* even in the middle of a frame. This reduces the time to change settings, but
* can ruin frames during the change. Only affects OmniVision sensors. */
static
int
fastset
;
/* = 0 */
/* Forces the palette to a specific value. If an application requests a
* different palette, it will be rejected. */
static
int
force_palette
;
/* = 0 */
/* Set tuner type, if not autodetected */
static
int
tuner
=
-
1
;
/* Allows proper exposure of objects that are illuminated from behind. Only
static
int
fastset
;
* affects OmniVision sensors. */
static
int
force_palette
;
static
int
backlight
;
/* = 0 */
static
int
tuner
=
-
1
;
static
int
backlight
;
/* If you change this, you must also change the MODULE_PARM definition */
#define OV511_MAX_UNIT_VIDEO 16
/* Allows specified minor numbers to be forced. They will be assigned in the
* order that devices are detected. Note that you cannot specify 0 as a minor
* number. If you do not specify any, the next available one will be used. This
* requires kernel 2.4.5 or later. */
static
int
unit_video
[
OV511_MAX_UNIT_VIDEO
];
static
int
unit_video
[
OV511_MAX_UNIT_VIDEO
];
static
int
remove_zeros
;
/* Remove zero-padding from uncompressed incoming data. This will compensate for
* the blocks of corruption that appear when the camera cannot keep up with the
* speed of the USB bus (eg. at low frame resolutions) */
static
int
remove_zeros
;
/* = 0 */
MODULE_PARM
(
autobright
,
"i"
);
MODULE_PARM
(
autobright
,
"i"
);
MODULE_PARM_DESC
(
autobright
,
"Sensor automatically changes brightness"
);
MODULE_PARM_DESC
(
autobright
,
"Sensor automatically changes brightness"
);
...
@@ -289,6 +231,10 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
...
@@ -289,6 +231,10 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
/**********************************************************************
* Miscellaneous Globals
**********************************************************************/
static
struct
usb_driver
ov511_driver
;
static
struct
usb_driver
ov511_driver
;
static
struct
ov51x_decomp_ops
*
ov511_decomp_ops
;
static
struct
ov51x_decomp_ops
*
ov511_decomp_ops
;
...
@@ -303,20 +249,28 @@ static int i2c_detect_tries = 5;
...
@@ -303,20 +249,28 @@ static int i2c_detect_tries = 5;
/* MMX support is present in kernel and CPU. Checked upon decomp module load. */
/* MMX support is present in kernel and CPU. Checked upon decomp module load. */
static
int
ov51x_mmx_available
;
static
int
ov51x_mmx_available
;
/* Function prototypes */
static
__devinitdata
struct
usb_device_id
device_table
[]
=
{
static
void
ov51x_clear_snapshot
(
struct
usb_ov511
*
);
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV511
)
},
static
int
ov51x_check_snapshot
(
struct
usb_ov511
*
);
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV511PLUS
)
},
static
inline
int
sensor_get_picture
(
struct
usb_ov511
*
,
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV518
)
},
struct
video_picture
*
);
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV518PLUS
)
},
static
int
sensor_get_exposure
(
struct
usb_ov511
*
,
unsigned
char
*
);
{
USB_DEVICE
(
VEND_MATTEL
,
PROD_ME2CAM
)
},
static
int
ov51x_control_ioctl
(
struct
inode
*
,
struct
file
*
,
unsigned
int
,
{
}
/* Terminating entry */
unsigned
long
);
};
MODULE_DEVICE_TABLE
(
usb
,
device_table
);
static
unsigned
char
yQuanTable511
[]
=
OV511_YQUANTABLE
;
static
unsigned
char
uvQuanTable511
[]
=
OV511_UVQUANTABLE
;
static
unsigned
char
yQuanTable518
[]
=
OV518_YQUANTABLE
;
static
unsigned
char
uvQuanTable518
[]
=
OV518_UVQUANTABLE
;
/**********************************************************************
/**********************************************************************
*
List of known OV511-based camera
s
*
Symbolic Name
s
**********************************************************************/
**********************************************************************/
static
struct
cam_list
clist
[]
=
{
/* Known OV511-based cameras */
static
struct
symbolic_list
camlist
[]
=
{
{
0
,
"Generic Camera (no ID)"
},
{
0
,
"Generic Camera (no ID)"
},
{
1
,
"Mustek WCam 3X"
},
{
1
,
"Mustek WCam 3X"
},
{
3
,
"D-Link DSB-C300"
},
{
3
,
"D-Link DSB-C300"
},
...
@@ -336,46 +290,78 @@ static struct cam_list clist[] = {
...
@@ -336,46 +290,78 @@ static struct cam_list clist[] = {
{
-
1
,
NULL
}
{
-
1
,
NULL
}
};
};
static
__devinitdata
struct
usb_device_id
device_table
[]
=
{
/* Video4Linux1 Palettes */
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV511
)
},
static
struct
symbolic_list
v4l1_plist
[]
=
{
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV511PLUS
)
},
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV518
)
},
{
USB_DEVICE
(
VEND_OMNIVISION
,
PROD_OV518PLUS
)
},
{
USB_DEVICE
(
VEND_MATTEL
,
PROD_ME2CAM
)
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
usb
,
device_table
);
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
static
struct
palette_list
plist
[]
=
{
{
VIDEO_PALETTE_GREY
,
"GREY"
},
{
VIDEO_PALETTE_GREY
,
"GREY"
},
{
VIDEO_PALETTE_HI240
,
"HI240"
},
{
VIDEO_PALETTE_HI240
,
"HI240"
},
{
VIDEO_PALETTE_RGB565
,
"RGB565"
},
{
VIDEO_PALETTE_RGB565
,
"RGB565"
},
{
VIDEO_PALETTE_RGB24
,
"RGB24"
},
{
VIDEO_PALETTE_RGB24
,
"RGB24"
},
{
VIDEO_PALETTE_RGB32
,
"RGB32"
},
{
VIDEO_PALETTE_RGB32
,
"RGB32"
},
{
VIDEO_PALETTE_RGB555
,
"RGB555"
},
{
VIDEO_PALETTE_RGB555
,
"RGB555"
},
{
VIDEO_PALETTE_YUV422
,
"YUV422"
},
{
VIDEO_PALETTE_YUV422
,
"YUV422"
},
{
VIDEO_PALETTE_YUYV
,
"YUYV"
},
{
VIDEO_PALETTE_YUYV
,
"YUYV"
},
{
VIDEO_PALETTE_UYVY
,
"UYVY"
},
{
VIDEO_PALETTE_UYVY
,
"UYVY"
},
{
VIDEO_PALETTE_YUV420
,
"YUV420"
},
{
VIDEO_PALETTE_YUV420
,
"YUV420"
},
{
VIDEO_PALETTE_YUV411
,
"YUV411"
},
{
VIDEO_PALETTE_YUV411
,
"YUV411"
},
{
VIDEO_PALETTE_RAW
,
"RAW"
},
{
VIDEO_PALETTE_RAW
,
"RAW"
},
{
VIDEO_PALETTE_YUV422P
,
"YUV422P"
},
{
VIDEO_PALETTE_YUV422P
,
"YUV422P"
},
{
VIDEO_PALETTE_YUV411P
,
"YUV411P"
},
{
VIDEO_PALETTE_YUV411P
,
"YUV411P"
},
{
VIDEO_PALETTE_YUV420P
,
"YUV420P"
},
{
VIDEO_PALETTE_YUV420P
,
"YUV420P"
},
{
VIDEO_PALETTE_YUV410P
,
"YUV410P"
},
{
VIDEO_PALETTE_YUV410P
,
"YUV410P"
},
{
-
1
,
NULL
}
{
-
1
,
NULL
}
};
};
#endif
static
unsigned
char
yQuanTable511
[]
=
OV511_YQUANTABLE
;
static
struct
symbolic_list
brglist
[]
=
{
static
unsigned
char
uvQuanTable511
[]
=
OV511_UVQUANTABLE
;
{
BRG_OV511
,
"OV511"
},
static
unsigned
char
yQuanTable518
[]
=
OV518_YQUANTABLE
;
{
BRG_OV511PLUS
,
"OV511+"
},
static
unsigned
char
uvQuanTable518
[]
=
OV518_UVQUANTABLE
;
{
BRG_OV518
,
"OV518"
},
{
BRG_OV518PLUS
,
"OV518+"
},
{
-
1
,
NULL
}
};
static
struct
symbolic_list
senlist
[]
=
{
{
SEN_OV76BE
,
"OV76BE"
},
{
SEN_OV7610
,
"OV7610"
},
{
SEN_OV7620
,
"OV7620"
},
{
SEN_OV7620AE
,
"OV7620AE"
},
{
SEN_OV6620
,
"OV6620"
},
{
SEN_OV6630
,
"OV6630"
},
{
SEN_OV6630AE
,
"OV6630AE"
},
{
SEN_OV6630AF
,
"OV6630AF"
},
{
SEN_OV8600
,
"OV8600"
},
{
SEN_KS0127
,
"KS0127"
},
{
SEN_KS0127B
,
"KS0127B"
},
{
SEN_SAA7111A
,
"SAA7111A"
},
{
-
1
,
NULL
}
};
/* URB error codes: */
static
struct
symbolic_list
urb_errlist
[]
=
{
{
-
ENOSR
,
"Buffer error (overrun)"
},
{
-
EPIPE
,
"Stalled (device not responding)"
},
{
-
EOVERFLOW
,
"Babble (bad cable?)"
},
{
-
EPROTO
,
"Bit-stuff error (bad cable?)"
},
{
-
EILSEQ
,
"CRC/Timeout"
},
{
-
ETIMEDOUT
,
"NAK (device does not respond)"
},
{
-
1
,
NULL
}
};
/**********************************************************************
* Prototypes
**********************************************************************/
static
void
ov51x_clear_snapshot
(
struct
usb_ov511
*
);
static
int
ov51x_check_snapshot
(
struct
usb_ov511
*
);
static
inline
int
sensor_get_picture
(
struct
usb_ov511
*
,
struct
video_picture
*
);
static
int
sensor_get_exposure
(
struct
usb_ov511
*
,
unsigned
char
*
);
static
int
ov51x_control_ioctl
(
struct
inode
*
,
struct
file
*
,
unsigned
int
,
unsigned
long
);
/**********************************************************************
/**********************************************************************
*
* Memory management
* Memory management
*
**********************************************************************/
**********************************************************************/
/* Here we want the physical address of the memory.
/* Here we want the physical address of the memory.
...
@@ -453,7 +439,7 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
...
@@ -453,7 +439,7 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
void
*
data
)
void
*
data
)
{
{
char
*
out
=
page
;
char
*
out
=
page
;
int
i
,
j
,
len
;
int
i
,
len
;
struct
usb_ov511
*
ov
=
data
;
struct
usb_ov511
*
ov
=
data
;
struct
video_picture
p
;
struct
video_picture
p
;
unsigned
char
exp
;
unsigned
char
exp
;
...
@@ -469,8 +455,7 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
...
@@ -469,8 +455,7 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
out
+=
sprintf
(
out
,
"driver_version : %s
\n
"
,
DRIVER_VERSION
);
out
+=
sprintf
(
out
,
"driver_version : %s
\n
"
,
DRIVER_VERSION
);
out
+=
sprintf
(
out
,
"custom_id : %d
\n
"
,
ov
->
customid
);
out
+=
sprintf
(
out
,
"custom_id : %d
\n
"
,
ov
->
customid
);
out
+=
sprintf
(
out
,
"model : %s
\n
"
,
ov
->
desc
?
out
+=
sprintf
(
out
,
"model : %s
\n
"
,
ov
->
desc
);
clist
[
ov
->
desc
].
description
:
"unknown"
);
out
+=
sprintf
(
out
,
"streaming : %s
\n
"
,
YES_NO
(
ov
->
streaming
));
out
+=
sprintf
(
out
,
"streaming : %s
\n
"
,
YES_NO
(
ov
->
streaming
));
out
+=
sprintf
(
out
,
"grabbing : %s
\n
"
,
YES_NO
(
ov
->
grabbing
));
out
+=
sprintf
(
out
,
"grabbing : %s
\n
"
,
YES_NO
(
ov
->
grabbing
));
out
+=
sprintf
(
out
,
"compress : %s
\n
"
,
YES_NO
(
ov
->
compress
));
out
+=
sprintf
(
out
,
"compress : %s
\n
"
,
YES_NO
(
ov
->
compress
));
...
@@ -491,36 +476,16 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
...
@@ -491,36 +476,16 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
ov
->
frame
[
i
].
depth
);
ov
->
frame
[
i
].
depth
);
out
+=
sprintf
(
out
,
" size : %d %d
\n
"
,
out
+=
sprintf
(
out
,
" size : %d %d
\n
"
,
ov
->
frame
[
i
].
width
,
ov
->
frame
[
i
].
height
);
ov
->
frame
[
i
].
width
,
ov
->
frame
[
i
].
height
);
out
+=
sprintf
(
out
,
" format : "
);
out
+=
sprintf
(
out
,
" format : %s
\n
"
,
for
(
j
=
0
;
plist
[
j
].
num
>=
0
;
j
++
)
{
symbolic
(
v4l1_plist
,
ov
->
frame
[
i
].
format
));
if
(
plist
[
j
].
num
==
ov
->
frame
[
i
].
format
)
{
out
+=
sprintf
(
out
,
"%s
\n
"
,
plist
[
j
].
name
);
break
;
}
}
if
(
plist
[
j
].
num
<
0
)
out
+=
sprintf
(
out
,
"unknown
\n
"
);
out
+=
sprintf
(
out
,
" data_buffer : 0x%p
\n
"
,
out
+=
sprintf
(
out
,
" data_buffer : 0x%p
\n
"
,
ov
->
frame
[
i
].
data
);
ov
->
frame
[
i
].
data
);
}
}
out
+=
sprintf
(
out
,
"snap_enabled : %s
\n
"
,
YES_NO
(
ov
->
snap_enabled
));
out
+=
sprintf
(
out
,
"snap_enabled : %s
\n
"
,
YES_NO
(
ov
->
snap_enabled
));
out
+=
sprintf
(
out
,
"bridge : %s
\n
"
,
out
+=
sprintf
(
out
,
"bridge : %s
\n
"
,
ov
->
bridge
==
BRG_OV511
?
"OV511"
:
symbolic
(
brglist
,
ov
->
bridge
));
ov
->
bridge
==
BRG_OV511PLUS
?
"OV511+"
:
ov
->
bridge
==
BRG_OV518
?
"OV518"
:
ov
->
bridge
==
BRG_OV518PLUS
?
"OV518+"
:
"unknown"
);
out
+=
sprintf
(
out
,
"sensor : %s
\n
"
,
out
+=
sprintf
(
out
,
"sensor : %s
\n
"
,
ov
->
sensor
==
SEN_OV6620
?
"OV6620"
:
symbolic
(
senlist
,
ov
->
sensor
));
ov
->
sensor
==
SEN_OV6630
?
"OV6630"
:
ov
->
sensor
==
SEN_OV7610
?
"OV7610"
:
ov
->
sensor
==
SEN_OV7620
?
"OV7620"
:
ov
->
sensor
==
SEN_OV7620AE
?
"OV7620AE"
:
ov
->
sensor
==
SEN_OV8600
?
"OV8600"
:
ov
->
sensor
==
SEN_KS0127
?
"KS0127"
:
ov
->
sensor
==
SEN_KS0127B
?
"KS0127B"
:
ov
->
sensor
==
SEN_SAA7111A
?
"SAA7111A"
:
"unknown"
);
out
+=
sprintf
(
out
,
"packet_size : %d
\n
"
,
ov
->
packet_size
);
out
+=
sprintf
(
out
,
"packet_size : %d
\n
"
,
ov
->
packet_size
);
out
+=
sprintf
(
out
,
"framebuffer : 0x%p
\n
"
,
ov
->
fbuf
);
out
+=
sprintf
(
out
,
"framebuffer : 0x%p
\n
"
,
ov
->
fbuf
);
...
@@ -582,89 +547,91 @@ ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
...
@@ -582,89 +547,91 @@ ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
}
}
static
void
static
void
create_proc_ov511_cam
(
struct
usb_ov511
*
ov
511
)
create_proc_ov511_cam
(
struct
usb_ov511
*
ov
)
{
{
char
dirname
[
4
];
char
dirname
[
10
];
if
(
!
ov511_proc_entry
||
!
ov
511
)
if
(
!
ov511_proc_entry
||
!
ov
)
return
;
return
;
/* Create per-device directory */
/* Create per-device directory */
s
printf
(
dirname
,
"%d"
,
ov511
->
vdev
.
minor
);
s
nprintf
(
dirname
,
10
,
"%d"
,
ov
->
vdev
.
minor
);
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/"
,
dirname
);
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/"
,
dirname
);
ov511
->
proc_devdir
=
create_proc_entry
(
dirname
,
S_IFDIR
,
ov
->
proc_devdir
=
create_proc_entry
(
dirname
,
S_IFDIR
,
ov511_proc_entry
);
ov511_proc_entry
);
if
(
!
ov
->
proc_devdir
)
if
(
!
ov511
->
proc_devdir
)
return
;
return
;
ov
->
proc_devdir
->
owner
=
THIS_MODULE
;
/* Create "info" entry (human readable device information) */
/* Create "info" entry (human readable device information) */
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/info"
,
dirname
);
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/info"
,
dirname
);
ov511
->
proc_info
=
create_proc_read_entry
(
"info"
,
ov
->
proc_info
=
create_proc_read_entry
(
"info"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
ov511
->
proc_devdir
,
ov
->
proc_devdir
,
ov511_read_proc_info
,
ov
);
ov511_read_proc_info
,
ov511
);
if
(
!
ov
->
proc_info
)
if
(
!
ov511
->
proc_info
)
return
;
return
;
ov
->
proc_info
->
owner
=
THIS_MODULE
;
/* Don't create it if old snapshot mode on (would cause race cond.) */
/* Don't create it if old snapshot mode on (would cause race cond.) */
if
(
!
snapshot
)
{
if
(
!
snapshot
)
{
/* Create "button" entry (snapshot button status) */
/* Create "button" entry (snapshot button status) */
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/button"
,
dirname
);
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/button"
,
dirname
);
ov
511
->
proc_button
=
create_proc_read_entry
(
"button"
,
ov
->
proc_button
=
create_proc_read_entry
(
"button"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
ov
511
->
proc_devdir
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
ov
->
proc_devdir
,
ov511_read_proc_button
,
ov
511
);
ov511_read_proc_button
,
ov
);
if
(
!
ov
511
->
proc_button
)
if
(
!
ov
->
proc_button
)
return
;
return
;
}
}
ov
->
proc_button
->
owner
=
THIS_MODULE
;
/* Create "control" entry (ioctl() interface) */
/* Create "control" entry (ioctl() interface) */
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/control"
,
dirname
);
PDEBUG
(
4
,
"creating /proc/video/ov511/%s/control"
,
dirname
);
lock_kernel
();
lock_kernel
();
ov
511
->
proc_control
=
create_proc_entry
(
"control"
,
ov
->
proc_control
=
create_proc_entry
(
"control"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
ov511
->
proc_devdir
);
ov
->
proc_devdir
);
if
(
!
ov
511
->
proc_control
)
{
if
(
!
ov
->
proc_control
)
{
unlock_kernel
();
unlock_kernel
();
return
;
return
;
}
}
ov511
->
proc_control
->
data
=
ov511
;
ov
->
proc_control
->
owner
=
THIS_MODULE
;
ov511
->
proc_control
->
proc_fops
=
&
ov511_control_fops
;
ov
->
proc_control
->
data
=
ov
;
ov
->
proc_control
->
proc_fops
=
&
ov511_control_fops
;
unlock_kernel
();
unlock_kernel
();
}
}
static
void
static
void
destroy_proc_ov511_cam
(
struct
usb_ov511
*
ov
511
)
destroy_proc_ov511_cam
(
struct
usb_ov511
*
ov
)
{
{
char
dirname
[
4
];
char
dirname
[
10
];
if
(
!
ov
511
||
!
ov511
->
proc_devdir
)
if
(
!
ov
||
!
ov
->
proc_devdir
)
return
;
return
;
s
printf
(
dirname
,
"%d"
,
ov511
->
vdev
.
minor
);
s
nprintf
(
dirname
,
10
,
"%d"
,
ov
->
vdev
.
minor
);
/* Destroy "control" entry */
/* Destroy "control" entry */
if
(
ov
511
->
proc_control
)
{
if
(
ov
->
proc_control
)
{
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/control"
,
dirname
);
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/control"
,
dirname
);
remove_proc_entry
(
"control"
,
ov
511
->
proc_devdir
);
remove_proc_entry
(
"control"
,
ov
->
proc_devdir
);
ov
511
->
proc_control
=
NULL
;
ov
->
proc_control
=
NULL
;
}
}
/* Destroy "button" entry */
/* Destroy "button" entry */
if
(
ov
511
->
proc_button
)
{
if
(
ov
->
proc_button
)
{
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/button"
,
dirname
);
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/button"
,
dirname
);
remove_proc_entry
(
"button"
,
ov
511
->
proc_devdir
);
remove_proc_entry
(
"button"
,
ov
->
proc_devdir
);
ov
511
->
proc_button
=
NULL
;
ov
->
proc_button
=
NULL
;
}
}
/* Destroy "info" entry */
/* Destroy "info" entry */
if
(
ov
511
->
proc_info
)
{
if
(
ov
->
proc_info
)
{
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/info"
,
dirname
);
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/info"
,
dirname
);
remove_proc_entry
(
"info"
,
ov
511
->
proc_devdir
);
remove_proc_entry
(
"info"
,
ov
->
proc_devdir
);
ov
511
->
proc_info
=
NULL
;
ov
->
proc_info
=
NULL
;
}
}
/* Destroy per-device directory */
/* Destroy per-device directory */
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/"
,
dirname
);
PDEBUG
(
4
,
"destroying /proc/video/ov511/%s/"
,
dirname
);
remove_proc_entry
(
dirname
,
ov511_proc_entry
);
remove_proc_entry
(
dirname
,
ov511_proc_entry
);
ov
511
->
proc_devdir
=
NULL
;
ov
->
proc_devdir
=
NULL
;
}
}
static
void
static
void
...
@@ -724,7 +691,7 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
...
@@ -724,7 +691,7 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
up
(
&
ov
->
cbuf_lock
);
up
(
&
ov
->
cbuf_lock
);
if
(
rc
<
0
)
if
(
rc
<
0
)
err
(
"reg write: error %d
"
,
rc
);
err
(
"reg write: error %d
: %s"
,
rc
,
symbolic
(
urb_errlist
,
rc
)
);
return
rc
;
return
rc
;
}
}
...
@@ -746,7 +713,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg)
...
@@ -746,7 +713,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg)
PDEBUG
(
5
,
"0x%02X:0x%02X"
,
reg
,
ov
->
cbuf
[
0
]);
PDEBUG
(
5
,
"0x%02X:0x%02X"
,
reg
,
ov
->
cbuf
[
0
]);
if
(
rc
<
0
)
if
(
rc
<
0
)
err
(
"reg read: error %d
"
,
rc
);
err
(
"reg read: error %d
: %s"
,
rc
,
symbolic
(
urb_errlist
,
rc
)
);
else
else
rc
=
ov
->
cbuf
[
0
];
rc
=
ov
->
cbuf
[
0
];
...
@@ -805,7 +772,8 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
...
@@ -805,7 +772,8 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
up
(
&
ov
->
cbuf_lock
);
up
(
&
ov
->
cbuf_lock
);
if
(
rc
<
0
)
if
(
rc
<
0
)
err
(
"reg write multiple: error %d"
,
rc
);
err
(
"reg write multiple: error %d: %s"
,
rc
,
symbolic
(
urb_errlist
,
rc
));
return
rc
;
return
rc
;
}
}
...
@@ -937,21 +905,17 @@ ov518_i2c_write_internal(struct usb_ov511 *ov,
...
@@ -937,21 +905,17 @@ ov518_i2c_write_internal(struct usb_ov511 *ov,
/* Select camera register */
/* Select camera register */
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_3
,
reg
);
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_3
,
reg
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Write "value" to I2C data port of OV511 */
/* Write "value" to I2C data port of OV511 */
rc
=
reg_w
(
ov
,
R51x_I2C_DATA
,
value
);
rc
=
reg_w
(
ov
,
R51x_I2C_DATA
,
value
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Initiate 3-byte write cycle */
/* Initiate 3-byte write cycle */
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x01
);
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x01
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
return
0
;
return
0
;
error:
err
(
"ov518 i2c write: error %d"
,
rc
);
return
rc
;
}
}
/* NOTE: Do not call this function directly! */
/* NOTE: Do not call this function directly! */
...
@@ -968,19 +932,19 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
...
@@ -968,19 +932,19 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
/* Select camera register */
/* Select camera register */
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_3
,
reg
);
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_3
,
reg
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Write "value" to I2C data port of OV511 */
/* Write "value" to I2C data port of OV511 */
rc
=
reg_w
(
ov
,
R51x_I2C_DATA
,
value
);
rc
=
reg_w
(
ov
,
R51x_I2C_DATA
,
value
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Initiate 3-byte write cycle */
/* Initiate 3-byte write cycle */
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x01
);
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x01
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
if
((
rc
&
2
)
==
0
)
/* Ack? */
if
((
rc
&
2
)
==
0
)
/* Ack? */
break
;
break
;
...
@@ -990,16 +954,11 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
...
@@ -990,16 +954,11 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
#endif
#endif
if
(
--
retries
<
0
)
{
if
(
--
retries
<
0
)
{
err
(
"i2c write retries exhausted"
);
err
(
"i2c write retries exhausted"
);
rc
=
-
1
;
return
-
1
;
goto
error
;
}
}
}
}
return
0
;
return
0
;
error:
err
(
"i2c write: error %d"
,
rc
);
return
rc
;
}
}
/* NOTE: Do not call this function directly!
/* NOTE: Do not call this function directly!
...
@@ -1014,25 +973,21 @@ ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
...
@@ -1014,25 +973,21 @@ ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
/* Select camera register */
/* Select camera register */
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_2
,
reg
);
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_2
,
reg
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Initiate 2-byte write cycle */
/* Initiate 2-byte write cycle */
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x03
);
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x03
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Initiate 2-byte read cycle */
/* Initiate 2-byte read cycle */
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x05
);
rc
=
reg_w
(
ov
,
R518_I2C_CTL
,
0x05
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
value
=
reg_r
(
ov
,
R51x_I2C_DATA
);
value
=
reg_r
(
ov
,
R51x_I2C_DATA
);
PDEBUG
(
5
,
"0x%02X:0x%02X"
,
reg
,
value
);
PDEBUG
(
5
,
"0x%02X:0x%02X"
,
reg
,
value
);
return
value
;
return
value
;
error:
err
(
"ov518 i2c read: error %d"
,
rc
);
return
rc
;
}
}
/* NOTE: Do not call this function directly!
/* NOTE: Do not call this function directly!
...
@@ -1046,15 +1001,15 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
...
@@ -1046,15 +1001,15 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
/* Select camera register */
/* Select camera register */
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_2
,
reg
);
rc
=
reg_w
(
ov
,
R51x_I2C_SADDR_2
,
reg
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
/* Initiate 2-byte write cycle */
/* Initiate 2-byte write cycle */
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x03
);
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x03
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
if
((
rc
&
2
)
==
0
)
/* Ack? */
if
((
rc
&
2
)
==
0
)
/* Ack? */
break
;
break
;
...
@@ -1064,8 +1019,7 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
...
@@ -1064,8 +1019,7 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
if
(
--
retries
<
0
)
{
if
(
--
retries
<
0
)
{
err
(
"i2c write retries exhausted"
);
err
(
"i2c write retries exhausted"
);
rc
=
-
1
;
return
-
1
;
goto
error
;
}
}
}
}
...
@@ -1073,23 +1027,22 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
...
@@ -1073,23 +1027,22 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
for
(
retries
=
OV511_I2C_RETRIES
;
;
)
{
/* Initiate 2-byte read cycle */
/* Initiate 2-byte read cycle */
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x05
);
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x05
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
do
rc
=
reg_r
(
ov
,
R511_I2C_CTL
);
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
while
(
rc
>
0
&&
((
rc
&
1
)
==
0
));
/* Retry until idle */
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
if
((
rc
&
2
)
==
0
)
/* Ack? */
if
((
rc
&
2
)
==
0
)
/* Ack? */
break
;
break
;
/* I2C abort */
/* I2C abort */
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x10
);
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x10
);
if
(
rc
<
0
)
goto
error
;
if
(
rc
<
0
)
return
rc
;
if
(
--
retries
<
0
)
{
if
(
--
retries
<
0
)
{
err
(
"i2c read retries exhausted"
);
err
(
"i2c read retries exhausted"
);
rc
=
-
1
;
return
-
1
;
goto
error
;
}
}
}
}
...
@@ -1100,13 +1053,9 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
...
@@ -1100,13 +1053,9 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
/* This is needed to make i2c_w() work */
/* This is needed to make i2c_w() work */
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x05
);
rc
=
reg_w
(
ov
,
R511_I2C_CTL
,
0x05
);
if
(
rc
<
0
)
if
(
rc
<
0
)
goto
error
;
return
rc
;
return
value
;
return
value
;
error:
err
(
"i2c read: error %d"
,
rc
);
return
rc
;
}
}
/* returns: negative is error, pos or zero is data */
/* returns: negative is error, pos or zero is data */
...
@@ -1311,22 +1260,17 @@ write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
...
@@ -1311,22 +1260,17 @@ write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
while
(
pRegvals
->
bus
!=
OV511_DONE_BUS
)
{
while
(
pRegvals
->
bus
!=
OV511_DONE_BUS
)
{
if
(
pRegvals
->
bus
==
OV511_REG_BUS
)
{
if
(
pRegvals
->
bus
==
OV511_REG_BUS
)
{
if
((
rc
=
reg_w
(
ov
,
pRegvals
->
reg
,
pRegvals
->
val
))
<
0
)
if
((
rc
=
reg_w
(
ov
,
pRegvals
->
reg
,
pRegvals
->
val
))
<
0
)
goto
error
;
return
rc
;
}
else
if
(
pRegvals
->
bus
==
OV511_I2C_BUS
)
{
}
else
if
(
pRegvals
->
bus
==
OV511_I2C_BUS
)
{
if
((
rc
=
i2c_w
(
ov
,
pRegvals
->
reg
,
pRegvals
->
val
))
<
0
)
if
((
rc
=
i2c_w
(
ov
,
pRegvals
->
reg
,
pRegvals
->
val
))
<
0
)
goto
error
;
return
rc
;
}
else
{
}
else
{
err
(
"Bad regval array"
);
err
(
"Bad regval array"
);
rc
=
-
1
;
return
-
1
;
goto
error
;
}
}
pRegvals
++
;
pRegvals
++
;
}
}
return
0
;
return
0
;
error:
err
(
"write regvals: error %d"
,
rc
);
return
rc
;
}
}
#ifdef OV511_DEBUG
#ifdef OV511_DEBUG
...
@@ -2394,13 +2338,13 @@ get_depth(int palette)
...
@@ -2394,13 +2338,13 @@ get_depth(int palette)
{
{
switch
(
palette
)
{
switch
(
palette
)
{
case
VIDEO_PALETTE_GREY
:
return
8
;
case
VIDEO_PALETTE_GREY
:
return
8
;
case
VIDEO_PALETTE_YUV420
:
return
12
;
case
VIDEO_PALETTE_YUV420P
:
return
12
;
/* Planar */
case
VIDEO_PALETTE_RGB565
:
return
16
;
case
VIDEO_PALETTE_RGB565
:
return
16
;
case
VIDEO_PALETTE_RGB24
:
return
24
;
case
VIDEO_PALETTE_RGB24
:
return
24
;
case
VIDEO_PALETTE_YUV422
:
return
16
;
case
VIDEO_PALETTE_YUV422
:
return
16
;
case
VIDEO_PALETTE_YUYV
:
return
16
;
case
VIDEO_PALETTE_YUYV
:
return
16
;
case
VIDEO_PALETTE_YUV420
:
return
12
;
case
VIDEO_PALETTE_YUV422P
:
return
16
;
/* Planar */
case
VIDEO_PALETTE_YUV422P
:
return
16
;
/* Planar */
case
VIDEO_PALETTE_YUV420P
:
return
12
;
/* Planar */
default:
return
0
;
/* Invalid format */
default:
return
0
;
/* Invalid format */
}
}
}
}
...
@@ -2803,11 +2747,11 @@ ov518_mode_init_regs(struct usb_ov511 *ov,
...
@@ -2803,11 +2747,11 @@ ov518_mode_init_regs(struct usb_ov511 *ov,
// /* Here I'm assuming that snapshot size == image size.
// /* Here I'm assuming that snapshot size == image size.
// * I hope that's always true. --claudio
// * I hope that's always true. --claudio
// */
// */
// pxcnt = sub_flag ? (ov
511
->subw >> 3) - 1 : mlist[i].pxcnt;
// pxcnt = sub_flag ? (ov->subw >> 3) - 1 : mlist[i].pxcnt;
// lncnt = sub_flag ? (ov
511
->subh >> 3) - 1 : mlist[i].lncnt;
// lncnt = sub_flag ? (ov->subh >> 3) - 1 : mlist[i].lncnt;
//
//
// reg_w(ov
511
, 0x12, pxcnt);
// reg_w(ov, 0x12, pxcnt);
// reg_w(ov
511
, 0x13, lncnt);
// reg_w(ov, 0x13, lncnt);
/******** Set the mode ********/
/******** Set the mode ********/
...
@@ -3475,6 +3419,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
...
@@ -3475,6 +3419,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
int
ret
=
ov
->
decomp_ops
->
decomp_400
(
int
ret
=
ov
->
decomp_ops
->
decomp_400
(
pIn0
,
pIn0
,
pOut0
,
pOut0
,
frame
->
compbuf
,
frame
->
rawwidth
,
frame
->
rawwidth
,
frame
->
rawheight
,
frame
->
rawheight
,
frame
->
bytes_recvd
);
frame
->
bytes_recvd
);
...
@@ -3483,6 +3428,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
...
@@ -3483,6 +3428,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
int
ret
=
ov
->
decomp_ops
->
decomp_420
(
int
ret
=
ov
->
decomp_ops
->
decomp_420
(
pIn0
,
pIn0
,
pOut0
,
pOut0
,
frame
->
compbuf
,
frame
->
rawwidth
,
frame
->
rawwidth
,
frame
->
rawheight
,
frame
->
rawheight
,
frame
->
bytes_recvd
);
frame
->
bytes_recvd
);
...
@@ -3682,7 +3628,7 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
...
@@ -3682,7 +3628,7 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
memset
(
frame
->
data
,
0
,
memset
(
frame
->
data
,
0
,
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
PDEBUG
(
4
,
"Dumping %d bytes"
,
frame
->
bytes_recvd
);
PDEBUG
(
4
,
"Dumping %d bytes"
,
frame
->
bytes_recvd
);
mem
move
(
frame
->
data
,
frame
->
rawdata
,
frame
->
bytes_recvd
);
mem
cpy
(
frame
->
data
,
frame
->
rawdata
,
frame
->
bytes_recvd
);
return
;
return
;
}
}
...
@@ -3719,7 +3665,7 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
...
@@ -3719,7 +3665,7 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
/* Deinterlace frame, if necessary */
/* Deinterlace frame, if necessary */
if
(
ov
->
sensor
==
SEN_SAA7111A
&&
frame
->
rawheight
==
480
)
{
if
(
ov
->
sensor
==
SEN_SAA7111A
&&
frame
->
rawheight
==
480
)
{
mem
move
(
frame
->
rawdata
,
frame
->
tempdata
,
mem
cpy
(
frame
->
rawdata
,
frame
->
tempdata
,
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
deinterlace
(
frame
,
RAWFMT_YUV420
,
frame
->
rawdata
,
deinterlace
(
frame
,
RAWFMT_YUV420
,
frame
->
rawdata
,
frame
->
tempdata
);
frame
->
tempdata
);
...
@@ -3747,18 +3693,19 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
...
@@ -3747,18 +3693,19 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
break
;
break
;
case
VIDEO_PALETTE_YUV420
:
case
VIDEO_PALETTE_YUV420
:
case
VIDEO_PALETTE_YUV420P
:
case
VIDEO_PALETTE_YUV420P
:
mem
move
(
frame
->
data
,
frame
->
tempdata
,
mem
cpy
(
frame
->
data
,
frame
->
tempdata
,
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
break
;
break
;
case
VIDEO_PALETTE_YUV422P
:
case
VIDEO_PALETTE_YUV422P
:
/* Data is converted in place, so copy it in advance */
/* Data is converted in place, so copy it in advance */
mem
move
(
frame
->
data
,
frame
->
tempdata
,
mem
cpy
(
frame
->
data
,
frame
->
tempdata
,
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
MAX_RAW_DATA_SIZE
(
frame
->
width
,
frame
->
height
));
yuv420p_to_yuv422p
(
frame
,
frame
->
data
);
yuv420p_to_yuv422p
(
frame
,
frame
->
data
);
break
;
break
;
default:
default:
err
(
"Cannot convert data to this format"
);
err
(
"Cannot convert data to %s"
,
symbolic
(
v4l1_plist
,
frame
->
format
));
}
}
if
(
fix_rgb_offset
)
if
(
fix_rgb_offset
)
...
@@ -3771,324 +3718,64 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
...
@@ -3771,324 +3718,64 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
*
*
**********************************************************************/
**********************************************************************/
static
in
t
static
in
line
void
ov511_move_data
(
struct
usb_ov511
*
ov
,
struct
urb
*
urb
)
ov511_move_data
(
struct
usb_ov511
*
ov
,
unsigned
char
*
in
,
int
n
)
{
{
unsigned
char
*
cdata
;
int
num
,
offset
;
int
data_size
,
num
,
offset
,
i
,
totlen
=
0
;
int
pnum
=
in
[
ov
->
packet_size
-
1
];
/* Get packet number */
int
aPackNum
[
FRAMES_PER_DESC
]
;
int
max_raw
=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
)
;
struct
ov511_frame
*
frame
;
struct
ov511_frame
*
frame
=
&
ov
->
frame
[
ov
->
curframe
]
;
struct
timeval
*
ts
;
struct
timeval
*
ts
;
PDEBUG
(
5
,
"Moving %d packets"
,
urb
->
number_of_packets
);
/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
* byte non-zero. The EOF packet has image width/height in the
data_size
=
ov
->
packet_size
-
1
;
* 10th and 11th bytes. The 9th byte is given as follows:
*
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
)
{
* bit 7: EOF
int
n
=
urb
->
iso_frame_desc
[
i
].
actual_length
;
* 6: compression enabled
int
st
=
urb
->
iso_frame_desc
[
i
].
status
;
* 5: 422/420/400 modes
* 4: 422/420/400 modes
urb
->
iso_frame_desc
[
i
].
actual_length
=
0
;
* 3: 1
urb
->
iso_frame_desc
[
i
].
status
=
0
;
* 2: snapshot button on
* 1: snapshot frame
cdata
=
urb
->
transfer_buffer
+
urb
->
iso_frame_desc
[
i
].
offset
;
* 0: even/odd field
*/
aPackNum
[
i
]
=
n
?
cdata
[
ov
->
packet_size
-
1
]
:
-
1
;
if
(
!
n
||
ov
->
curframe
==
-
1
)
continue
;
if
(
st
)
PDEBUG
(
2
,
"data error: [%d] len=%d, status=%d"
,
i
,
n
,
st
);
frame
=
&
ov
->
frame
[
ov
->
curframe
];
/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
* byte non-zero. The EOF packet has image width/height in the
* 10th and 11th bytes. The 9th byte is given as follows:
*
* bit 7: EOF
* 6: compression enabled
* 5: 422/420/400 modes
* 4: 422/420/400 modes
* 3: 1
* 2: snapshot button on
* 1: snapshot frame
* 0: even/odd field
*/
if
(
printph
)
{
info
(
"packet header (%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x"
,
cdata
[
ov
->
packet_size
-
1
],
cdata
[
0
],
cdata
[
1
],
cdata
[
2
],
cdata
[
3
],
cdata
[
4
],
cdata
[
5
],
cdata
[
6
],
cdata
[
7
],
cdata
[
8
],
cdata
[
9
],
cdata
[
10
],
cdata
[
11
]);
}
/* Check for SOF/EOF packet */
if
((
cdata
[
0
]
|
cdata
[
1
]
|
cdata
[
2
]
|
cdata
[
3
]
|
cdata
[
4
]
|
cdata
[
5
]
|
cdata
[
6
]
|
cdata
[
7
])
||
(
~
cdata
[
8
]
&
0x08
))
goto
check_middle
;
/* Frame end */
if
(
cdata
[
8
]
&
0x80
)
{
ts
=
(
struct
timeval
*
)(
frame
->
data
+
MAX_FRAME_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
do_gettimeofday
(
ts
);
/* Get the actual frame size from the EOF header */
frame
->
rawwidth
=
((
int
)(
cdata
[
9
])
+
1
)
*
8
;
frame
->
rawheight
=
((
int
)(
cdata
[
10
])
+
1
)
*
8
;
PDEBUG
(
4
,
"Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d, recvd=%d"
,
ov
->
curframe
,
(
int
)(
cdata
[
ov
->
packet_size
-
1
]),
frame
->
rawwidth
,
frame
->
rawheight
,
frame
->
bytes_recvd
);
/* Validate the header data */
RESTRICT_TO_RANGE
(
frame
->
rawwidth
,
ov
->
minwidth
,
ov
->
maxwidth
);
RESTRICT_TO_RANGE
(
frame
->
rawheight
,
ov
->
minheight
,
ov
->
maxheight
);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE
(
frame
->
bytes_recvd
,
8
,
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
if
(
frame
->
scanstate
==
STATE_LINES
)
{
int
iFrameNext
;
frame
->
grabstate
=
FRAME_DONE
;
// FIXME: Is this right?
if
(
waitqueue_active
(
&
frame
->
wq
))
{
frame
->
grabstate
=
FRAME_DONE
;
wake_up_interruptible
(
&
frame
->
wq
);
}
/* If next frame is ready or grabbing,
* point to it */
iFrameNext
=
(
ov
->
curframe
+
1
)
%
OV511_NUMFRAMES
;
if
(
ov
->
frame
[
iFrameNext
].
grabstate
==
FRAME_READY
||
ov
->
frame
[
iFrameNext
].
grabstate
==
FRAME_GRABBING
)
{
ov
->
curframe
=
iFrameNext
;
ov
->
frame
[
iFrameNext
].
scanstate
=
STATE_SCANNING
;
}
else
{
if
(
frame
->
grabstate
==
FRAME_DONE
)
{
PDEBUG
(
4
,
"Frame done! congratulations"
);
}
else
{
PDEBUG
(
4
,
"Frame not ready? state = %d"
,
ov
->
frame
[
iFrameNext
].
grabstate
);
}
ov
->
curframe
=
-
1
;
}
}
else
{
PDEBUG
(
5
,
"Frame done, but not scanning"
);
}
/* Image corruption caused by misplaced frame->segment = 0
* fixed by carlosf@conectiva.com.br
*/
}
else
{
/* Frame start */
PDEBUG
(
4
,
"Frame start, framenum = %d"
,
ov
->
curframe
);
/* Check to see if it's a snapshot frame */
/* FIXME?? Should the snapshot reset go here? Performance? */
if
(
cdata
[
8
]
&
0x02
)
{
frame
->
snapshot
=
1
;
PDEBUG
(
3
,
"snapshot detected"
);
}
frame
->
scanstate
=
STATE_LINES
;
frame
->
bytes_recvd
=
0
;
frame
->
compressed
=
cdata
[
8
]
&
0x40
;
}
check_middle:
/* Are we in a frame? */
if
(
frame
->
scanstate
!=
STATE_LINES
)
{
PDEBUG
(
5
,
"Not in a frame; packet skipped"
);
continue
;
}
#if 0
/* Skip packet if first 9 bytes are zero. These are common, so
* we use a less expensive test here instead of later */
if (frame->compressed) {
int b, skip = 1;
for (b = 0; b < 9; b++) {
if (cdata[b])
skip=0;
}
if (skip) {
PDEBUG(5, "Skipping packet (all zero)");
continue;
}
}
#endif
/* If frame start, skip header */
if
(
frame
->
bytes_recvd
==
0
)
offset
=
9
;
else
offset
=
0
;
num
=
n
-
offset
-
1
;
/* Dump all data exactly as received */
if
(
dumppix
==
2
)
{
frame
->
bytes_recvd
+=
n
-
1
;
if
(
frame
->
bytes_recvd
<=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
))
memmove
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
(
n
-
1
),
&
cdata
[
0
],
n
-
1
);
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
}
else
if
(
!
frame
->
compressed
&&
!
remove_zeros
)
{
frame
->
bytes_recvd
+=
num
;
if
(
frame
->
bytes_recvd
<=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
))
memmove
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
num
,
&
cdata
[
offset
],
num
);
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
}
else
{
/* Remove all-zero FIFO lines (aligned 32-byte blocks) */
int
b
,
in
=
0
,
allzero
,
copied
=
0
;
if
(
offset
)
{
frame
->
bytes_recvd
+=
32
-
offset
;
// Bytes out
memmove
(
frame
->
rawdata
,
&
cdata
[
offset
],
32
-
offset
);
in
+=
32
;
}
while
(
in
<
n
-
1
)
{
allzero
=
1
;
for
(
b
=
0
;
b
<
32
;
b
++
)
{
if
(
cdata
[
in
+
b
])
{
allzero
=
0
;
break
;
}
}
if
(
allzero
)
{
/* Don't copy it */
}
else
{
if
(
frame
->
bytes_recvd
+
copied
+
32
<=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
))
{
memmove
(
frame
->
rawdata
+
frame
->
bytes_recvd
+
copied
,
&
cdata
[
in
],
32
);
copied
+=
32
;
}
else
{
PDEBUG
(
3
,
"Raw data buffer overrun!!"
);
}
}
in
+=
32
;
}
frame
->
bytes_recvd
+=
copied
;
}
if
(
printph
)
{
info
(
"ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x"
,
pnum
,
in
[
0
],
in
[
1
],
in
[
2
],
in
[
3
],
in
[
4
],
in
[
5
],
in
[
6
],
in
[
7
],
in
[
8
],
in
[
9
],
in
[
10
],
in
[
11
]);
}
}
PDEBUG
(
5
,
"pn: %d %d %d %d %d %d %d %d %d %d"
,
/* Check for SOF/EOF packet */
aPackNum
[
0
],
aPackNum
[
1
],
aPackNum
[
2
],
aPackNum
[
3
],
aPackNum
[
4
],
if
((
in
[
0
]
|
in
[
1
]
|
in
[
2
]
|
in
[
3
]
|
in
[
4
]
|
in
[
5
]
|
in
[
6
]
|
in
[
7
])
||
aPackNum
[
5
],
aPackNum
[
6
],
aPackNum
[
7
],
aPackNum
[
8
],
aPackNum
[
9
]);
(
~
in
[
8
]
&
0x08
))
goto
check_middle
;
return
totlen
;
}
static
int
ov518_move_data
(
struct
usb_ov511
*
ov
,
struct
urb
*
urb
)
{
unsigned
char
*
cdata
;
int
i
,
data_size
,
totlen
=
0
;
struct
ov511_frame
*
frame
;
struct
timeval
*
ts
;
PDEBUG
(
5
,
"Moving %d packets"
,
urb
->
number_of_packets
);
/* OV518(+) has no packet numbering */
data_size
=
ov
->
packet_size
;
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
)
{
/* Frame end */
int
n
=
urb
->
iso_frame_desc
[
i
].
actual_length
;
if
(
in
[
8
]
&
0x80
)
{
int
st
=
urb
->
iso_frame_desc
[
i
].
status
;
ts
=
(
struct
timeval
*
)(
frame
->
data
urb
->
iso_frame_desc
[
i
].
actual_length
=
0
;
urb
->
iso_frame_desc
[
i
].
status
=
0
;
cdata
=
urb
->
transfer_buffer
+
urb
->
iso_frame_desc
[
i
].
offset
;
if
(
!
n
)
{
PDEBUG
(
4
,
"Zero-length packet"
);
continue
;
}
if
(
ov
->
curframe
==
-
1
)
{
PDEBUG
(
4
,
"No frame currently active"
);
continue
;
}
if
(
st
)
PDEBUG
(
2
,
"data error: [%d] len=%d, status=%d"
,
i
,
n
,
st
);
frame
=
&
ov
->
frame
[
ov
->
curframe
];
if
(
printph
)
{
info
(
"packet header: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x"
,
cdata
[
0
],
cdata
[
1
],
cdata
[
2
],
cdata
[
3
],
cdata
[
4
],
cdata
[
5
],
cdata
[
6
],
cdata
[
7
],
cdata
[
8
],
cdata
[
9
],
cdata
[
10
],
cdata
[
11
]);
}
/* A false positive here is likely, until OVT gives me
* the definitive SOF/EOF format */
if
((
!
(
cdata
[
0
]
|
cdata
[
1
]
|
cdata
[
2
]
|
cdata
[
3
]
|
cdata
[
5
]))
&&
cdata
[
6
])
{
if
(
frame
->
scanstate
==
STATE_LINES
)
{
PDEBUG
(
4
,
"Detected frame end/start"
);
goto
eof
;
}
else
{
//scanstate == STATE_SCANNING
/* Frame start */
PDEBUG
(
4
,
"Frame start, framenum = %d"
,
ov
->
curframe
);
goto
sof
;
}
}
else
{
goto
check_middle
;
}
eof:
ts
=
(
struct
timeval
*
)(
frame
->
data
+
MAX_FRAME_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
+
MAX_FRAME_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
do_gettimeofday
(
ts
);
do_gettimeofday
(
ts
);
PDEBUG
(
4
,
"Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d"
,
/* Get the actual frame size from the EOF header */
ov
->
curframe
,
frame
->
rawwidth
=
((
int
)(
in
[
9
])
+
1
)
*
8
;
(
int
)(
cdata
[
9
]),
(
int
)(
cdata
[
10
]),
frame
->
bytes_recvd
)
;
frame
->
rawheight
=
((
int
)(
in
[
10
])
+
1
)
*
8
;
// FIXME: Since we don't know the header formats yet,
PDEBUG
(
4
,
"Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d"
,
// there is no way to know what the actual image size is
ov
->
curframe
,
pnum
,
frame
->
rawwidth
,
frame
->
rawheight
,
frame
->
rawwidth
=
frame
->
width
;
frame
->
bytes_recvd
);
frame
->
rawheight
=
frame
->
height
;
/* Validate the header data */
/* Validate the header data */
RESTRICT_TO_RANGE
(
frame
->
rawwidth
,
ov
->
minwidth
,
ov
->
maxwidth
);
RESTRICT_TO_RANGE
(
frame
->
rawwidth
,
ov
->
minwidth
,
ov
->
maxwidth
);
RESTRICT_TO_RANGE
(
frame
->
rawheight
,
ov
->
minheight
,
ov
->
maxheight
);
RESTRICT_TO_RANGE
(
frame
->
rawheight
,
ov
->
minheight
,
ov
->
maxheight
);
/* Don't allow byte count to exceed buffer size */
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE
(
frame
->
bytes_recvd
,
RESTRICT_TO_RANGE
(
frame
->
bytes_recvd
,
8
,
max_raw
);
8
,
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
if
(
frame
->
scanstate
==
STATE_LINES
)
{
if
(
frame
->
scanstate
==
STATE_LINES
)
{
int
iFrameNext
;
int
nextf
;
frame
->
grabstate
=
FRAME_DONE
;
// FIXME: Is this right?
frame
->
grabstate
=
FRAME_DONE
;
// FIXME: Is this right?
...
@@ -4099,115 +3786,277 @@ ov518_move_data(struct usb_ov511 *ov, struct urb *urb)
...
@@ -4099,115 +3786,277 @@ ov518_move_data(struct usb_ov511 *ov, struct urb *urb)
/* If next frame is ready or grabbing,
/* If next frame is ready or grabbing,
* point to it */
* point to it */
iFrameNext
=
(
ov
->
curframe
+
1
)
%
OV511_NUMFRAMES
;
nextf
=
(
ov
->
curframe
+
1
)
%
OV511_NUMFRAMES
;
if
(
ov
->
frame
[
iFrameNext
].
grabstate
==
FRAME_READY
if
(
ov
->
frame
[
nextf
].
grabstate
==
FRAME_READY
||
ov
->
frame
[
iFrameNext
].
grabstate
==
FRAME_GRABBING
)
{
||
ov
->
frame
[
nextf
].
grabstate
==
FRAME_GRABBING
)
{
ov
->
curframe
=
iFrameNext
;
ov
->
curframe
=
nextf
;
ov
->
frame
[
iFrameNext
].
scanstate
=
STATE_SCANNING
;
ov
->
frame
[
nextf
].
scanstate
=
STATE_SCANNING
;
frame
=
&
ov
->
frame
[
iFrameNext
];
}
else
{
}
else
{
if
(
frame
->
grabstate
==
FRAME_DONE
)
{
if
(
frame
->
grabstate
==
FRAME_DONE
)
{
PDEBUG
(
4
,
"
Frame done! congratulations
"
);
PDEBUG
(
4
,
"
** Frame done **
"
);
}
else
{
}
else
{
PDEBUG
(
4
,
"Frame not ready? state = %d"
,
PDEBUG
(
4
,
"Frame not ready? state = %d"
,
ov
->
frame
[
iFrameNext
].
grabstate
);
ov
->
frame
[
nextf
].
grabstate
);
}
}
ov
->
curframe
=
-
1
;
ov
->
curframe
=
-
1
;
PDEBUG
(
4
,
"SOF dropped (no active frame)"
);
continue
;
/* Nowhere to store this frame */
}
}
}
else
{
PDEBUG
(
5
,
"Frame done, but not scanning"
);
}
}
/* Image corruption caused by misplaced frame->segment = 0
/* Image corruption caused by misplaced frame->segment = 0
* fixed by carlosf@conectiva.com.br
* fixed by carlosf@conectiva.com.br
*/
*/
sof:
}
else
{
PDEBUG
(
4
,
"Starting capture on frame %d"
,
frame
->
framenum
);
/* Frame start */
// Snapshot not reverse-engineered yet.
PDEBUG
(
4
,
"Frame start, framenum = %d"
,
ov
->
curframe
);
#if 0
/* Check to see if it's a snapshot frame */
/* Check to see if it's a snapshot frame */
/* FIXME?? Should the snapshot reset go here? Performance? */
/* FIXME?? Should the snapshot reset go here? Performance? */
if (
cdata
[8] & 0x02) {
if
(
in
[
8
]
&
0x02
)
{
frame
->
snapshot
=
1
;
frame
->
snapshot
=
1
;
PDEBUG
(
3
,
"snapshot detected"
);
PDEBUG
(
3
,
"snapshot detected"
);
}
}
#endif
frame
->
scanstate
=
STATE_LINES
;
frame
->
scanstate
=
STATE_LINES
;
frame
->
bytes_recvd
=
0
;
frame
->
bytes_recvd
=
0
;
// frame->compressed = 1;
frame
->
compressed
=
in
[
8
]
&
0x40
;
}
check_middle:
check_middle:
/* Are we in a frame? */
/* Are we in a frame? */
if
(
frame
->
scanstate
!=
STATE_LINES
)
{
if
(
frame
->
scanstate
!=
STATE_LINES
)
{
PDEBUG
(
4
,
"scanstate: no SOF yet"
);
PDEBUG
(
5
,
"Not in a frame; packet skipped"
);
continue
;
return
;
}
/* If frame start, skip header */
if
(
frame
->
bytes_recvd
==
0
)
offset
=
9
;
else
offset
=
0
;
num
=
n
-
offset
-
1
;
/* Dump all data exactly as received */
if
(
dumppix
==
2
)
{
frame
->
bytes_recvd
+=
n
-
1
;
if
(
frame
->
bytes_recvd
<=
max_raw
)
memcpy
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
(
n
-
1
),
in
,
n
-
1
);
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
max_raw
);
}
else
if
(
!
frame
->
compressed
&&
!
remove_zeros
)
{
frame
->
bytes_recvd
+=
num
;
if
(
frame
->
bytes_recvd
<=
max_raw
)
memcpy
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
num
,
in
+
offset
,
num
);
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
max_raw
);
}
else
{
/* Remove all-zero FIFO lines (aligned 32-byte blocks) */
int
b
,
read
=
0
,
allzero
,
copied
=
0
;
if
(
offset
)
{
frame
->
bytes_recvd
+=
32
-
offset
;
// Bytes out
memcpy
(
frame
->
rawdata
,
in
+
offset
,
32
-
offset
);
read
+=
32
;
}
}
/* Dump all data exactly as received */
while
(
read
<
n
-
1
)
{
if
(
dumppix
==
2
)
{
allzero
=
1
;
frame
->
bytes_recvd
+=
n
;
for
(
b
=
0
;
b
<
32
;
b
++
)
{
if
(
frame
->
bytes_recvd
<=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
))
if
(
in
[
read
+
b
])
{
memmove
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
n
,
allzero
=
0
;
&
cdata
[
0
],
n
);
break
;
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
}
else
{
/* All incoming data are divided into 8-byte segments. If the
* segment contains all zero bytes, it must be skipped. These
* zero-segments allow the OV518 to mainain a constant data rate
* regardless of the effectiveness of the compression. Segments
* are aligned relative to the beginning of each isochronous
* packet. The first segment is a header (the decompressor
* skips it later).
*/
int
b
,
in
=
0
,
allzero
,
copied
=
0
;
while
(
in
<
n
)
{
allzero
=
1
;
for
(
b
=
0
;
b
<
8
;
b
++
)
{
if
(
cdata
[
in
+
b
])
{
allzero
=
0
;
break
;
}
}
}
}
if
(
allzero
)
{
if
(
allzero
)
{
/* Don't copy it */
/* Don't copy it */
}
else
{
if
(
frame
->
bytes_recvd
+
copied
+
32
<=
max_raw
)
{
memcpy
(
frame
->
rawdata
+
frame
->
bytes_recvd
+
copied
,
in
+
read
,
32
);
copied
+=
32
;
}
else
{
}
else
{
if
(
frame
->
bytes_recvd
+
copied
+
8
PDEBUG
(
3
,
"Raw data buffer overrun!!"
);
<=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
))
{
memmove
(
frame
->
rawdata
+
frame
->
bytes_recvd
+
copied
,
&
cdata
[
in
],
8
);
copied
+=
8
;
}
else
{
PDEBUG
(
3
,
"Raw data buffer overrun!!"
);
}
}
}
in
+=
8
;
}
}
frame
->
bytes_recvd
+=
copied
;
read
+=
32
;
}
}
}
return
totlen
;
frame
->
bytes_recvd
+=
copied
;
}
}
static
inline
void
ov518_move_data
(
struct
usb_ov511
*
ov
,
unsigned
char
*
in
,
int
n
)
{
int
max_raw
=
MAX_RAW_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
);
struct
ov511_frame
*
frame
=
&
ov
->
frame
[
ov
->
curframe
];
struct
timeval
*
ts
;
if
(
printph
)
{
info
(
"ph: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x"
,
in
[
0
],
in
[
1
],
in
[
2
],
in
[
3
],
in
[
4
],
in
[
5
],
in
[
6
],
in
[
7
],
in
[
8
],
in
[
9
],
in
[
10
],
in
[
11
]);
}
/* A false positive here is likely, until OVT gives me
* the definitive SOF/EOF format */
if
((
!
(
in
[
0
]
|
in
[
1
]
|
in
[
2
]
|
in
[
3
]
|
in
[
5
]))
&&
in
[
6
])
{
if
(
frame
->
scanstate
==
STATE_LINES
)
{
PDEBUG
(
4
,
"Detected frame end/start"
);
goto
eof
;
}
else
{
//scanstate == STATE_SCANNING
/* Frame start */
PDEBUG
(
4
,
"Frame start, framenum = %d"
,
ov
->
curframe
);
goto
sof
;
}
}
else
{
goto
check_middle
;
}
eof:
ts
=
(
struct
timeval
*
)(
frame
->
data
+
MAX_FRAME_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
do_gettimeofday
(
ts
);
PDEBUG
(
4
,
"Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d"
,
ov
->
curframe
,
(
int
)(
in
[
9
]),
(
int
)(
in
[
10
]),
frame
->
bytes_recvd
);
// FIXME: Since we don't know the header formats yet,
// there is no way to know what the actual image size is
frame
->
rawwidth
=
frame
->
width
;
frame
->
rawheight
=
frame
->
height
;
/* Validate the header data */
RESTRICT_TO_RANGE
(
frame
->
rawwidth
,
ov
->
minwidth
,
ov
->
maxwidth
);
RESTRICT_TO_RANGE
(
frame
->
rawheight
,
ov
->
minheight
,
ov
->
maxheight
);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE
(
frame
->
bytes_recvd
,
8
,
max_raw
);
if
(
frame
->
scanstate
==
STATE_LINES
)
{
int
nextf
;
frame
->
grabstate
=
FRAME_DONE
;
// FIXME: Is this right?
if
(
waitqueue_active
(
&
frame
->
wq
))
{
frame
->
grabstate
=
FRAME_DONE
;
wake_up_interruptible
(
&
frame
->
wq
);
}
/* If next frame is ready or grabbing,
* point to it */
nextf
=
(
ov
->
curframe
+
1
)
%
OV511_NUMFRAMES
;
if
(
ov
->
frame
[
nextf
].
grabstate
==
FRAME_READY
||
ov
->
frame
[
nextf
].
grabstate
==
FRAME_GRABBING
)
{
ov
->
curframe
=
nextf
;
ov
->
frame
[
nextf
].
scanstate
=
STATE_SCANNING
;
frame
=
&
ov
->
frame
[
nextf
];
}
else
{
if
(
frame
->
grabstate
==
FRAME_DONE
)
{
PDEBUG
(
4
,
"** Frame done **"
);
}
else
{
PDEBUG
(
4
,
"Frame not ready? state = %d"
,
ov
->
frame
[
nextf
].
grabstate
);
}
ov
->
curframe
=
-
1
;
PDEBUG
(
4
,
"SOF dropped (no active frame)"
);
return
;
/* Nowhere to store this frame */
}
}
sof:
PDEBUG
(
4
,
"Starting capture on frame %d"
,
frame
->
framenum
);
// Snapshot not reverse-engineered yet.
#if 0
/* Check to see if it's a snapshot frame */
/* FIXME?? Should the snapshot reset go here? Performance? */
if (in[8] & 0x02) {
frame->snapshot = 1;
PDEBUG(3, "snapshot detected");
}
#endif
frame
->
scanstate
=
STATE_LINES
;
frame
->
bytes_recvd
=
0
;
// frame->compressed = 1;
check_middle:
/* Are we in a frame? */
if
(
frame
->
scanstate
!=
STATE_LINES
)
{
PDEBUG
(
4
,
"scanstate: no SOF yet"
);
return
;
}
/* Dump all data exactly as received */
if
(
dumppix
==
2
)
{
frame
->
bytes_recvd
+=
n
;
if
(
frame
->
bytes_recvd
<=
max_raw
)
memcpy
(
frame
->
rawdata
+
frame
->
bytes_recvd
-
n
,
in
,
n
);
else
PDEBUG
(
3
,
"Raw data buffer overrun!! (%d)"
,
frame
->
bytes_recvd
-
max_raw
);
}
else
{
/* All incoming data are divided into 8-byte segments. If the
* segment contains all zero bytes, it must be skipped. These
* zero-segments allow the OV518 to mainain a constant data rate
* regardless of the effectiveness of the compression. Segments
* are aligned relative to the beginning of each isochronous
* packet. The first segment is a header (the decompressor
* skips it later).
*/
int
b
,
read
=
0
,
allzero
,
copied
=
0
;
while
(
read
<
n
)
{
allzero
=
1
;
for
(
b
=
0
;
b
<
8
;
b
++
)
{
if
(
in
[
read
+
b
])
{
allzero
=
0
;
break
;
}
}
if
(
allzero
)
{
/* Don't copy it */
}
else
{
if
(
frame
->
bytes_recvd
+
copied
+
8
<=
max_raw
)
{
memcpy
(
frame
->
rawdata
+
frame
->
bytes_recvd
+
copied
,
in
+
read
,
8
);
copied
+=
8
;
}
else
{
PDEBUG
(
3
,
"Raw data buffer overrun!!"
);
}
}
read
+=
8
;
}
frame
->
bytes_recvd
+=
copied
;
}
}
}
static
void
static
void
ov51x_isoc_irq
(
struct
urb
*
urb
)
ov51x_isoc_irq
(
struct
urb
*
urb
)
{
{
int
len
;
int
i
;
struct
usb_ov511
*
ov
;
struct
usb_ov511
*
ov
;
struct
ov511_sbuf
*
sbuf
;
if
(
!
urb
->
context
)
{
if
(
!
urb
->
context
)
{
PDEBUG
(
4
,
"no context"
);
PDEBUG
(
4
,
"no context"
);
return
;
return
;
}
}
ov
=
(
struct
usb_ov511
*
)
urb
->
context
;
sbuf
=
urb
->
context
;
ov
=
sbuf
->
ov
;
if
(
!
ov
||
!
ov
->
dev
||
!
ov
->
user
)
{
if
(
!
ov
||
!
ov
->
dev
||
!
ov
->
user
)
{
PDEBUG
(
4
,
"no device, or not open"
);
PDEBUG
(
4
,
"no device, or not open"
);
...
@@ -4219,16 +4068,52 @@ ov51x_isoc_irq(struct urb *urb)
...
@@ -4219,16 +4068,52 @@ ov51x_isoc_irq(struct urb *urb)
return
;
return
;
}
}
if
(
urb
->
status
==
-
ENOENT
||
urb
->
status
==
-
ECONNRESET
)
{
PDEBUG
(
4
,
"URB unlinked"
);
return
;
}
if
(
urb
->
status
!=
-
EINPROGRESS
&&
urb
->
status
!=
0
)
{
err
(
"ERROR: urb->status=%d: %s"
,
urb
->
status
,
symbolic
(
urb_errlist
,
urb
->
status
));
return
;
}
/* Copy the data received into our frame buffer */
/* Copy the data received into our frame buffer */
if
(
ov
->
curframe
>=
0
)
{
PDEBUG
(
5
,
"sbuf[%d]: Moving %d packets"
,
sbuf
->
n
,
if
(
ov
->
bclass
==
BCL_OV511
)
urb
->
number_of_packets
);
len
=
ov511_move_data
(
ov
,
urb
);
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
)
{
else
if
(
ov
->
bclass
==
BCL_OV518
)
/* Warning: Don't call *_move_data() if no frame active! */
len
=
ov518_move_data
(
ov
,
urb
);
if
(
ov
->
curframe
>=
0
)
{
else
int
n
=
urb
->
iso_frame_desc
[
i
].
actual_length
;
err
(
"Unknown bridge device (%d)"
,
ov
->
bridge
);
int
st
=
urb
->
iso_frame_desc
[
i
].
status
;
}
else
if
(
waitqueue_active
(
&
ov
->
wq
))
{
unsigned
char
*
cdata
;
wake_up_interruptible
(
&
ov
->
wq
);
urb
->
iso_frame_desc
[
i
].
actual_length
=
0
;
urb
->
iso_frame_desc
[
i
].
status
=
0
;
cdata
=
urb
->
transfer_buffer
+
urb
->
iso_frame_desc
[
i
].
offset
;
if
(
!
n
)
{
PDEBUG
(
4
,
"Zero-length packet"
);
continue
;
}
if
(
st
)
PDEBUG
(
2
,
"data error: [%d] len=%d, status=%d"
,
i
,
n
,
st
);
if
(
ov
->
bclass
==
BCL_OV511
)
ov511_move_data
(
ov
,
cdata
,
n
);
else
if
(
ov
->
bclass
==
BCL_OV518
)
ov518_move_data
(
ov
,
cdata
,
n
);
else
err
(
"Unknown bridge device (%d)"
,
ov
->
bridge
);
}
else
if
(
waitqueue_active
(
&
ov
->
wq
))
{
wake_up_interruptible
(
&
ov
->
wq
);
}
}
}
urb
->
dev
=
ov
->
dev
;
urb
->
dev
=
ov
->
dev
;
...
@@ -4297,14 +4182,13 @@ ov51x_init_isoc(struct usb_ov511 *ov)
...
@@ -4297,14 +4182,13 @@ ov51x_init_isoc(struct usb_ov511 *ov)
for
(
n
=
0
;
n
<
OV511_NUMSBUF
;
n
++
)
{
for
(
n
=
0
;
n
<
OV511_NUMSBUF
;
n
++
)
{
urb
=
usb_alloc_urb
(
FRAMES_PER_DESC
,
GFP_KERNEL
);
urb
=
usb_alloc_urb
(
FRAMES_PER_DESC
,
GFP_KERNEL
);
if
(
!
urb
)
{
if
(
!
urb
)
{
err
(
"init isoc: usb_alloc_urb ret. NULL"
);
err
(
"init isoc: usb_alloc_urb ret. NULL"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
ov
->
sbuf
[
n
].
urb
=
urb
;
ov
->
sbuf
[
n
].
urb
=
urb
;
urb
->
dev
=
ov
->
dev
;
urb
->
dev
=
ov
->
dev
;
urb
->
context
=
ov
;
urb
->
context
=
&
ov
->
sbuf
[
n
]
;
urb
->
pipe
=
usb_rcvisocpipe
(
ov
->
dev
,
OV511_ENDPOINT_ADDRESS
);
urb
->
pipe
=
usb_rcvisocpipe
(
ov
->
dev
,
OV511_ENDPOINT_ADDRESS
);
urb
->
transfer_flags
=
USB_ISO_ASAP
;
urb
->
transfer_flags
=
USB_ISO_ASAP
;
urb
->
transfer_buffer
=
ov
->
sbuf
[
n
].
data
;
urb
->
transfer_buffer
=
ov
->
sbuf
[
n
].
data
;
...
@@ -4334,10 +4218,23 @@ ov51x_init_isoc(struct usb_ov511 *ov)
...
@@ -4334,10 +4218,23 @@ ov51x_init_isoc(struct usb_ov511 *ov)
}
}
static
void
static
void
ov51x_
stop
_isoc
(
struct
usb_ov511
*
ov
)
ov51x_
unlink
_isoc
(
struct
usb_ov511
*
ov
)
{
{
int
n
;
int
n
;
/* Unschedule all of the iso td's */
for
(
n
=
OV511_NUMSBUF
-
1
;
n
>=
0
;
n
--
)
{
if
(
ov
->
sbuf
[
n
].
urb
)
{
usb_unlink_urb
(
ov
->
sbuf
[
n
].
urb
);
usb_free_urb
(
ov
->
sbuf
[
n
].
urb
);
ov
->
sbuf
[
n
].
urb
=
NULL
;
}
}
}
static
void
ov51x_stop_isoc
(
struct
usb_ov511
*
ov
)
{
if
(
!
ov
->
streaming
||
!
ov
->
dev
)
if
(
!
ov
->
streaming
||
!
ov
->
dev
)
return
;
return
;
...
@@ -4347,15 +4244,7 @@ ov51x_stop_isoc(struct usb_ov511 *ov)
...
@@ -4347,15 +4244,7 @@ ov51x_stop_isoc(struct usb_ov511 *ov)
ov
->
streaming
=
0
;
ov
->
streaming
=
0
;
/* Unschedule all of the iso td's */
ov51x_unlink_isoc
(
ov
);
for
(
n
=
OV511_NUMSBUF
-
1
;
n
>=
0
;
n
--
)
{
if
(
ov
->
sbuf
[
n
].
urb
)
{
ov
->
sbuf
[
n
].
urb
->
next
=
NULL
;
usb_unlink_urb
(
ov
->
sbuf
[
n
].
urb
);
usb_free_urb
(
ov
->
sbuf
[
n
].
urb
);
ov
->
sbuf
[
n
].
urb
=
NULL
;
}
}
}
}
static
int
static
int
...
@@ -4409,6 +4298,55 @@ ov51x_new_frame(struct usb_ov511 *ov, int framenum)
...
@@ -4409,6 +4298,55 @@ ov51x_new_frame(struct usb_ov511 *ov, int framenum)
*
*
***************************************************************************/
***************************************************************************/
/*
* - You must acquire buf_lock before entering this function.
* - Because this code will free any non-null pointer, you must be sure to null
* them if you explicitly free them somewhere else!
*/
static
void
ov51x_do_dealloc
(
struct
usb_ov511
*
ov
)
{
int
i
;
PDEBUG
(
4
,
"entered"
);
if
(
ov
->
fbuf
)
{
rvfree
(
ov
->
fbuf
,
OV511_NUMFRAMES
*
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
ov
->
fbuf
=
NULL
;
}
if
(
ov
->
rawfbuf
)
{
vfree
(
ov
->
rawfbuf
);
ov
->
rawfbuf
=
NULL
;
}
if
(
ov
->
tempfbuf
)
{
vfree
(
ov
->
tempfbuf
);
ov
->
tempfbuf
=
NULL
;
}
for
(
i
=
0
;
i
<
OV511_NUMSBUF
;
i
++
)
{
if
(
ov
->
sbuf
[
i
].
data
)
{
kfree
(
ov
->
sbuf
[
i
].
data
);
ov
->
sbuf
[
i
].
data
=
NULL
;
}
}
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
ov
->
frame
[
i
].
data
=
NULL
;
ov
->
frame
[
i
].
rawdata
=
NULL
;
ov
->
frame
[
i
].
tempdata
=
NULL
;
if
(
ov
->
frame
[
i
].
compbuf
)
{
free_page
((
unsigned
long
)
ov
->
frame
[
i
].
compbuf
);
ov
->
frame
[
i
].
compbuf
=
NULL
;
}
}
PDEBUG
(
4
,
"buffer memory deallocated"
);
ov
->
buf_state
=
BUF_NOT_ALLOCATED
;
PDEBUG
(
4
,
"leaving"
);
}
static
int
static
int
ov51x_alloc
(
struct
usb_ov511
*
ov
)
ov51x_alloc
(
struct
usb_ov511
*
ov
)
{
{
...
@@ -4434,40 +4372,23 @@ ov51x_alloc(struct usb_ov511 *ov)
...
@@ -4434,40 +4372,23 @@ ov51x_alloc(struct usb_ov511 *ov)
goto
error
;
goto
error
;
ov
->
rawfbuf
=
vmalloc
(
raw_bufsize
);
ov
->
rawfbuf
=
vmalloc
(
raw_bufsize
);
if
(
!
ov
->
rawfbuf
)
{
if
(
!
ov
->
rawfbuf
)
rvfree
(
ov
->
fbuf
,
data_bufsize
);
ov
->
fbuf
=
NULL
;
goto
error
;
goto
error
;
}
memset
(
ov
->
rawfbuf
,
0
,
raw_bufsize
);
memset
(
ov
->
rawfbuf
,
0
,
raw_bufsize
);
ov
->
tempfbuf
=
vmalloc
(
raw_bufsize
);
ov
->
tempfbuf
=
vmalloc
(
raw_bufsize
);
if
(
!
ov
->
tempfbuf
)
{
if
(
!
ov
->
tempfbuf
)
vfree
(
ov
->
rawfbuf
);
ov
->
rawfbuf
=
NULL
;
rvfree
(
ov
->
fbuf
,
data_bufsize
);
ov
->
fbuf
=
NULL
;
goto
error
;
goto
error
;
}
memset
(
ov
->
tempfbuf
,
0
,
raw_bufsize
);
memset
(
ov
->
tempfbuf
,
0
,
raw_bufsize
);
for
(
i
=
0
;
i
<
OV511_NUMSBUF
;
i
++
)
{
for
(
i
=
0
;
i
<
OV511_NUMSBUF
;
i
++
)
{
ov
->
sbuf
[
i
].
data
=
kmalloc
(
FRAMES_PER_DESC
*
ov
->
sbuf
[
i
].
data
=
kmalloc
(
FRAMES_PER_DESC
*
MAX_FRAME_SIZE_PER_DESC
,
GFP_KERNEL
);
MAX_FRAME_SIZE_PER_DESC
,
GFP_KERNEL
);
if
(
!
ov
->
sbuf
[
i
].
data
)
{
if
(
!
ov
->
sbuf
[
i
].
data
)
while
(
--
i
)
{
kfree
(
ov
->
sbuf
[
i
].
data
);
ov
->
sbuf
[
i
].
data
=
NULL
;
}
vfree
(
ov
->
tempfbuf
);
ov
->
tempfbuf
=
NULL
;
vfree
(
ov
->
rawfbuf
);
ov
->
rawfbuf
=
NULL
;
rvfree
(
ov
->
fbuf
,
data_bufsize
);
ov
->
fbuf
=
NULL
;
goto
error
;
goto
error
;
}
PDEBUG
(
4
,
"sbuf[%d] @ %p"
,
i
,
ov
->
sbuf
[
i
].
data
);
PDEBUG
(
4
,
"sbuf[%d] @ %p"
,
i
,
ov
->
sbuf
[
i
].
data
);
}
}
...
@@ -4477,6 +4398,12 @@ ov51x_alloc(struct usb_ov511 *ov)
...
@@ -4477,6 +4398,12 @@ ov51x_alloc(struct usb_ov511 *ov)
+
i
*
MAX_RAW_DATA_SIZE
(
w
,
h
);
+
i
*
MAX_RAW_DATA_SIZE
(
w
,
h
);
ov
->
frame
[
i
].
tempdata
=
ov
->
tempfbuf
ov
->
frame
[
i
].
tempdata
=
ov
->
tempfbuf
+
i
*
MAX_RAW_DATA_SIZE
(
w
,
h
);
+
i
*
MAX_RAW_DATA_SIZE
(
w
,
h
);
ov
->
frame
[
i
].
compbuf
=
(
unsigned
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
ov
->
frame
[
i
].
compbuf
)
goto
error
;
PDEBUG
(
4
,
"frame[%d] @ %p"
,
i
,
ov
->
frame
[
i
].
data
);
PDEBUG
(
4
,
"frame[%d] @ %p"
,
i
,
ov
->
frame
[
i
].
data
);
}
}
...
@@ -4486,57 +4413,12 @@ ov51x_alloc(struct usb_ov511 *ov)
...
@@ -4486,57 +4413,12 @@ ov51x_alloc(struct usb_ov511 *ov)
PDEBUG
(
4
,
"leaving"
);
PDEBUG
(
4
,
"leaving"
);
return
0
;
return
0
;
error:
error:
ov
->
buf_state
=
BUF_NOT_ALLOCATED
;
ov
51x_do_dealloc
(
ov
)
;
up
(
&
ov
->
buf_lock
);
up
(
&
ov
->
buf_lock
);
PDEBUG
(
4
,
"errored"
);
PDEBUG
(
4
,
"errored"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
/*
* - You must acquire buf_lock before entering this function.
* - Because this code will free any non-null pointer, you must be sure to null
* them if you explicitly free them somewhere else!
*/
static
void
ov51x_do_dealloc
(
struct
usb_ov511
*
ov
)
{
int
i
;
PDEBUG
(
4
,
"entered"
);
if
(
ov
->
fbuf
)
{
rvfree
(
ov
->
fbuf
,
OV511_NUMFRAMES
*
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
));
ov
->
fbuf
=
NULL
;
}
if
(
ov
->
rawfbuf
)
{
vfree
(
ov
->
rawfbuf
);
ov
->
rawfbuf
=
NULL
;
}
if
(
ov
->
tempfbuf
)
{
vfree
(
ov
->
tempfbuf
);
ov
->
tempfbuf
=
NULL
;
}
for
(
i
=
0
;
i
<
OV511_NUMSBUF
;
i
++
)
{
if
(
ov
->
sbuf
[
i
].
data
)
{
kfree
(
ov
->
sbuf
[
i
].
data
);
ov
->
sbuf
[
i
].
data
=
NULL
;
}
}
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
ov
->
frame
[
i
].
data
=
NULL
;
ov
->
frame
[
i
].
rawdata
=
NULL
;
ov
->
frame
[
i
].
tempdata
=
NULL
;
}
PDEBUG
(
4
,
"buffer memory deallocated"
);
ov
->
buf_state
=
BUF_NOT_ALLOCATED
;
PDEBUG
(
4
,
"leaving"
);
}
static
void
static
void
ov51x_buf_callback
(
unsigned
long
data
)
ov51x_buf_callback
(
unsigned
long
data
)
{
{
...
@@ -4585,9 +4467,16 @@ ov51x_dealloc(struct usb_ov511 *ov, int now)
...
@@ -4585,9 +4467,16 @@ ov51x_dealloc(struct usb_ov511 *ov, int now)
*
*
***************************************************************************/
***************************************************************************/
#ifdef OV511_OLD_V4L
static
int
static
int
ov51x_v4l1_open
(
struct
video_device
*
vdev
,
int
flags
)
ov51x_v4l1_open
(
struct
video_device
*
vdev
,
int
flags
)
{
{
#else
static
int
ov51x_v4l1_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
video_device
*
vdev
=
video_devdata
(
file
);
#endif
struct
usb_ov511
*
ov
=
vdev
->
priv
;
struct
usb_ov511
*
ov
=
vdev
->
priv
;
int
err
,
i
;
int
err
,
i
;
...
@@ -4639,9 +4528,16 @@ ov51x_v4l1_open(struct video_device *vdev, int flags)
...
@@ -4639,9 +4528,16 @@ ov51x_v4l1_open(struct video_device *vdev, int flags)
return
err
;
return
err
;
}
}
#ifdef OV511_OLD_V4L
static
void
static
void
ov51x_v4l1_close
(
struct
video_device
*
vdev
)
ov51x_v4l1_close
(
struct
video_device
*
vdev
)
{
{
#else
static
int
ov51x_v4l1_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
video_device
*
vdev
=
video_devdata
(
file
);
#endif
struct
usb_ov511
*
ov
=
vdev
->
priv
;
struct
usb_ov511
*
ov
=
vdev
->
priv
;
PDEBUG
(
4
,
"ov511_close"
);
PDEBUG
(
4
,
"ov511_close"
);
...
@@ -4674,32 +4570,19 @@ ov51x_v4l1_close(struct video_device *vdev)
...
@@ -4674,32 +4570,19 @@ ov51x_v4l1_close(struct video_device *vdev)
kfree
(
ov
);
kfree
(
ov
);
ov
=
NULL
;
ov
=
NULL
;
}
}
}
static
int
ov51x_v4l1_init_done
(
struct
video_device
*
vdev
)
{
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
create_proc_ov511_cam
(
vdev
->
priv
);
#endif
#ifdef OV511_OLD_V4L
return
;
#else
return
0
;
return
0
;
}
#endif
static
long
ov51x_v4l1_write
(
struct
video_device
*
vdev
,
const
char
*
buf
,
unsigned
long
count
,
int
noblock
)
{
return
-
EINVAL
;
}
}
/* Do not call this function directly! */
/* Do not call this function directly! */
static
int
static
int
ov51x_v4l1_ioctl_internal
(
struct
video_device
*
vde
v
,
unsigned
int
cmd
,
ov51x_v4l1_ioctl_internal
(
struct
usb_ov511
*
o
v
,
unsigned
int
cmd
,
void
*
arg
)
void
*
arg
)
{
{
struct
usb_ov511
*
ov
=
vdev
->
priv
;
PDEBUG
(
5
,
"IOCtl: 0x%X"
,
cmd
);
PDEBUG
(
5
,
"IOCtl: 0x%X"
,
cmd
);
if
(
!
ov
->
dev
)
if
(
!
ov
->
dev
)
...
@@ -4708,95 +4591,79 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -4708,95 +4591,79 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
VIDIOCGCAP
:
case
VIDIOCGCAP
:
{
{
struct
video_capability
b
;
struct
video_capability
*
b
=
arg
;
PDEBUG
(
4
,
"VIDIOCGCAP"
);
PDEBUG
(
4
,
"VIDIOCGCAP"
);
memset
(
&
b
,
0
,
sizeof
(
b
));
memset
(
b
,
0
,
sizeof
(
struct
video_capability
));
sprintf
(
b
.
name
,
"%s USB Camera"
,
sprintf
(
b
->
name
,
"%s USB Camera"
,
ov
->
bridge
==
BRG_OV511
?
"OV511"
:
symbolic
(
brglist
,
ov
->
bridge
));
ov
->
bridge
==
BRG_OV511PLUS
?
"OV511+"
:
b
->
type
=
VID_TYPE_CAPTURE
|
VID_TYPE_SUBCAPTURE
;
ov
->
bridge
==
BRG_OV518
?
"OV518"
:
ov
->
bridge
==
BRG_OV518PLUS
?
"OV518+"
:
"unknown"
);
b
.
type
=
VID_TYPE_CAPTURE
|
VID_TYPE_SUBCAPTURE
;
if
(
ov
->
has_tuner
)
if
(
ov
->
has_tuner
)
b
.
type
|=
VID_TYPE_TUNER
;
b
->
type
|=
VID_TYPE_TUNER
;
b
.
channels
=
ov
->
num_inputs
;
b
->
channels
=
ov
->
num_inputs
;
b
.
audios
=
ov
->
has_audio_proc
?
1
:
0
;
b
->
audios
=
ov
->
has_audio_proc
?
1
:
0
;
b
.
maxwidth
=
ov
->
maxwidth
;
b
->
maxwidth
=
ov
->
maxwidth
;
b
.
maxheight
=
ov
->
maxheight
;
b
->
maxheight
=
ov
->
maxheight
;
b
.
minwidth
=
ov
->
minwidth
;
b
->
minwidth
=
ov
->
minwidth
;
b
.
minheight
=
ov
->
minheight
;
b
->
minheight
=
ov
->
minheight
;
if
(
copy_to_user
(
arg
,
&
b
,
sizeof
(
b
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCGCHAN
:
case
VIDIOCGCHAN
:
{
{
struct
video_channel
v
;
struct
video_channel
*
v
=
arg
;
PDEBUG
(
4
,
"VIDIOCGCHAN"
);
PDEBUG
(
4
,
"VIDIOCGCHAN"
);
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
if
((
unsigned
)(
v
->
channel
)
>=
ov
->
num_inputs
)
{
return
-
EFAULT
;
err
(
"Invalid channel (%d)"
,
v
->
channel
);
if
((
unsigned
)(
v
.
channel
)
>=
ov
->
num_inputs
)
{
err
(
"Invalid channel (%d)"
,
v
.
channel
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
v
.
norm
=
ov
->
norm
;
v
->
norm
=
ov
->
norm
;
v
.
type
=
(
ov
->
has_tuner
)
?
VIDEO_TYPE_TV
:
VIDEO_TYPE_CAMERA
;
v
->
type
=
(
ov
->
has_tuner
)
?
VIDEO_TYPE_TV
:
VIDEO_TYPE_CAMERA
;
v
.
flags
=
(
ov
->
has_tuner
)
?
VIDEO_VC_TUNER
:
0
;
v
->
flags
=
(
ov
->
has_tuner
)
?
VIDEO_VC_TUNER
:
0
;
v
.
flags
|=
(
ov
->
has_audio_proc
)
?
VIDEO_VC_AUDIO
:
0
;
v
->
flags
|=
(
ov
->
has_audio_proc
)
?
VIDEO_VC_AUDIO
:
0
;
// v
.
flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
// v
->
flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
v
.
tuners
=
(
ov
->
has_tuner
)
?
1
:
0
;
v
->
tuners
=
(
ov
->
has_tuner
)
?
1
:
0
;
decoder_get_input_name
(
ov
,
v
.
channel
,
v
.
name
);
decoder_get_input_name
(
ov
,
v
->
channel
,
v
->
name
);
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCSCHAN
:
case
VIDIOCSCHAN
:
{
{
struct
video_channel
v
;
struct
video_channel
*
v
=
arg
;
int
err
;
int
err
;
PDEBUG
(
4
,
"VIDIOCSCHAN"
);
PDEBUG
(
4
,
"VIDIOCSCHAN"
);
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
/* Make sure it's not a camera */
/* Make sure it's not a camera */
if
(
!
ov
->
has_decoder
)
{
if
(
!
ov
->
has_decoder
)
{
if
(
v
.
channel
==
0
)
if
(
v
->
channel
==
0
)
return
0
;
return
0
;
else
else
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
v
.
norm
!=
VIDEO_MODE_PAL
&&
if
(
v
->
norm
!=
VIDEO_MODE_PAL
&&
v
.
norm
!=
VIDEO_MODE_NTSC
&&
v
->
norm
!=
VIDEO_MODE_NTSC
&&
v
.
norm
!=
VIDEO_MODE_SECAM
&&
v
->
norm
!=
VIDEO_MODE_SECAM
&&
v
.
norm
!=
VIDEO_MODE_AUTO
)
{
v
->
norm
!=
VIDEO_MODE_AUTO
)
{
err
(
"Invalid norm (%d)"
,
v
.
norm
);
err
(
"Invalid norm (%d)"
,
v
->
norm
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
((
unsigned
)(
v
.
channel
)
>=
ov
->
num_inputs
)
{
if
((
unsigned
)(
v
->
channel
)
>=
ov
->
num_inputs
)
{
err
(
"Invalid channel (%d)"
,
v
.
channel
);
err
(
"Invalid channel (%d)"
,
v
->
channel
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
err
=
decoder_set_input
(
ov
,
v
.
channel
);
err
=
decoder_set_input
(
ov
,
v
->
channel
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
decoder_set_norm
(
ov
,
v
.
norm
);
err
=
decoder_set_norm
(
ov
,
v
->
norm
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
...
@@ -4804,43 +4671,37 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -4804,43 +4671,37 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
}
}
case
VIDIOCGPICT
:
case
VIDIOCGPICT
:
{
{
struct
video_picture
p
;
struct
video_picture
*
p
=
arg
;
PDEBUG
(
4
,
"VIDIOCGPICT"
);
PDEBUG
(
4
,
"VIDIOCGPICT"
);
memset
(
&
p
,
0
,
sizeof
(
p
));
memset
(
p
,
0
,
sizeof
(
struct
video_picture
));
if
(
sensor_get_picture
(
ov
,
p
))
if
(
sensor_get_picture
(
ov
,
&
p
))
return
-
EIO
;
return
-
EIO
;
if
(
copy_to_user
(
arg
,
&
p
,
sizeof
(
p
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCSPICT
:
case
VIDIOCSPICT
:
{
{
struct
video_picture
p
;
struct
video_picture
*
p
=
arg
;
int
i
;
int
i
;
PDEBUG
(
4
,
"VIDIOCSPICT"
);
PDEBUG
(
4
,
"VIDIOCSPICT"
);
if
(
copy_from_user
(
&
p
,
arg
,
sizeof
(
p
)))
if
(
!
get_depth
(
p
->
palette
))
return
-
EFAULT
;
if
(
!
get_depth
(
p
.
palette
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
sensor_set_picture
(
ov
,
&
p
))
if
(
sensor_set_picture
(
ov
,
p
))
return
-
EIO
;
return
-
EIO
;
if
(
force_palette
&&
p
.
palette
!=
force_palette
)
{
if
(
force_palette
&&
p
->
palette
!=
force_palette
)
{
info
(
"Palette rejected (%d)"
,
p
.
palette
);
info
(
"Palette rejected (%s)"
,
symbolic
(
v4l1_plist
,
p
->
palette
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
// FIXME: Format should be independent of frames
// FIXME: Format should be independent of frames
if
(
p
.
palette
!=
ov
->
frame
[
0
].
format
)
{
if
(
p
->
palette
!=
ov
->
frame
[
0
].
format
)
{
PDEBUG
(
4
,
"Detected format change"
);
PDEBUG
(
4
,
"Detected format change"
);
/* If we're collecting previous frame wait
/* If we're collecting previous frame wait
...
@@ -4849,79 +4710,73 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -4849,79 +4710,73 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
if
(
signal_pending
(
current
))
return
-
EINTR
;
if
(
signal_pending
(
current
))
return
-
EINTR
;
mode_init_regs
(
ov
,
ov
->
frame
[
0
].
width
,
mode_init_regs
(
ov
,
ov
->
frame
[
0
].
width
,
ov
->
frame
[
0
].
height
,
p
.
palette
,
ov
->
sub_flag
);
ov
->
frame
[
0
].
height
,
p
->
palette
,
ov
->
sub_flag
);
}
}
PDEBUG
(
4
,
"Setting depth=%d, palette=%d"
,
p
.
depth
,
p
.
palette
);
PDEBUG
(
4
,
"Setting depth=%d, palette=%s"
,
p
->
depth
,
symbolic
(
v4l1_plist
,
p
->
palette
));
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
ov
->
frame
[
i
].
depth
=
p
.
depth
;
ov
->
frame
[
i
].
depth
=
p
->
depth
;
ov
->
frame
[
i
].
format
=
p
.
palette
;
ov
->
frame
[
i
].
format
=
p
->
palette
;
}
}
return
0
;
return
0
;
}
}
case
VIDIOCGCAPTURE
:
case
VIDIOCGCAPTURE
:
{
{
int
vf
;
int
*
vf
=
arg
;
PDEBUG
(
4
,
"VIDIOCGCAPTURE"
);
PDEBUG
(
4
,
"VIDIOCGCAPTURE"
);
if
(
copy_from_user
(
&
vf
,
arg
,
sizeof
(
vf
)))
ov
->
sub_flag
=
*
vf
;
return
-
EFAULT
;
ov
->
sub_flag
=
vf
;
return
0
;
return
0
;
}
}
case
VIDIOCSCAPTURE
:
case
VIDIOCSCAPTURE
:
{
{
struct
video_capture
vc
;
struct
video_capture
*
vc
=
arg
;
PDEBUG
(
4
,
"VIDIOCSCAPTURE"
);
PDEBUG
(
4
,
"VIDIOCSCAPTURE"
);
if
(
copy_from_user
(
&
vc
,
arg
,
sizeof
(
vc
)))
if
(
vc
->
flags
)
return
-
EFAULT
;
if
(
vc
.
flags
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
vc
.
decimation
)
if
(
vc
->
decimation
)
return
-
EINVAL
;
return
-
EINVAL
;
vc
.
x
&=
~
3L
;
vc
->
x
&=
~
3L
;
vc
.
y
&=
~
1L
;
vc
->
y
&=
~
1L
;
vc
.
y
&=
~
31L
;
vc
->
y
&=
~
31L
;
if
(
vc
.
width
==
0
)
if
(
vc
->
width
==
0
)
vc
.
width
=
32
;
vc
->
width
=
32
;
vc
.
height
/=
16
;
vc
->
height
/=
16
;
vc
.
height
*=
16
;
vc
->
height
*=
16
;
if
(
vc
.
height
==
0
)
if
(
vc
->
height
==
0
)
vc
.
height
=
16
;
vc
->
height
=
16
;
ov
->
subx
=
vc
.
x
;
ov
->
subx
=
vc
->
x
;
ov
->
suby
=
vc
.
y
;
ov
->
suby
=
vc
->
y
;
ov
->
subw
=
vc
.
width
;
ov
->
subw
=
vc
->
width
;
ov
->
subh
=
vc
.
height
;
ov
->
subh
=
vc
->
height
;
return
0
;
return
0
;
}
}
case
VIDIOCSWIN
:
case
VIDIOCSWIN
:
{
{
struct
video_window
vw
;
struct
video_window
*
vw
=
arg
;
int
i
,
result
;
int
i
,
result
;
if
(
copy_from_user
(
&
vw
,
arg
,
sizeof
(
vw
)))
PDEBUG
(
4
,
"VIDIOCSWIN: %dx%d"
,
vw
->
width
,
vw
->
height
);
return
-
EFAULT
;
PDEBUG
(
4
,
"VIDIOCSWIN: width=%d, height=%d"
,
vw
.
width
,
vw
.
height
);
#if 0
#if 0
if (vw
.
flags)
if (vw
->
flags)
return -EINVAL;
return -EINVAL;
if (vw
.
clipcount)
if (vw
->
clipcount)
return -EINVAL;
return -EINVAL;
if (vw
.
height != ov->maxheight)
if (vw
->
height != ov->maxheight)
return -EINVAL;
return -EINVAL;
if (vw
.
width != ov->maxwidth)
if (vw
->
width != ov->maxwidth)
return -EINVAL;
return -EINVAL;
#endif
#endif
...
@@ -4930,140 +4785,132 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -4930,140 +4785,132 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
interruptible_sleep_on
(
&
ov
->
wq
);
interruptible_sleep_on
(
&
ov
->
wq
);
if
(
signal_pending
(
current
))
return
-
EINTR
;
if
(
signal_pending
(
current
))
return
-
EINTR
;
result
=
mode_init_regs
(
ov
,
vw
.
width
,
vw
.
height
,
result
=
mode_init_regs
(
ov
,
vw
->
width
,
vw
->
height
,
ov
->
frame
[
0
].
format
,
ov
->
sub_flag
);
ov
->
frame
[
0
].
format
,
ov
->
sub_flag
);
if
(
result
<
0
)
if
(
result
<
0
)
return
result
;
return
result
;
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
for
(
i
=
0
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
ov
->
frame
[
i
].
width
=
vw
.
width
;
ov
->
frame
[
i
].
width
=
vw
->
width
;
ov
->
frame
[
i
].
height
=
vw
.
height
;
ov
->
frame
[
i
].
height
=
vw
->
height
;
}
}
return
0
;
return
0
;
}
}
case
VIDIOCGWIN
:
case
VIDIOCGWIN
:
{
{
struct
video_window
vw
;
struct
video_window
*
vw
=
arg
;
memset
(
&
vw
,
0
,
sizeof
(
vw
));
vw
.
x
=
0
;
/* FIXME */
vw
.
y
=
0
;
vw
.
width
=
ov
->
frame
[
0
].
width
;
vw
.
height
=
ov
->
frame
[
0
].
height
;
vw
.
flags
=
30
;
PDEBUG
(
4
,
"VIDIOCGWIN: %dx%d"
,
vw
.
width
,
vw
.
height
);
memset
(
vw
,
0
,
sizeof
(
struct
video_window
));
vw
->
x
=
0
;
/* FIXME */
vw
->
y
=
0
;
vw
->
width
=
ov
->
frame
[
0
].
width
;
vw
->
height
=
ov
->
frame
[
0
].
height
;
vw
->
flags
=
30
;
if
(
copy_to_user
(
arg
,
&
vw
,
sizeof
(
vw
)))
PDEBUG
(
4
,
"VIDIOCGWIN: %dx%d"
,
vw
->
width
,
vw
->
height
);
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCGMBUF
:
case
VIDIOCGMBUF
:
{
{
struct
video_mbuf
vm
;
struct
video_mbuf
*
vm
=
arg
;
int
i
;
int
i
;
PDEBUG
(
4
,
"VIDIOCGMBUF"
);
PDEBUG
(
4
,
"VIDIOCGMBUF"
);
memset
(
&
vm
,
0
,
sizeof
(
vm
));
memset
(
vm
,
0
,
sizeof
(
struct
video_mbuf
));
vm
.
size
=
OV511_NUMFRAMES
vm
->
size
=
OV511_NUMFRAMES
*
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
);
*
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
);
vm
.
frames
=
OV511_NUMFRAMES
;
vm
->
frames
=
OV511_NUMFRAMES
;
vm
.
offsets
[
0
]
=
0
;
vm
->
offsets
[
0
]
=
0
;
for
(
i
=
1
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
for
(
i
=
1
;
i
<
OV511_NUMFRAMES
;
i
++
)
{
vm
.
offsets
[
i
]
=
vm
.
offsets
[
i
-
1
]
vm
->
offsets
[
i
]
=
vm
->
offsets
[
i
-
1
]
+
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
);
+
MAX_DATA_SIZE
(
ov
->
maxwidth
,
ov
->
maxheight
);
}
}
if
(
copy_to_user
((
void
*
)
arg
,
(
void
*
)
&
vm
,
sizeof
(
vm
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCMCAPTURE
:
case
VIDIOCMCAPTURE
:
{
{
struct
video_mmap
vm
;
struct
video_mmap
*
vm
=
arg
;
int
ret
,
depth
;
int
ret
,
depth
;
unsigned
int
f
=
vm
->
frame
;
if
(
copy_from_user
((
void
*
)
&
vm
,
(
void
*
)
arg
,
sizeof
(
vm
)))
PDEBUG
(
4
,
"VIDIOCMCAPTURE: frame: %d, %dx%d, %s"
,
f
,
vm
->
width
,
return
-
EFAULT
;
vm
->
height
,
symbolic
(
v4l1_plist
,
vm
->
format
));
PDEBUG
(
4
,
"CMCAPTURE"
);
PDEBUG
(
4
,
"frame: %d, size: %dx%d, format: %d"
,
vm
.
frame
,
vm
.
width
,
vm
.
height
,
vm
.
format
);
depth
=
get_depth
(
vm
.
format
);
depth
=
get_depth
(
vm
->
format
);
if
(
!
depth
)
{
if
(
!
depth
)
{
err
(
"VIDIOCMCAPTURE: invalid format (%d)"
,
vm
.
format
);
err
(
"VIDIOCMCAPTURE: invalid format (%s)"
,
symbolic
(
v4l1_plist
,
vm
->
format
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
(
unsigned
)
vm
.
frame
>=
OV511_NUMFRAMES
)
{
if
(
f
>=
OV511_NUMFRAMES
)
{
err
(
"VIDIOCMCAPTURE: invalid frame (%d)"
,
vm
.
frame
);
err
(
"VIDIOCMCAPTURE: invalid frame (%d)"
,
f
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
vm
.
width
>
ov
->
maxwidth
if
(
vm
->
width
>
ov
->
maxwidth
||
vm
.
height
>
ov
->
maxheight
)
{
||
vm
->
height
>
ov
->
maxheight
)
{
err
(
"VIDIOCMCAPTURE: requested dimensions too big"
);
err
(
"VIDIOCMCAPTURE: requested dimensions too big"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
(
ov
->
frame
[
vm
.
frame
].
grabstate
==
FRAME_GRABBING
)
{
if
(
ov
->
frame
[
f
].
grabstate
==
FRAME_GRABBING
)
{
PDEBUG
(
4
,
"VIDIOCMCAPTURE: already grabbing"
);
PDEBUG
(
4
,
"VIDIOCMCAPTURE: already grabbing"
);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
if
(
force_palette
&&
vm
.
format
!=
force_palette
)
{
if
(
force_palette
&&
(
vm
->
format
!=
force_palette
))
{
info
(
"palette rejected (%d)"
,
vm
.
format
);
info
(
"palette rejected (%s)"
,
symbolic
(
v4l1_plist
,
vm
->
format
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
((
ov
->
frame
[
vm
.
frame
].
width
!=
vm
.
width
)
||
if
((
ov
->
frame
[
f
].
width
!=
vm
->
width
)
||
(
ov
->
frame
[
vm
.
frame
].
height
!=
vm
.
height
)
||
(
ov
->
frame
[
f
].
height
!=
vm
->
height
)
||
(
ov
->
frame
[
vm
.
frame
].
format
!=
vm
.
format
)
||
(
ov
->
frame
[
f
].
format
!=
vm
->
format
)
||
(
ov
->
frame
[
vm
.
frame
].
sub_flag
!=
ov
->
sub_flag
)
||
(
ov
->
frame
[
f
].
sub_flag
!=
ov
->
sub_flag
)
||
(
ov
->
frame
[
vm
.
frame
].
depth
!=
depth
))
{
(
ov
->
frame
[
f
].
depth
!=
depth
))
{
PDEBUG
(
4
,
"VIDIOCMCAPTURE: change in image parameters"
);
PDEBUG
(
4
,
"VIDIOCMCAPTURE: change in image parameters"
);
/* If we're collecting previous frame wait
/* If we're collecting previous frame wait
before changing modes */
before changing modes */
interruptible_sleep_on
(
&
ov
->
wq
);
interruptible_sleep_on
(
&
ov
->
wq
);
if
(
signal_pending
(
current
))
return
-
EINTR
;
if
(
signal_pending
(
current
))
return
-
EINTR
;
ret
=
mode_init_regs
(
ov
,
vm
.
width
,
vm
.
height
,
ret
=
mode_init_regs
(
ov
,
vm
->
width
,
vm
->
height
,
vm
.
format
,
ov
->
sub_flag
);
vm
->
format
,
ov
->
sub_flag
);
#if 0
#if 0
if (ret < 0) {
if (ret < 0) {
PDEBUG(1, "Got error while initializing regs ");
PDEBUG(1, "Got error while initializing regs ");
return ret;
return ret;
}
}
#endif
#endif
ov
->
frame
[
vm
.
frame
].
width
=
vm
.
width
;
ov
->
frame
[
f
].
width
=
vm
->
width
;
ov
->
frame
[
vm
.
frame
].
height
=
vm
.
height
;
ov
->
frame
[
f
].
height
=
vm
->
height
;
ov
->
frame
[
vm
.
frame
].
format
=
vm
.
format
;
ov
->
frame
[
f
].
format
=
vm
->
format
;
ov
->
frame
[
vm
.
frame
].
sub_flag
=
ov
->
sub_flag
;
ov
->
frame
[
f
].
sub_flag
=
ov
->
sub_flag
;
ov
->
frame
[
vm
.
frame
].
depth
=
depth
;
ov
->
frame
[
f
].
depth
=
depth
;
}
}
/* Mark it as ready */
/* Mark it as ready */
ov
->
frame
[
vm
.
frame
].
grabstate
=
FRAME_READY
;
ov
->
frame
[
f
].
grabstate
=
FRAME_READY
;
PDEBUG
(
4
,
"VIDIOCMCAPTURE: renewing frame %d"
,
vm
.
frame
);
PDEBUG
(
4
,
"VIDIOCMCAPTURE: renewing frame %d"
,
f
);
return
ov51x_new_frame
(
ov
,
vm
.
frame
);
return
ov51x_new_frame
(
ov
,
f
);
}
}
case
VIDIOCSYNC
:
case
VIDIOCSYNC
:
{
{
int
fnum
,
rc
;
unsigned
int
fnum
=
*
((
unsigned
int
*
)
arg
)
;
struct
ov511_frame
*
frame
;
struct
ov511_frame
*
frame
;
int
rc
;
if
(
copy_from_user
((
void
*
)
&
fnum
,
arg
,
sizeof
(
int
)))
return
-
EFAULT
;
if
(
(
unsigned
)
fnum
>=
OV511_NUMFRAMES
)
{
if
(
fnum
>=
OV511_NUMFRAMES
)
{
err
(
"VIDIOCSYNC: invalid frame (%d)"
,
fnum
);
err
(
"VIDIOCSYNC: invalid frame (%d)"
,
fnum
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -5125,124 +4972,105 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -5125,124 +4972,105 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
}
}
case
VIDIOCGFBUF
:
case
VIDIOCGFBUF
:
{
{
struct
video_buffer
vb
;
struct
video_buffer
*
vb
=
arg
;
PDEBUG
(
4
,
"VIDIOC
SCHAN
"
);
PDEBUG
(
4
,
"VIDIOC
GFBUF
"
);
memset
(
&
vb
,
0
,
sizeof
(
vb
));
memset
(
vb
,
0
,
sizeof
(
struct
video_buffer
));
vb
.
base
=
NULL
;
/* frame buffer not supported, not used */
if
(
copy_to_user
((
void
*
)
arg
,
(
void
*
)
&
vb
,
sizeof
(
vb
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCGUNIT
:
case
VIDIOCGUNIT
:
{
{
struct
video_unit
vu
;
struct
video_unit
*
vu
=
arg
;
PDEBUG
(
4
,
"VIDIOCGUNIT"
);
PDEBUG
(
4
,
"VIDIOCGUNIT"
);
memset
(
&
vu
,
0
,
sizeof
(
vu
));
memset
(
vu
,
0
,
sizeof
(
struct
video_unit
));
vu
.
video
=
ov
->
vdev
.
minor
;
/* Video minor */
vu
.
vbi
=
VIDEO_NO_UNIT
;
/* VBI minor */
vu
.
radio
=
VIDEO_NO_UNIT
;
/* Radio minor */
vu
.
audio
=
VIDEO_NO_UNIT
;
/* Audio minor */
vu
.
teletext
=
VIDEO_NO_UNIT
;
/* Teletext minor */
if
(
copy_to_user
((
void
*
)
arg
,
(
void
*
)
&
vu
,
sizeof
(
vu
)))
vu
->
video
=
ov
->
vdev
.
minor
;
return
-
EFAULT
;
vu
->
vbi
=
VIDEO_NO_UNIT
;
vu
->
radio
=
VIDEO_NO_UNIT
;
vu
->
audio
=
VIDEO_NO_UNIT
;
vu
->
teletext
=
VIDEO_NO_UNIT
;
return
0
;
return
0
;
}
}
case
VIDIOCGTUNER
:
case
VIDIOCGTUNER
:
{
{
struct
video_tuner
v
;
struct
video_tuner
*
v
=
arg
;
PDEBUG
(
4
,
"VIDIOCGTUNER"
);
PDEBUG
(
4
,
"VIDIOCGTUNER"
);
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
if
(
!
ov
->
has_tuner
||
v
->
tuner
)
// Only tuner 0
return
-
EFAULT
;
if
(
!
ov
->
has_tuner
||
v
.
tuner
)
// Only tuner 0
return
-
EINVAL
;
return
-
EINVAL
;
strcpy
(
v
.
name
,
"Television"
);
strcpy
(
v
->
name
,
"Television"
);
// FIXME: Need a way to get the real values
// FIXME: Need a way to get the real values
v
.
rangelow
=
0
;
v
->
rangelow
=
0
;
v
.
rangehigh
=
~
0
;
v
->
rangehigh
=
~
0
;
v
.
flags
=
VIDEO_TUNER_PAL
|
VIDEO_TUNER_NTSC
|
v
->
flags
=
VIDEO_TUNER_PAL
|
VIDEO_TUNER_NTSC
VIDEO_TUNER_SECAM
;
|
VIDEO_TUNER_SECAM
;
v
.
mode
=
0
;
/* FIXME: Not sure what this is yet */
v
->
mode
=
0
;
/* FIXME: Not sure what this is yet */
v
.
signal
=
0xFFFF
;
/* unknown */
v
->
signal
=
0xFFFF
;
/* unknown */
call_i2c_clients
(
ov
,
cmd
,
&
v
);
call_i2c_clients
(
ov
,
cmd
,
v
);
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCSTUNER
:
case
VIDIOCSTUNER
:
{
{
struct
video_tuner
v
;
struct
video_tuner
*
v
=
arg
;
int
err
;
int
err
;
PDEBUG
(
4
,
"VIDIOCSTUNER"
);
PDEBUG
(
4
,
"VIDIOCSTUNER"
);
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
/* Only no or one tuner for now */
/* Only no or one tuner for now */
if
(
!
ov
->
has_tuner
||
v
.
tuner
)
if
(
!
ov
->
has_tuner
||
v
->
tuner
)
return
-
EINVAL
;
return
-
EINVAL
;
/* and it only has certain valid modes */
/* and it only has certain valid modes */
if
(
v
.
mode
!=
VIDEO_MODE_PAL
&&
if
(
v
->
mode
!=
VIDEO_MODE_PAL
&&
v
.
mode
!=
VIDEO_MODE_NTSC
&&
v
->
mode
!=
VIDEO_MODE_NTSC
&&
v
.
mode
!=
VIDEO_MODE_SECAM
)
return
-
EOPNOTSUPP
;
v
->
mode
!=
VIDEO_MODE_SECAM
)
return
-
EOPNOTSUPP
;
/* Is this right/necessary? */
/* Is this right/necessary? */
err
=
decoder_set_norm
(
ov
,
v
.
mode
);
err
=
decoder_set_norm
(
ov
,
v
->
mode
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
call_i2c_clients
(
ov
,
cmd
,
&
v
);
call_i2c_clients
(
ov
,
cmd
,
v
);
return
0
;
return
0
;
}
}
case
VIDIOCGFREQ
:
case
VIDIOCGFREQ
:
{
{
unsigned
long
v
=
ov
->
freq
;
unsigned
long
v
=
*
((
unsigned
long
*
)
arg
)
;
PDEBUG
(
4
,
"VIDIOCGFREQ"
);
PDEBUG
(
4
,
"VIDIOCGFREQ"
);
if
(
!
ov
->
has_tuner
)
if
(
!
ov
->
has_tuner
)
return
-
EINVAL
;
return
-
EINVAL
;
v
=
ov
->
freq
;
#if 0
#if 0
/* FIXME: this is necessary for testing */
/* FIXME: this is necessary for testing */
v = 46*16;
v = 46*16;
#endif
#endif
if
(
copy_to_user
(
arg
,
&
v
,
sizeof
(
v
)))
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
VIDIOCSFREQ
:
case
VIDIOCSFREQ
:
{
{
unsigned
long
v
;
unsigned
long
v
=
*
((
unsigned
long
*
)
arg
);
PDEBUG
(
4
,
"VIDIOCSFREQ: %lx"
,
v
);
if
(
!
ov
->
has_tuner
)
if
(
!
ov
->
has_tuner
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
copy_from_user
(
&
v
,
arg
,
sizeof
(
v
)))
return
-
EFAULT
;
PDEBUG
(
4
,
"VIDIOCSFREQ: %lx"
,
v
);
ov
->
freq
=
v
;
ov
->
freq
=
v
;
call_i2c_clients
(
ov
,
cmd
,
&
v
);
call_i2c_clients
(
ov
,
cmd
,
&
v
);
...
@@ -5262,25 +5090,110 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
...
@@ -5262,25 +5090,110 @@ ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
return
0
;
return
0
;
}
}
#ifdef OV511_OLD_V4L
/* This is implemented as video_generic_ioctl() in the new V4L's videodev.c */
int
ov51x_v4l1_generic_ioctl
(
struct
video_device
*
vdev
,
unsigned
int
cmd
,
void
*
arg
)
{
char
sbuf
[
128
];
void
*
mbuf
=
NULL
;
void
*
parg
=
NULL
;
int
err
=
-
EINVAL
;
/* Copy arguments into temp kernel buffer */
switch
(
_IOC_DIR
(
cmd
))
{
case
_IOC_NONE
:
parg
=
arg
;
break
;
case
_IOC_READ
:
/* some v4l ioctls are marked wrong ... */
case
_IOC_WRITE
:
case
(
_IOC_WRITE
|
_IOC_READ
):
if
(
_IOC_SIZE
(
cmd
)
<=
sizeof
(
sbuf
))
{
parg
=
sbuf
;
}
else
{
/* too big to allocate from stack */
mbuf
=
kmalloc
(
_IOC_SIZE
(
cmd
),
GFP_KERNEL
);
if
(
NULL
==
mbuf
)
return
-
ENOMEM
;
parg
=
mbuf
;
}
err
=
-
EFAULT
;
if
(
copy_from_user
(
parg
,
arg
,
_IOC_SIZE
(
cmd
)))
goto
out
;
break
;
}
err
=
ov51x_v4l1_ioctl_internal
(
vdev
->
priv
,
cmd
,
parg
);
if
(
err
==
-
ENOIOCTLCMD
)
err
=
-
EINVAL
;
if
(
err
<
0
)
goto
out
;
/* Copy results into user buffer */
switch
(
_IOC_DIR
(
cmd
))
{
case
_IOC_READ
:
case
(
_IOC_WRITE
|
_IOC_READ
):
if
(
copy_to_user
(
arg
,
parg
,
_IOC_SIZE
(
cmd
)))
err
=
-
EFAULT
;
break
;
}
out:
if
(
mbuf
)
kfree
(
mbuf
);
return
err
;
}
static
int
static
int
ov51x_v4l1_ioctl
(
struct
video_device
*
vdev
,
unsigned
int
cmd
,
void
*
arg
)
ov51x_v4l1_ioctl
(
struct
video_device
*
vdev
,
unsigned
int
cmd
,
void
*
arg
)
{
{
struct
usb_ov511
*
ov
=
vdev
->
priv
;
int
rc
;
int
rc
;
if
(
down_interruptible
(
&
ov
->
lock
))
return
-
EINTR
;
rc
=
ov51x_v4l1_generic_ioctl
(
vdev
,
cmd
,
arg
);
up
(
&
ov
->
lock
);
return
rc
;
}
#else
/* If new V4L API */
static
int
ov51x_v4l1_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
void
*
arg
)
{
struct
video_device
*
vdev
=
video_devdata
(
file
);
struct
usb_ov511
*
ov
=
vdev
->
priv
;
struct
usb_ov511
*
ov
=
vdev
->
priv
;
int
rc
;
if
(
down_interruptible
(
&
ov
->
lock
))
if
(
down_interruptible
(
&
ov
->
lock
))
return
-
EINTR
;
return
-
EINTR
;
rc
=
ov51x_v4l1_ioctl_internal
(
vde
v
,
cmd
,
arg
);
rc
=
ov51x_v4l1_ioctl_internal
(
o
v
,
cmd
,
arg
);
up
(
&
ov
->
lock
);
up
(
&
ov
->
lock
);
return
rc
;
return
rc
;
}
}
#endif
/* OV511_OLD_V4L */
#ifdef OV511_OLD_V4L
static
inline
long
static
inline
long
ov51x_v4l1_read
(
struct
video_device
*
vdev
,
char
*
buf
,
unsigned
long
count
,
ov51x_v4l1_read
(
struct
video_device
*
vdev
,
char
*
buf
,
unsigned
long
count
,
int
noblock
)
int
noblock
)
{
{
#else
static
inline
int
ov51x_v4l1_read
(
struct
file
*
file
,
char
*
buf
,
size_t
cnt
,
loff_t
*
ppos
)
{
struct
video_device
*
vdev
=
video_devdata
(
file
);
int
noblock
=
file
->
f_flags
&
O_NONBLOCK
;
unsigned
long
count
=
cnt
;
#endif
struct
usb_ov511
*
ov
=
vdev
->
priv
;
struct
usb_ov511
*
ov
=
vdev
->
priv
;
int
i
,
rc
=
0
,
frmx
=
-
1
;
int
i
,
rc
=
0
,
frmx
=
-
1
;
struct
ov511_frame
*
frame
;
struct
ov511_frame
*
frame
;
...
@@ -5429,12 +5342,23 @@ ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count,
...
@@ -5429,12 +5342,23 @@ ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count,
return
rc
;
return
rc
;
}
}
static
int
static
int
#ifdef OV511_OLD_V4L
ov51x_v4l1_mmap
(
struct
vm_area_struct
*
vma
,
struct
video_device
*
vdev
,
ov51x_v4l1_mmap
(
struct
vm_area_struct
*
vma
,
struct
video_device
*
vdev
,
const
char
*
adr
,
unsigned
long
size
)
const
char
*
adr
,
unsigned
long
size
)
{
{
struct
usb_ov511
*
ov
=
vdev
->
priv
;
unsigned
long
start
=
(
unsigned
long
)
adr
;
unsigned
long
start
=
(
unsigned
long
)
adr
;
#else
/* New V4L API */
ov51x_v4l1_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
struct
video_device
*
vdev
=
video_devdata
(
file
);
unsigned
long
start
=
vma
->
vm_start
;
unsigned
long
size
=
vma
->
vm_end
-
vma
->
vm_start
;
#endif
/* OV511_OLD_V4L */
struct
usb_ov511
*
ov
=
vdev
->
priv
;
unsigned
long
page
,
pos
;
unsigned
long
page
,
pos
;
if
(
ov
->
dev
==
NULL
)
if
(
ov
->
dev
==
NULL
)
...
@@ -5453,7 +5377,8 @@ ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
...
@@ -5453,7 +5377,8 @@ ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
pos
=
(
unsigned
long
)
ov
->
fbuf
;
pos
=
(
unsigned
long
)
ov
->
fbuf
;
while
(
size
>
0
)
{
while
(
size
>
0
)
{
page
=
kvirt_to_pa
(
pos
);
page
=
kvirt_to_pa
(
pos
);
if
(
remap_page_range
(
vma
,
start
,
page
,
PAGE_SIZE
,
PAGE_SHARED
))
{
if
(
remap_page_range
(
vma
,
start
,
page
,
PAGE_SIZE
,
PAGE_SHARED
))
{
up
(
&
ov
->
lock
);
up
(
&
ov
->
lock
);
return
-
EAGAIN
;
return
-
EAGAIN
;
}
}
...
@@ -5469,6 +5394,7 @@ ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
...
@@ -5469,6 +5394,7 @@ ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
return
0
;
return
0
;
}
}
#ifdef OV511_OLD_V4L
static
struct
video_device
vdev_template
=
{
static
struct
video_device
vdev_template
=
{
owner:
THIS_MODULE
,
owner:
THIS_MODULE
,
name:
"OV511 USB Camera"
,
name:
"OV511 USB Camera"
,
...
@@ -5477,12 +5403,32 @@ static struct video_device vdev_template = {
...
@@ -5477,12 +5403,32 @@ static struct video_device vdev_template = {
open:
ov51x_v4l1_open
,
open:
ov51x_v4l1_open
,
close:
ov51x_v4l1_close
,
close:
ov51x_v4l1_close
,
read:
ov51x_v4l1_read
,
read:
ov51x_v4l1_read
,
write:
ov51x_v4l1_write
,
ioctl:
ov51x_v4l1_ioctl
,
ioctl:
ov51x_v4l1_ioctl
,
mmap:
ov51x_v4l1_mmap
,
mmap:
ov51x_v4l1_mmap
,
initialize:
ov51x_v4l1_init_done
,
};
};
#else
/* New V4L API */
static
struct
file_operations
ov511_fops
=
{
owner:
THIS_MODULE
,
open:
ov51x_v4l1_open
,
release:
ov51x_v4l1_close
,
read:
ov51x_v4l1_read
,
mmap:
ov51x_v4l1_mmap
,
ioctl:
video_generic_ioctl
,
llseek:
no_llseek
,
};
static
struct
video_device
vdev_template
=
{
owner:
THIS_MODULE
,
name:
"OV511 USB Camera"
,
type:
VID_TYPE_CAPTURE
,
hardware:
VID_HARDWARE_OV511
,
fops:
&
ov511_fops
,
kernel_ioctl:
ov51x_v4l1_ioctl
,
};
#endif
/* OV511_OLD_V4L */
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
static
int
static
int
ov51x_control_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
ov51x_control_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
...
@@ -5497,7 +5443,7 @@ ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
...
@@ -5497,7 +5443,7 @@ ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if
(
!
pde
)
if
(
!
pde
)
return
-
ENOENT
;
return
-
ENOENT
;
ov
=
(
struct
usb_ov511
*
)
pde
->
data
;
ov
=
pde
->
data
;
if
(
!
ov
)
if
(
!
ov
)
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -6067,19 +6013,18 @@ ov6xx0_configure(struct usb_ov511 *ov)
...
@@ -6067,19 +6013,18 @@ ov6xx0_configure(struct usb_ov511 *ov)
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
err
(
"Error detecting sensor type"
);
err
(
"Error detecting sensor type"
);
return
-
1
;
return
-
1
;
}
else
if
((
rc
&
3
)
==
0
)
{
}
info
(
"Sensor is an OV6630"
);
if
((
rc
&
3
)
==
0
)
ov
->
sensor
=
SEN_OV6630
;
ov
->
sensor
=
SEN_OV6630
;
}
else
if
((
rc
&
3
)
==
1
)
{
else
if
((
rc
&
3
)
==
1
)
info
(
"Sensor is an OV6620"
);
ov
->
sensor
=
SEN_OV6620
;
ov
->
sensor
=
SEN_OV6620
;
}
else
if
((
rc
&
3
)
==
2
)
{
else
if
((
rc
&
3
)
==
2
)
info
(
"Sensor is an OV6630AE"
);
ov
->
sensor
=
SEN_OV6630
;
ov
->
sensor
=
SEN_OV6630
;
}
else
if
((
rc
&
3
)
==
3
)
{
else
if
((
rc
&
3
)
==
3
)
info
(
"Sensor is an OV6630AF"
);
ov
->
sensor
=
SEN_OV6630
;
ov
->
sensor
=
SEN_OV6630
;
}
info
(
"Sensor is an %s"
,
symbolic
(
senlist
,
ov
->
sensor
));
/* Set sensor-specific vars */
/* Set sensor-specific vars */
ov
->
maxwidth
=
352
;
ov
->
maxwidth
=
352
;
...
@@ -6165,7 +6110,7 @@ ks0127_configure(struct usb_ov511 *ov)
...
@@ -6165,7 +6110,7 @@ ks0127_configure(struct usb_ov511 *ov)
/* This initializes the SAA7111A video decoder. */
/* This initializes the SAA7111A video decoder. */
static
int
static
int
saa7111a_configure
(
struct
usb_ov511
*
ov
511
)
saa7111a_configure
(
struct
usb_ov511
*
ov
)
{
{
int
rc
;
int
rc
;
...
@@ -6210,44 +6155,44 @@ saa7111a_configure(struct usb_ov511 *ov511)
...
@@ -6210,44 +6155,44 @@ saa7111a_configure(struct usb_ov511 *ov511)
#endif
#endif
/* Set sensor-specific vars */
/* Set sensor-specific vars */
ov
511
->
maxwidth
=
640
;
ov
->
maxwidth
=
640
;
ov
511
->
maxheight
=
480
;
/* Even/Odd fields */
ov
->
maxheight
=
480
;
/* Even/Odd fields */
ov
511
->
minwidth
=
320
;
ov
->
minwidth
=
320
;
ov
511
->
minheight
=
240
;
/* Even field only */
ov
->
minheight
=
240
;
/* Even field only */
ov
511
->
has_decoder
=
1
;
ov
->
has_decoder
=
1
;
ov
511
->
num_inputs
=
8
;
ov
->
num_inputs
=
8
;
ov
511
->
norm
=
VIDEO_MODE_AUTO
;
ov
->
norm
=
VIDEO_MODE_AUTO
;
ov
511
->
stop_during_set
=
0
;
/* Decoder guarantees stable image */
ov
->
stop_during_set
=
0
;
/* Decoder guarantees stable image */
/* Decoder doesn't change these values, so we use these instead of
/* Decoder doesn't change these values, so we use these instead of
* acutally reading the registers (which doesn't work) */
* acutally reading the registers (which doesn't work) */
ov
511
->
brightness
=
0x80
<<
8
;
ov
->
brightness
=
0x80
<<
8
;
ov
511
->
contrast
=
0x40
<<
9
;
ov
->
contrast
=
0x40
<<
9
;
ov
511
->
colour
=
0x40
<<
9
;
ov
->
colour
=
0x40
<<
9
;
ov
511
->
hue
=
32768
;
ov
->
hue
=
32768
;
PDEBUG
(
4
,
"Writing SAA7111A registers"
);
PDEBUG
(
4
,
"Writing SAA7111A registers"
);
if
(
write_regvals
(
ov
511
,
aRegvalsNormSAA7111A
))
if
(
write_regvals
(
ov
,
aRegvalsNormSAA7111A
))
return
-
1
;
return
-
1
;
/* Detect version of decoder. This must be done after writing the
/* Detect version of decoder. This must be done after writing the
* initial regs or the decoder will lock up. */
* initial regs or the decoder will lock up. */
rc
=
i2c_r
(
ov
511
,
0x00
);
rc
=
i2c_r
(
ov
,
0x00
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
err
(
"Error detecting sensor version"
);
err
(
"Error detecting sensor version"
);
return
-
1
;
return
-
1
;
}
else
{
}
else
{
info
(
"Sensor is an SAA7111A (version 0x%x)"
,
rc
);
info
(
"Sensor is an SAA7111A (version 0x%x)"
,
rc
);
ov
511
->
sensor
=
SEN_SAA7111A
;
ov
->
sensor
=
SEN_SAA7111A
;
}
}
// FIXME: Fix this for OV518(+)
// FIXME: Fix this for OV518(+)
/* Latch to negative edge of clock. Otherwise, we get incorrect
/* Latch to negative edge of clock. Otherwise, we get incorrect
* colors and jitter in the digital signal. */
* colors and jitter in the digital signal. */
if
(
ov
511
->
bclass
==
BCL_OV511
)
if
(
ov
->
bclass
==
BCL_OV511
)
reg_w
(
ov
511
,
0x11
,
0x00
);
reg_w
(
ov
,
0x11
,
0x00
);
else
else
warn
(
"SAA7111A not yet supported with OV518/OV518+"
);
warn
(
"SAA7111A not yet supported with OV518/OV518+"
);
...
@@ -6258,8 +6203,6 @@ saa7111a_configure(struct usb_ov511 *ov511)
...
@@ -6258,8 +6203,6 @@ saa7111a_configure(struct usb_ov511 *ov511)
static
int
static
int
ov511_configure
(
struct
usb_ov511
*
ov
)
ov511_configure
(
struct
usb_ov511
*
ov
)
{
{
int
i
;
static
struct
ov511_regvals
aRegvalsInit511
[]
=
{
static
struct
ov511_regvals
aRegvalsInit511
[]
=
{
{
OV511_REG_BUS
,
R51x_SYS_RESET
,
0x7f
},
{
OV511_REG_BUS
,
R51x_SYS_RESET
,
0x7f
},
{
OV511_REG_BUS
,
R51x_SYS_INIT
,
0x01
},
{
OV511_REG_BUS
,
R51x_SYS_INIT
,
0x01
},
...
@@ -6301,24 +6244,18 @@ ov511_configure(struct usb_ov511 *ov)
...
@@ -6301,24 +6244,18 @@ ov511_configure(struct usb_ov511 *ov)
goto
error
;
goto
error
;
}
}
ov
->
desc
=
-
1
;
PDEBUG
(
1
,
"CustomID = %d"
,
ov
->
customid
);
PDEBUG
(
1
,
"CustomID = %d"
,
ov
->
customid
);
for
(
i
=
0
;
clist
[
i
].
id
>=
0
;
i
++
)
{
ov
->
desc
=
symbolic
(
camlist
,
ov
->
customid
);
if
(
ov
->
customid
==
clist
[
i
].
id
)
{
info
(
"model: %s"
,
ov
->
desc
);
info
(
"model: %s"
,
clist
[
i
].
description
);
ov
->
desc
=
i
;
break
;
}
}
if
(
clist
[
i
].
id
==
-
1
)
{
if
(
0
==
strcmp
(
ov
->
desc
,
NOT_DEFINED_STR
)
)
{
err
(
"Camera type (%d) not recognized"
,
ov
->
customid
);
err
(
"Camera type (%d) not recognized"
,
ov
->
customid
);
err
(
"Please notify "
EMAIL
" of the name,"
);
err
(
"Please notify "
EMAIL
" of the name,"
);
err
(
"manufacturer, model, and this number of your camera."
);
err
(
"manufacturer, model, and this number of your camera."
);
err
(
"Also include the output of the detection process."
);
err
(
"Also include the output of the detection process."
);
}
}
if
(
clist
[
i
].
id
==
6
)
{
/* USB Life TV (NTSC) */
if
(
ov
->
custom
id
==
6
)
{
/* USB Life TV (NTSC) */
ov
->
tuner_type
=
8
;
/* Temic 4036FY5 3X 1981 */
ov
->
tuner_type
=
8
;
/* Temic 4036FY5 3X 1981 */
}
}
...
@@ -6545,7 +6482,6 @@ ov518_configure(struct usb_ov511 *ov)
...
@@ -6545,7 +6482,6 @@ ov518_configure(struct usb_ov511 *ov)
*
*
***************************************************************************/
***************************************************************************/
/* 2.2.x compatibility */
static
void
*
static
void
*
ov51x_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
,
ov51x_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
,
const
struct
usb_device_id
*
id
)
const
struct
usb_device_id
*
id
)
...
@@ -6592,29 +6528,24 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6592,29 +6528,24 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
switch
(
dev
->
descriptor
.
idProduct
)
{
switch
(
dev
->
descriptor
.
idProduct
)
{
case
PROD_OV511
:
case
PROD_OV511
:
info
(
"USB OV511 camera found"
);
ov
->
bridge
=
BRG_OV511
;
ov
->
bridge
=
BRG_OV511
;
ov
->
bclass
=
BCL_OV511
;
ov
->
bclass
=
BCL_OV511
;
break
;
break
;
case
PROD_OV511PLUS
:
case
PROD_OV511PLUS
:
info
(
"USB OV511+ camera found"
);
ov
->
bridge
=
BRG_OV511PLUS
;
ov
->
bridge
=
BRG_OV511PLUS
;
ov
->
bclass
=
BCL_OV511
;
ov
->
bclass
=
BCL_OV511
;
break
;
break
;
case
PROD_OV518
:
case
PROD_OV518
:
info
(
"USB OV518 camera found"
);
ov
->
bridge
=
BRG_OV518
;
ov
->
bridge
=
BRG_OV518
;
ov
->
bclass
=
BCL_OV518
;
ov
->
bclass
=
BCL_OV518
;
break
;
break
;
case
PROD_OV518PLUS
:
case
PROD_OV518PLUS
:
info
(
"USB OV518+ camera found"
);
ov
->
bridge
=
BRG_OV518PLUS
;
ov
->
bridge
=
BRG_OV518PLUS
;
ov
->
bclass
=
BCL_OV518
;
ov
->
bclass
=
BCL_OV518
;
break
;
break
;
case
PROD_ME2CAM
:
case
PROD_ME2CAM
:
if
(
dev
->
descriptor
.
idVendor
!=
VEND_MATTEL
)
if
(
dev
->
descriptor
.
idVendor
!=
VEND_MATTEL
)
goto
error
;
goto
error
;
info
(
"Intel Play Me2Cam (OV511+) found"
);
ov
->
bridge
=
BRG_OV511PLUS
;
ov
->
bridge
=
BRG_OV511PLUS
;
ov
->
bclass
=
BCL_OV511
;
ov
->
bclass
=
BCL_OV511
;
break
;
break
;
...
@@ -6623,6 +6554,8 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6623,6 +6554,8 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
goto
error_dealloc
;
goto
error_dealloc
;
}
}
info
(
"USB %s video device found"
,
symbolic
(
brglist
,
ov
->
bridge
));
/* Workaround for some applications that want data in RGB
/* Workaround for some applications that want data in RGB
* instead of BGR. */
* instead of BGR. */
if
(
force_rgb
)
if
(
force_rgb
)
...
@@ -6656,6 +6589,12 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6656,6 +6589,12 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
init_waitqueue_head
(
&
ov
->
frame
[
i
].
wq
);
init_waitqueue_head
(
&
ov
->
frame
[
i
].
wq
);
}
}
for
(
i
=
0
;
i
<
OV511_NUMSBUF
;
i
++
)
{
ov
->
sbuf
[
i
].
ov
=
ov
;
spin_lock_init
(
&
ov
->
sbuf
[
i
].
lock
);
ov
->
sbuf
[
i
].
n
=
i
;
}
/* Unnecessary? (This is done on open(). Need to make sure variables
/* Unnecessary? (This is done on open(). Need to make sure variables
* are properly initialized without this before removing it, though). */
* are properly initialized without this before removing it, though). */
if
(
ov51x_set_default_params
(
ov
)
<
0
)
if
(
ov51x_set_default_params
(
ov
)
<
0
)
...
@@ -6690,11 +6629,13 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6690,11 +6629,13 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
info
(
"Device registered on minor %d"
,
ov
->
vdev
.
minor
);
info
(
"Device registered on minor %d"
,
ov
->
vdev
.
minor
);
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
create_proc_ov511_cam
(
ov
);
#endif
return
ov
;
return
ov
;
error:
error:
err
(
"Camera initialization failed"
);
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
/* Safe to call even if entry doesn't exist */
/* Safe to call even if entry doesn't exist */
destroy_proc_ov511_cam
(
ov
);
destroy_proc_ov511_cam
(
ov
);
...
@@ -6707,9 +6648,6 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6707,9 +6648,6 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
up
(
&
ov
->
cbuf_lock
);
up
(
&
ov
->
cbuf_lock
);
}
}
usb_driver_release_interface
(
&
ov511_driver
,
&
dev
->
actconfig
->
interface
[
ov
->
iface
]);
error_dealloc:
error_dealloc:
if
(
ov
)
{
if
(
ov
)
{
kfree
(
ov
);
kfree
(
ov
);
...
@@ -6717,6 +6655,7 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
...
@@ -6717,6 +6655,7 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
}
}
error_out:
error_out:
err
(
"Camera initialization failed"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -6749,22 +6688,12 @@ ov51x_disconnect(struct usb_device *dev, void *ptr)
...
@@ -6749,22 +6688,12 @@ ov51x_disconnect(struct usb_device *dev, void *ptr)
ov
->
streaming
=
0
;
ov
->
streaming
=
0
;
/* Unschedule all of the iso td's */
ov51x_unlink_isoc
(
ov
);
for
(
n
=
OV511_NUMSBUF
-
1
;
n
>=
0
;
n
--
)
{
if
(
ov
->
sbuf
[
n
].
urb
)
{
ov
->
sbuf
[
n
].
urb
->
next
=
NULL
;
usb_unlink_urb
(
ov
->
sbuf
[
n
].
urb
);
usb_free_urb
(
ov
->
sbuf
[
n
].
urb
);
ov
->
sbuf
[
n
].
urb
=
NULL
;
}
}
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
destroy_proc_ov511_cam
(
ov
);
destroy_proc_ov511_cam
(
ov
);
#endif
#endif
usb_driver_release_interface
(
&
ov511_driver
,
&
ov
->
dev
->
actconfig
->
interface
[
ov
->
iface
]);
ov
->
dev
=
NULL
;
ov
->
dev
=
NULL
;
/* Free the memory */
/* Free the memory */
...
...
drivers/usb/ov511.h
View file @
d7b09335
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
#ifdef OV511_DEBUG
#ifdef OV511_DEBUG
#define PDEBUG(level, fmt, args...) \
#define PDEBUG(level, fmt, args...) \
if (debug >= (level)) info("[
" __PRETTY_FUNCTION__ ":%d] " fmt,
\
if (debug >= (level)) info("[
%s:%d] " fmt,
\
__LINE__ , ## args)
__
PRETTY_FUNCTION__, __
LINE__ , ## args)
#else
#else
#define PDEBUG(level, fmt, args...) do {} while(0)
#define PDEBUG(level, fmt, args...) do {} while(0)
#endif
#endif
...
@@ -243,6 +243,16 @@
...
@@ -243,6 +243,16 @@
#define OV511_ENDPOINT_ADDRESS 1
/* Isoc endpoint number */
#define OV511_ENDPOINT_ADDRESS 1
/* Isoc endpoint number */
#define OV511_NUMFRAMES 2
#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
#error "OV511_NUMFRAMES is too high"
#endif
#define OV511_NUMSBUF 2
/* Control transfers use up to 4 bytes */
#define OV511_CBUF_SIZE 4
/* Bridge types */
/* Bridge types */
enum
{
enum
{
BRG_UNKNOWN
,
BRG_UNKNOWN
,
...
@@ -376,9 +386,14 @@ struct ov511_i2c_struct {
...
@@ -376,9 +386,14 @@ struct ov511_i2c_struct {
struct ov511_i2c_struct)
struct ov511_i2c_struct)
/* ------------- End IOCTL interface -------------- */
/* ------------- End IOCTL interface -------------- */
struct
usb_ov511
;
/* Forward declaration */
struct
ov511_sbuf
{
struct
ov511_sbuf
{
char
*
data
;
struct
usb_ov511
*
ov
;
unsigned
char
*
data
;
struct
urb
*
urb
;
struct
urb
*
urb
;
spinlock_t
lock
;
int
n
;
};
};
enum
{
enum
{
...
@@ -401,9 +416,10 @@ struct ov511_regvals {
...
@@ -401,9 +416,10 @@ struct ov511_regvals {
struct
ov511_frame
{
struct
ov511_frame
{
int
framenum
;
/* Index of this frame */
int
framenum
;
/* Index of this frame */
char
*
data
;
/* Frame buffer */
unsigned
char
*
data
;
/* Frame buffer */
char
*
tempdata
;
/* Temp buffer for multi-stage conversions */
unsigned
char
*
tempdata
;
/* Temp buffer for multi-stage conversions */
char
*
rawdata
;
/* Raw camera data buffer */
unsigned
char
*
rawdata
;
/* Raw camera data buffer */
unsigned
char
*
compbuf
;
/* Temp buffer for decompressor */
int
depth
;
/* Bytes per pixel */
int
depth
;
/* Bytes per pixel */
int
width
;
/* Width application is expecting */
int
width
;
/* Width application is expecting */
...
@@ -428,27 +444,20 @@ struct ov511_frame {
...
@@ -428,27 +444,20 @@ struct ov511_frame {
int
snapshot
;
/* True if frame was a snapshot */
int
snapshot
;
/* True if frame was a snapshot */
};
};
#define DECOMP_INTERFACE_VER
2
#define DECOMP_INTERFACE_VER
3
/* Compression module operations */
/* Compression module operations */
struct
ov51x_decomp_ops
{
struct
ov51x_decomp_ops
{
int
(
*
decomp_400
)(
unsigned
char
*
,
unsigned
char
*
,
int
,
int
,
int
);
int
(
*
decomp_400
)(
unsigned
char
*
,
unsigned
char
*
,
unsigned
char
*
,
int
(
*
decomp_420
)(
unsigned
char
*
,
unsigned
char
*
,
int
,
int
,
int
);
int
,
int
,
int
);
int
(
*
decomp_422
)(
unsigned
char
*
,
unsigned
char
*
,
int
,
int
,
int
);
int
(
*
decomp_420
)(
unsigned
char
*
,
unsigned
char
*
,
unsigned
char
*
,
int
,
int
,
int
);
int
(
*
decomp_422
)(
unsigned
char
*
,
unsigned
char
*
,
unsigned
char
*
,
int
,
int
,
int
);
void
(
*
decomp_lock
)(
void
);
void
(
*
decomp_lock
)(
void
);
void
(
*
decomp_unlock
)(
void
);
void
(
*
decomp_unlock
)(
void
);
};
};
#define OV511_NUMFRAMES 2
#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
#error "OV511_NUMFRAMES is too high"
#endif
#define OV511_NUMSBUF 2
/* Control transfers use up to 4 bytes */
#define OV511_CBUF_SIZE 4
struct
usb_ov511
{
struct
usb_ov511
{
struct
video_device
vdev
;
struct
video_device
vdev
;
...
@@ -456,7 +465,7 @@ struct usb_ov511 {
...
@@ -456,7 +465,7 @@ struct usb_ov511 {
struct
usb_device
*
dev
;
struct
usb_device
*
dev
;
int
customid
;
int
customid
;
int
desc
;
char
*
desc
;
unsigned
char
iface
;
unsigned
char
iface
;
/* Determined by sensor type */
/* Determined by sensor type */
...
@@ -490,9 +499,9 @@ struct usb_ov511 {
...
@@ -490,9 +499,9 @@ struct usb_ov511 {
int
lightfreq
;
/* Power (lighting) frequency */
int
lightfreq
;
/* Power (lighting) frequency */
int
bandfilt
;
/* Banding filter enabled flag */
int
bandfilt
;
/* Banding filter enabled flag */
char
*
fbuf
;
/* Videodev buffer area */
unsigned
char
*
fbuf
;
/* Videodev buffer area */
char
*
tempfbuf
;
/* Temporary (intermediate) buffer area */
unsigned
char
*
tempfbuf
;
/* Temporary (intermediate) buffer area */
char
*
rawfbuf
;
/* Raw camera data buffer area */
unsigned
char
*
rawfbuf
;
/* Raw camera data buffer area */
int
sub_flag
;
/* Pix Array subcapture on flag */
int
sub_flag
;
/* Pix Array subcapture on flag */
int
subx
;
/* Pix Array subcapture x offset */
int
subx
;
/* Pix Array subcapture x offset */
...
@@ -556,16 +565,29 @@ struct usb_ov511 {
...
@@ -556,16 +565,29 @@ struct usb_ov511 {
struct
semaphore
cbuf_lock
;
struct
semaphore
cbuf_lock
;
};
};
struct
cam_list
{
/* Used to represent a list of values and their respective symbolic names */
int
id
;
struct
symbolic_list
{
char
*
description
;
};
struct
palette_list
{
int
num
;
int
num
;
char
*
name
;
char
*
name
;
};
};
#define NOT_DEFINED_STR "Unknown"
/* Returns the name of the matching element in the symbolic_list array. The
* end of the list must be marked with an element that has a NULL name.
*/
static
inline
char
*
symbolic
(
struct
symbolic_list
list
[],
int
num
)
{
int
i
;
for
(
i
=
0
;
list
[
i
].
name
!=
NULL
;
i
++
)
if
(
list
[
i
].
num
==
num
)
return
(
list
[
i
].
name
);
return
(
NOT_DEFINED_STR
);
}
struct
mode_list_518
{
struct
mode_list_518
{
int
width
;
int
width
;
int
height
;
int
height
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment