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
002b40d8
Commit
002b40d8
authored
Oct 27, 2002
by
Alan Cox
Committed by
Linus Torvalds
Oct 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] cpia driver update from maintainer
parent
4a142aba
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1179 additions
and
391 deletions
+1179
-391
drivers/media/video/cpia.c
drivers/media/video/cpia.c
+1129
-368
drivers/media/video/cpia.h
drivers/media/video/cpia.h
+41
-16
drivers/media/video/cpia_pp.c
drivers/media/video/cpia_pp.c
+5
-4
drivers/media/video/cpia_usb.c
drivers/media/video/cpia_usb.c
+4
-3
No files found.
drivers/media/video/cpia.c
View file @
002b40d8
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
* (C) Copyright 1999-2000 Peter Pregler
* (C) Copyright 1999-2000 Peter Pregler
* (C) Copyright 1999-2000 Scott J. Bertin
* (C) Copyright 1999-2000 Scott J. Bertin
* (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
* (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
* (C) Copyright 2000 STMicroelectronics
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -30,7 +31,6 @@
...
@@ -30,7 +31,6 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/ctype.h>
...
@@ -101,6 +101,7 @@ MODULE_SUPPORTED_DEVICE("video");
...
@@ -101,6 +101,7 @@ MODULE_SUPPORTED_DEVICE("video");
#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
...
@@ -131,6 +132,7 @@ MODULE_SUPPORTED_DEVICE("video");
...
@@ -131,6 +132,7 @@ MODULE_SUPPORTED_DEVICE("video");
#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
...
@@ -139,6 +141,7 @@ MODULE_SUPPORTED_DEVICE("video");
...
@@ -139,6 +141,7 @@ MODULE_SUPPORTED_DEVICE("video");
#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
enum
{
enum
{
FRAME_READY
,
/* Ready to grab into */
FRAME_READY
,
/* Ready to grab into */
...
@@ -164,6 +167,25 @@ enum {
...
@@ -164,6 +167,25 @@ enum {
#define COMMAND_SETFLICKERCTRL 0x2000
#define COMMAND_SETFLICKERCTRL 0x2000
#define COMMAND_SETVLOFFSET 0x4000
#define COMMAND_SETVLOFFSET 0x4000
#define COMMAND_SETLIGHTS 0x8000
#define COMMAND_SETLIGHTS 0x8000
#define ROUND_UP_EXP_FOR_FLICKER 15
/* Constants for automatic frame rate adjustment */
#define MAX_EXP 302
#define MAX_EXP_102 255
#define LOW_EXP 140
#define VERY_LOW_EXP 70
#define TC 94
#define EXP_ACC_DARK 50
#define EXP_ACC_LIGHT 90
#define HIGH_COMP_102 160
#define MAX_COMP 239
#define DARK_TIME 3
#define LIGHT_TIME 3
/* Maximum number of 10ms loops to wait for the stream to become ready */
#define READY_TIMEOUT 100
/* Developer's Guide Table 5 p 3-34
/* Developer's Guide Table 5 p 3-34
* indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
* indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
static
u8
flicker_jumps
[
2
][
2
][
4
]
=
static
u8
flicker_jumps
[
2
][
2
][
4
]
=
...
@@ -173,6 +195,10 @@ static u8 flicker_jumps[2][2][4] =
...
@@ -173,6 +195,10 @@ static u8 flicker_jumps[2][2][4] =
/* forward declaration of local function */
/* forward declaration of local function */
static
void
reset_camera_struct
(
struct
cam_data
*
cam
);
static
void
reset_camera_struct
(
struct
cam_data
*
cam
);
static
int
find_over_exposure
(
int
brightness
);
static
void
set_flicker
(
struct
cam_params
*
params
,
volatile
u32
*
command_flags
,
int
on
);
/**********************************************************************
/**********************************************************************
*
*
...
@@ -291,12 +317,6 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -291,12 +317,6 @@ static int cpia_read_proc(char *page, char **start, off_t off,
out
+=
sprintf
(
out
,
"video_size: %s
\n
"
,
out
+=
sprintf
(
out
,
"video_size: %s
\n
"
,
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
"CIF "
:
"QCIF"
);
"CIF "
:
"QCIF"
);
out
+=
sprintf
(
out
,
"sub_sample: %s
\n
"
,
cam
->
params
.
format
.
subSample
==
SUBSAMPLE_420
?
"420"
:
"422"
);
out
+=
sprintf
(
out
,
"yuv_order: %s
\n
"
,
cam
->
params
.
format
.
yuvOrder
==
YUVORDER_YUYV
?
"YUYV"
:
"UYVY"
);
out
+=
sprintf
(
out
,
"roi: (%3d, %3d) to (%3d, %3d)
\n
"
,
out
+=
sprintf
(
out
,
"roi: (%3d, %3d) to (%3d, %3d)
\n
"
,
cam
->
params
.
roi
.
colStart
*
8
,
cam
->
params
.
roi
.
colStart
*
8
,
cam
->
params
.
roi
.
rowStart
*
4
,
cam
->
params
.
roi
.
rowStart
*
4
,
...
@@ -331,11 +351,17 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -331,11 +351,17 @@ static int cpia_read_proc(char *page, char **start, off_t off,
2
*
cam
->
params
.
streamStartLine
,
0
,
2
*
cam
->
params
.
streamStartLine
,
0
,
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
288
:
144
,
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
288
:
144
,
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
240
:
120
);
cam
->
params
.
format
.
videoSize
==
VIDEOSIZE_CIF
?
240
:
120
);
out
+=
sprintf
(
out
,
"sub_sample: %8s %8s %8s %8s
\n
"
,
cam
->
params
.
format
.
subSample
==
SUBSAMPLE_420
?
"420"
:
"422"
,
"420"
,
"422"
,
"422"
);
out
+=
sprintf
(
out
,
"yuv_order: %8s %8s %8s %8s
\n
"
,
cam
->
params
.
format
.
yuvOrder
==
YUVORDER_YUYV
?
"YUYV"
:
"UYVY"
,
"YUYV"
,
"UYVY"
,
"YUYV"
);
out
+=
sprintf
(
out
,
"ecp_timing: %8s %8s %8s %8s
\n
"
,
out
+=
sprintf
(
out
,
"ecp_timing: %8s %8s %8s %8s
\n
"
,
cam
->
params
.
ecpTiming
?
"slow"
:
"normal"
,
"slow"
,
cam
->
params
.
ecpTiming
?
"slow"
:
"normal"
,
"slow"
,
"normal"
,
"normal"
);
"normal"
,
"normal"
);
if
(
cam
->
params
.
colourBalance
.
balanceMode
IsAuto
)
{
if
(
cam
->
params
.
colourBalance
.
balanceMode
==
2
)
{
sprintf
(
tmpstr
,
"auto"
);
sprintf
(
tmpstr
,
"auto"
);
}
else
{
}
else
{
sprintf
(
tmpstr
,
"manual"
);
sprintf
(
tmpstr
,
"manual"
);
...
@@ -385,31 +411,33 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -385,31 +411,33 @@ static int cpia_read_proc(char *page, char **start, off_t off,
1
<<
cam
->
params
.
exposure
.
gain
,
1
,
1
);
1
<<
cam
->
params
.
exposure
.
gain
,
1
,
1
);
if
(
cam
->
params
.
version
.
firmwareVersion
==
1
&&
if
(
cam
->
params
.
version
.
firmwareVersion
==
1
&&
cam
->
params
.
version
.
firmwareRevision
==
2
)
cam
->
params
.
version
.
firmwareRevision
==
2
)
/* 1-02 firmware limits fineExp to 127 */
/* 1-02 firmware limits fineExp
/2
to 127 */
tmp
=
25
5
;
tmp
=
25
4
;
else
else
tmp
=
51
1
;
tmp
=
51
0
;
out
+=
sprintf
(
out
,
"fine_exp: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"fine_exp: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
exposure
.
fineExp
*
2
,
0
,
tmp
,
0
);
cam
->
params
.
exposure
.
fineExp
*
2
,
0
,
tmp
,
0
);
if
(
cam
->
params
.
version
.
firmwareVersion
==
1
&&
if
(
cam
->
params
.
version
.
firmwareVersion
==
1
&&
cam
->
params
.
version
.
firmwareRevision
==
2
)
cam
->
params
.
version
.
firmwareRevision
==
2
)
/* 1-02 firmware limits coarseExpHi to 0 */
/* 1-02 firmware limits coarseExpHi to 0 */
tmp
=
255
;
tmp
=
MAX_EXP_102
;
else
else
tmp
=
65535
;
tmp
=
MAX_EXP
;
out
+=
sprintf
(
out
,
"coarse_exp: %8d %8d %8d"
out
+=
sprintf
(
out
,
"coarse_exp: %8d %8d %8d"
" %8d
\n
"
,
cam
->
params
.
exposure
.
coarseExpLo
+
" %8d
\n
"
,
cam
->
params
.
exposure
.
coarseExpLo
+
256
*
cam
->
params
.
exposure
.
coarseExpHi
,
0
,
tmp
,
185
);
256
*
cam
->
params
.
exposure
.
coarseExpHi
,
0
,
tmp
,
185
);
out
+=
sprintf
(
out
,
"red_comp: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"red_comp: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
exposure
.
redComp
,
220
,
255
,
220
);
cam
->
params
.
exposure
.
redComp
,
COMP_RED
,
255
,
COMP_RED
);
out
+=
sprintf
(
out
,
"green1_comp: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"green1_comp: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
exposure
.
green1Comp
,
214
,
255
,
214
);
cam
->
params
.
exposure
.
green1Comp
,
COMP_GREEN1
,
255
,
COMP_GREEN1
);
out
+=
sprintf
(
out
,
"green2_comp: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"green2_comp: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
exposure
.
green2Comp
,
214
,
255
,
214
);
cam
->
params
.
exposure
.
green2Comp
,
COMP_GREEN2
,
255
,
COMP_GREEN2
);
out
+=
sprintf
(
out
,
"blue_comp: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"blue_comp: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
exposure
.
blueComp
,
230
,
255
,
230
);
cam
->
params
.
exposure
.
blueComp
,
COMP_BLUE
,
255
,
COMP_BLUE
);
out
+=
sprintf
(
out
,
"apcor_gain1: %#8x %#8x %#8x %#8x
\n
"
,
out
+=
sprintf
(
out
,
"apcor_gain1: %#8x %#8x %#8x %#8x
\n
"
,
cam
->
params
.
apcor
.
gain1
,
0
,
0xff
,
0x1c
);
cam
->
params
.
apcor
.
gain1
,
0
,
0xff
,
0x1c
);
...
@@ -433,9 +461,14 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -433,9 +461,14 @@ static int cpia_read_proc(char *page, char **start, off_t off,
out
+=
sprintf
(
out
,
"mains_frequency: %8d %8d %8d %8d"
out
+=
sprintf
(
out
,
"mains_frequency: %8d %8d %8d %8d"
" only 50/60
\n
"
,
" only 50/60
\n
"
,
cam
->
mainsFreq
?
60
:
50
,
50
,
60
,
50
);
cam
->
mainsFreq
?
60
:
50
,
50
,
60
,
50
);
out
+=
sprintf
(
out
,
"allowable_overexposure: %8d %8d %8d %8d
\n
"
,
if
(
cam
->
params
.
flickerControl
.
allowableOverExposure
<
0
)
cam
->
params
.
flickerControl
.
allowableOverExposure
,
0
,
out
+=
sprintf
(
out
,
"allowable_overexposure: %4dauto auto %8d auto
\n
"
,
255
,
0
);
-
cam
->
params
.
flickerControl
.
allowableOverExposure
,
255
);
else
out
+=
sprintf
(
out
,
"allowable_overexposure: %8d auto %8d auto
\n
"
,
cam
->
params
.
flickerControl
.
allowableOverExposure
,
255
);
out
+=
sprintf
(
out
,
"compression_mode: "
);
out
+=
sprintf
(
out
,
"compression_mode: "
);
switch
(
cam
->
params
.
compression
.
mode
)
{
switch
(
cam
->
params
.
compression
.
mode
)
{
case
CPIA_COMPRESSION_NONE
:
case
CPIA_COMPRESSION_NONE
:
...
@@ -453,8 +486,8 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -453,8 +486,8 @@ static int cpia_read_proc(char *page, char **start, off_t off,
}
}
out
+=
sprintf
(
out
,
" none,auto,manual auto
\n
"
);
out
+=
sprintf
(
out
,
" none,auto,manual auto
\n
"
);
out
+=
sprintf
(
out
,
"decimation_enable: %8s %8s %8s %8s
\n
"
,
out
+=
sprintf
(
out
,
"decimation_enable: %8s %8s %8s %8s
\n
"
,
cam
->
params
.
compression
.
decimation
==
cam
->
params
.
compression
.
decimation
==
DECIMATION_ENAB
?
"on"
:
"off"
,
"off"
,
"o
ff"
,
DECIMATION_ENAB
?
"on"
:
"off"
,
"off"
,
"o
n"
,
"off"
);
"off"
);
out
+=
sprintf
(
out
,
"compression_target: %9s %9s %9s %9s
\n
"
,
out
+=
sprintf
(
out
,
"compression_target: %9s %9s %9s %9s
\n
"
,
cam
->
params
.
compressionTarget
.
frTargeting
==
cam
->
params
.
compressionTarget
.
frTargeting
==
...
@@ -462,13 +495,13 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -462,13 +495,13 @@ static int cpia_read_proc(char *page, char **start, off_t off,
"framerate"
:
"quality"
,
"framerate"
:
"quality"
,
"framerate"
,
"quality"
,
"quality"
);
"framerate"
,
"quality"
,
"quality"
);
out
+=
sprintf
(
out
,
"target_framerate: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"target_framerate: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
compressionTarget
.
targetFR
,
0
,
30
,
7
);
cam
->
params
.
compressionTarget
.
targetFR
,
1
,
30
,
15
);
out
+=
sprintf
(
out
,
"target_quality: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"target_quality: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
compressionTarget
.
targetQ
,
0
,
255
,
10
);
cam
->
params
.
compressionTarget
.
targetQ
,
1
,
64
,
5
);
out
+=
sprintf
(
out
,
"y_threshold: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"y_threshold: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
yuvThreshold
.
yThreshold
,
0
,
31
,
15
);
cam
->
params
.
yuvThreshold
.
yThreshold
,
0
,
31
,
6
);
out
+=
sprintf
(
out
,
"uv_threshold: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"uv_threshold: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
yuvThreshold
.
uvThreshold
,
0
,
31
,
15
);
cam
->
params
.
yuvThreshold
.
uvThreshold
,
0
,
31
,
6
);
out
+=
sprintf
(
out
,
"hysteresis: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"hysteresis: %8d %8d %8d %8d
\n
"
,
cam
->
params
.
compressionParams
.
hysteresis
,
0
,
255
,
3
);
cam
->
params
.
compressionParams
.
hysteresis
,
0
,
255
,
3
);
out
+=
sprintf
(
out
,
"threshold_max: %8d %8d %8d %8d
\n
"
,
out
+=
sprintf
(
out
,
"threshold_max: %8d %8d %8d %8d
\n
"
,
...
@@ -511,6 +544,47 @@ static int cpia_read_proc(char *page, char **start, off_t off,
...
@@ -511,6 +544,47 @@ static int cpia_read_proc(char *page, char **start, off_t off,
return
len
;
return
len
;
}
}
static
int
match
(
char
*
checkstr
,
char
**
buffer
,
unsigned
long
*
count
,
int
*
find_colon
,
int
*
err
)
{
int
ret
,
colon_found
=
1
;
int
len
=
strlen
(
checkstr
);
ret
=
(
len
<=
*
count
&&
strncmp
(
*
buffer
,
checkstr
,
len
)
==
0
);
if
(
ret
)
{
*
buffer
+=
len
;
*
count
-=
len
;
if
(
*
find_colon
)
{
colon_found
=
0
;
while
(
*
count
&&
(
**
buffer
==
' '
||
**
buffer
==
'\t'
||
(
!
colon_found
&&
**
buffer
==
':'
)))
{
if
(
**
buffer
==
':'
)
colon_found
=
1
;
--*
count
;
++*
buffer
;
}
if
(
!*
count
||
!
colon_found
)
*
err
=
-
EINVAL
;
*
find_colon
=
0
;
}
}
return
ret
;
}
static
unsigned
long
int
value
(
char
**
buffer
,
unsigned
long
*
count
,
int
*
err
)
{
char
*
p
;
unsigned
long
int
ret
;
ret
=
simple_strtoul
(
*
buffer
,
&
p
,
0
);
if
(
p
==
*
buffer
)
*
err
=
-
EINVAL
;
else
{
*
count
-=
p
-
*
buffer
;
*
buffer
=
p
;
}
return
ret
;
}
static
int
cpia_write_proc
(
struct
file
*
file
,
const
char
*
buf
,
static
int
cpia_write_proc
(
struct
file
*
file
,
const
char
*
buf
,
unsigned
long
count
,
void
*
data
)
unsigned
long
count
,
void
*
data
)
{
{
...
@@ -565,45 +639,11 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -565,45 +639,11 @@ static int cpia_write_proc(struct file *file, const char *buf,
memcpy
(
&
new_params
,
&
cam
->
params
,
sizeof
(
struct
cam_params
));
memcpy
(
&
new_params
,
&
cam
->
params
,
sizeof
(
struct
cam_params
));
new_mains
=
cam
->
mainsFreq
;
new_mains
=
cam
->
mainsFreq
;
#define MATCH(x) \
#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
({ \
#define VALUE (value(&buffer,&count, &retval))
int _len = strlen(x), _ret, _colon_found; \
_ret = (_len <= count && strncmp(buffer, x, _len) == 0); \
if (_ret) { \
buffer += _len; \
count -= _len; \
if (find_colon) { \
_colon_found = 0; \
while (count && (*buffer == ' ' || *buffer == '\t' || \
(!_colon_found && *buffer == ':'))) { \
if (*buffer == ':') \
_colon_found = 1; \
--count; \
++buffer; \
} \
if (!count || !_colon_found) \
retval = -EINVAL; \
find_colon = 0; \
} \
} \
_ret; \
})
#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
new_params.version.firmwareRevision == (y))
new_params.version.firmwareRevision == (y))
#define VALUE \
({ \
char *_p; \
unsigned long int _ret; \
_ret = simple_strtoul(buffer, &_p, 0); \
if (_p == buffer) \
retval = -EINVAL; \
else { \
count -= _p - buffer; \
buffer = _p; \
} \
_ret; \
})
retval
=
0
;
retval
=
0
;
while
(
count
&&
!
retval
)
{
while
(
count
&&
!
retval
)
{
find_colon
=
1
;
find_colon
=
1
;
...
@@ -618,6 +658,12 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -618,6 +658,12 @@ static int cpia_write_proc(struct file *file, const char *buf,
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
}
command_flags
|=
COMMAND_SETCOLOURPARAMS
;
command_flags
|=
COMMAND_SETCOLOURPARAMS
;
if
(
new_params
.
flickerControl
.
allowableOverExposure
<
0
)
new_params
.
flickerControl
.
allowableOverExposure
=
-
find_over_exposure
(
new_params
.
colourParams
.
brightness
);
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
if
(
MATCH
(
"contrast"
))
{
}
else
if
(
MATCH
(
"contrast"
))
{
if
(
!
retval
)
if
(
!
retval
)
val
=
VALUE
;
val
=
VALUE
;
...
@@ -686,6 +732,7 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -686,6 +732,7 @@ static int cpia_write_proc(struct file *file, const char *buf,
command_flags
|=
COMMAND_SETFLICKERCTRL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
}
command_flags
|=
COMMAND_SETSENSORFPS
;
command_flags
|=
COMMAND_SETSENSORFPS
;
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
}
else
if
(
MATCH
(
"stream_start_line"
))
{
}
else
if
(
MATCH
(
"stream_start_line"
))
{
if
(
!
retval
)
if
(
!
retval
)
val
=
VALUE
;
val
=
VALUE
;
...
@@ -700,6 +747,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -700,6 +747,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
else
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
}
}
else
if
(
MATCH
(
"sub_sample"
))
{
if
(
!
retval
&&
MATCH
(
"420"
))
new_params
.
format
.
subSample
=
SUBSAMPLE_420
;
else
if
(
!
retval
&&
MATCH
(
"422"
))
new_params
.
format
.
subSample
=
SUBSAMPLE_422
;
else
retval
=
-
EINVAL
;
command_flags
|=
COMMAND_SETFORMAT
;
}
else
if
(
MATCH
(
"yuv_order"
))
{
if
(
!
retval
&&
MATCH
(
"YUYV"
))
new_params
.
format
.
yuvOrder
=
YUVORDER_YUYV
;
else
if
(
!
retval
&&
MATCH
(
"UYVY"
))
new_params
.
format
.
yuvOrder
=
YUVORDER_UYVY
;
else
retval
=
-
EINVAL
;
command_flags
|=
COMMAND_SETFORMAT
;
}
else
if
(
MATCH
(
"ecp_timing"
))
{
}
else
if
(
MATCH
(
"ecp_timing"
))
{
if
(
!
retval
&&
MATCH
(
"normal"
))
if
(
!
retval
&&
MATCH
(
"normal"
))
new_params
.
ecpTiming
=
0
;
new_params
.
ecpTiming
=
0
;
...
@@ -711,9 +776,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -711,9 +776,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
command_flags
|=
COMMAND_SETECPTIMING
;
command_flags
|=
COMMAND_SETECPTIMING
;
}
else
if
(
MATCH
(
"color_balance_mode"
))
{
}
else
if
(
MATCH
(
"color_balance_mode"
))
{
if
(
!
retval
&&
MATCH
(
"manual"
))
if
(
!
retval
&&
MATCH
(
"manual"
))
new_params
.
colourBalance
.
balanceMode
IsAuto
=
0
;
new_params
.
colourBalance
.
balanceMode
=
3
;
else
if
(
!
retval
&&
MATCH
(
"auto"
))
else
if
(
!
retval
&&
MATCH
(
"auto"
))
new_params
.
colourBalance
.
balanceMode
IsAuto
=
1
;
new_params
.
colourBalance
.
balanceMode
=
2
;
else
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -723,9 +788,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -723,9 +788,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
<=
212
)
if
(
val
<=
212
)
{
new_params
.
colourBalance
.
redGain
=
val
;
new_params
.
colourBalance
.
redGain
=
val
;
else
new_params
.
colourBalance
.
balanceMode
=
1
;
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
}
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
...
@@ -734,9 +800,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -734,9 +800,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
<=
212
)
if
(
val
<=
212
)
{
new_params
.
colourBalance
.
greenGain
=
val
;
new_params
.
colourBalance
.
greenGain
=
val
;
else
new_params
.
colourBalance
.
balanceMode
=
1
;
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
}
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
...
@@ -745,9 +812,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -745,9 +812,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
<=
212
)
if
(
val
<=
212
)
{
new_params
.
colourBalance
.
blueGain
=
val
;
new_params
.
colourBalance
.
blueGain
=
val
;
else
new_params
.
colourBalance
.
balanceMode
=
1
;
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
}
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
command_flags
|=
COMMAND_SETCOLOURBALANCE
;
...
@@ -784,8 +852,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -784,8 +852,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
else
if
(
!
retval
&&
MATCH
(
"manual"
))
{
else
if
(
!
retval
&&
MATCH
(
"manual"
))
{
if
(
new_params
.
exposure
.
expMode
==
2
)
if
(
new_params
.
exposure
.
expMode
==
2
)
new_params
.
exposure
.
expMode
=
3
;
new_params
.
exposure
.
expMode
=
3
;
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
new_params
.
flickerControl
.
flickerMode
=
0
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -807,32 +876,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -807,32 +876,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
switch
(
val
)
{
switch
(
val
)
{
case
1
:
case
1
:
new_params
.
exposure
.
gain
=
0
;
new_params
.
exposure
.
gain
=
0
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
break
;
break
;
case
2
:
case
2
:
new_params
.
exposure
.
gain
=
1
;
new_params
.
exposure
.
gain
=
1
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
break
;
break
;
case
4
:
case
4
:
new_params
.
exposure
.
gain
=
2
;
new_params
.
exposure
.
gain
=
2
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
break
;
break
;
case
8
:
case
8
:
new_params
.
exposure
.
gain
=
3
;
new_params
.
exposure
.
gain
=
3
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
break
;
break
;
default:
default:
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
break
;
break
;
}
}
new_params
.
exposure
.
expMode
=
1
;
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
if
(
new_params
.
exposure
.
gain
>
if
(
new_params
.
exposure
.
gain
>
new_params
.
exposure
.
gainMode
-
1
)
new_params
.
exposure
.
gainMode
-
1
)
...
@@ -840,16 +901,18 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -840,16 +901,18 @@ static int cpia_write_proc(struct file *file, const char *buf,
}
}
}
else
if
(
MATCH
(
"fine_exp"
))
{
}
else
if
(
MATCH
(
"fine_exp"
))
{
if
(
!
retval
)
if
(
!
retval
)
val
=
VALUE
;
val
=
VALUE
/
2
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
<
256
)
{
if
(
val
<
256
)
{
/* 1-02 firmware limits fineExp to 127*/
/* 1-02 firmware limits fineExp
/2
to 127*/
if
(
FIRMWARE_VERSION
(
1
,
2
)
&&
val
>
127
)
if
(
FIRMWARE_VERSION
(
1
,
2
)
&&
val
>
127
)
val
=
127
;
val
=
127
;
new_params
.
exposure
.
fineExp
=
val
;
new_params
.
exposure
.
fineExp
=
val
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
exposure
.
expMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
new_params
.
flickerControl
.
flickerMode
=
0
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
}
else
...
@@ -860,17 +923,18 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -860,17 +923,18 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
<
65536
)
{
if
(
val
<=
MAX_EXP
)
{
/* 1-02 firmware limits
if
(
FIRMWARE_VERSION
(
1
,
2
)
&&
* coarseExp to 255 */
val
>
MAX_EXP_102
)
if
(
FIRMWARE_VERSION
(
1
,
2
)
&&
val
>
255
)
val
=
MAX_EXP_102
;
val
=
255
;
new_params
.
exposure
.
coarseExpLo
=
new_params
.
exposure
.
coarseExpLo
=
val
&
0xff
;
val
&
0xff
;
new_params
.
exposure
.
coarseExpHi
=
new_params
.
exposure
.
coarseExpHi
=
val
>>
8
;
val
>>
8
;
new_params
.
exposure
.
expMode
=
1
;
new_params
.
exposure
.
expMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
new_params
.
flickerControl
.
flickerMode
=
0
;
new_params
.
flickerControl
.
flickerMode
=
0
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
}
else
...
@@ -881,8 +945,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -881,8 +945,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
>=
220
&&
val
<=
255
)
{
if
(
val
>=
COMP_RED
&&
val
<=
255
)
{
new_params
.
exposure
.
redComp
=
val
;
new_params
.
exposure
.
redComp
=
val
;
new_params
.
exposure
.
compMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -892,8 +957,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -892,8 +957,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
>=
214
&&
val
<=
255
)
{
if
(
val
>=
COMP_GREEN1
&&
val
<=
255
)
{
new_params
.
exposure
.
green1Comp
=
val
;
new_params
.
exposure
.
green1Comp
=
val
;
new_params
.
exposure
.
compMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -903,8 +969,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -903,8 +969,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
>=
214
&&
val
<=
255
)
{
if
(
val
>=
COMP_GREEN2
&&
val
<=
255
)
{
new_params
.
exposure
.
green2Comp
=
val
;
new_params
.
exposure
.
green2Comp
=
val
;
new_params
.
exposure
.
compMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -914,8 +981,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -914,8 +981,9 @@ static int cpia_write_proc(struct file *file, const char *buf,
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
val
>=
230
&&
val
<=
255
)
{
if
(
val
>=
COMP_BLUE
&&
val
<=
255
)
{
new_params
.
exposure
.
blueComp
=
val
;
new_params
.
exposure
.
blueComp
=
val
;
new_params
.
exposure
.
compMode
=
1
;
command_flags
|=
COMMAND_SETEXPOSURE
;
command_flags
|=
COMMAND_SETEXPOSURE
;
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -1010,12 +1078,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1010,12 +1078,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
command_flags
|=
COMMAND_SETVLOFFSET
;
command_flags
|=
COMMAND_SETVLOFFSET
;
}
else
if
(
MATCH
(
"flicker_control"
))
{
}
else
if
(
MATCH
(
"flicker_control"
))
{
if
(
!
retval
&&
MATCH
(
"on"
))
{
if
(
!
retval
&&
MATCH
(
"on"
))
{
new_params
.
flickerControl
.
flickerMode
=
1
;
set_flicker
(
&
new_params
,
&
command_flags
,
1
);
new_params
.
exposure
.
expMode
=
2
;
}
else
if
(
!
retval
&&
MATCH
(
"off"
))
{
command_flags
|=
COMMAND_SETEXPOSURE
;
set_flicker
(
&
new_params
,
&
command_flags
,
0
);
}
else
if
(
!
retval
&&
MATCH
(
"off"
))
}
else
new_params
.
flickerControl
.
flickerMode
=
0
;
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
...
@@ -1039,16 +1105,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1039,16 +1105,24 @@ static int cpia_write_proc(struct file *file, const char *buf,
}
else
}
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
}
else
if
(
MATCH
(
"allowable_overexposure"
))
{
}
else
if
(
MATCH
(
"allowable_overexposure"
))
{
if
(
!
retval
)
if
(
!
retval
&&
MATCH
(
"auto"
))
{
val
=
VALUE
;
new_params
.
flickerControl
.
allowableOverExposure
=
-
find_over_exposure
(
new_params
.
colourParams
.
brightness
);
if
(
!
retval
)
{
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
if
(
val
<=
0xff
)
{
new_params
.
flickerControl
.
allowableOverExposure
=
val
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
}
else
{
retval
=
-
EINVAL
;
if
(
!
retval
)
val
=
VALUE
;
if
(
!
retval
)
{
if
(
val
<=
0xff
)
{
new_params
.
flickerControl
.
allowableOverExposure
=
val
;
if
(
new_params
.
flickerControl
.
flickerMode
!=
0
)
command_flags
|=
COMMAND_SETFLICKERCTRL
;
}
else
retval
=
-
EINVAL
;
}
}
}
}
else
if
(
MATCH
(
"compression_mode"
))
{
}
else
if
(
MATCH
(
"compression_mode"
))
{
if
(
!
retval
&&
MATCH
(
"none"
))
if
(
!
retval
&&
MATCH
(
"none"
))
...
@@ -1067,6 +1141,8 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1067,6 +1141,8 @@ static int cpia_write_proc(struct file *file, const char *buf,
}
else
if
(
MATCH
(
"decimation_enable"
))
{
}
else
if
(
MATCH
(
"decimation_enable"
))
{
if
(
!
retval
&&
MATCH
(
"off"
))
if
(
!
retval
&&
MATCH
(
"off"
))
new_params
.
compression
.
decimation
=
0
;
new_params
.
compression
.
decimation
=
0
;
else
if
(
!
retval
&&
MATCH
(
"on"
))
new_params
.
compression
.
decimation
=
1
;
else
else
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
...
@@ -1086,16 +1162,23 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1086,16 +1162,23 @@ static int cpia_write_proc(struct file *file, const char *buf,
if
(
!
retval
)
if
(
!
retval
)
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
if
(
!
retval
)
{
new_params
.
compressionTarget
.
targetFR
=
val
;
if
(
val
>
0
&&
val
<=
30
)
new_params
.
compressionTarget
.
targetFR
=
val
;
else
retval
=
-
EINVAL
;
}
command_flags
|=
COMMAND_SETCOMPRESSIONTARGET
;
command_flags
|=
COMMAND_SETCOMPRESSIONTARGET
;
}
else
if
(
MATCH
(
"target_quality"
))
{
}
else
if
(
MATCH
(
"target_quality"
))
{
if
(
!
retval
)
if
(
!
retval
)
val
=
VALUE
;
val
=
VALUE
;
if
(
!
retval
)
if
(
!
retval
)
{
new_params
.
compressionTarget
.
targetQ
=
val
;
if
(
val
>
0
&&
val
<=
64
)
new_params
.
compressionTarget
.
targetQ
=
val
;
else
retval
=
-
EINVAL
;
}
command_flags
|=
COMMAND_SETCOMPRESSIONTARGET
;
command_flags
|=
COMMAND_SETCOMPRESSIONTARGET
;
}
else
if
(
MATCH
(
"y_threshold"
))
{
}
else
if
(
MATCH
(
"y_threshold"
))
{
if
(
!
retval
)
if
(
!
retval
)
...
@@ -1247,10 +1330,8 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1247,10 +1330,8 @@ static int cpia_write_proc(struct file *file, const char *buf,
}
}
}
}
#undef MATCH
#undef MATCH
#undef FIRMWARE_VERSION
#undef VALUE
#undef VALUE
#undef FIND_VALUE
#undef FIRMWARE_VERSION
#undef FIND_END
if
(
!
retval
)
{
if
(
!
retval
)
{
if
(
command_flags
&
COMMAND_SETCOLOURPARAMS
)
{
if
(
command_flags
&
COMMAND_SETCOLOURPARAMS
)
{
/* Adjust cam->vp to reflect these changes */
/* Adjust cam->vp to reflect these changes */
...
@@ -1261,7 +1342,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
...
@@ -1261,7 +1342,10 @@ static int cpia_write_proc(struct file *file, const char *buf,
cam
->
vp
.
colour
=
cam
->
vp
.
colour
=
new_params
.
colourParams
.
saturation
*
65535
/
100
;
new_params
.
colourParams
.
saturation
*
65535
/
100
;
}
}
if
((
command_flags
&
COMMAND_SETEXPOSURE
)
&&
new_params
.
exposure
.
expMode
==
2
)
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
memcpy
(
&
cam
->
params
,
&
new_params
,
sizeof
(
struct
cam_params
));
memcpy
(
&
cam
->
params
,
&
new_params
,
sizeof
(
struct
cam_params
));
cam
->
mainsFreq
=
new_mains
;
cam
->
mainsFreq
=
new_mains
;
cam
->
cmd_queue
|=
command_flags
;
cam
->
cmd_queue
|=
command_flags
;
...
@@ -1294,11 +1378,11 @@ static void create_proc_cpia_cam(struct cam_data *cam)
...
@@ -1294,11 +1378,11 @@ static void create_proc_cpia_cam(struct cam_data *cam)
ent
->
read_proc
=
cpia_read_proc
;
ent
->
read_proc
=
cpia_read_proc
;
ent
->
write_proc
=
cpia_write_proc
;
ent
->
write_proc
=
cpia_write_proc
;
/*
/*
size of the proc entry is 3
672
bytes for the standard webcam;
size of the proc entry is 3
736
bytes for the standard webcam;
the extra features of the QX3 microscope add 18
8
bytes.
the extra features of the QX3 microscope add 18
9
bytes.
(we have not yet probed the camera to see which type it is).
(we have not yet probed the camera to see which type it is).
*/
*/
ent
->
size
=
3
672
+
188
;
ent
->
size
=
3
736
+
189
;
cam
->
proc_entry
=
ent
;
cam
->
proc_entry
=
ent
;
}
}
...
@@ -1324,10 +1408,12 @@ static void proc_cpia_create(void)
...
@@ -1324,10 +1408,12 @@ static void proc_cpia_create(void)
LOG
(
"Unable to initialise /proc/cpia
\n
"
);
LOG
(
"Unable to initialise /proc/cpia
\n
"
);
}
}
#ifdef MODULE
static
void
proc_cpia_destroy
(
void
)
static
void
proc_cpia_destroy
(
void
)
{
{
remove_proc_entry
(
"cpia"
,
0
);
remove_proc_entry
(
"cpia"
,
0
);
}
}
#endif
/*MODULE*/
#endif
/* CONFIG_PROC_FS */
#endif
/* CONFIG_PROC_FS */
/* ----------------------- debug functions ---------------------- */
/* ----------------------- debug functions ---------------------- */
...
@@ -1410,9 +1496,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1410,9 +1496,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
288
;
cam
->
vw
.
height
=
288
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
0
;
cam
->
params
.
roi
.
colStart
=
0
;
cam
->
params
.
roi
.
colEnd
=
44
;
cam
->
params
.
roi
.
rowStart
=
0
;
cam
->
params
.
roi
.
rowStart
=
0
;
cam
->
params
.
roi
.
rowEnd
=
72
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_SIF
:
case
VIDEOSIZE_SIF
:
...
@@ -1420,9 +1504,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1420,9 +1504,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
240
;
cam
->
vw
.
height
=
240
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
2
;
cam
->
params
.
roi
.
colStart
=
2
;
cam
->
params
.
roi
.
colEnd
=
42
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowEnd
=
66
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_288_216
:
case
VIDEOSIZE_288_216
:
...
@@ -1430,9 +1512,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1430,9 +1512,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
216
;
cam
->
vw
.
height
=
216
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
4
;
cam
->
params
.
roi
.
colStart
=
4
;
cam
->
params
.
roi
.
colEnd
=
40
;
cam
->
params
.
roi
.
rowStart
=
9
;
cam
->
params
.
roi
.
rowStart
=
9
;
cam
->
params
.
roi
.
rowEnd
=
63
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_256_192
:
case
VIDEOSIZE_256_192
:
...
@@ -1440,9 +1520,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1440,9 +1520,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
192
;
cam
->
vw
.
height
=
192
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
6
;
cam
->
params
.
roi
.
colStart
=
6
;
cam
->
params
.
roi
.
colEnd
=
38
;
cam
->
params
.
roi
.
rowStart
=
12
;
cam
->
params
.
roi
.
rowStart
=
12
;
cam
->
params
.
roi
.
rowEnd
=
60
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_224_168
:
case
VIDEOSIZE_224_168
:
...
@@ -1450,9 +1528,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1450,9 +1528,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
168
;
cam
->
vw
.
height
=
168
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
8
;
cam
->
params
.
roi
.
colStart
=
8
;
cam
->
params
.
roi
.
colEnd
=
36
;
cam
->
params
.
roi
.
rowStart
=
15
;
cam
->
params
.
roi
.
rowStart
=
15
;
cam
->
params
.
roi
.
rowEnd
=
57
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_192_144
:
case
VIDEOSIZE_192_144
:
...
@@ -1460,9 +1536,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1460,9 +1536,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
144
;
cam
->
vw
.
height
=
144
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_CIF
;
cam
->
params
.
roi
.
colStart
=
10
;
cam
->
params
.
roi
.
colStart
=
10
;
cam
->
params
.
roi
.
colEnd
=
34
;
cam
->
params
.
roi
.
rowStart
=
18
;
cam
->
params
.
roi
.
rowStart
=
18
;
cam
->
params
.
roi
.
rowEnd
=
54
;
cam
->
params
.
streamStartLine
=
120
;
cam
->
params
.
streamStartLine
=
120
;
break
;
break
;
case
VIDEOSIZE_QCIF
:
case
VIDEOSIZE_QCIF
:
...
@@ -1470,9 +1544,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1470,9 +1544,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
144
;
cam
->
vw
.
height
=
144
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
0
;
cam
->
params
.
roi
.
colStart
=
0
;
cam
->
params
.
roi
.
colEnd
=
22
;
cam
->
params
.
roi
.
rowStart
=
0
;
cam
->
params
.
roi
.
rowStart
=
0
;
cam
->
params
.
roi
.
rowEnd
=
36
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
case
VIDEOSIZE_QSIF
:
case
VIDEOSIZE_QSIF
:
...
@@ -1480,9 +1552,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1480,9 +1552,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
120
;
cam
->
vw
.
height
=
120
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
1
;
cam
->
params
.
roi
.
colStart
=
1
;
cam
->
params
.
roi
.
colEnd
=
21
;
cam
->
params
.
roi
.
rowStart
=
3
;
cam
->
params
.
roi
.
rowStart
=
3
;
cam
->
params
.
roi
.
rowEnd
=
33
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
case
VIDEOSIZE_128_96
:
case
VIDEOSIZE_128_96
:
...
@@ -1490,9 +1560,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1490,9 +1560,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
96
;
cam
->
vw
.
height
=
96
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
3
;
cam
->
params
.
roi
.
colStart
=
3
;
cam
->
params
.
roi
.
colEnd
=
19
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowEnd
=
30
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
case
VIDEOSIZE_88_72
:
case
VIDEOSIZE_88_72
:
...
@@ -1500,9 +1568,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1500,9 +1568,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
72
;
cam
->
vw
.
height
=
72
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
5
;
cam
->
params
.
roi
.
colStart
=
5
;
cam
->
params
.
roi
.
colEnd
=
16
;
cam
->
params
.
roi
.
rowStart
=
9
;
cam
->
params
.
roi
.
rowStart
=
9
;
cam
->
params
.
roi
.
rowEnd
=
27
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
case
VIDEOSIZE_64_48
:
case
VIDEOSIZE_64_48
:
...
@@ -1510,9 +1576,7 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1510,9 +1576,7 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
48
;
cam
->
vw
.
height
=
48
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
7
;
cam
->
params
.
roi
.
colStart
=
7
;
cam
->
params
.
roi
.
colEnd
=
15
;
cam
->
params
.
roi
.
rowStart
=
12
;
cam
->
params
.
roi
.
rowStart
=
12
;
cam
->
params
.
roi
.
rowEnd
=
24
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
case
VIDEOSIZE_48_48
:
case
VIDEOSIZE_48_48
:
...
@@ -1520,15 +1584,26 @@ static void set_vw_size(struct cam_data *cam)
...
@@ -1520,15 +1584,26 @@ static void set_vw_size(struct cam_data *cam)
cam
->
vw
.
height
=
48
;
cam
->
vw
.
height
=
48
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
format
.
videoSize
=
VIDEOSIZE_QCIF
;
cam
->
params
.
roi
.
colStart
=
8
;
cam
->
params
.
roi
.
colStart
=
8
;
cam
->
params
.
roi
.
colEnd
=
14
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowStart
=
6
;
cam
->
params
.
roi
.
rowEnd
=
30
;
cam
->
params
.
streamStartLine
=
60
;
cam
->
params
.
streamStartLine
=
60
;
break
;
break
;
default:
default:
LOG
(
"bad videosize value: %d
\n
"
,
cam
->
video_size
);
LOG
(
"bad videosize value: %d
\n
"
,
cam
->
video_size
);
return
;
}
}
if
(
cam
->
vc
.
width
==
0
)
cam
->
vc
.
width
=
cam
->
vw
.
width
;
if
(
cam
->
vc
.
height
==
0
)
cam
->
vc
.
height
=
cam
->
vw
.
height
;
cam
->
params
.
roi
.
colStart
+=
cam
->
vc
.
x
>>
3
;
cam
->
params
.
roi
.
colEnd
=
cam
->
params
.
roi
.
colStart
+
(
cam
->
vc
.
width
>>
3
);
cam
->
params
.
roi
.
rowStart
+=
cam
->
vc
.
y
>>
2
;
cam
->
params
.
roi
.
rowEnd
=
cam
->
params
.
roi
.
rowStart
+
(
cam
->
vc
.
height
>>
2
);
return
;
return
;
}
}
...
@@ -1668,29 +1743,6 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
...
@@ -1668,29 +1743,6 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
cam
->
params
.
exposure
.
green1Comp
=
data
[
5
];
cam
->
params
.
exposure
.
green1Comp
=
data
[
5
];
cam
->
params
.
exposure
.
green2Comp
=
data
[
6
];
cam
->
params
.
exposure
.
green2Comp
=
data
[
6
];
cam
->
params
.
exposure
.
blueComp
=
data
[
7
];
cam
->
params
.
exposure
.
blueComp
=
data
[
7
];
/* If the *Comp parameters are wacko, generate
* a warning, and reset them back to default
* values. - rich@annexia.org
*/
if
(
cam
->
params
.
exposure
.
redComp
<
220
||
cam
->
params
.
exposure
.
redComp
>
255
||
cam
->
params
.
exposure
.
green1Comp
<
214
||
cam
->
params
.
exposure
.
green1Comp
>
255
||
cam
->
params
.
exposure
.
green2Comp
<
214
||
cam
->
params
.
exposure
.
green2Comp
>
255
||
cam
->
params
.
exposure
.
blueComp
<
230
||
cam
->
params
.
exposure
.
blueComp
>
255
)
{
printk
(
KERN_WARNING
"*_comp parameters have gone AWOL (%d/%d/%d/%d) - reseting them
\n
"
,
cam
->
params
.
exposure
.
redComp
,
cam
->
params
.
exposure
.
green1Comp
,
cam
->
params
.
exposure
.
green2Comp
,
cam
->
params
.
exposure
.
blueComp
);
cam
->
params
.
exposure
.
redComp
=
220
;
cam
->
params
.
exposure
.
green1Comp
=
214
;
cam
->
params
.
exposure
.
green2Comp
=
214
;
cam
->
params
.
exposure
.
blueComp
=
230
;
}
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
param_lock
);
break
;
break
;
...
@@ -1756,6 +1808,122 @@ static int do_command_extended(struct cam_data *cam, u16 command,
...
@@ -1756,6 +1808,122 @@ static int do_command_extended(struct cam_data *cam, u16 command,
**********************************************************************/
**********************************************************************/
#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
static
int
convert420
(
unsigned
char
*
yuv
,
unsigned
char
*
rgb
,
int
out_fmt
,
int
linesize
,
int
mmap_kludge
)
{
int
y
,
u
,
v
,
r
,
g
,
b
,
y1
;
/* Odd lines use the same u and v as the previous line.
* Because of compression, it is necessary to get this
* information from the decoded image. */
switch
(
out_fmt
)
{
case
VIDEO_PALETTE_RGB555
:
y
=
(
*
yuv
++
-
16
)
*
76310
;
y1
=
(
*
yuv
-
16
)
*
76310
;
r
=
((
*
(
rgb
+
1
-
linesize
))
&
0x7c
)
<<
1
;
g
=
((
*
(
rgb
-
linesize
))
&
0xe0
)
>>
4
|
((
*
(
rgb
+
1
-
linesize
))
&
0x03
)
<<
6
;
b
=
((
*
(
rgb
-
linesize
))
&
0x1f
)
<<
3
;
u
=
(
-
53294
*
r
-
104635
*
g
+
157929
*
b
)
/
5756495
;
v
=
(
157968
*
r
-
132278
*
g
-
25690
*
b
)
/
5366159
;
r
=
104635
*
v
;
g
=
-
25690
*
u
-
53294
*
v
;
b
=
132278
*
u
;
*
rgb
++
=
((
LIMIT
(
g
+
y
)
&
0xf8
)
<<
2
)
|
(
LIMIT
(
b
+
y
)
>>
3
);
*
rgb
++
=
((
LIMIT
(
r
+
y
)
&
0xf8
)
>>
1
)
|
(
LIMIT
(
g
+
y
)
>>
6
);
*
rgb
++
=
((
LIMIT
(
g
+
y1
)
&
0xf8
)
<<
2
)
|
(
LIMIT
(
b
+
y1
)
>>
3
);
*
rgb
=
((
LIMIT
(
r
+
y1
)
&
0xf8
)
>>
1
)
|
(
LIMIT
(
g
+
y1
)
>>
6
);
return
4
;
case
VIDEO_PALETTE_RGB565
:
y
=
(
*
yuv
++
-
16
)
*
76310
;
y1
=
(
*
yuv
-
16
)
*
76310
;
r
=
(
*
(
rgb
+
1
-
linesize
))
&
0xf8
;
g
=
((
*
(
rgb
-
linesize
))
&
0xe0
)
>>
3
|
((
*
(
rgb
+
1
-
linesize
))
&
0x07
)
<<
5
;
b
=
((
*
(
rgb
-
linesize
))
&
0x1f
)
<<
3
;
u
=
(
-
53294
*
r
-
104635
*
g
+
157929
*
b
)
/
5756495
;
v
=
(
157968
*
r
-
132278
*
g
-
25690
*
b
)
/
5366159
;
r
=
104635
*
v
;
g
=
-
25690
*
u
-
53294
*
v
;
b
=
132278
*
u
;
*
rgb
++
=
((
LIMIT
(
g
+
y
)
&
0xfc
)
<<
3
)
|
(
LIMIT
(
b
+
y
)
>>
3
);
*
rgb
++
=
(
LIMIT
(
r
+
y
)
&
0xf8
)
|
(
LIMIT
(
g
+
y
)
>>
5
);
*
rgb
++
=
((
LIMIT
(
g
+
y1
)
&
0xfc
)
<<
3
)
|
(
LIMIT
(
b
+
y1
)
>>
3
);
*
rgb
=
(
LIMIT
(
r
+
y1
)
&
0xf8
)
|
(
LIMIT
(
g
+
y1
)
>>
5
);
return
4
;
break
;
case
VIDEO_PALETTE_RGB24
:
case
VIDEO_PALETTE_RGB32
:
y
=
(
*
yuv
++
-
16
)
*
76310
;
y1
=
(
*
yuv
-
16
)
*
76310
;
if
(
mmap_kludge
)
{
r
=
*
(
rgb
+
2
-
linesize
);
g
=
*
(
rgb
+
1
-
linesize
);
b
=
*
(
rgb
-
linesize
);
}
else
{
r
=
*
(
rgb
-
linesize
);
g
=
*
(
rgb
+
1
-
linesize
);
b
=
*
(
rgb
+
2
-
linesize
);
}
u
=
(
-
53294
*
r
-
104635
*
g
+
157929
*
b
)
/
5756495
;
v
=
(
157968
*
r
-
132278
*
g
-
25690
*
b
)
/
5366159
;
r
=
104635
*
v
;
g
=
-
25690
*
u
+
-
53294
*
v
;
b
=
132278
*
u
;
if
(
mmap_kludge
)
{
*
rgb
++
=
LIMIT
(
b
+
y
);
*
rgb
++
=
LIMIT
(
g
+
y
);
*
rgb
++
=
LIMIT
(
r
+
y
);
if
(
out_fmt
==
VIDEO_PALETTE_RGB32
)
rgb
++
;
*
rgb
++
=
LIMIT
(
b
+
y1
);
*
rgb
++
=
LIMIT
(
g
+
y1
);
*
rgb
=
LIMIT
(
r
+
y1
);
}
else
{
*
rgb
++
=
LIMIT
(
r
+
y
);
*
rgb
++
=
LIMIT
(
g
+
y
);
*
rgb
++
=
LIMIT
(
b
+
y
);
if
(
out_fmt
==
VIDEO_PALETTE_RGB32
)
rgb
++
;
*
rgb
++
=
LIMIT
(
r
+
y1
);
*
rgb
++
=
LIMIT
(
g
+
y1
);
*
rgb
=
LIMIT
(
b
+
y1
);
}
if
(
out_fmt
==
VIDEO_PALETTE_RGB32
)
return
8
;
return
6
;
case
VIDEO_PALETTE_YUV422
:
case
VIDEO_PALETTE_YUYV
:
y
=
*
yuv
++
;
u
=
*
(
rgb
+
1
-
linesize
);
y1
=
*
yuv
;
v
=
*
(
rgb
+
3
-
linesize
);
*
rgb
++
=
y
;
*
rgb
++
=
u
;
*
rgb
++
=
y1
;
*
rgb
=
v
;
return
4
;
case
VIDEO_PALETTE_UYVY
:
u
=
*
(
rgb
-
linesize
);
y
=
*
yuv
++
;
v
=
*
(
rgb
+
2
-
linesize
);
y1
=
*
yuv
;
*
rgb
++
=
u
;
*
rgb
++
=
y
;
*
rgb
++
=
v
;
*
rgb
=
y1
;
return
4
;
case
VIDEO_PALETTE_GREY
:
*
rgb
++
=
*
yuv
++
;
*
rgb
=
*
yuv
;
return
2
;
default:
DBG
(
"Empty: %d
\n
"
,
out_fmt
);
return
0
;
}
}
static
int
yuvconvert
(
unsigned
char
*
yuv
,
unsigned
char
*
rgb
,
int
out_fmt
,
static
int
yuvconvert
(
unsigned
char
*
yuv
,
unsigned
char
*
rgb
,
int
out_fmt
,
int
in_uyvy
,
int
mmap_kludge
)
int
in_uyvy
,
int
mmap_kludge
)
{
{
...
@@ -1887,7 +2055,8 @@ static int skipcount(int count, int fmt)
...
@@ -1887,7 +2055,8 @@ static int skipcount(int count, int fmt)
static
int
parse_picture
(
struct
cam_data
*
cam
,
int
size
)
static
int
parse_picture
(
struct
cam_data
*
cam
,
int
size
)
{
{
u8
*
obuf
,
*
ibuf
,
*
end_obuf
;
u8
*
obuf
,
*
ibuf
,
*
end_obuf
;
int
ll
,
in_uyvy
,
compressed
,
origsize
,
out_fmt
;
int
ll
,
in_uyvy
,
compressed
,
decimation
,
even_line
,
origsize
,
out_fmt
;
int
rows
,
cols
,
linesize
,
subsample_422
;
/* make sure params don't change while we are decoding */
/* make sure params don't change while we are decoding */
down
(
&
cam
->
param_lock
);
down
(
&
cam
->
param_lock
);
...
@@ -1910,11 +2079,12 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1910,11 +2079,12 @@ static int parse_picture(struct cam_data *cam, int size)
return
-
1
;
return
-
1
;
}
}
if
(
ibuf
[
17
]
!=
SUBSAMPLE_422
)
{
if
(
ibuf
[
17
]
!=
SUBSAMPLE_42
0
&&
ibuf
[
17
]
!=
SUBSAMPLE_42
2
)
{
LOG
(
"illegal subtype %d
\n
"
,
ibuf
[
17
]);
LOG
(
"illegal subtype %d
\n
"
,
ibuf
[
17
]);
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
param_lock
);
return
-
1
;
return
-
1
;
}
}
subsample_422
=
ibuf
[
17
]
==
SUBSAMPLE_422
;
if
(
ibuf
[
18
]
!=
YUVORDER_YUYV
&&
ibuf
[
18
]
!=
YUVORDER_UYVY
)
{
if
(
ibuf
[
18
]
!=
YUVORDER_YUYV
&&
ibuf
[
18
]
!=
YUVORDER_UYVY
)
{
LOG
(
"illegal yuvorder %d
\n
"
,
ibuf
[
18
]);
LOG
(
"illegal yuvorder %d
\n
"
,
ibuf
[
18
]);
...
@@ -1923,8 +2093,6 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1923,8 +2093,6 @@ static int parse_picture(struct cam_data *cam, int size)
}
}
in_uyvy
=
ibuf
[
18
]
==
YUVORDER_UYVY
;
in_uyvy
=
ibuf
[
18
]
==
YUVORDER_UYVY
;
#if 0
/* FIXME: ROI mismatch occurs when switching capture sizes */
if
((
ibuf
[
24
]
!=
cam
->
params
.
roi
.
colStart
)
||
if
((
ibuf
[
24
]
!=
cam
->
params
.
roi
.
colStart
)
||
(
ibuf
[
25
]
!=
cam
->
params
.
roi
.
colEnd
)
||
(
ibuf
[
25
]
!=
cam
->
params
.
roi
.
colEnd
)
||
(
ibuf
[
26
]
!=
cam
->
params
.
roi
.
rowStart
)
||
(
ibuf
[
26
]
!=
cam
->
params
.
roi
.
rowStart
)
||
...
@@ -1933,7 +2101,9 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1933,7 +2101,9 @@ static int parse_picture(struct cam_data *cam, int size)
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
param_lock
);
return
-
1
;
return
-
1
;
}
}
#endif
cols
=
8
*
(
ibuf
[
25
]
-
ibuf
[
24
]);
rows
=
4
*
(
ibuf
[
27
]
-
ibuf
[
26
]);
if
((
ibuf
[
28
]
!=
NOT_COMPRESSED
)
&&
(
ibuf
[
28
]
!=
COMPRESSED
))
{
if
((
ibuf
[
28
]
!=
NOT_COMPRESSED
)
&&
(
ibuf
[
28
]
!=
COMPRESSED
))
{
LOG
(
"illegal compression %d
\n
"
,
ibuf
[
28
]);
LOG
(
"illegal compression %d
\n
"
,
ibuf
[
28
]);
...
@@ -1942,12 +2112,13 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1942,12 +2112,13 @@ static int parse_picture(struct cam_data *cam, int size)
}
}
compressed
=
(
ibuf
[
28
]
==
COMPRESSED
);
compressed
=
(
ibuf
[
28
]
==
COMPRESSED
);
if
(
ibuf
[
29
]
!=
NO_DECIMATION
)
{
if
(
ibuf
[
29
]
!=
NO_DECIMATION
&&
ibuf
[
29
]
!=
DECIMATION_ENAB
)
{
LOG
(
"
decimation not supported
\n
"
);
LOG
(
"
illegal decimation %d
\n
"
,
ibuf
[
29
]
);
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
param_lock
);
return
-
1
;
return
-
1
;
}
}
decimation
=
(
ibuf
[
29
]
==
DECIMATION_ENAB
);
cam
->
params
.
yuvThreshold
.
yThreshold
=
ibuf
[
30
];
cam
->
params
.
yuvThreshold
.
yThreshold
=
ibuf
[
30
];
cam
->
params
.
yuvThreshold
.
uvThreshold
=
ibuf
[
31
];
cam
->
params
.
yuvThreshold
.
uvThreshold
=
ibuf
[
31
];
cam
->
params
.
status
.
systemState
=
ibuf
[
32
];
cam
->
params
.
status
.
systemState
=
ibuf
[
32
];
...
@@ -1961,10 +2132,12 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1961,10 +2132,12 @@ static int parse_picture(struct cam_data *cam, int size)
cam
->
fps
=
ibuf
[
41
];
cam
->
fps
=
ibuf
[
41
];
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
param_lock
);
linesize
=
skipcount
(
cols
,
out_fmt
);
ibuf
+=
FRAME_HEADER_SIZE
;
ibuf
+=
FRAME_HEADER_SIZE
;
size
-=
FRAME_HEADER_SIZE
;
size
-=
FRAME_HEADER_SIZE
;
ll
=
ibuf
[
0
]
|
(
ibuf
[
1
]
<<
8
);
ll
=
ibuf
[
0
]
|
(
ibuf
[
1
]
<<
8
);
ibuf
+=
2
;
ibuf
+=
2
;
even_line
=
1
;
while
(
size
>
0
)
{
while
(
size
>
0
)
{
size
-=
(
ll
+
2
);
size
-=
(
ll
+
2
);
...
@@ -1975,16 +2148,24 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1975,16 +2148,24 @@ static int parse_picture(struct cam_data *cam, int size)
while
(
ll
>
1
)
{
while
(
ll
>
1
)
{
if
(
!
compressed
||
(
compressed
&&
!
(
*
ibuf
&
1
)))
{
if
(
!
compressed
||
(
compressed
&&
!
(
*
ibuf
&
1
)))
{
if
(
subsample_422
||
even_line
)
{
obuf
+=
yuvconvert
(
ibuf
,
obuf
,
out_fmt
,
obuf
+=
yuvconvert
(
ibuf
,
obuf
,
out_fmt
,
in_uyvy
,
cam
->
mmap_kludge
);
in_uyvy
,
cam
->
mmap_kludge
);
ibuf
+=
4
;
ibuf
+=
4
;
ll
-=
4
;
ll
-=
4
;
}
else
{
/* SUBSAMPLE_420 on an odd line */
obuf
+=
convert420
(
ibuf
,
obuf
,
out_fmt
,
linesize
,
cam
->
mmap_kludge
);
ibuf
+=
2
;
ll
-=
2
;
}
}
else
{
}
else
{
/*skip compressed interval from previous frame*/
/*skip compressed interval from previous frame*/
int
skipsize
=
skipcount
(
*
ibuf
>>
1
,
out_fmt
);
obuf
+=
skipcount
(
*
ibuf
>>
1
,
out_fmt
);
obuf
+=
skipsize
;
if
(
obuf
>
end_obuf
)
{
if
(
obuf
>
end_obuf
)
{
LOG
(
"Insufficient
data in buffer
\n
"
);
LOG
(
"Insufficient
buffer size
\n
"
);
return
-
1
;
return
-
1
;
}
}
++
ibuf
;
++
ibuf
;
...
@@ -1998,7 +2179,7 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -1998,7 +2179,7 @@ static int parse_picture(struct cam_data *cam, int size)
return
-
1
;
return
-
1
;
}
}
ibuf
++
;
/* skip over EOL */
++
ibuf
;
/* skip over EOL */
if
((
size
>
3
)
&&
(
ibuf
[
0
]
==
EOI
)
&&
(
ibuf
[
1
]
==
EOI
)
&&
if
((
size
>
3
)
&&
(
ibuf
[
0
]
==
EOI
)
&&
(
ibuf
[
1
]
==
EOI
)
&&
(
ibuf
[
2
]
==
EOI
)
&&
(
ibuf
[
3
]
==
EOI
))
{
(
ibuf
[
2
]
==
EOI
)
&&
(
ibuf
[
3
]
==
EOI
))
{
...
@@ -2006,10 +2187,17 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -2006,10 +2187,17 @@ static int parse_picture(struct cam_data *cam, int size)
break
;
break
;
}
}
if
(
decimation
)
{
/* skip the odd lines for now */
obuf
+=
linesize
;
}
if
(
size
>
1
)
{
if
(
size
>
1
)
{
ll
=
ibuf
[
0
]
|
(
ibuf
[
1
]
<<
8
);
ll
=
ibuf
[
0
]
|
(
ibuf
[
1
]
<<
8
);
ibuf
+=
2
;
/* skip over line length */
ibuf
+=
2
;
/* skip over line length */
}
}
if
(
!
decimation
)
even_line
=
!
even_line
;
}
else
{
}
else
{
LOG
(
"line length was not 1 but %d after %d/%d bytes
\n
"
,
LOG
(
"line length was not 1 but %d after %d/%d bytes
\n
"
,
ll
,
origsize
-
size
,
origsize
);
ll
,
origsize
-
size
,
origsize
);
...
@@ -2017,6 +2205,25 @@ static int parse_picture(struct cam_data *cam, int size)
...
@@ -2017,6 +2205,25 @@ static int parse_picture(struct cam_data *cam, int size)
}
}
}
}
if
(
decimation
)
{
/* interpolate odd rows */
int
i
,
j
;
u8
*
prev
,
*
next
;
prev
=
cam
->
decompressed_frame
.
data
;
obuf
=
prev
+
linesize
;
next
=
obuf
+
linesize
;
for
(
i
=
1
;
i
<
rows
-
1
;
i
+=
2
)
{
for
(
j
=
0
;
j
<
linesize
;
++
j
)
{
*
obuf
++
=
((
int
)
*
prev
++
+
*
next
++
)
/
2
;
}
prev
+=
linesize
;
obuf
+=
linesize
;
next
+=
linesize
;
}
/* last row is odd, just copy previous row */
memcpy
(
obuf
,
prev
,
linesize
);
}
cam
->
decompressed_frame
.
count
=
obuf
-
cam
->
decompressed_frame
.
data
;
cam
->
decompressed_frame
.
count
=
obuf
-
cam
->
decompressed_frame
.
data
;
return
cam
->
decompressed_frame
.
count
;
return
cam
->
decompressed_frame
.
count
;
...
@@ -2029,6 +2236,38 @@ static inline int init_stream_cap(struct cam_data *cam)
...
@@ -2029,6 +2236,38 @@ static inline int init_stream_cap(struct cam_data *cam)
0
,
cam
->
params
.
streamStartLine
,
0
,
0
);
0
,
cam
->
params
.
streamStartLine
,
0
,
0
);
}
}
/* find_over_exposure
* Finds a suitable value of OverExposure for use with SetFlickerCtrl
* Some calculation is required because this value changes with the brightness
* set with SetColourParameters
*
* Parameters: Brightness - last brightness value set with SetColourParameters
*
* Returns: OverExposure value to use with SetFlickerCtrl
*/
#define FLICKER_MAX_EXPOSURE 250
#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
#define FLICKER_BRIGHTNESS_CONSTANT 59
static
int
find_over_exposure
(
int
brightness
)
{
int
MaxAllowableOverExposure
,
OverExposure
;
MaxAllowableOverExposure
=
FLICKER_MAX_EXPOSURE
-
brightness
-
FLICKER_BRIGHTNESS_CONSTANT
;
if
(
MaxAllowableOverExposure
<
FLICKER_ALLOWABLE_OVER_EXPOSURE
)
{
OverExposure
=
MaxAllowableOverExposure
;
}
else
{
OverExposure
=
FLICKER_ALLOWABLE_OVER_EXPOSURE
;
}
return
OverExposure
;
}
#undef FLICKER_MAX_EXPOSURE
#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
#undef FLICKER_BRIGHTNESS_CONSTANT
/* update various camera modes and settings */
/* update various camera modes and settings */
static
void
dispatch_commands
(
struct
cam_data
*
cam
)
static
void
dispatch_commands
(
struct
cam_data
*
cam
)
{
{
...
@@ -2039,17 +2278,6 @@ static void dispatch_commands(struct cam_data *cam)
...
@@ -2039,17 +2278,6 @@ static void dispatch_commands(struct cam_data *cam)
}
}
DEB_BYTE
(
cam
->
cmd_queue
);
DEB_BYTE
(
cam
->
cmd_queue
);
DEB_BYTE
(
cam
->
cmd_queue
>>
8
);
DEB_BYTE
(
cam
->
cmd_queue
>>
8
);
if
(
cam
->
cmd_queue
&
COMMAND_SETCOLOURPARAMS
)
do_command
(
cam
,
CPIA_COMMAND_SetColourParams
,
cam
->
params
.
colourParams
.
brightness
,
cam
->
params
.
colourParams
.
contrast
,
cam
->
params
.
colourParams
.
saturation
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSION
)
do_command
(
cam
,
CPIA_COMMAND_SetCompression
,
cam
->
params
.
compression
.
mode
,
cam
->
params
.
compression
.
decimation
,
0
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETFORMAT
)
{
if
(
cam
->
cmd_queue
&
COMMAND_SETFORMAT
)
{
do_command
(
cam
,
CPIA_COMMAND_SetFormat
,
do_command
(
cam
,
CPIA_COMMAND_SetFormat
,
cam
->
params
.
format
.
videoSize
,
cam
->
params
.
format
.
videoSize
,
...
@@ -2061,37 +2289,30 @@ static void dispatch_commands(struct cam_data *cam)
...
@@ -2061,37 +2289,30 @@ static void dispatch_commands(struct cam_data *cam)
cam
->
first_frame
=
1
;
cam
->
first_frame
=
1
;
}
}
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSIONTARGET
)
if
(
cam
->
cmd_queue
&
COMMAND_SETCOLOURPARAMS
)
do_command
(
cam
,
CPIA_COMMAND_SetCompressionTarget
,
do_command
(
cam
,
CPIA_COMMAND_SetColourParams
,
cam
->
params
.
compressionTarget
.
frTargeting
,
cam
->
params
.
colourParams
.
brightness
,
cam
->
params
.
compressionTarget
.
targetFR
,
cam
->
params
.
colourParams
.
contrast
,
cam
->
params
.
compressionTarget
.
targetQ
,
0
);
cam
->
params
.
colourParams
.
saturation
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETYUVTHRESH
)
do_command
(
cam
,
CPIA_COMMAND_SetYUVThresh
,
cam
->
params
.
yuvThreshold
.
yThreshold
,
cam
->
params
.
yuvThreshold
.
uvThreshold
,
0
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETECPTIMING
)
if
(
cam
->
cmd_queue
&
COMMAND_SETAPCOR
)
do_command
(
cam
,
CPIA_COMMAND_SetECPTiming
,
do_command
(
cam
,
CPIA_COMMAND_SetApcor
,
cam
->
params
.
ecpTiming
,
0
,
0
,
0
);
cam
->
params
.
apcor
.
gain1
,
cam
->
params
.
apcor
.
gain2
,
cam
->
params
.
apcor
.
gain4
,
cam
->
params
.
apcor
.
gain8
);
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSIONPARAMS
)
if
(
cam
->
cmd_queue
&
COMMAND_SETVLOFFSET
)
do_command_extended
(
cam
,
CPIA_COMMAND_SetCompressionParams
,
do_command
(
cam
,
CPIA_COMMAND_SetVLOffset
,
0
,
0
,
0
,
0
,
cam
->
params
.
vlOffset
.
gain1
,
cam
->
params
.
compressionParams
.
hysteresis
,
cam
->
params
.
vlOffset
.
gain2
,
cam
->
params
.
compressionParams
.
threshMax
,
cam
->
params
.
vlOffset
.
gain4
,
cam
->
params
.
compressionParams
.
smallStep
,
cam
->
params
.
vlOffset
.
gain8
);
cam
->
params
.
compressionParams
.
largeStep
,
cam
->
params
.
compressionParams
.
decimationHysteresis
,
cam
->
params
.
compressionParams
.
frDiffStepThresh
,
cam
->
params
.
compressionParams
.
qDiffStepThresh
,
cam
->
params
.
compressionParams
.
decimationThreshMod
);
if
(
cam
->
cmd_queue
&
COMMAND_SETEXPOSURE
)
if
(
cam
->
cmd_queue
&
COMMAND_SETEXPOSURE
)
{
do_command_extended
(
cam
,
CPIA_COMMAND_SetExposure
,
do_command_extended
(
cam
,
CPIA_COMMAND_SetExposure
,
cam
->
params
.
exposure
.
gainMode
,
cam
->
params
.
exposure
.
gainMode
,
cam
->
params
.
exposure
.
expMode
,
1
,
cam
->
params
.
exposure
.
compMode
,
cam
->
params
.
exposure
.
compMode
,
cam
->
params
.
exposure
.
centreWeight
,
cam
->
params
.
exposure
.
centreWeight
,
cam
->
params
.
exposure
.
gain
,
cam
->
params
.
exposure
.
gain
,
...
@@ -2102,12 +2323,21 @@ static void dispatch_commands(struct cam_data *cam)
...
@@ -2102,12 +2323,21 @@ static void dispatch_commands(struct cam_data *cam)
cam
->
params
.
exposure
.
green1Comp
,
cam
->
params
.
exposure
.
green1Comp
,
cam
->
params
.
exposure
.
green2Comp
,
cam
->
params
.
exposure
.
green2Comp
,
cam
->
params
.
exposure
.
blueComp
);
cam
->
params
.
exposure
.
blueComp
);
if
(
cam
->
params
.
exposure
.
expMode
!=
1
)
{
do_command_extended
(
cam
,
CPIA_COMMAND_SetExposure
,
0
,
cam
->
params
.
exposure
.
expMode
,
0
,
0
,
cam
->
params
.
exposure
.
gain
,
cam
->
params
.
exposure
.
fineExp
,
cam
->
params
.
exposure
.
coarseExpLo
,
cam
->
params
.
exposure
.
coarseExpHi
,
0
,
0
,
0
,
0
);
}
}
if
(
cam
->
cmd_queue
&
COMMAND_SETCOLOURBALANCE
)
{
if
(
cam
->
cmd_queue
&
COMMAND_SETCOLOURBALANCE
)
{
if
(
cam
->
params
.
colourBalance
.
balanceModeIsAuto
)
{
if
(
cam
->
params
.
colourBalance
.
balanceMode
==
1
)
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
2
,
0
,
0
,
0
);
}
else
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
1
,
1
,
cam
->
params
.
colourBalance
.
redGain
,
cam
->
params
.
colourBalance
.
redGain
,
...
@@ -2116,32 +2346,59 @@ static void dispatch_commands(struct cam_data *cam)
...
@@ -2116,32 +2346,59 @@ static void dispatch_commands(struct cam_data *cam)
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
3
,
0
,
0
,
0
);
3
,
0
,
0
,
0
);
}
}
if
(
cam
->
params
.
colourBalance
.
balanceMode
==
2
)
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
2
,
0
,
0
,
0
);
}
if
(
cam
->
params
.
colourBalance
.
balanceMode
==
3
)
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
3
,
0
,
0
,
0
);
}
}
}
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSIONTARGET
)
do_command
(
cam
,
CPIA_COMMAND_SetCompressionTarget
,
cam
->
params
.
compressionTarget
.
frTargeting
,
cam
->
params
.
compressionTarget
.
targetFR
,
cam
->
params
.
compressionTarget
.
targetQ
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETYUVTHRESH
)
do_command
(
cam
,
CPIA_COMMAND_SetYUVThresh
,
cam
->
params
.
yuvThreshold
.
yThreshold
,
cam
->
params
.
yuvThreshold
.
uvThreshold
,
0
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSIONPARAMS
)
do_command_extended
(
cam
,
CPIA_COMMAND_SetCompressionParams
,
0
,
0
,
0
,
0
,
cam
->
params
.
compressionParams
.
hysteresis
,
cam
->
params
.
compressionParams
.
threshMax
,
cam
->
params
.
compressionParams
.
smallStep
,
cam
->
params
.
compressionParams
.
largeStep
,
cam
->
params
.
compressionParams
.
decimationHysteresis
,
cam
->
params
.
compressionParams
.
frDiffStepThresh
,
cam
->
params
.
compressionParams
.
qDiffStepThresh
,
cam
->
params
.
compressionParams
.
decimationThreshMod
);
if
(
cam
->
cmd_queue
&
COMMAND_SETCOMPRESSION
)
do_command
(
cam
,
CPIA_COMMAND_SetCompression
,
cam
->
params
.
compression
.
mode
,
cam
->
params
.
compression
.
decimation
,
0
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETSENSORFPS
)
if
(
cam
->
cmd_queue
&
COMMAND_SETSENSORFPS
)
do_command
(
cam
,
CPIA_COMMAND_SetSensorFPS
,
do_command
(
cam
,
CPIA_COMMAND_SetSensorFPS
,
cam
->
params
.
sensorFps
.
divisor
,
cam
->
params
.
sensorFps
.
divisor
,
cam
->
params
.
sensorFps
.
baserate
,
0
,
0
);
cam
->
params
.
sensorFps
.
baserate
,
0
,
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETAPCOR
)
do_command
(
cam
,
CPIA_COMMAND_SetApcor
,
cam
->
params
.
apcor
.
gain1
,
cam
->
params
.
apcor
.
gain2
,
cam
->
params
.
apcor
.
gain4
,
cam
->
params
.
apcor
.
gain8
);
if
(
cam
->
cmd_queue
&
COMMAND_SETFLICKERCTRL
)
if
(
cam
->
cmd_queue
&
COMMAND_SETFLICKERCTRL
)
do_command
(
cam
,
CPIA_COMMAND_SetFlickerCtrl
,
do_command
(
cam
,
CPIA_COMMAND_SetFlickerCtrl
,
cam
->
params
.
flickerControl
.
flickerMode
,
cam
->
params
.
flickerControl
.
flickerMode
,
cam
->
params
.
flickerControl
.
coarseJump
,
cam
->
params
.
flickerControl
.
coarseJump
,
cam
->
params
.
flickerControl
.
allowableOverExposure
,
0
);
abs
(
cam
->
params
.
flickerControl
.
allowableOverExposure
),
0
);
if
(
cam
->
cmd_queue
&
COMMAND_SETVLOFFSET
)
if
(
cam
->
cmd_queue
&
COMMAND_SETECPTIMING
)
do_command
(
cam
,
CPIA_COMMAND_SetVLOffset
,
do_command
(
cam
,
CPIA_COMMAND_SetECPTiming
,
cam
->
params
.
vlOffset
.
gain1
,
cam
->
params
.
ecpTiming
,
0
,
0
,
0
);
cam
->
params
.
vlOffset
.
gain2
,
cam
->
params
.
vlOffset
.
gain4
,
cam
->
params
.
vlOffset
.
gain8
);
if
(
cam
->
cmd_queue
&
COMMAND_PAUSE
)
if
(
cam
->
cmd_queue
&
COMMAND_PAUSE
)
do_command
(
cam
,
CPIA_COMMAND_EndStreamCap
,
0
,
0
,
0
,
0
);
do_command
(
cam
,
CPIA_COMMAND_EndStreamCap
,
0
,
0
,
0
,
0
);
...
@@ -2149,20 +2406,416 @@ static void dispatch_commands(struct cam_data *cam)
...
@@ -2149,20 +2406,416 @@ static void dispatch_commands(struct cam_data *cam)
if
(
cam
->
cmd_queue
&
COMMAND_RESUME
)
if
(
cam
->
cmd_queue
&
COMMAND_RESUME
)
init_stream_cap
(
cam
);
init_stream_cap
(
cam
);
if
(
cam
->
cmd_queue
&
COMMAND_SETLIGHTS
&&
cam
->
params
.
qx3
.
qx3_detected
)
{
if
(
cam
->
cmd_queue
&
COMMAND_SETLIGHTS
&&
cam
->
params
.
qx3
.
qx3_detected
)
int
p1
=
(
cam
->
params
.
qx3
.
bottomlight
==
0
)
<<
1
;
{
int
p2
=
(
cam
->
params
.
qx3
.
toplight
==
0
)
<<
3
;
int
p1
=
(
cam
->
params
.
qx3
.
bottomlight
==
0
)
<<
1
;
do_command
(
cam
,
CPIA_COMMAND_WriteVCReg
,
0x90
,
0x8F
,
0x50
,
0
);
int
p2
=
(
cam
->
params
.
qx3
.
toplight
==
0
)
<<
3
;
do_command
(
cam
,
CPIA_COMMAND_WriteMCPort
,
2
,
0
,
(
p1
|
p2
|
0xE0
),
0
);
do_command
(
cam
,
CPIA_COMMAND_WriteVCReg
,
0x90
,
0x8F
,
0x50
,
0
);
}
do_command
(
cam
,
CPIA_COMMAND_WriteMCPort
,
2
,
0
,
(
p1
|
p2
|
0xE0
),
0
);
}
up
(
&
cam
->
param_lock
);
cam
->
cmd_queue
=
COMMAND_NONE
;
cam
->
cmd_queue
=
COMMAND_NONE
;
up
(
&
cam
->
param_lock
);
return
;
return
;
}
}
static
void
set_flicker
(
struct
cam_params
*
params
,
volatile
u32
*
command_flags
,
int
on
)
{
/* Everything in here is from the Windows driver */
#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
params->version.firmwareRevision == (y))
/* define for compgain calculation */
#define COMPGAIN(base, curexp, newexp) \
(u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
(u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
int
currentexp
=
params
->
exposure
.
coarseExpLo
+
params
->
exposure
.
coarseExpHi
*
256
;
int
startexp
;
if
(
on
)
{
int
cj
=
params
->
flickerControl
.
coarseJump
;
params
->
flickerControl
.
flickerMode
=
1
;
params
->
flickerControl
.
disabled
=
0
;
if
(
params
->
exposure
.
expMode
!=
2
)
*
command_flags
|=
COMMAND_SETEXPOSURE
;
params
->
exposure
.
expMode
=
2
;
currentexp
=
currentexp
<<
params
->
exposure
.
gain
;
params
->
exposure
.
gain
=
0
;
/* round down current exposure to nearest value */
startexp
=
(
currentexp
+
ROUND_UP_EXP_FOR_FLICKER
)
/
cj
;
if
(
startexp
<
1
)
startexp
=
1
;
startexp
=
(
startexp
*
cj
)
-
1
;
if
(
FIRMWARE_VERSION
(
1
,
2
))
while
(
startexp
>
MAX_EXP_102
)
startexp
-=
cj
;
else
while
(
startexp
>
MAX_EXP
)
startexp
-=
cj
;
params
->
exposure
.
coarseExpLo
=
startexp
&
0xff
;
params
->
exposure
.
coarseExpHi
=
startexp
>>
8
;
if
(
currentexp
>
startexp
)
{
if
(
currentexp
>
(
2
*
startexp
))
currentexp
=
2
*
startexp
;
params
->
exposure
.
redComp
=
COMPGAIN
(
COMP_RED
,
currentexp
,
startexp
);
params
->
exposure
.
green1Comp
=
COMPGAIN
(
COMP_GREEN1
,
currentexp
,
startexp
);
params
->
exposure
.
green2Comp
=
COMPGAIN
(
COMP_GREEN2
,
currentexp
,
startexp
);
params
->
exposure
.
blueComp
=
COMPGAIN
(
COMP_BLUE
,
currentexp
,
startexp
);
}
else
{
params
->
exposure
.
redComp
=
COMP_RED
;
params
->
exposure
.
green1Comp
=
COMP_GREEN1
;
params
->
exposure
.
green2Comp
=
COMP_GREEN2
;
params
->
exposure
.
blueComp
=
COMP_BLUE
;
}
if
(
FIRMWARE_VERSION
(
1
,
2
))
params
->
exposure
.
compMode
=
0
;
else
params
->
exposure
.
compMode
=
1
;
params
->
apcor
.
gain1
=
0x18
;
params
->
apcor
.
gain2
=
0x18
;
params
->
apcor
.
gain4
=
0x16
;
params
->
apcor
.
gain8
=
0x14
;
*
command_flags
|=
COMMAND_SETAPCOR
;
}
else
{
params
->
flickerControl
.
flickerMode
=
0
;
params
->
flickerControl
.
disabled
=
1
;
/* Coarse = average of equivalent coarse for each comp channel */
startexp
=
EXP_FROM_COMP
(
COMP_RED
,
params
->
exposure
.
redComp
,
currentexp
);
startexp
+=
EXP_FROM_COMP
(
COMP_GREEN1
,
params
->
exposure
.
green1Comp
,
currentexp
);
startexp
+=
EXP_FROM_COMP
(
COMP_GREEN2
,
params
->
exposure
.
green2Comp
,
currentexp
);
startexp
+=
EXP_FROM_COMP
(
COMP_BLUE
,
params
->
exposure
.
blueComp
,
currentexp
);
startexp
=
startexp
>>
2
;
while
(
startexp
>
MAX_EXP
&&
params
->
exposure
.
gain
<
params
->
exposure
.
gainMode
-
1
)
{
startexp
=
startexp
>>
1
;
++
params
->
exposure
.
gain
;
}
if
(
FIRMWARE_VERSION
(
1
,
2
)
&&
startexp
>
MAX_EXP_102
)
startexp
=
MAX_EXP_102
;
if
(
startexp
>
MAX_EXP
)
startexp
=
MAX_EXP
;
params
->
exposure
.
coarseExpLo
=
startexp
&
0xff
;
params
->
exposure
.
coarseExpHi
=
startexp
>>
8
;
params
->
exposure
.
redComp
=
COMP_RED
;
params
->
exposure
.
green1Comp
=
COMP_GREEN1
;
params
->
exposure
.
green2Comp
=
COMP_GREEN2
;
params
->
exposure
.
blueComp
=
COMP_BLUE
;
params
->
exposure
.
compMode
=
1
;
*
command_flags
|=
COMMAND_SETEXPOSURE
;
params
->
apcor
.
gain1
=
0x18
;
params
->
apcor
.
gain2
=
0x16
;
params
->
apcor
.
gain4
=
0x24
;
params
->
apcor
.
gain8
=
0x34
;
*
command_flags
|=
COMMAND_SETAPCOR
;
}
params
->
vlOffset
.
gain1
=
20
;
params
->
vlOffset
.
gain2
=
24
;
params
->
vlOffset
.
gain4
=
26
;
params
->
vlOffset
.
gain8
=
26
;
*
command_flags
|=
COMMAND_SETVLOFFSET
;
#undef FIRMWARE_VERSION
#undef EXP_FROM_COMP
#undef COMPGAIN
}
#define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \
cam->params.version.firmwareRevision == (y))
/* monitor the exposure and adjust the sensor frame rate if needed */
static
void
monitor_exposure
(
struct
cam_data
*
cam
)
{
u8
exp_acc
,
bcomp
,
gain
,
coarseL
,
cmd
[
8
],
data
[
8
];
int
retval
,
light_exp
,
dark_exp
,
very_dark_exp
;
int
old_exposure
,
new_exposure
,
framerate
;
/* get necessary stats and register settings from camera */
/* do_command can't handle this, so do it ourselves */
cmd
[
0
]
=
CPIA_COMMAND_ReadVPRegs
>>
8
;
cmd
[
1
]
=
CPIA_COMMAND_ReadVPRegs
&
0xff
;
cmd
[
2
]
=
30
;
cmd
[
3
]
=
4
;
cmd
[
4
]
=
9
;
cmd
[
5
]
=
8
;
cmd
[
6
]
=
8
;
cmd
[
7
]
=
0
;
retval
=
cam
->
ops
->
transferCmd
(
cam
->
lowlevel_data
,
cmd
,
data
);
if
(
retval
)
{
LOG
(
"ReadVPRegs(30,4,9,8) - failed, retval=%d
\n
"
,
retval
);
return
;
}
exp_acc
=
data
[
0
];
bcomp
=
data
[
1
];
gain
=
data
[
2
];
coarseL
=
data
[
3
];
down
(
&
cam
->
param_lock
);
light_exp
=
cam
->
params
.
colourParams
.
brightness
+
TC
-
50
+
EXP_ACC_LIGHT
;
if
(
light_exp
>
255
)
light_exp
=
255
;
dark_exp
=
cam
->
params
.
colourParams
.
brightness
+
TC
-
50
-
EXP_ACC_DARK
;
if
(
dark_exp
<
0
)
dark_exp
=
0
;
very_dark_exp
=
dark_exp
/
2
;
old_exposure
=
cam
->
params
.
exposure
.
coarseExpHi
*
256
+
cam
->
params
.
exposure
.
coarseExpLo
;
if
(
!
cam
->
params
.
flickerControl
.
disabled
)
{
/* Flicker control on */
int
max_comp
=
FIRMWARE_VERSION
(
1
,
2
)
?
MAX_COMP
:
HIGH_COMP_102
;
bcomp
+=
128
;
/* decode */
if
(
bcomp
>=
max_comp
&&
exp_acc
<
dark_exp
)
{
/* dark */
if
(
exp_acc
<
very_dark_exp
)
{
/* very dark */
if
(
cam
->
exposure_status
==
EXPOSURE_VERY_DARK
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_VERY_DARK
;
cam
->
exposure_count
=
1
;
}
}
else
{
/* just dark */
if
(
cam
->
exposure_status
==
EXPOSURE_DARK
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_DARK
;
cam
->
exposure_count
=
1
;
}
}
}
else
if
(
old_exposure
<=
LOW_EXP
||
exp_acc
>
light_exp
)
{
/* light */
if
(
old_exposure
<=
VERY_LOW_EXP
)
{
/* very light */
if
(
cam
->
exposure_status
==
EXPOSURE_VERY_LIGHT
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_VERY_LIGHT
;
cam
->
exposure_count
=
1
;
}
}
else
{
/* just light */
if
(
cam
->
exposure_status
==
EXPOSURE_LIGHT
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_LIGHT
;
cam
->
exposure_count
=
1
;
}
}
}
else
{
/* not dark or light */
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
}
}
else
{
/* Flicker control off */
if
(
old_exposure
>=
MAX_EXP
&&
exp_acc
<
dark_exp
)
{
/* dark */
if
(
exp_acc
<
very_dark_exp
)
{
/* very dark */
if
(
cam
->
exposure_status
==
EXPOSURE_VERY_DARK
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_VERY_DARK
;
cam
->
exposure_count
=
1
;
}
}
else
{
/* just dark */
if
(
cam
->
exposure_status
==
EXPOSURE_DARK
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_DARK
;
cam
->
exposure_count
=
1
;
}
}
}
else
if
(
old_exposure
<=
LOW_EXP
||
exp_acc
>
light_exp
)
{
/* light */
if
(
old_exposure
<=
VERY_LOW_EXP
)
{
/* very light */
if
(
cam
->
exposure_status
==
EXPOSURE_VERY_LIGHT
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_VERY_LIGHT
;
cam
->
exposure_count
=
1
;
}
}
else
{
/* just light */
if
(
cam
->
exposure_status
==
EXPOSURE_LIGHT
)
++
cam
->
exposure_count
;
else
{
cam
->
exposure_status
=
EXPOSURE_LIGHT
;
cam
->
exposure_count
=
1
;
}
}
}
else
{
/* not dark or light */
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
}
}
framerate
=
cam
->
fps
;
if
(
framerate
>
30
||
framerate
<
1
)
framerate
=
1
;
if
(
!
cam
->
params
.
flickerControl
.
disabled
)
{
/* Flicker control on */
if
((
cam
->
exposure_status
==
EXPOSURE_VERY_DARK
||
cam
->
exposure_status
==
EXPOSURE_DARK
)
&&
cam
->
exposure_count
>=
DARK_TIME
*
framerate
&&
cam
->
params
.
sensorFps
.
divisor
<
3
)
{
/* dark for too long */
++
cam
->
params
.
sensorFps
.
divisor
;
cam
->
cmd_queue
|=
COMMAND_SETSENSORFPS
;
cam
->
params
.
flickerControl
.
coarseJump
=
flicker_jumps
[
cam
->
mainsFreq
]
[
cam
->
params
.
sensorFps
.
baserate
]
[
cam
->
params
.
sensorFps
.
divisor
];
cam
->
cmd_queue
|=
COMMAND_SETFLICKERCTRL
;
new_exposure
=
cam
->
params
.
flickerControl
.
coarseJump
-
1
;
while
(
new_exposure
<
old_exposure
/
2
)
new_exposure
+=
cam
->
params
.
flickerControl
.
coarseJump
;
cam
->
params
.
exposure
.
coarseExpLo
=
new_exposure
&
0xff
;
cam
->
params
.
exposure
.
coarseExpHi
=
new_exposure
>>
8
;
cam
->
cmd_queue
|=
COMMAND_SETEXPOSURE
;
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
LOG
(
"Automatically decreasing sensor_fps
\n
"
);
}
else
if
((
cam
->
exposure_status
==
EXPOSURE_VERY_LIGHT
||
cam
->
exposure_status
==
EXPOSURE_LIGHT
)
&&
cam
->
exposure_count
>=
LIGHT_TIME
*
framerate
&&
cam
->
params
.
sensorFps
.
divisor
>
0
)
{
/* light for too long */
int
max_exp
=
FIRMWARE_VERSION
(
1
,
2
)
?
MAX_EXP_102
:
MAX_EXP
;
--
cam
->
params
.
sensorFps
.
divisor
;
cam
->
cmd_queue
|=
COMMAND_SETSENSORFPS
;
cam
->
params
.
flickerControl
.
coarseJump
=
flicker_jumps
[
cam
->
mainsFreq
]
[
cam
->
params
.
sensorFps
.
baserate
]
[
cam
->
params
.
sensorFps
.
divisor
];
cam
->
cmd_queue
|=
COMMAND_SETFLICKERCTRL
;
new_exposure
=
cam
->
params
.
flickerControl
.
coarseJump
-
1
;
while
(
new_exposure
<
2
*
old_exposure
&&
new_exposure
+
cam
->
params
.
flickerControl
.
coarseJump
<
max_exp
)
new_exposure
+=
cam
->
params
.
flickerControl
.
coarseJump
;
cam
->
params
.
exposure
.
coarseExpLo
=
new_exposure
&
0xff
;
cam
->
params
.
exposure
.
coarseExpHi
=
new_exposure
>>
8
;
cam
->
cmd_queue
|=
COMMAND_SETEXPOSURE
;
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
LOG
(
"Automatically increasing sensor_fps
\n
"
);
}
}
else
{
/* Flicker control off */
if
((
cam
->
exposure_status
==
EXPOSURE_VERY_DARK
||
cam
->
exposure_status
==
EXPOSURE_DARK
)
&&
cam
->
exposure_count
>=
DARK_TIME
*
framerate
&&
cam
->
params
.
sensorFps
.
divisor
<
3
)
{
/* dark for too long */
++
cam
->
params
.
sensorFps
.
divisor
;
cam
->
cmd_queue
|=
COMMAND_SETSENSORFPS
;
if
(
cam
->
params
.
exposure
.
gain
>
0
)
{
--
cam
->
params
.
exposure
.
gain
;
cam
->
cmd_queue
|=
COMMAND_SETEXPOSURE
;
}
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
LOG
(
"Automatically decreasing sensor_fps
\n
"
);
}
else
if
((
cam
->
exposure_status
==
EXPOSURE_VERY_LIGHT
||
cam
->
exposure_status
==
EXPOSURE_LIGHT
)
&&
cam
->
exposure_count
>=
LIGHT_TIME
*
framerate
&&
cam
->
params
.
sensorFps
.
divisor
>
0
)
{
/* light for too long */
--
cam
->
params
.
sensorFps
.
divisor
;
cam
->
cmd_queue
|=
COMMAND_SETSENSORFPS
;
if
(
cam
->
params
.
exposure
.
gain
<
cam
->
params
.
exposure
.
gainMode
-
1
)
{
++
cam
->
params
.
exposure
.
gain
;
cam
->
cmd_queue
|=
COMMAND_SETEXPOSURE
;
}
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
LOG
(
"Automatically increasing sensor_fps
\n
"
);
}
}
up
(
&
cam
->
param_lock
);
}
/*-----------------------------------------------------------------*/
/* if flicker is switched off, this function switches it back on.It checks,
however, that conditions are suitable before restarting it.
This should only be called for firmware version 1.2.
It also adjust the colour balance when an exposure step is detected - as
long as flicker is running
*/
static
void
restart_flicker
(
struct
cam_data
*
cam
)
{
int
cam_exposure
,
old_exp
;
if
(
!
FIRMWARE_VERSION
(
1
,
2
))
return
;
down
(
&
cam
->
param_lock
);
if
(
cam
->
params
.
flickerControl
.
flickerMode
==
0
||
cam
->
raw_image
[
39
]
==
0
)
{
up
(
&
cam
->
param_lock
);
return
;
}
cam_exposure
=
cam
->
raw_image
[
39
]
*
2
;
old_exp
=
cam
->
params
.
exposure
.
coarseExpLo
+
cam
->
params
.
exposure
.
coarseExpHi
*
256
;
/*
see how far away camera exposure is from a valid
flicker exposure value
*/
cam_exposure
%=
cam
->
params
.
flickerControl
.
coarseJump
;
if
(
!
cam
->
params
.
flickerControl
.
disabled
&&
cam_exposure
<=
cam
->
params
.
flickerControl
.
coarseJump
-
3
)
{
/* Flicker control auto-disabled */
cam
->
params
.
flickerControl
.
disabled
=
1
;
}
if
(
cam
->
params
.
flickerControl
.
disabled
&&
cam
->
params
.
flickerControl
.
flickerMode
&&
old_exp
>
cam
->
params
.
flickerControl
.
coarseJump
+
ROUND_UP_EXP_FOR_FLICKER
)
{
/* exposure is now high enough to switch
flicker control back on */
set_flicker
(
&
cam
->
params
,
&
cam
->
cmd_queue
,
1
);
if
((
cam
->
cmd_queue
&
COMMAND_SETEXPOSURE
)
&&
cam
->
params
.
exposure
.
expMode
==
2
)
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
}
up
(
&
cam
->
param_lock
);
}
#undef FIRMWARE_VERSION
static
int
clear_stall
(
struct
cam_data
*
cam
)
{
/* FIXME: Does this actually work? */
LOG
(
"Clearing stall
\n
"
);
cam
->
ops
->
streamRead
(
cam
->
lowlevel_data
,
cam
->
raw_image
,
0
);
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
);
return
cam
->
params
.
status
.
streamState
!=
STREAM_PAUSED
;
}
/* kernel thread function to read image from camera */
/* kernel thread function to read image from camera */
static
void
fetch_frame
(
void
*
data
)
static
int
fetch_frame
(
void
*
data
)
{
{
int
image_size
,
retry
;
int
image_size
,
retry
;
struct
cam_data
*
cam
=
(
struct
cam_data
*
)
data
;
struct
cam_data
*
cam
=
(
struct
cam_data
*
)
data
;
...
@@ -2179,41 +2832,54 @@ static void fetch_frame(void *data)
...
@@ -2179,41 +2832,54 @@ static void fetch_frame(void *data)
/* load first frame always uncompressed */
/* load first frame always uncompressed */
if
(
cam
->
first_frame
&&
if
(
cam
->
first_frame
&&
cam
->
params
.
compression
.
mode
!=
CPIA_COMPRESSION_NONE
)
cam
->
params
.
compression
.
mode
!=
CPIA_COMPRESSION_NONE
)
{
do_command
(
cam
,
CPIA_COMMAND_SetCompression
,
do_command
(
cam
,
CPIA_COMMAND_SetCompression
,
CPIA_COMPRESSION_NONE
,
CPIA_COMPRESSION_NONE
,
NO_DECIMATION
,
0
,
0
);
NO_DECIMATION
,
0
,
0
);
/* Trial & error - Discarding a frame prevents the
first frame from having an error in the data. */
do_command
(
cam
,
CPIA_COMMAND_DiscardFrame
,
0
,
0
,
0
,
0
);
}
/* init camera upload */
/* init camera upload */
if
(
do_command
(
cam
,
CPIA_COMMAND_SetGrabMode
,
CPIA_GRAB_CONTINUOUS
,
0
,
0
,
0
))
continue
;
if
(
do_command
(
cam
,
CPIA_COMMAND_GrabFrame
,
0
,
if
(
do_command
(
cam
,
CPIA_COMMAND_GrabFrame
,
0
,
cam
->
params
.
streamStartLine
,
0
,
0
))
cam
->
params
.
streamStartLine
,
0
,
0
))
continue
;
continue
;
if
(
cam
->
ops
->
wait_for_stream_ready
)
{
if
(
cam
->
ops
->
wait_for_stream_ready
)
{
/* loop until image ready */
/* loop until image ready */
int
count
=
0
;
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
);
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
);
while
(
cam
->
params
.
status
.
streamState
!=
STREAM_READY
)
{
while
(
cam
->
params
.
status
.
streamState
!=
STREAM_READY
)
{
if
(
++
count
>
READY_TIMEOUT
)
break
;
if
(
cam
->
params
.
status
.
streamState
==
STREAM_PAUSED
)
{
/* Bad news */
if
(
!
clear_stall
(
cam
))
return
-
EIO
;
}
cond_resched
();
cond_resched
();
/* sleep for 10 ms, hopefully ;) */
current
->
state
=
TASK_INTERRUPTIBLE
;
current
->
state
=
TASK_INTERRUPTIBLE
;
/* sleep for 10 ms, hopefully ;) */
schedule_timeout
(
10
*
HZ
/
1000
);
schedule_timeout
(
10
*
HZ
/
1000
);
if
(
signal_pending
(
current
))
if
(
signal_pending
(
current
))
return
;
return
-
EINTR
;
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
);
0
,
0
,
0
,
0
);
}
}
if
(
cam
->
params
.
status
.
streamState
!=
STREAM_READY
)
{
continue
;
}
}
}
/* grab image from camera */
cond_resched
();
cond_resched
();
/* grab image from camera */
oldjif
=
jiffies
;
oldjif
=
jiffies
;
image_size
=
cam
->
ops
->
streamRead
(
cam
->
lowlevel_data
,
image_size
=
cam
->
ops
->
streamRead
(
cam
->
lowlevel_data
,
cam
->
raw_image
,
0
);
cam
->
raw_image
,
0
);
...
@@ -2227,6 +2893,14 @@ static void fetch_frame(void *data)
...
@@ -2227,6 +2893,14 @@ static void fetch_frame(void *data)
cam
->
transfer_rate
=
diff
==
0
?
rate
:
rate
/
diff
;
cam
->
transfer_rate
=
diff
==
0
?
rate
:
rate
/
diff
;
/* diff==0 ? unlikely but possible */
/* diff==0 ? unlikely but possible */
/* Switch flicker control back on if it got turned off */
restart_flicker
(
cam
);
/* If AEC is enabled, monitor the exposure and
adjust the sensor frame rate if needed */
if
(
cam
->
params
.
exposure
.
expMode
==
2
)
monitor_exposure
(
cam
);
/* camera idle now so dispatch queued commands */
/* camera idle now so dispatch queued commands */
dispatch_commands
(
cam
);
dispatch_commands
(
cam
);
...
@@ -2238,12 +2912,28 @@ static void fetch_frame(void *data)
...
@@ -2238,12 +2912,28 @@ static void fetch_frame(void *data)
/* decompress and convert image to by copying it from
/* decompress and convert image to by copying it from
* raw_image to decompressed_frame
* raw_image to decompressed_frame
*/
*/
cond_resched
();
cond_resched
();
cam
->
image_size
=
parse_picture
(
cam
,
image_size
);
cam
->
image_size
=
parse_picture
(
cam
,
image_size
);
if
(
cam
->
image_size
<=
0
)
if
(
cam
->
image_size
<=
0
)
{
DBG
(
"parse_picture failed %d
\n
"
,
cam
->
image_size
);
DBG
(
"parse_picture failed %d
\n
"
,
cam
->
image_size
);
else
if
(
cam
->
params
.
compression
.
mode
!=
CPIA_COMPRESSION_NONE
)
{
/* Compression may not work right if we
had a bad frame, get the next one
uncompressed. */
cam
->
first_frame
=
1
;
do_command
(
cam
,
CPIA_COMMAND_SetGrabMode
,
CPIA_GRAB_SINGLE
,
0
,
0
,
0
);
/* FIXME: Trial & error - need up to 70ms for
the grab mode change to complete ? */
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
70
*
HZ
/
1000
);
if
(
signal_pending
(
current
))
return
-
EINTR
;
}
}
else
break
;
break
;
}
}
...
@@ -2257,66 +2947,51 @@ static void fetch_frame(void *data)
...
@@ -2257,66 +2947,51 @@ static void fetch_frame(void *data)
}
else
}
else
cam
->
decompressed_frame
.
state
=
FRAME_DONE
;
cam
->
decompressed_frame
.
state
=
FRAME_DONE
;
#if 0
if (cam->first_frame &&
cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
cam->first_frame = 0;
cam->cmd_queue |= COMMAND_SETCOMPRESSION;
}
#else
if
(
cam
->
first_frame
)
{
if
(
cam
->
first_frame
)
{
cam
->
first_frame
=
0
;
cam
->
first_frame
=
0
;
cam
->
cmd_queue
|=
COMMAND_SETCOMPRESSION
;
do_command
(
cam
,
CPIA_COMMAND_SetCompression
,
cam
->
cmd_queue
|=
COMMAND_SETEXPOSURE
;
cam
->
params
.
compression
.
mode
,
cam
->
params
.
compression
.
decimation
,
0
,
0
);
/* Switch from single-grab to continuous grab */
do_command
(
cam
,
CPIA_COMMAND_SetGrabMode
,
CPIA_GRAB_CONTINUOUS
,
0
,
0
,
0
);
}
}
#endif
return
0
;
}
}
return
-
EIO
;
}
}
static
int
capture_frame
(
struct
cam_data
*
cam
,
struct
video_mmap
*
vm
)
static
int
capture_frame
(
struct
cam_data
*
cam
,
struct
video_mmap
*
vm
)
{
{
int
retval
=
0
;
if
(
!
cam
->
frame_buf
)
{
if
(
!
cam
->
frame_buf
)
{
/* we do lazy allocation */
/* we do lazy allocation */
if
((
retval
=
allocate_frame_buf
(
cam
)))
int
err
;
return
retval
;
if
((
err
=
allocate_frame_buf
(
cam
)))
return
err
;
}
}
/* FIXME: the first frame seems to be captured by the camera
without regards to any initial settings, so we throw away
that one, the next one is generated with our settings
(exposure, color balance, ...)
*/
if
(
cam
->
first_frame
)
{
cam
->
curframe
=
vm
->
frame
;
cam
->
frame
[
cam
->
curframe
].
state
=
FRAME_READY
;
fetch_frame
(
cam
);
if
(
cam
->
frame
[
cam
->
curframe
].
state
!=
FRAME_DONE
)
retval
=
-
EIO
;
}
cam
->
curframe
=
vm
->
frame
;
cam
->
curframe
=
vm
->
frame
;
cam
->
frame
[
cam
->
curframe
].
state
=
FRAME_READY
;
cam
->
frame
[
cam
->
curframe
].
state
=
FRAME_READY
;
fetch_frame
(
cam
);
return
fetch_frame
(
cam
);
if
(
cam
->
frame
[
cam
->
curframe
].
state
!=
FRAME_DONE
)
retval
=-
EIO
;
return
retval
;
}
}
static
int
goto_high_power
(
struct
cam_data
*
cam
)
static
int
goto_high_power
(
struct
cam_data
*
cam
)
{
{
if
(
do_command
(
cam
,
CPIA_COMMAND_GotoHiPower
,
0
,
0
,
0
,
0
))
if
(
do_command
(
cam
,
CPIA_COMMAND_GotoHiPower
,
0
,
0
,
0
,
0
))
return
-
1
;
return
-
EIO
;
mdelay
(
100
);
/* windows driver does it too */
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
40
*
HZ
/
1000
);
/* windows driver does it too */
if
(
signal_pending
(
current
))
return
-
EINTR
;
if
(
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
))
if
(
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
))
return
-
1
;
return
-
EIO
;
if
(
cam
->
params
.
status
.
systemState
==
HI_POWER_STATE
)
{
if
(
cam
->
params
.
status
.
systemState
==
HI_POWER_STATE
)
{
DBG
(
"camera now in HIGH power state
\n
"
);
DBG
(
"camera now in HIGH power state
\n
"
);
return
0
;
return
0
;
}
}
printstatus
(
cam
);
printstatus
(
cam
);
return
-
1
;
return
-
EIO
;
}
}
static
int
goto_low_power
(
struct
cam_data
*
cam
)
static
int
goto_low_power
(
struct
cam_data
*
cam
)
...
@@ -2335,8 +3010,10 @@ static int goto_low_power(struct cam_data *cam)
...
@@ -2335,8 +3010,10 @@ static int goto_low_power(struct cam_data *cam)
static
void
save_camera_state
(
struct
cam_data
*
cam
)
static
void
save_camera_state
(
struct
cam_data
*
cam
)
{
{
do_command
(
cam
,
CPIA_COMMAND_GetColourBalance
,
0
,
0
,
0
,
0
);
if
(
!
(
cam
->
cmd_queue
&
COMMAND_SETCOLOURBALANCE
))
do_command
(
cam
,
CPIA_COMMAND_GetExposure
,
0
,
0
,
0
,
0
);
do_command
(
cam
,
CPIA_COMMAND_GetColourBalance
,
0
,
0
,
0
,
0
);
if
(
!
(
cam
->
cmd_queue
&
COMMAND_SETEXPOSURE
))
do_command
(
cam
,
CPIA_COMMAND_GetExposure
,
0
,
0
,
0
,
0
);
DBG
(
"%d/%d/%d/%d/%d/%d/%d/%d
\n
"
,
DBG
(
"%d/%d/%d/%d/%d/%d/%d/%d
\n
"
,
cam
->
params
.
exposure
.
gain
,
cam
->
params
.
exposure
.
gain
,
...
@@ -2353,44 +3030,8 @@ static void save_camera_state(struct cam_data *cam)
...
@@ -2353,44 +3030,8 @@ static void save_camera_state(struct cam_data *cam)
cam
->
params
.
colourBalance
.
blueGain
);
cam
->
params
.
colourBalance
.
blueGain
);
}
}
static
void
set_camera_state
(
struct
cam_data
*
cam
)
static
int
set_camera_state
(
struct
cam_data
*
cam
)
{
{
if
(
cam
->
params
.
colourBalance
.
balanceModeIsAuto
)
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
2
,
0
,
0
,
0
);
}
else
{
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
1
,
cam
->
params
.
colourBalance
.
redGain
,
cam
->
params
.
colourBalance
.
greenGain
,
cam
->
params
.
colourBalance
.
blueGain
);
do_command
(
cam
,
CPIA_COMMAND_SetColourBalance
,
3
,
0
,
0
,
0
);
}
do_command_extended
(
cam
,
CPIA_COMMAND_SetExposure
,
cam
->
params
.
exposure
.
gainMode
,
1
,
1
,
cam
->
params
.
exposure
.
centreWeight
,
cam
->
params
.
exposure
.
gain
,
cam
->
params
.
exposure
.
fineExp
,
cam
->
params
.
exposure
.
coarseExpLo
,
cam
->
params
.
exposure
.
coarseExpHi
,
cam
->
params
.
exposure
.
redComp
,
cam
->
params
.
exposure
.
green1Comp
,
cam
->
params
.
exposure
.
green2Comp
,
cam
->
params
.
exposure
.
blueComp
);
do_command_extended
(
cam
,
CPIA_COMMAND_SetExposure
,
0
,
3
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
if
(
!
cam
->
params
.
exposure
.
gainMode
)
cam
->
params
.
exposure
.
gainMode
=
2
;
if
(
!
cam
->
params
.
exposure
.
expMode
)
cam
->
params
.
exposure
.
expMode
=
2
;
if
(
!
cam
->
params
.
exposure
.
centreWeight
)
cam
->
params
.
exposure
.
centreWeight
=
1
;
cam
->
cmd_queue
=
COMMAND_SETCOMPRESSION
|
cam
->
cmd_queue
=
COMMAND_SETCOMPRESSION
|
COMMAND_SETCOMPRESSIONTARGET
|
COMMAND_SETCOMPRESSIONTARGET
|
COMMAND_SETCOLOURPARAMS
|
COMMAND_SETCOLOURPARAMS
|
...
@@ -2398,18 +3039,29 @@ static void set_camera_state(struct cam_data *cam)
...
@@ -2398,18 +3039,29 @@ static void set_camera_state(struct cam_data *cam)
COMMAND_SETYUVTHRESH
|
COMMAND_SETYUVTHRESH
|
COMMAND_SETECPTIMING
|
COMMAND_SETECPTIMING
|
COMMAND_SETCOMPRESSIONPARAMS
|
COMMAND_SETCOMPRESSIONPARAMS
|
#if 0
COMMAND_SETEXPOSURE
|
COMMAND_SETEXPOSURE
|
#endif
COMMAND_SETCOLOURBALANCE
|
COMMAND_SETCOLOURBALANCE
|
COMMAND_SETSENSORFPS
|
COMMAND_SETSENSORFPS
|
COMMAND_SETAPCOR
|
COMMAND_SETAPCOR
|
COMMAND_SETFLICKERCTRL
|
COMMAND_SETFLICKERCTRL
|
COMMAND_SETVLOFFSET
;
COMMAND_SETVLOFFSET
;
do_command
(
cam
,
CPIA_COMMAND_SetGrabMode
,
CPIA_GRAB_SINGLE
,
0
,
0
,
0
);
dispatch_commands
(
cam
);
dispatch_commands
(
cam
);
/* Wait 6 frames for the sensor to get all settings and
AEC/ACB to settle */
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
((
6
*
(
cam
->
params
.
sensorFps
.
baserate
?
33
:
40
)
*
(
1
<<
cam
->
params
.
sensorFps
.
divisor
)
+
10
)
*
HZ
/
1000
);
if
(
signal_pending
(
current
))
return
-
EINTR
;
save_camera_state
(
cam
);
save_camera_state
(
cam
);
return
;
return
0
;
}
}
static
void
get_version_information
(
struct
cam_data
*
cam
)
static
void
get_version_information
(
struct
cam_data
*
cam
)
...
@@ -2424,14 +3076,16 @@ static void get_version_information(struct cam_data *cam)
...
@@ -2424,14 +3076,16 @@ static void get_version_information(struct cam_data *cam)
/* initialize camera */
/* initialize camera */
static
int
reset_camera
(
struct
cam_data
*
cam
)
static
int
reset_camera
(
struct
cam_data
*
cam
)
{
{
int
err
;
/* Start the camera in low power mode */
/* Start the camera in low power mode */
if
(
goto_low_power
(
cam
))
{
if
(
goto_low_power
(
cam
))
{
if
(
cam
->
params
.
status
.
systemState
!=
WARM_BOOT_STATE
)
if
(
cam
->
params
.
status
.
systemState
!=
WARM_BOOT_STATE
)
return
-
ENODEV
;
return
-
ENODEV
;
/* FIXME: this is just dirty trial and error */
/* FIXME: this is just dirty trial and error */
reset_camera_struct
(
cam
);
err
=
goto_high_power
(
cam
);
goto_high_power
(
cam
);
if
(
err
)
return
err
;
do_command
(
cam
,
CPIA_COMMAND_DiscardFrame
,
0
,
0
,
0
,
0
);
do_command
(
cam
,
CPIA_COMMAND_DiscardFrame
,
0
,
0
,
0
,
0
);
if
(
goto_low_power
(
cam
))
if
(
goto_low_power
(
cam
))
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -2439,12 +3093,18 @@ static int reset_camera(struct cam_data *cam)
...
@@ -2439,12 +3093,18 @@ static int reset_camera(struct cam_data *cam)
/* procedure described in developer's guide p3-28 */
/* procedure described in developer's guide p3-28 */
/* Check the firmware version
FIXME: should we check PNPID?
*/
/* Check the firmware version
.
*/
cam
->
params
.
version
.
firmwareVersion
=
0
;
cam
->
params
.
version
.
firmwareVersion
=
0
;
get_version_information
(
cam
);
get_version_information
(
cam
);
if
(
cam
->
params
.
version
.
firmwareVersion
!=
1
)
if
(
cam
->
params
.
version
.
firmwareVersion
!=
1
)
return
-
ENODEV
;
return
-
ENODEV
;
/* A bug in firmware 1-02 limits gainMode to 2 */
if
(
cam
->
params
.
version
.
firmwareRevision
<=
2
&&
cam
->
params
.
exposure
.
gainMode
>
2
)
{
cam
->
params
.
exposure
.
gainMode
=
2
;
}
/* set QX3 detected flag */
/* set QX3 detected flag */
cam
->
params
.
qx3
.
qx3_detected
=
(
cam
->
params
.
pnpID
.
vendor
==
0x0813
&&
cam
->
params
.
qx3
.
qx3_detected
=
(
cam
->
params
.
pnpID
.
vendor
==
0x0813
&&
cam
->
params
.
pnpID
.
product
==
0x0001
);
cam
->
params
.
pnpID
.
product
==
0x0001
);
...
@@ -2458,8 +3118,9 @@ static int reset_camera(struct cam_data *cam)
...
@@ -2458,8 +3118,9 @@ static int reset_camera(struct cam_data *cam)
STREAM_NOT_READY
,
0
);
STREAM_NOT_READY
,
0
);
/* GotoHiPower */
/* GotoHiPower */
if
(
goto_high_power
(
cam
))
err
=
goto_high_power
(
cam
);
return
-
ENODEV
;
if
(
err
)
return
err
;
/* Check the camera status */
/* Check the camera status */
if
(
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
))
if
(
do_command
(
cam
,
CPIA_COMMAND_GetCameraStatus
,
0
,
0
,
0
,
0
))
...
@@ -2492,9 +3153,13 @@ static int reset_camera(struct cam_data *cam)
...
@@ -2492,9 +3153,13 @@ static int reset_camera(struct cam_data *cam)
do_command
(
cam
,
CPIA_COMMAND_GetVPVersion
,
0
,
0
,
0
,
0
);
do_command
(
cam
,
CPIA_COMMAND_GetVPVersion
,
0
,
0
,
0
,
0
);
/* set camera to a known state */
/* set camera to a known state */
set_camera_state
(
cam
);
return
set_camera_state
(
cam
);
}
return
0
;
static
void
put_cam
(
struct
cpia_camera_ops
*
ops
)
{
if
(
ops
->
owner
)
__MOD_DEC_USE_COUNT
(
ops
->
owner
);
}
}
/* ------------------------- V4L interface --------------------- */
/* ------------------------- V4L interface --------------------- */
...
@@ -2508,7 +3173,10 @@ static int cpia_open(struct inode *inode, struct file *file)
...
@@ -2508,7 +3173,10 @@ static int cpia_open(struct inode *inode, struct file *file)
DBG
(
"Internal error, cam_data not found!
\n
"
);
DBG
(
"Internal error, cam_data not found!
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
if
(
!
try_inc_mod_count
(
cam
->
ops
->
owner
))
return
-
ENODEV
;
down
(
&
cam
->
busy_lock
);
down
(
&
cam
->
busy_lock
);
err
=
-
EBUSY
;
err
=
-
EBUSY
;
if
(
cam
->
open_count
>
0
)
{
if
(
cam
->
open_count
>
0
)
{
...
@@ -2522,7 +3190,7 @@ static int cpia_open(struct inode *inode, struct file *file)
...
@@ -2522,7 +3190,7 @@ static int cpia_open(struct inode *inode, struct file *file)
if
(
!
cam
->
raw_image
)
if
(
!
cam
->
raw_image
)
goto
oops
;
goto
oops
;
}
}
if
(
!
cam
->
decompressed_frame
.
data
)
{
if
(
!
cam
->
decompressed_frame
.
data
)
{
cam
->
decompressed_frame
.
data
=
rvmalloc
(
CPIA_MAX_FRAME_SIZE
);
cam
->
decompressed_frame
.
data
=
rvmalloc
(
CPIA_MAX_FRAME_SIZE
);
if
(
!
cam
->
decompressed_frame
.
data
)
if
(
!
cam
->
decompressed_frame
.
data
)
...
@@ -2539,6 +3207,9 @@ static int cpia_open(struct inode *inode, struct file *file)
...
@@ -2539,6 +3207,9 @@ static int cpia_open(struct inode *inode, struct file *file)
cam
->
ops
->
close
(
cam
->
lowlevel_data
);
cam
->
ops
->
close
(
cam
->
lowlevel_data
);
goto
oops
;
goto
oops
;
}
}
if
(
signal_pending
(
current
))
return
-
EINTR
;
/* Set ownership of /proc/cpia/videoX to current user */
/* Set ownership of /proc/cpia/videoX to current user */
if
(
cam
->
proc_entry
)
if
(
cam
->
proc_entry
)
...
@@ -2552,6 +3223,7 @@ static int cpia_open(struct inode *inode, struct file *file)
...
@@ -2552,6 +3223,7 @@ static int cpia_open(struct inode *inode, struct file *file)
++
cam
->
open_count
;
++
cam
->
open_count
;
file
->
private_data
=
dev
;
file
->
private_data
=
dev
;
up
(
&
cam
->
busy_lock
);
return
0
;
return
0
;
oops:
oops:
...
@@ -2564,6 +3236,7 @@ static int cpia_open(struct inode *inode, struct file *file)
...
@@ -2564,6 +3236,7 @@ static int cpia_open(struct inode *inode, struct file *file)
cam
->
raw_image
=
NULL
;
cam
->
raw_image
=
NULL
;
}
}
up
(
&
cam
->
busy_lock
);
up
(
&
cam
->
busy_lock
);
put_cam
(
cam
->
ops
);
return
err
;
return
err
;
}
}
...
@@ -2591,6 +3264,8 @@ static int cpia_close(struct inode *inode, struct file *file)
...
@@ -2591,6 +3264,8 @@ static int cpia_close(struct inode *inode, struct file *file)
/* close cpia */
/* close cpia */
cam
->
ops
->
close
(
cam
->
lowlevel_data
);
cam
->
ops
->
close
(
cam
->
lowlevel_data
);
put_cam
(
cam
->
ops
);
}
}
if
(
--
cam
->
open_count
==
0
)
{
if
(
--
cam
->
open_count
==
0
)
{
...
@@ -2621,6 +3296,7 @@ static int cpia_read(struct file *file, char *buf,
...
@@ -2621,6 +3296,7 @@ static int cpia_read(struct file *file, char *buf,
{
{
struct
video_device
*
dev
=
file
->
private_data
;
struct
video_device
*
dev
=
file
->
private_data
;
struct
cam_data
*
cam
=
dev
->
priv
;
struct
cam_data
*
cam
=
dev
->
priv
;
int
err
;
/* make this _really_ smp and multithread-safe */
/* make this _really_ smp and multithread-safe */
if
(
down_interruptible
(
&
cam
->
busy_lock
))
if
(
down_interruptible
(
&
cam
->
busy_lock
))
...
@@ -2647,19 +3323,17 @@ static int cpia_read(struct file *file, char *buf,
...
@@ -2647,19 +3323,17 @@ static int cpia_read(struct file *file, char *buf,
/* upload frame */
/* upload frame */
cam
->
decompressed_frame
.
state
=
FRAME_READY
;
cam
->
decompressed_frame
.
state
=
FRAME_READY
;
cam
->
mmap_kludge
=
0
;
cam
->
mmap_kludge
=
0
;
fetch_frame
(
cam
);
if
((
err
=
fetch_frame
(
cam
))
!=
0
)
{
if
(
cam
->
decompressed_frame
.
state
!=
FRAME_DONE
)
{
DBG
(
"ERROR from fetch_frame: %d
\n
"
,
err
);
DBG
(
"upload failed %d/%d
\n
"
,
cam
->
decompressed_frame
.
count
,
cam
->
decompressed_frame
.
state
);
up
(
&
cam
->
busy_lock
);
up
(
&
cam
->
busy_lock
);
return
-
EIO
;
return
err
;
}
}
cam
->
decompressed_frame
.
state
=
FRAME_UNUSED
;
cam
->
decompressed_frame
.
state
=
FRAME_UNUSED
;
/* copy data to user space */
/* copy data to user space */
if
(
cam
->
decompressed_frame
.
count
>
count
)
{
if
(
cam
->
decompressed_frame
.
count
>
count
)
{
DBG
(
"count wrong: %d, %lu
\n
"
,
cam
->
decompressed_frame
.
count
,
DBG
(
"count wrong: %d, %lu
\n
"
,
cam
->
decompressed_frame
.
count
,
count
);
(
unsigned
long
)
count
);
up
(
&
cam
->
busy_lock
);
up
(
&
cam
->
busy_lock
);
return
-
EFAULT
;
return
-
EFAULT
;
}
}
...
@@ -2698,7 +3372,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2698,7 +3372,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
DBG
(
"VIDIOCGCAP
\n
"
);
DBG
(
"VIDIOCGCAP
\n
"
);
strcpy
(
b
->
name
,
"CPiA Camera"
);
strcpy
(
b
->
name
,
"CPiA Camera"
);
b
->
type
=
VID_TYPE_CAPTURE
;
b
->
type
=
VID_TYPE_CAPTURE
|
VID_TYPE_SUBCAPTURE
;
b
->
channels
=
1
;
b
->
channels
=
1
;
b
->
audios
=
0
;
b
->
audios
=
0
;
b
->
maxwidth
=
352
;
/* VIDEOSIZE_CIF */
b
->
maxwidth
=
352
;
/* VIDEOSIZE_CIF */
...
@@ -2754,8 +3428,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2754,8 +3428,8 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
DBG
(
"VIDIOCSPICT
\n
"
);
DBG
(
"VIDIOCSPICT
\n
"
);
/* check validity */
/* check validity */
DBG
(
"palette: %d
\n
"
,
vp
.
palette
);
DBG
(
"palette: %d
\n
"
,
vp
->
palette
);
DBG
(
"depth: %d
\n
"
,
vp
.
depth
);
DBG
(
"depth: %d
\n
"
,
vp
->
depth
);
if
(
!
valid_mode
(
vp
->
palette
,
vp
->
depth
))
{
if
(
!
valid_mode
(
vp
->
palette
,
vp
->
depth
))
{
retval
=
-
EINVAL
;
retval
=
-
EINVAL
;
break
;
break
;
...
@@ -2825,6 +3499,10 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2825,6 +3499,10 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
break
;
break
;
}
}
cam
->
video_size
=
video_size
;
cam
->
video_size
=
video_size
;
/* video size is changing, reset the subcapture area */
memset
(
&
cam
->
vc
,
0
,
sizeof
(
cam
->
vc
));
set_vw_size
(
cam
);
set_vw_size
(
cam
);
DBG
(
"%d / %d
\n
"
,
cam
->
vw
.
width
,
cam
->
vw
.
height
);
DBG
(
"%d / %d
\n
"
,
cam
->
vw
.
width
,
cam
->
vw
.
height
);
cam
->
cmd_queue
|=
COMMAND_SETFORMAT
;
cam
->
cmd_queue
|=
COMMAND_SETFORMAT
;
...
@@ -2904,6 +3582,10 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2904,6 +3582,10 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
}
}
if
(
video_size
!=
cam
->
video_size
)
{
if
(
video_size
!=
cam
->
video_size
)
{
cam
->
video_size
=
video_size
;
cam
->
video_size
=
video_size
;
/* video size is changing, reset the subcapture area */
memset
(
&
cam
->
vc
,
0
,
sizeof
(
cam
->
vc
));
set_vw_size
(
cam
);
set_vw_size
(
cam
);
cam
->
cmd_queue
|=
COMMAND_SETFORMAT
;
cam
->
cmd_queue
|=
COMMAND_SETFORMAT
;
dispatch_commands
(
cam
);
dispatch_commands
(
cam
);
...
@@ -2946,6 +3628,77 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2946,6 +3628,77 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
break
;
break
;
}
}
case
VIDIOCGCAPTURE
:
DBG
(
"VIDIOCGCAPTURE
\n
"
);
if
(
copy_to_user
(
arg
,
&
cam
->
vc
,
sizeof
(
struct
video_capture
)))
retval
=
-
EFAULT
;
break
;
case
VIDIOCSCAPTURE
:
{
struct
video_capture
vc
;
DBG
(
"VIDIOCSCAPTURE
\n
"
);
if
(
copy_from_user
(
&
vc
,
arg
,
sizeof
(
vc
)))
{
retval
=
-
EFAULT
;
break
;
}
if
(
vc
.
decimation
!=
0
)
{
/* How should this be used? */
retval
=
-
EINVAL
;
break
;
}
if
(
vc
.
flags
!=
0
)
{
/* Even/odd grab not supported */
retval
=
-
EINVAL
;
break
;
}
/* Clip to the resolution we can set for the ROI
(every 8 columns and 4 rows) */
vc
.
x
=
vc
.
x
&
~
(
__u32
)
7
;
vc
.
y
=
vc
.
y
&
~
(
__u32
)
3
;
vc
.
width
=
vc
.
width
&
~
(
__u32
)
7
;
vc
.
height
=
vc
.
height
&
~
(
__u32
)
3
;
if
(
vc
.
width
==
0
||
vc
.
height
==
0
||
vc
.
x
+
vc
.
width
>
cam
->
vw
.
width
||
vc
.
y
+
vc
.
height
>
cam
->
vw
.
height
)
{
retval
=
-
EINVAL
;
break
;
}
DBG
(
"%d,%d/%dx%d
\n
"
,
vc
.
x
,
vc
.
y
,
vc
.
width
,
vc
.
height
);
down
(
&
cam
->
param_lock
);
cam
->
vc
.
x
=
vc
.
x
;
cam
->
vc
.
y
=
vc
.
y
;
cam
->
vc
.
width
=
vc
.
width
;
cam
->
vc
.
height
=
vc
.
height
;
set_vw_size
(
cam
);
cam
->
cmd_queue
|=
COMMAND_SETFORMAT
;
up
(
&
cam
->
param_lock
);
/* setformat ignored by camera during streaming,
* so stop/dispatch/start */
dispatch_commands
(
cam
);
break
;
}
case
VIDIOCGUNIT
:
{
struct
video_unit
vu
;
vu
.
video
=
cam
->
vdev
.
minor
;
vu
.
vbi
=
VIDEO_NO_UNIT
;
vu
.
radio
=
VIDEO_NO_UNIT
;
vu
.
audio
=
VIDEO_NO_UNIT
;
vu
.
teletext
=
VIDEO_NO_UNIT
;
break
;
}
/* pointless to implement overlay with this camera */
/* pointless to implement overlay with this camera */
case
VIDIOCCAPTURE
:
case
VIDIOCCAPTURE
:
case
VIDIOCGFBUF
:
case
VIDIOCGFBUF
:
...
@@ -2966,7 +3719,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
...
@@ -2966,7 +3719,6 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
break
;
break
;
}
}
up
(
&
cam
->
param_lock
);
up
(
&
cam
->
busy_lock
);
up
(
&
cam
->
busy_lock
);
return
retval
;
return
retval
;
}
}
...
@@ -3057,7 +3809,7 @@ static void reset_camera_struct(struct cam_data *cam)
...
@@ -3057,7 +3809,7 @@ static void reset_camera_struct(struct cam_data *cam)
cam
->
params
.
colourParams
.
brightness
=
50
;
cam
->
params
.
colourParams
.
brightness
=
50
;
cam
->
params
.
colourParams
.
contrast
=
48
;
cam
->
params
.
colourParams
.
contrast
=
48
;
cam
->
params
.
colourParams
.
saturation
=
50
;
cam
->
params
.
colourParams
.
saturation
=
50
;
cam
->
params
.
exposure
.
gainMode
=
2
;
cam
->
params
.
exposure
.
gainMode
=
4
;
cam
->
params
.
exposure
.
expMode
=
2
;
/* AEC */
cam
->
params
.
exposure
.
expMode
=
2
;
/* AEC */
cam
->
params
.
exposure
.
compMode
=
1
;
cam
->
params
.
exposure
.
compMode
=
1
;
cam
->
params
.
exposure
.
centreWeight
=
1
;
cam
->
params
.
exposure
.
centreWeight
=
1
;
...
@@ -3065,27 +3817,31 @@ static void reset_camera_struct(struct cam_data *cam)
...
@@ -3065,27 +3817,31 @@ static void reset_camera_struct(struct cam_data *cam)
cam
->
params
.
exposure
.
fineExp
=
0
;
cam
->
params
.
exposure
.
fineExp
=
0
;
cam
->
params
.
exposure
.
coarseExpLo
=
185
;
cam
->
params
.
exposure
.
coarseExpLo
=
185
;
cam
->
params
.
exposure
.
coarseExpHi
=
0
;
cam
->
params
.
exposure
.
coarseExpHi
=
0
;
cam
->
params
.
exposure
.
redComp
=
220
;
cam
->
params
.
exposure
.
redComp
=
COMP_RED
;
cam
->
params
.
exposure
.
green1Comp
=
214
;
cam
->
params
.
exposure
.
green1Comp
=
COMP_GREEN1
;
cam
->
params
.
exposure
.
green2Comp
=
214
;
cam
->
params
.
exposure
.
green2Comp
=
COMP_GREEN2
;
cam
->
params
.
exposure
.
blueComp
=
230
;
cam
->
params
.
exposure
.
blueComp
=
COMP_BLUE
;
cam
->
params
.
colourBalance
.
balanceMode
IsAuto
=
1
;
cam
->
params
.
colourBalance
.
balanceMode
=
2
;
/* ACB */
cam
->
params
.
colourBalance
.
redGain
=
32
;
cam
->
params
.
colourBalance
.
redGain
=
32
;
cam
->
params
.
colourBalance
.
greenGain
=
6
;
cam
->
params
.
colourBalance
.
greenGain
=
6
;
cam
->
params
.
colourBalance
.
blueGain
=
92
;
cam
->
params
.
colourBalance
.
blueGain
=
92
;
cam
->
params
.
apcor
.
gain1
=
0x1
c
;
cam
->
params
.
apcor
.
gain1
=
0x1
8
;
cam
->
params
.
apcor
.
gain2
=
0x1
a
;
cam
->
params
.
apcor
.
gain2
=
0x1
6
;
cam
->
params
.
apcor
.
gain4
=
0x2
d
;
cam
->
params
.
apcor
.
gain4
=
0x2
4
;
cam
->
params
.
apcor
.
gain8
=
0x
2a
;
cam
->
params
.
apcor
.
gain8
=
0x
34
;
cam
->
params
.
flickerControl
.
flickerMode
=
0
;
cam
->
params
.
flickerControl
.
flickerMode
=
0
;
cam
->
params
.
flickerControl
.
disabled
=
1
;
cam
->
params
.
flickerControl
.
coarseJump
=
cam
->
params
.
flickerControl
.
coarseJump
=
flicker_jumps
[
cam
->
mainsFreq
]
flicker_jumps
[
cam
->
mainsFreq
]
[
cam
->
params
.
sensorFps
.
baserate
]
[
cam
->
params
.
sensorFps
.
baserate
]
[
cam
->
params
.
sensorFps
.
divisor
];
[
cam
->
params
.
sensorFps
.
divisor
];
cam
->
params
.
vlOffset
.
gain1
=
24
;
cam
->
params
.
flickerControl
.
allowableOverExposure
=
cam
->
params
.
vlOffset
.
gain2
=
28
;
-
find_over_exposure
(
cam
->
params
.
colourParams
.
brightness
);
cam
->
params
.
vlOffset
.
gain4
=
30
;
cam
->
params
.
vlOffset
.
gain1
=
20
;
cam
->
params
.
vlOffset
.
gain8
=
30
;
cam
->
params
.
vlOffset
.
gain2
=
24
;
cam
->
params
.
vlOffset
.
gain4
=
26
;
cam
->
params
.
vlOffset
.
gain8
=
26
;
cam
->
params
.
compressionParams
.
hysteresis
=
3
;
cam
->
params
.
compressionParams
.
hysteresis
=
3
;
cam
->
params
.
compressionParams
.
threshMax
=
11
;
cam
->
params
.
compressionParams
.
threshMax
=
11
;
cam
->
params
.
compressionParams
.
smallStep
=
1
;
cam
->
params
.
compressionParams
.
smallStep
=
1
;
...
@@ -3097,6 +3853,7 @@ static void reset_camera_struct(struct cam_data *cam)
...
@@ -3097,6 +3853,7 @@ static void reset_camera_struct(struct cam_data *cam)
/* End of default values from Software Developer's Guide */
/* End of default values from Software Developer's Guide */
cam
->
transfer_rate
=
0
;
cam
->
transfer_rate
=
0
;
cam
->
exposure_status
=
EXPOSURE_NORMAL
;
/* Set Sensor FPS to 15fps. This seems better than 30fps
/* Set Sensor FPS to 15fps. This seems better than 30fps
* for indoor lighting. */
* for indoor lighting. */
...
@@ -3131,17 +3888,21 @@ static void reset_camera_struct(struct cam_data *cam)
...
@@ -3131,17 +3888,21 @@ static void reset_camera_struct(struct cam_data *cam)
cam
->
vp
.
depth
=
24
;
/* to be set by user */
cam
->
vp
.
depth
=
24
;
/* to be set by user */
cam
->
vp
.
palette
=
VIDEO_PALETTE_RGB24
;
/* to be set by user */
cam
->
vp
.
palette
=
VIDEO_PALETTE_RGB24
;
/* to be set by user */
cam
->
vc
.
x
=
0
;
cam
->
vc
.
y
=
0
;
cam
->
vc
.
width
=
0
;
cam
->
vc
.
height
=
0
;
cam
->
vw
.
x
=
0
;
cam
->
vw
.
x
=
0
;
cam
->
vw
.
y
=
0
;
cam
->
vw
.
y
=
0
;
set_vw_size
(
cam
);
set_vw_size
(
cam
);
cam
->
vw
.
chromakey
=
0
;
cam
->
vw
.
chromakey
=
0
;
/* PP NOTE: my extension to use vw.flags for this, bear it! */
cam
->
vw
.
flags
=
0
;
cam
->
vw
.
flags
=
0
;
cam
->
vw
.
clipcount
=
0
;
cam
->
vw
.
clipcount
=
0
;
cam
->
vw
.
clips
=
NULL
;
cam
->
vw
.
clips
=
NULL
;
cam
->
cmd_queue
=
COMMAND_NONE
;
cam
->
cmd_queue
=
COMMAND_NONE
;
cam
->
first_frame
=
0
;
cam
->
first_frame
=
1
;
return
;
return
;
}
}
...
...
drivers/media/video/cpia.h
View file @
002b40d8
...
@@ -26,13 +26,13 @@
...
@@ -26,13 +26,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#define CPIA_MAJ_VER
0
#define CPIA_MAJ_VER
1
#define CPIA_MIN_VER
8
#define CPIA_MIN_VER
2
#define CPIA_PATCH_VER
1
#define CPIA_PATCH_VER
2
#define CPIA_PP_MAJ_VER
0
#define CPIA_PP_MAJ_VER
1
#define CPIA_PP_MIN_VER
8
#define CPIA_PP_MIN_VER
2
#define CPIA_PP_PATCH_VER
1
#define CPIA_PP_PATCH_VER
2
#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4)
/* CIF at RGB32 */
#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4)
/* CIF at RGB32 */
#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
/* align above to PAGE_SIZE */
#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
/* align above to PAGE_SIZE */
...
@@ -93,6 +93,11 @@ struct cpia_camera_ops
...
@@ -93,6 +93,11 @@ struct cpia_camera_ops
* is STREAM_READY before calling streamRead.
* is STREAM_READY before calling streamRead.
*/
*/
int
wait_for_stream_ready
;
int
wait_for_stream_ready
;
/*
* Used to maintain lowlevel module usage counts
*/
struct
module
*
owner
;
};
};
struct
cpia_frame
{
struct
cpia_frame
{
...
@@ -150,7 +155,7 @@ struct cam_params {
...
@@ -150,7 +155,7 @@ struct cam_params {
u8
blueComp
;
u8
blueComp
;
}
exposure
;
}
exposure
;
struct
{
struct
{
u8
balanceMode
IsAuto
;
u8
balanceMode
;
u8
redGain
;
u8
redGain
;
u8
greenGain
;
u8
greenGain
;
u8
blueGain
;
u8
blueGain
;
...
@@ -166,9 +171,10 @@ struct cam_params {
...
@@ -166,9 +171,10 @@ struct cam_params {
u8
gain8
;
u8
gain8
;
}
apcor
;
}
apcor
;
struct
{
struct
{
u8
disabled
;
u8
flickerMode
;
u8
flickerMode
;
u8
coarseJump
;
u8
coarseJump
;
u8
allowableOverExposure
;
int
allowableOverExposure
;
}
flickerControl
;
}
flickerControl
;
struct
{
struct
{
u8
gain1
;
u8
gain1
;
...
@@ -261,6 +267,7 @@ struct cam_data {
...
@@ -261,6 +267,7 @@ struct cam_data {
struct
video_device
vdev
;
/* v4l videodev */
struct
video_device
vdev
;
/* v4l videodev */
struct
video_picture
vp
;
/* v4l camera settings */
struct
video_picture
vp
;
/* v4l camera settings */
struct
video_window
vw
;
/* v4l capture area */
struct
video_window
vw
;
/* v4l capture area */
struct
video_capture
vc
;
/* v4l subcapture area */
/* mmap interface */
/* mmap interface */
int
curframe
;
/* the current frame to grab into */
int
curframe
;
/* the current frame to grab into */
...
@@ -271,6 +278,8 @@ struct cam_data {
...
@@ -271,6 +278,8 @@ struct cam_data {
int
first_frame
;
int
first_frame
;
int
mmap_kludge
;
/* 'wrong' byte order for mmap */
int
mmap_kludge
;
/* 'wrong' byte order for mmap */
volatile
u32
cmd_queue
;
/* queued commands */
volatile
u32
cmd_queue
;
/* queued commands */
int
exposure_status
;
/* EXPOSURE_* */
int
exposure_count
;
/* number of frames at this status */
};
};
/* cpia_register_camera is called by low level driver for each camera.
/* cpia_register_camera is called by low level driver for each camera.
...
@@ -382,15 +391,27 @@ void cpia_unregister_camera(struct cam_data *cam);
...
@@ -382,15 +391,27 @@ void cpia_unregister_camera(struct cam_data *cam);
#define VP_STATE_ACB_RMAX 0x40
#define VP_STATE_ACB_RMAX 0x40
#define VP_STATE_ACB_GMAX 0x80
#define VP_STATE_ACB_GMAX 0x80
/* default (minimum) compensation values */
#define COMP_RED 220
#define COMP_GREEN1 214
#define COMP_GREEN2 COMP_GREEN1
#define COMP_BLUE 230
/* exposure status */
#define EXPOSURE_VERY_LIGHT 0
#define EXPOSURE_LIGHT 1
#define EXPOSURE_NORMAL 2
#define EXPOSURE_DARK 3
#define EXPOSURE_VERY_DARK 4
/* ErrorCode */
/* ErrorCode */
#define ERROR_FLICKER_BELOW_MIN_EXP 0x01
/*flicker exposure got below minimum exposure */
#define ERROR_FLICKER_BELOW_MIN_EXP 0x01
/*flicker exposure got below minimum exposure */
#define ALOG(fmt,args...) printk(fmt, ##args)
#define ALOG(fmt,args...) printk(fmt, ##args)
#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args)
#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args)
#ifdef _CPIA_DEBUG_
#ifdef _CPIA_DEBUG_
#define ADBG(
lineno,fmt,args...) printk(fmt, jiffies, lineno
, ##args)
#define ADBG(
fmt,args...) printk(fmt, jiffies
, ##args)
#define DBG(fmt,args...) ADBG(
(__LINE__), KERN_DEBUG __FILE__" (%ld):" __FUNCTION__ "(%d):" fmt
, ##args)
#define DBG(fmt,args...) ADBG(
KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __FUNCTION__, __LINE__
, ##args)
#else
#else
#define DBG(fmn,args...) do {} while(0)
#define DBG(fmn,args...) do {} while(0)
#endif
#endif
...
@@ -400,15 +421,19 @@ void cpia_unregister_camera(struct cam_data *cam);
...
@@ -400,15 +421,19 @@ void cpia_unregister_camera(struct cam_data *cam);
(p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
(p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
(p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
(p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
static
inline
void
cpia_add_to_list
(
struct
cam_data
*
l
,
struct
cam_data
*
drv
)
static
inline
void
cpia_add_to_list
(
struct
cam_data
*
*
l
,
struct
cam_data
**
drv_p
)
{
{
drv
->
next
=
l
;
struct
cam_data
*
drv
;
drv
->
previous
=
&
l
;
drv
=
*
drv_p
;
l
=
drv
;
drv
->
next
=
*
l
;
drv
->
previous
=
l
;
*
l
=
drv
;
}
}
static
inline
void
cpia_remove_from_list
(
struct
cam_data
*
drv
)
static
inline
void
cpia_remove_from_list
(
struct
cam_data
*
*
drv_p
)
{
{
struct
cam_data
*
drv
;
drv
=
*
drv_p
;
if
(
drv
->
previous
!=
NULL
)
{
if
(
drv
->
previous
!=
NULL
)
{
if
(
drv
->
next
!=
NULL
)
if
(
drv
->
next
!=
NULL
)
drv
->
next
->
previous
=
drv
->
previous
;
drv
->
next
->
previous
=
drv
->
previous
;
...
...
drivers/media/video/cpia_pp.c
View file @
002b40d8
...
@@ -157,7 +157,8 @@ static struct cpia_camera_ops cpia_pp_ops =
...
@@ -157,7 +157,8 @@ static struct cpia_camera_ops cpia_pp_ops =
cpia_pp_streamStop
,
cpia_pp_streamStop
,
cpia_pp_streamRead
,
cpia_pp_streamRead
,
cpia_pp_close
,
cpia_pp_close
,
1
1
,
THIS_MODULE
};
};
static
struct
cam_data
*
cam_list
;
static
struct
cam_data
*
cam_list
;
...
@@ -565,7 +566,7 @@ static int cpia_pp_register(struct parport *port)
...
@@ -565,7 +566,7 @@ static int cpia_pp_register(struct parport *port)
return
-
ENXIO
;
return
-
ENXIO
;
}
}
spin_lock
(
&
cam_list_lock_pp
);
spin_lock
(
&
cam_list_lock_pp
);
cpia_add_to_list
(
cam_list
,
cpia
);
cpia_add_to_list
(
&
cam_list
,
&
cpia
);
spin_unlock
(
&
cam_list_lock_pp
);
spin_unlock
(
&
cam_list_lock_pp
);
return
0
;
return
0
;
...
@@ -575,11 +576,11 @@ static void cpia_pp_detach (struct parport *port)
...
@@ -575,11 +576,11 @@ static void cpia_pp_detach (struct parport *port)
{
{
struct
cam_data
*
cpia
;
struct
cam_data
*
cpia
;
spin_lock
(
&
cam_list_lock_pp
);
for
(
cpia
=
cam_list
;
cpia
!=
NULL
;
cpia
=
cpia
->
next
)
{
for
(
cpia
=
cam_list
;
cpia
!=
NULL
;
cpia
=
cpia
->
next
)
{
struct
pp_cam_entry
*
cam
=
cpia
->
lowlevel_data
;
struct
pp_cam_entry
*
cam
=
cpia
->
lowlevel_data
;
if
(
cam
&&
cam
->
port
->
number
==
port
->
number
)
{
if
(
cam
&&
cam
->
port
->
number
==
port
->
number
)
{
cpia_remove_from_list
(
cpia
);
spin_lock
(
&
cam_list_lock_pp
);
cpia_remove_from_list
(
&
cpia
);
spin_unlock
(
&
cam_list_lock_pp
);
spin_unlock
(
&
cam_list_lock_pp
);
cpia_unregister_camera
(
cpia
);
cpia_unregister_camera
(
cpia
);
...
...
drivers/media/video/cpia_usb.c
View file @
002b40d8
...
@@ -100,7 +100,8 @@ static struct cpia_camera_ops cpia_usb_ops = {
...
@@ -100,7 +100,8 @@ static struct cpia_camera_ops cpia_usb_ops = {
cpia_usb_streamStop
,
cpia_usb_streamStop
,
cpia_usb_streamRead
,
cpia_usb_streamRead
,
cpia_usb_close
,
cpia_usb_close
,
0
0
,
THIS_MODULE
};
};
static
struct
cam_data
*
cam_list
;
static
struct
cam_data
*
cam_list
;
...
@@ -548,7 +549,7 @@ static int cpia_probe(struct usb_interface *intf,
...
@@ -548,7 +549,7 @@ static int cpia_probe(struct usb_interface *intf,
}
}
spin_lock
(
&
cam_list_lock_usb
);
spin_lock
(
&
cam_list_lock_usb
);
cpia_add_to_list
(
cam_list
,
cam
);
cpia_add_to_list
(
&
cam_list
,
&
cam
);
spin_unlock
(
&
cam_list_lock_usb
);
spin_unlock
(
&
cam_list_lock_usb
);
dev_set_drvdata
(
&
intf
->
dev
,
cam
);
dev_set_drvdata
(
&
intf
->
dev
,
cam
);
...
@@ -602,7 +603,7 @@ static void cpia_disconnect(struct usb_interface *intf)
...
@@ -602,7 +603,7 @@ static void cpia_disconnect(struct usb_interface *intf)
ucpia
=
(
struct
usb_cpia
*
)
cam
->
lowlevel_data
;
ucpia
=
(
struct
usb_cpia
*
)
cam
->
lowlevel_data
;
spin_lock
(
&
cam_list_lock_usb
);
spin_lock
(
&
cam_list_lock_usb
);
cpia_remove_from_list
(
cam
);
cpia_remove_from_list
(
&
cam
);
spin_unlock
(
&
cam_list_lock_usb
);
spin_unlock
(
&
cam_list_lock_usb
);
/* Don't even try to reset the altsetting if we're disconnected */
/* Don't even try to reset the altsetting if we're disconnected */
...
...
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