1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
#ifndef __LINUX_se401_H
#define __LINUX_se401_H
#include <asm/uaccess.h>
#include "compat.h"
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/smp_lock.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#include <linux/mutex.h>
#endif
#define se401_DEBUG /* Turn on debug messages */
#ifdef se401_DEBUG
# define PDEBUG(level, fmt, args...) \
if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
#else
# define PDEBUG(level, fmt, args...) do {} while(0)
#endif
/* An almost drop-in replacement for sleep_on_interruptible */
#define wait_interruptible(test, queue, wait) \
{ \
add_wait_queue(queue, wait); \
set_current_state(TASK_INTERRUPTIBLE); \
if (test) \
schedule(); \
remove_wait_queue(queue, wait); \
set_current_state(TASK_RUNNING); \
if (signal_pending(current)) \
break; \
}
#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
#define SE401_REQ_CAPTURE_FRAME 0x43
#define SE401_REQ_GET_BRT 0x44
#define SE401_REQ_SET_BRT 0x45
#define SE401_REQ_GET_WIDTH 0x4c
#define SE401_REQ_SET_WIDTH 0x4d
#define SE401_REQ_GET_HEIGHT 0x4e
#define SE401_REQ_SET_HEIGHT 0x4f
#define SE401_REQ_GET_OUTPUT_MODE 0x50
#define SE401_REQ_SET_OUTPUT_MODE 0x51
#define SE401_REQ_GET_EXT_FEATURE 0x52
#define SE401_REQ_SET_EXT_FEATURE 0x53
#define SE401_REQ_CAMERA_POWER 0x56
#define SE401_REQ_LED_CONTROL 0x57
#define SE401_REQ_BIOS 0xff
#define SE401_BIOS_READ 0x07
#define SE401_FORMAT_BAYER 0x40
/* Hyundai hv7131b registers
7121 and 7141 should be the same (haven't really checked...) */
/* Mode registers: */
#define HV7131_REG_MODE_A 0x00
#define HV7131_REG_MODE_B 0x01
#define HV7131_REG_MODE_C 0x02
/* Frame registers: */
#define HV7131_REG_FRSU 0x10
#define HV7131_REG_FRSL 0x11
#define HV7131_REG_FCSU 0x12
#define HV7131_REG_FCSL 0x13
#define HV7131_REG_FWHU 0x14
#define HV7131_REG_FWHL 0x15
#define HV7131_REG_FWWU 0x16
#define HV7131_REG_FWWL 0x17
/* Timing registers: */
#define HV7131_REG_THBU 0x20
#define HV7131_REG_THBL 0x21
#define HV7131_REG_TVBU 0x22
#define HV7131_REG_TVBL 0x23
#define HV7131_REG_TITU 0x25
#define HV7131_REG_TITM 0x26
#define HV7131_REG_TITL 0x27
#define HV7131_REG_TMCD 0x28
/* Adjust Registers: */
#define HV7131_REG_ARLV 0x30
#define HV7131_REG_ARCG 0x31
#define HV7131_REG_AGCG 0x32
#define HV7131_REG_ABCG 0x33
#define HV7131_REG_APBV 0x34
#define HV7131_REG_ASLP 0x54
/* Offset Registers: */
#define HV7131_REG_OFSR 0x50
#define HV7131_REG_OFSG 0x51
#define HV7131_REG_OFSB 0x52
/* REset level statistics registers: */
#define HV7131_REG_LOREFNOH 0x57
#define HV7131_REG_LOREFNOL 0x58
#define HV7131_REG_HIREFNOH 0x59
#define HV7131_REG_HIREFNOL 0x5a
/* se401 registers */
#define SE401_OPERATINGMODE 0x2000
/* size of usb transfers */
#define SE401_PACKETSIZE 4096
/* number of queued bulk transfers to use, should be about 8 */
#define SE401_NUMSBUF 1
/* read the usb specs for this one :) */
#define SE401_VIDEO_ENDPOINT 1
#define SE401_BUTTON_ENDPOINT 2
/* number of frames supported by the v4l part */
#define SE401_NUMFRAMES 2
/* scratch buffers for passing data to the decoders */
#define SE401_NUMSCRATCH 32
/* maximum amount of data in a JangGu packet */
#define SE401_VLCDATALEN 1024
/* number of nul sized packets to receive before kicking the camera */
#define SE401_MAX_NULLPACKETS 4000
/* number of decoding errors before kicking the camera */
#define SE401_MAX_ERRORS 200
struct usb_device;
struct se401_sbuf {
unsigned char *data;
};
enum {
FRAME_UNUSED, /* Unused (no MCAPTURE) */
FRAME_READY, /* Ready to start grabbing */
FRAME_GRABBING, /* In the process of being grabbed into */
FRAME_DONE, /* Finished grabbing, but not been synced yet */
FRAME_ERROR, /* Something bad happened while processing */
};
enum {
FMT_BAYER,
FMT_JANGGU,
};
enum {
BUFFER_UNUSED,
BUFFER_READY,
BUFFER_BUSY,
BUFFER_DONE,
};
struct se401_scratch {
unsigned char *data;
volatile int state;
int offset;
int length;
};
struct se401_frame {
unsigned char *data; /* Frame buffer */
volatile int grabstate; /* State of grabbing */
unsigned char *curline;
int curlinepix;
int curpix;
};
struct usb_se401 {
struct video_device vdev;
/* Device structure */
struct usb_device *dev;
unsigned char iface;
char *camera_name;
int change;
int brightness;
int hue;
int rgain;
int ggain;
int bgain;
int expose_h;
int expose_m;
int expose_l;
int resetlevel;
int enhance;
int format;
int sizes;
int *width;
int *height;
int cwidth; /* current width */
int cheight; /* current height */
int palette;
int maxframesize;
int cframesize; /* current framesize */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
struct mutex lock;
#else
struct semaphore lock;
#endif
int user; /* user count for exclusive use */
int removed; /* device disconnected */
int streaming; /* Are we streaming video? */
char *fbuf; /* Videodev buffer area */
struct urb *urb[SE401_NUMSBUF];
struct urb *inturb;
int button;
int buttonpressed;
int curframe; /* Current receiving frame */
struct se401_frame frame[SE401_NUMFRAMES];
int readcount;
int framecount;
int error;
int dropped;
int scratch_next;
int scratch_use;
int scratch_overflow;
struct se401_scratch scratch[SE401_NUMSCRATCH];
/* Decoder specific data: */
unsigned char vlcdata[SE401_VLCDATALEN];
int vlcdatapos;
int bayeroffset;
struct se401_sbuf sbuf[SE401_NUMSBUF];
wait_queue_head_t wq; /* Processes waiting */
int nullpackets;
};
#endif
|