diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-06-30 14:50:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:14:49 -0400 |
commit | 6a7eba24e4f0ff725d33159f6265e3a79d53a833 (patch) | |
tree | 3e50d669cb91affbcfad9333d74ddc452783094f /drivers/media/video/gspca/gspca.c | |
parent | d43fa32fec442571f10f5d0c3b553413288728de (diff) |
V4L/DVB (8157): gspca: all subdrivers
- remaning subdrivers added
- remove the decoding helper and some specific frame decodings
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 579 |
1 files changed, 120 insertions, 459 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 423ebbdc4b4f..5583c53e4863 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -35,24 +35,24 @@ | |||
35 | 35 | ||
36 | #include "gspca.h" | 36 | #include "gspca.h" |
37 | 37 | ||
38 | /* option */ | 38 | #undef CONFIG_VIDEO_V4L1_COMPAT |
39 | #define GSPCA_HLP 0 | ||
40 | 39 | ||
41 | /* global values */ | 40 | /* global values */ |
42 | #define DEF_NURBS 2 /* default number of URBs (mmap) */ | 41 | #define DEF_NURBS 2 /* default number of URBs (mmap) */ |
42 | #define USR_NURBS 5 /* default number of URBs (userptr) */ | ||
43 | 43 | ||
44 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | 44 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); |
45 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 45 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
47 | 47 | ||
48 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) | 48 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) |
49 | static const char version[] = "0.2.15"; | 49 | static const char version[] = "2.1.0"; |
50 | 50 | ||
51 | static int video_nr = -1; | 51 | static int video_nr = -1; |
52 | 52 | ||
53 | static int comp_fac = 30; /* Buffer size ratio when compressed in % */ | 53 | static int comp_fac = 30; /* Buffer size ratio when compressed in % */ |
54 | 54 | ||
55 | #ifdef GSPCA_DEBUG | 55 | #ifdef VIDEO_ADV_DEBUG |
56 | int gspca_debug = D_ERR | D_PROBE; | 56 | int gspca_debug = D_ERR | D_PROBE; |
57 | EXPORT_SYMBOL(gspca_debug); | 57 | EXPORT_SYMBOL(gspca_debug); |
58 | 58 | ||
@@ -81,224 +81,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) | |||
81 | #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ | 81 | #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ |
82 | #define GSPCA_MEMORY_READ 7 | 82 | #define GSPCA_MEMORY_READ 7 |
83 | 83 | ||
84 | #ifndef GSPCA_HLP | ||
85 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) | 84 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) |
86 | #else | ||
87 | #define GSPCA_BUF_FLAG_DECODE 0x1000 /* internal buffer flag */ | ||
88 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE \ | ||
89 | | GSPCA_BUF_FLAG_DECODE) | ||
90 | |||
91 | static int autostart = 4; | ||
92 | module_param(autostart, int, 0644); | ||
93 | MODULE_PARM_DESC(autostart, | ||
94 | "Automatically start the helper process"); | ||
95 | |||
96 | /* try to start the helper process */ | ||
97 | static void start_hlp(void) | ||
98 | { | ||
99 | int ret; | ||
100 | static char *argv[] = {"gspca_hlp", NULL}; | ||
101 | static char *env[] = {NULL}; | ||
102 | |||
103 | if (autostart <= 0) { | ||
104 | if (autostart < 0) | ||
105 | PDEBUG(D_ERR|D_PROBE, "Too many helper restart"); | ||
106 | return; | ||
107 | } | ||
108 | autostart--; | ||
109 | if (autostart == 0) | ||
110 | autostart = -1; | ||
111 | ret = call_usermodehelper("/sbin/gspca_hlp", argv, env, | ||
112 | UMH_WAIT_EXEC); | ||
113 | if (ret != 0) | ||
114 | PDEBUG(D_ERR|D_PROBE, | ||
115 | "/sbin/gspca_hlp start failed %d", ret); | ||
116 | } | ||
117 | |||
118 | /* /dev/gspca_hlp stuff */ | ||
119 | #include <linux/miscdevice.h> | ||
120 | #include "gspca_hlp.h" | ||
121 | |||
122 | /* !! possible decodings defined in decoder.c */ | ||
123 | static __u32 bayer_to_tb[] = { | ||
124 | V4L2_PIX_FMT_SBGGR8, | ||
125 | V4L2_PIX_FMT_YUYV, | ||
126 | V4L2_PIX_FMT_YUV420, | ||
127 | V4L2_PIX_FMT_RGB24, | ||
128 | V4L2_PIX_FMT_BGR24, | ||
129 | V4L2_PIX_FMT_RGB565, | ||
130 | }; | ||
131 | static __u32 jpeg_to_tb[] = { | ||
132 | V4L2_PIX_FMT_JPEG, | ||
133 | V4L2_PIX_FMT_YUYV, | ||
134 | V4L2_PIX_FMT_YUV420, | ||
135 | V4L2_PIX_FMT_RGB24, | ||
136 | V4L2_PIX_FMT_BGR24, | ||
137 | V4L2_PIX_FMT_RGB565, | ||
138 | }; | ||
139 | |||
140 | /* /dev/gspca_hlp device */ | ||
141 | struct hlp_dev { | ||
142 | struct gspca_dev *gspca_dev; /* associated device */ | ||
143 | struct gspca_frame *frame; /* frame being decoded */ | ||
144 | __u32 pixfmt; /* webcam pixel format */ | ||
145 | atomic_t nevent; /* nb of frames ready to decode */ | ||
146 | wait_queue_head_t wq; /* wait queue */ | ||
147 | char fr_d; /* next frame to decode */ | ||
148 | } *hlp; | ||
149 | |||
150 | static int hlp_open(struct inode *inode, struct file *file) | ||
151 | { | ||
152 | struct hlp_dev *hlp_dev; | ||
153 | |||
154 | PDEBUG(D_CONF, "hlp open"); | ||
155 | if (hlp != 0) | ||
156 | return -EBUSY; | ||
157 | hlp_dev = kzalloc(sizeof *hlp_dev, GFP_KERNEL); | ||
158 | if (hlp_dev == NULL) { | ||
159 | err("couldn't kzalloc hlp struct"); | ||
160 | return -EIO; | ||
161 | } | ||
162 | init_waitqueue_head(&hlp_dev->wq); | ||
163 | file->private_data = hlp_dev; | ||
164 | hlp = hlp_dev; | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int hlp_close(struct inode *inode, struct file *file) | ||
169 | { | ||
170 | struct gspca_dev *gspca_dev; | ||
171 | int mode; | ||
172 | |||
173 | PDEBUG(D_CONF, "hlp close"); | ||
174 | file->private_data = NULL; | ||
175 | |||
176 | /* stop decoding */ | ||
177 | gspca_dev = hlp->gspca_dev; | ||
178 | if (gspca_dev != 0) { | ||
179 | mode = gspca_dev->curr_mode; | ||
180 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; | ||
181 | } | ||
182 | |||
183 | /* destroy the helper structure */ | ||
184 | kfree(hlp); | ||
185 | hlp = 0; | ||
186 | |||
187 | /* try to restart the helper process */ | ||
188 | start_hlp(); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static ssize_t hlp_read(struct file *file, char __user *buf, | ||
193 | size_t cnt, loff_t *ppos) | ||
194 | { | ||
195 | struct hlp_dev *hlp_dev = file->private_data; | ||
196 | struct gspca_dev *gspca_dev; | ||
197 | struct gspca_frame *frame; | ||
198 | struct gspca_hlp_read_hd head; | ||
199 | int i, j, len, ret; | ||
200 | |||
201 | PDEBUG(D_FRAM, "hlp read (%d)", cnt); | ||
202 | |||
203 | /* check / wait till a frame is ready */ | ||
204 | for (;;) { | ||
205 | gspca_dev = hlp_dev->gspca_dev; | ||
206 | if (gspca_dev != 0 && gspca_dev->streaming) { | ||
207 | i = hlp_dev->fr_d; /* frame to decode */ | ||
208 | j = gspca_dev->fr_queue[i]; | ||
209 | frame = &gspca_dev->frame[j]; | ||
210 | if (frame->v4l2_buf.flags & GSPCA_BUF_FLAG_DECODE) | ||
211 | break; | ||
212 | } | ||
213 | ret = wait_event_interruptible(hlp_dev->wq, | ||
214 | atomic_read(&hlp_dev->nevent) > 0); | ||
215 | if (ret < 0) { /* helper process is killed */ | ||
216 | autostart = 0; /* don't restart it */ | ||
217 | return ret; | ||
218 | } | ||
219 | } | ||
220 | atomic_dec(&hlp_dev->nevent); | ||
221 | hlp_dev->fr_d = (i + 1) % gspca_dev->nframes; | ||
222 | PDEBUG(D_FRAM, "hlp read q:%d i:%d d:%d o:%d", | ||
223 | gspca_dev->fr_q, | ||
224 | gspca_dev->fr_i, | ||
225 | hlp_dev->fr_d, | ||
226 | gspca_dev->fr_o); | ||
227 | |||
228 | hlp_dev->frame = frame; /* memorize the current frame */ | ||
229 | len = frame->v4l2_buf.bytesused; | ||
230 | if (cnt < sizeof head - sizeof head.data + len) | ||
231 | /*fixme: special errno?*/ | ||
232 | return -EINVAL; | ||
233 | head.pixfmt_out = gspca_dev->pixfmt; | ||
234 | head.pixfmt_in = hlp_dev->pixfmt; | ||
235 | head.width = gspca_dev->width; | ||
236 | head.height = gspca_dev->height; | ||
237 | copy_to_user(buf, &head, sizeof head); | ||
238 | copy_to_user(buf + sizeof head - sizeof head.data, | ||
239 | frame->data, len); | ||
240 | return sizeof head - sizeof head.data + len; | ||
241 | } | ||
242 | |||
243 | static ssize_t hlp_write(struct file *file, | ||
244 | const char __user *buf, | ||
245 | size_t cnt, loff_t *ppos) | ||
246 | { | ||
247 | struct hlp_dev *hlp_dev = file->private_data; | ||
248 | struct gspca_dev *gspca_dev; | ||
249 | struct gspca_frame *frame; | ||
250 | |||
251 | PDEBUG(D_FRAM, "hlp write (%d)", cnt); | ||
252 | gspca_dev = hlp_dev->gspca_dev; | ||
253 | if (gspca_dev == 0) | ||
254 | return cnt; | ||
255 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
256 | return -ERESTARTSYS; | ||
257 | if (!gspca_dev->streaming) | ||
258 | goto out; | ||
259 | frame = hlp_dev->frame; | ||
260 | hlp_dev->frame = 0; | ||
261 | if (frame == 0) | ||
262 | goto out; | ||
263 | if (cnt > frame->v4l2_buf.length) { | ||
264 | PDEBUG(D_ERR|D_FRAM, "bad frame size %d - %d", | ||
265 | cnt, frame->v4l2_buf.length); | ||
266 | cnt = -EINVAL; | ||
267 | goto out; | ||
268 | } | ||
269 | copy_from_user(frame->data, buf, cnt); | ||
270 | frame->v4l2_buf.bytesused = cnt; | ||
271 | frame->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | ||
272 | | GSPCA_BUF_FLAG_DECODE); | ||
273 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
274 | mutex_unlock(&gspca_dev->queue_lock); | ||
275 | atomic_inc(&gspca_dev->nevent); | ||
276 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | ||
277 | PDEBUG(D_FRAM, "hlp write q:%d i:%d d:%d o:%d", | ||
278 | gspca_dev->fr_q, | ||
279 | gspca_dev->fr_i, | ||
280 | hlp_dev->fr_d, | ||
281 | gspca_dev->fr_o); | ||
282 | return cnt; | ||
283 | out: | ||
284 | mutex_unlock(&gspca_dev->queue_lock); | ||
285 | return cnt; | ||
286 | } | ||
287 | |||
288 | static struct file_operations hlp_fops = { | ||
289 | .owner = THIS_MODULE, | ||
290 | .open = hlp_open, | ||
291 | .release = hlp_close, | ||
292 | .read = hlp_read, | ||
293 | .write = hlp_write, | ||
294 | .llseek = no_llseek | ||
295 | }; | ||
296 | static struct miscdevice hlp_device = { | ||
297 | .minor = MISC_DYNAMIC_MINOR, | ||
298 | .name = "gspca_hlp", | ||
299 | .fops = &hlp_fops, | ||
300 | }; | ||
301 | #endif | ||
302 | 85 | ||
303 | /* | 86 | /* |
304 | * VMA operations. | 87 | * VMA operations. |
@@ -331,10 +114,14 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
331 | struct urb *urb) | 114 | struct urb *urb) |
332 | { | 115 | { |
333 | struct gspca_frame *frame; | 116 | struct gspca_frame *frame; |
334 | unsigned char *data; /* address of data in the iso message */ | 117 | __u8 *data; /* address of data in the iso message */ |
335 | int i, j, len, st; | 118 | int i, j, len, st; |
336 | cam_pkt_op pkt_scan; | 119 | cam_pkt_op pkt_scan; |
337 | 120 | ||
121 | if (urb->status != 0) { | ||
122 | PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); | ||
123 | return; /* disconnection ? */ | ||
124 | } | ||
338 | pkt_scan = gspca_dev->sd_desc->pkt_scan; | 125 | pkt_scan = gspca_dev->sd_desc->pkt_scan; |
339 | for (i = 0; i < urb->number_of_packets; i++) { | 126 | for (i = 0; i < urb->number_of_packets; i++) { |
340 | 127 | ||
@@ -350,20 +137,21 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
350 | 137 | ||
351 | /* check the packet status and length */ | 138 | /* check the packet status and length */ |
352 | len = urb->iso_frame_desc[i].actual_length; | 139 | len = urb->iso_frame_desc[i].actual_length; |
140 | if (len == 0) | ||
141 | continue; | ||
353 | st = urb->iso_frame_desc[i].status; | 142 | st = urb->iso_frame_desc[i].status; |
354 | if (st) { | 143 | if (st) { |
355 | PDEBUG(D_ERR, "ISOC data error: [%d] len=%d, status=%d", | 144 | PDEBUG(D_ERR, |
145 | "ISOC data error: [%d] len=%d, status=%d", | ||
356 | i, len, st); | 146 | i, len, st); |
357 | gspca_dev->last_packet_type = DISCARD_PACKET; | 147 | gspca_dev->last_packet_type = DISCARD_PACKET; |
358 | continue; | 148 | continue; |
359 | } | 149 | } |
360 | if (len == 0) | ||
361 | continue; | ||
362 | 150 | ||
363 | /* let the packet be analyzed by the subdriver */ | 151 | /* let the packet be analyzed by the subdriver */ |
364 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", | 152 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", |
365 | i, urb->iso_frame_desc[i].offset, len); | 153 | i, urb->iso_frame_desc[i].offset, len); |
366 | data = (unsigned char *) urb->transfer_buffer | 154 | data = (__u8 *) urb->transfer_buffer |
367 | + urb->iso_frame_desc[i].offset; | 155 | + urb->iso_frame_desc[i].offset; |
368 | pkt_scan(gspca_dev, frame, data, len); | 156 | pkt_scan(gspca_dev, frame, data, len); |
369 | } | 157 | } |
@@ -390,7 +178,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
390 | * buffers are in user space (userptr). The frame detection | 178 | * buffers are in user space (userptr). The frame detection |
391 | * and copy is done by the application. | 179 | * and copy is done by the application. |
392 | */ | 180 | */ |
393 | static void isoc_irq_mmap(struct urb *urb) | 181 | static void isoc_irq_mmap(struct urb *urb |
182 | ) | ||
394 | { | 183 | { |
395 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 184 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
396 | 185 | ||
@@ -400,7 +189,8 @@ static void isoc_irq_mmap(struct urb *urb) | |||
400 | fill_frame(gspca_dev, urb); | 189 | fill_frame(gspca_dev, urb); |
401 | } | 190 | } |
402 | 191 | ||
403 | static void isoc_irq_user(struct urb *urb) | 192 | static void isoc_irq_user(struct urb *urb |
193 | ) | ||
404 | { | 194 | { |
405 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 195 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
406 | int i; | 196 | int i; |
@@ -459,7 +249,7 @@ static void isoc_transfer(struct gspca_dev *gspca_dev) | |||
459 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | 249 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, |
460 | int packet_type, | 250 | int packet_type, |
461 | struct gspca_frame *frame, | 251 | struct gspca_frame *frame, |
462 | unsigned char *data, | 252 | __u8 *data, |
463 | int len) | 253 | int len) |
464 | { | 254 | { |
465 | int i, j; | 255 | int i, j; |
@@ -503,23 +293,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | |||
503 | /* if last packet, wake the application and advance in the queue */ | 293 | /* if last packet, wake the application and advance in the queue */ |
504 | if (packet_type == LAST_PACKET) { | 294 | if (packet_type == LAST_PACKET) { |
505 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; | 295 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; |
506 | #ifndef GSPCA_HLP | ||
507 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | 296 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; |
508 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | 297 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; |
509 | atomic_inc(&gspca_dev->nevent); | 298 | atomic_inc(&gspca_dev->nevent); |
510 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | 299 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ |
511 | #else /*GSPCA_HLP*/ | ||
512 | if (hlp != 0 && hlp->gspca_dev == gspca_dev) { | ||
513 | frame->v4l2_buf.flags |= GSPCA_BUF_FLAG_DECODE; | ||
514 | atomic_inc(&hlp->nevent); | ||
515 | wake_up_interruptible(&hlp->wq); | ||
516 | } else { | ||
517 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
518 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
519 | atomic_inc(&gspca_dev->nevent); | ||
520 | wake_up_interruptible(&gspca_dev->wq); /* new frame */ | ||
521 | } | ||
522 | #endif /*GSPCA_HLP*/ | ||
523 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; | 300 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; |
524 | gspca_dev->fr_i = i; | 301 | gspca_dev->fr_i = i; |
525 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", | 302 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", |
@@ -581,13 +358,13 @@ static void rvfree(void *mem, unsigned long size) | |||
581 | static __u32 get_v4l2_depth(__u32 pixfmt) | 358 | static __u32 get_v4l2_depth(__u32 pixfmt) |
582 | { | 359 | { |
583 | switch (pixfmt) { | 360 | switch (pixfmt) { |
584 | case V4L2_PIX_FMT_BGR32: | 361 | /* case V4L2_PIX_FMT_BGR32: |
585 | case V4L2_PIX_FMT_RGB32: | 362 | case V4L2_PIX_FMT_RGB32: |
586 | return 32; | 363 | return 32; */ |
587 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ | 364 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ |
588 | case V4L2_PIX_FMT_BGR24: | 365 | case V4L2_PIX_FMT_BGR24: |
589 | return 24; | 366 | return 24; |
590 | case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ | 367 | /* case V4L2_PIX_FMT_RGB565: * 'RGBP' */ |
591 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ | 368 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ |
592 | case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ | 369 | case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ |
593 | return 16; | 370 | return 16; |
@@ -596,6 +373,9 @@ static __u32 get_v4l2_depth(__u32 pixfmt) | |||
596 | case V4L2_PIX_FMT_MJPEG: | 373 | case V4L2_PIX_FMT_MJPEG: |
597 | case V4L2_PIX_FMT_JPEG: | 374 | case V4L2_PIX_FMT_JPEG: |
598 | case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ | 375 | case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ |
376 | case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ | ||
377 | case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ | ||
378 | case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed BGGR bayer */ | ||
599 | return 8; | 379 | return 8; |
600 | } | 380 | } |
601 | PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", | 381 | PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", |
@@ -603,7 +383,7 @@ static __u32 get_v4l2_depth(__u32 pixfmt) | |||
603 | (pixfmt >> 8) & 0xff, | 383 | (pixfmt >> 8) & 0xff, |
604 | (pixfmt >> 16) & 0xff, | 384 | (pixfmt >> 16) & 0xff, |
605 | pixfmt >> 24); | 385 | pixfmt >> 24); |
606 | return -EINVAL; | 386 | return 24; |
607 | } | 387 | } |
608 | 388 | ||
609 | static int gspca_get_buff_size(struct gspca_dev *gspca_dev) | 389 | static int gspca_get_buff_size(struct gspca_dev *gspca_dev) |
@@ -632,7 +412,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
632 | count = GSPCA_MAX_FRAMES; | 412 | count = GSPCA_MAX_FRAMES; |
633 | /* if compressed (JPEG), reduce the buffer size */ | 413 | /* if compressed (JPEG), reduce the buffer size */ |
634 | if (gspca_is_compressed(gspca_dev->pixfmt)) | 414 | if (gspca_is_compressed(gspca_dev->pixfmt)) |
635 | frsz = (frsz * comp_fac) / 100 + 600; /* plus JPEG header */ | 415 | frsz = (frsz * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ |
636 | frsz = PAGE_ALIGN(frsz); | 416 | frsz = PAGE_ALIGN(frsz); |
637 | PDEBUG(D_STREAM, "new fr_sz: %d", frsz); | 417 | PDEBUG(D_STREAM, "new fr_sz: %d", frsz); |
638 | gspca_dev->frsz = frsz; | 418 | gspca_dev->frsz = frsz; |
@@ -660,17 +440,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
660 | } | 440 | } |
661 | } | 441 | } |
662 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | 442 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; |
663 | #ifdef GSPCA_HLP | ||
664 | { | ||
665 | struct hlp_dev *hlp_dev; | ||
666 | |||
667 | hlp_dev = hlp; | ||
668 | if (hlp != 0 && hlp_dev->gspca_dev == gspca_dev) { | ||
669 | hlp_dev->fr_d = 0; | ||
670 | atomic_set(&hlp_dev->nevent, 0); | ||
671 | } | ||
672 | } | ||
673 | #endif /*GSPCA_HLP*/ | ||
674 | gspca_dev->last_packet_type = DISCARD_PACKET; | 443 | gspca_dev->last_packet_type = DISCARD_PACKET; |
675 | gspca_dev->sequence = 0; | 444 | gspca_dev->sequence = 0; |
676 | atomic_set(&gspca_dev->nevent, 0); | 445 | atomic_set(&gspca_dev->nevent, 0); |
@@ -752,13 +521,14 @@ struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) | |||
752 | int i, ret; | 521 | int i, ret; |
753 | 522 | ||
754 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 523 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
524 | ep = NULL; | ||
755 | i = gspca_dev->alt; /* previous alt setting */ | 525 | i = gspca_dev->alt; /* previous alt setting */ |
756 | while (--i > 0) { /* alt 0 is unusable */ | 526 | while (--i > 0) { /* alt 0 is unusable */ |
757 | ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); | 527 | ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); |
758 | if (ep) | 528 | if (ep) |
759 | break; | 529 | break; |
760 | } | 530 | } |
761 | if (i <= 0) { | 531 | if (ep == NULL) { |
762 | err("no ISOC endpoint found"); | 532 | err("no ISOC endpoint found"); |
763 | return NULL; | 533 | return NULL; |
764 | } | 534 | } |
@@ -796,11 +566,14 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
796 | "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); | 566 | "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); |
797 | /*fixme:change for userptr*/ | 567 | /*fixme:change for userptr*/ |
798 | /*fixme:don't submit all URBs when userptr*/ | 568 | /*fixme:don't submit all URBs when userptr*/ |
799 | gspca_dev->nurbs = nurbs = DEF_NURBS; | 569 | if (gspca_dev->memory == V4L2_MEMORY_MMAP) { |
800 | if (gspca_dev->memory == V4L2_MEMORY_MMAP) | ||
801 | usb_complete = isoc_irq_mmap; | 570 | usb_complete = isoc_irq_mmap; |
802 | else | 571 | nurbs = DEF_NURBS; |
572 | } else { | ||
803 | usb_complete = isoc_irq_user; | 573 | usb_complete = isoc_irq_user; |
574 | nurbs = USR_NURBS; | ||
575 | } | ||
576 | gspca_dev->nurbs = nurbs; | ||
804 | for (n = 0; n < nurbs; n++) { | 577 | for (n = 0; n < nurbs; n++) { |
805 | urb = usb_alloc_urb(npkt, GFP_KERNEL); | 578 | urb = usb_alloc_urb(npkt, GFP_KERNEL); |
806 | if (!urb) { | 579 | if (!urb) { |
@@ -904,16 +677,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) | |||
904 | { | 677 | { |
905 | gspca_dev->streaming = 0; | 678 | gspca_dev->streaming = 0; |
906 | atomic_set(&gspca_dev->nevent, 0); | 679 | atomic_set(&gspca_dev->nevent, 0); |
907 | #ifdef GSPCA_HLP | ||
908 | { | ||
909 | struct hlp_dev *hlp_dev; | ||
910 | |||
911 | hlp_dev = hlp; | ||
912 | if (hlp_dev != 0 | ||
913 | && hlp_dev->gspca_dev == gspca_dev) | ||
914 | atomic_set(&hlp_dev->nevent, 0); | ||
915 | } | ||
916 | #endif | ||
917 | if (gspca_dev->present) { | 680 | if (gspca_dev->present) { |
918 | gspca_dev->sd_desc->stopN(gspca_dev); | 681 | gspca_dev->sd_desc->stopN(gspca_dev); |
919 | destroy_urbs(gspca_dev); | 682 | destroy_urbs(gspca_dev); |
@@ -979,15 +742,11 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, | |||
979 | struct v4l2_fmtdesc *fmtdesc) | 742 | struct v4l2_fmtdesc *fmtdesc) |
980 | { | 743 | { |
981 | struct gspca_dev *gspca_dev = priv; | 744 | struct gspca_dev *gspca_dev = priv; |
982 | int i; | 745 | int i, j, index; |
983 | #ifndef GSPCA_HLP | ||
984 | int j, index; | ||
985 | __u32 fmt_tb[8]; | 746 | __u32 fmt_tb[8]; |
986 | #endif | ||
987 | 747 | ||
988 | PDEBUG(D_CONF, "enum fmt cap"); | 748 | PDEBUG(D_CONF, "enum fmt cap"); |
989 | 749 | ||
990 | #ifndef GSPCA_HLP | ||
991 | /* give an index to each format */ | 750 | /* give an index to each format */ |
992 | index = 0; | 751 | index = 0; |
993 | j = 0; | 752 | j = 0; |
@@ -1013,36 +772,6 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, | |||
1013 | fmtdesc->pixelformat = fmt_tb[index]; | 772 | fmtdesc->pixelformat = fmt_tb[index]; |
1014 | if (gspca_is_compressed(fmt_tb[index])) | 773 | if (gspca_is_compressed(fmt_tb[index])) |
1015 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; | 774 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; |
1016 | #else /*GSPCA_HLP*/ | ||
1017 | /* !! code tied to the decoding functions in decoder.c */ | ||
1018 | i = gspca_dev->cam.nmodes - 1; | ||
1019 | if (fmtdesc->index == 0) { /* (assume one format per subdriver) */ | ||
1020 | fmtdesc->pixelformat = gspca_dev->cam.cam_mode[i].pixfmt; | ||
1021 | if (gspca_is_compressed(fmtdesc->pixelformat)) | ||
1022 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
1023 | } else { | ||
1024 | if (hlp == 0 | ||
1025 | || (hlp->gspca_dev != 0 | ||
1026 | && hlp->gspca_dev != gspca_dev)) | ||
1027 | return -EINVAL; | ||
1028 | switch (gspca_dev->cam.cam_mode[i].pixfmt) { | ||
1029 | case V4L2_PIX_FMT_JPEG: | ||
1030 | if (fmtdesc->index >= sizeof jpeg_to_tb | ||
1031 | / sizeof jpeg_to_tb[0]) | ||
1032 | return -EINVAL; | ||
1033 | fmtdesc->pixelformat = jpeg_to_tb[fmtdesc->index]; | ||
1034 | break; | ||
1035 | case V4L2_PIX_FMT_SBGGR8: | ||
1036 | if (fmtdesc->index >= sizeof bayer_to_tb | ||
1037 | / sizeof bayer_to_tb[0]) | ||
1038 | return -EINVAL; | ||
1039 | fmtdesc->pixelformat = bayer_to_tb[fmtdesc->index]; | ||
1040 | break; | ||
1041 | default: | ||
1042 | return -EINVAL; | ||
1043 | } | ||
1044 | } | ||
1045 | #endif /*GSPCA_HLP*/ | ||
1046 | fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 775 | fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1047 | fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; | 776 | fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; |
1048 | fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; | 777 | fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; |
@@ -1057,25 +786,12 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, | |||
1057 | { | 786 | { |
1058 | struct gspca_dev *gspca_dev = priv; | 787 | struct gspca_dev *gspca_dev = priv; |
1059 | 788 | ||
1060 | #ifdef GSPCA_HLP | 789 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1061 | int i; | 790 | return -EINVAL; |
1062 | |||
1063 | /* if the pixel format is not the one of the device and | ||
1064 | * if the helper is inactive or busy, restore */ | ||
1065 | i = gspca_dev->curr_mode; | ||
1066 | if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[i].pixfmt) { | ||
1067 | struct hlp_dev *hlp_dev; | ||
1068 | |||
1069 | hlp_dev = hlp; | ||
1070 | if (hlp_dev == 0 || hlp_dev->gspca_dev != gspca_dev) | ||
1071 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; | ||
1072 | } | ||
1073 | #endif /*GSPCA_HLP*/ | ||
1074 | |||
1075 | fmt->fmt.pix.width = gspca_dev->width; | 791 | fmt->fmt.pix.width = gspca_dev->width; |
1076 | fmt->fmt.pix.height = gspca_dev->height; | 792 | fmt->fmt.pix.height = gspca_dev->height; |
1077 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; | 793 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; |
1078 | #ifdef GSPCA_DEBUG | 794 | #ifdef VIDEO_ADV_DEBUG |
1079 | if (gspca_debug & D_CONF) { | 795 | if (gspca_debug & D_CONF) { |
1080 | PDEBUG_MODE("get fmt cap", | 796 | PDEBUG_MODE("get fmt cap", |
1081 | fmt->fmt.pix.pixelformat, | 797 | fmt->fmt.pix.pixelformat, |
@@ -1099,13 +815,15 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, | |||
1099 | { | 815 | { |
1100 | int w, h, mode, mode2, frsz; | 816 | int w, h, mode, mode2, frsz; |
1101 | 817 | ||
818 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
819 | return -EINVAL; | ||
1102 | w = fmt->fmt.pix.width; | 820 | w = fmt->fmt.pix.width; |
1103 | h = fmt->fmt.pix.height; | 821 | h = fmt->fmt.pix.height; |
1104 | 822 | ||
1105 | /* (luvcview problem) */ | 823 | /* (luvcview problem) */ |
1106 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | 824 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) |
1107 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; | 825 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; |
1108 | #ifdef GSPCA_DEBUG | 826 | #ifdef VIDEO_ADV_DEBUG |
1109 | if (gspca_debug & D_CONF) | 827 | if (gspca_debug & D_CONF) |
1110 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | 828 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); |
1111 | #endif | 829 | #endif |
@@ -1121,44 +839,11 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, | |||
1121 | if (mode2 >= 0) { | 839 | if (mode2 >= 0) { |
1122 | mode = mode2; | 840 | mode = mode2; |
1123 | } else { | 841 | } else { |
1124 | __u32 pixfmt; | ||
1125 | |||
1126 | pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; | ||
1127 | #ifndef GSPCA_HLP | ||
1128 | 842 | ||
1129 | /* no chance, return this mode */ | 843 | /* no chance, return this mode */ |
1130 | fmt->fmt.pix.pixelformat = pixfmt; | 844 | fmt->fmt.pix.pixelformat = |
1131 | #else /*GSPCA_HLP*/ | 845 | gspca_dev->cam.cam_mode[mode].pixfmt; |
1132 | if (hlp != 0 | 846 | #ifdef VIDEO_ADV_DEBUG |
1133 | && (hlp->gspca_dev == 0 | ||
1134 | || hlp->gspca_dev == gspca_dev) | ||
1135 | /* decoding works for JPEG and Bayer only */ | ||
1136 | && (pixfmt == V4L2_PIX_FMT_JPEG | ||
1137 | || pixfmt == V4L2_PIX_FMT_SBGGR8)) { | ||
1138 | switch (fmt->fmt.pix.pixelformat) { | ||
1139 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' */ | ||
1140 | case V4L2_PIX_FMT_BGR24: /* 'BGR3' */ | ||
1141 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ | ||
1142 | case V4L2_PIX_FMT_YUV420: /* 'YU12' */ | ||
1143 | case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ | ||
1144 | break; | ||
1145 | default: { | ||
1146 | /* return any of the supported fmt's */ | ||
1147 | __u8 u; | ||
1148 | |||
1149 | u = get_jiffies_64(); | ||
1150 | u %= sizeof bayer_to_tb | ||
1151 | / sizeof bayer_to_tb[0] - 1; | ||
1152 | fmt->fmt.pix.pixelformat = | ||
1153 | bayer_to_tb[u + 1]; | ||
1154 | break; | ||
1155 | } | ||
1156 | } | ||
1157 | } else { | ||
1158 | fmt->fmt.pix.pixelformat = pixfmt; | ||
1159 | } | ||
1160 | #endif /*GSPCA_HLP*/ | ||
1161 | #ifdef GSPCA_DEBUG | ||
1162 | if (gspca_debug & D_CONF) { | 847 | if (gspca_debug & D_CONF) { |
1163 | PDEBUG_MODE("new format", | 848 | PDEBUG_MODE("new format", |
1164 | fmt->fmt.pix.pixelformat, | 849 | fmt->fmt.pix.pixelformat, |
@@ -1198,7 +883,17 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1198 | struct gspca_dev *gspca_dev = priv; | 883 | struct gspca_dev *gspca_dev = priv; |
1199 | int ret; | 884 | int ret; |
1200 | 885 | ||
1201 | #ifdef GSPCA_DEBUG | 886 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
887 | /* if v4l1 got JPEG */ | ||
888 | if (fmt->fmt.pix.pixelformat == 0 | ||
889 | && gspca_dev->streaming) { | ||
890 | fmt->fmt.pix.width = gspca_dev->width; | ||
891 | fmt->fmt.pix.height = gspca_dev->height; | ||
892 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; | ||
893 | return 0; | ||
894 | } | ||
895 | #endif | ||
896 | #ifdef VIDEO_ADV_DEBUG | ||
1202 | if (gspca_debug & D_CONF) { | 897 | if (gspca_debug & D_CONF) { |
1203 | PDEBUG_MODE("set fmt cap", | 898 | PDEBUG_MODE("set fmt cap", |
1204 | fmt->fmt.pix.pixelformat, | 899 | fmt->fmt.pix.pixelformat, |
@@ -1218,14 +913,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1218 | goto out; | 913 | goto out; |
1219 | } | 914 | } |
1220 | 915 | ||
1221 | #ifndef GSPCA_HLP | ||
1222 | if (ret == gspca_dev->curr_mode) | 916 | if (ret == gspca_dev->curr_mode) |
1223 | goto out; /* same mode */ | 917 | goto out; /* same mode */ |
1224 | #else /*GSPCA_HLP*/ | ||
1225 | if (ret == gspca_dev->curr_mode | ||
1226 | && gspca_dev->pixfmt == fmt->fmt.pix.pixelformat) | ||
1227 | goto out; /* same mode */ | ||
1228 | #endif /*GSPCA_HLP*/ | ||
1229 | 918 | ||
1230 | if (gspca_dev->streaming) { | 919 | if (gspca_dev->streaming) { |
1231 | ret = -EBUSY; | 920 | ret = -EBUSY; |
@@ -1236,26 +925,6 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1236 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; | 925 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; |
1237 | gspca_dev->curr_mode = ret; | 926 | gspca_dev->curr_mode = ret; |
1238 | 927 | ||
1239 | #ifdef GSPCA_HLP | ||
1240 | /* if frame decoding is required */ | ||
1241 | if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[ret].pixfmt) { | ||
1242 | struct hlp_dev *hlp_dev; | ||
1243 | |||
1244 | hlp_dev = hlp; | ||
1245 | if (hlp_dev == 0 | ||
1246 | || (hlp_dev->gspca_dev != 0 | ||
1247 | && hlp_dev->gspca_dev != gspca_dev)) { /* helper busy */ | ||
1248 | fmt->fmt.pix.pixelformat = | ||
1249 | gspca_dev->pixfmt = | ||
1250 | gspca_dev->cam.cam_mode[ret].pixfmt; | ||
1251 | } else { /* helper active */ | ||
1252 | hlp_dev->gspca_dev = gspca_dev; | ||
1253 | hlp_dev->pixfmt = gspca_dev->cam.cam_mode[ret].pixfmt; | ||
1254 | hlp_dev->fr_d = gspca_dev->fr_i; | ||
1255 | } | ||
1256 | } else if (hlp != 0 && hlp->gspca_dev == gspca_dev) | ||
1257 | hlp->gspca_dev = 0; | ||
1258 | #endif /*GSPCA_HLP*/ | ||
1259 | ret = 0; | 928 | ret = 0; |
1260 | out: | 929 | out: |
1261 | mutex_unlock(&gspca_dev->queue_lock); | 930 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1294,7 +963,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
1294 | } | 963 | } |
1295 | gspca_dev->users++; | 964 | gspca_dev->users++; |
1296 | file->private_data = gspca_dev; | 965 | file->private_data = gspca_dev; |
1297 | #ifdef GSPCA_DEBUG | 966 | #ifdef VIDEO_ADV_DEBUG |
1298 | /* activate the v4l2 debug */ | 967 | /* activate the v4l2 debug */ |
1299 | if (gspca_debug & D_V4L2) | 968 | if (gspca_debug & D_V4L2) |
1300 | gspca_dev->vdev.debug |= 3; | 969 | gspca_dev->vdev.debug |= 3; |
@@ -1329,22 +998,6 @@ static int dev_close(struct inode *inode, struct file *file) | |||
1329 | frame_free(gspca_dev); | 998 | frame_free(gspca_dev); |
1330 | gspca_dev->capt_file = 0; | 999 | gspca_dev->capt_file = 0; |
1331 | gspca_dev->memory = GSPCA_MEMORY_NO; | 1000 | gspca_dev->memory = GSPCA_MEMORY_NO; |
1332 | #ifdef GSPCA_HLP | ||
1333 | { | ||
1334 | struct hlp_dev *hlp_dev; | ||
1335 | int mode; | ||
1336 | |||
1337 | hlp_dev = hlp; | ||
1338 | if (hlp_dev != 0 | ||
1339 | && hlp_dev->gspca_dev == gspca_dev) { | ||
1340 | hlp_dev->gspca_dev = 0; | ||
1341 | hlp_dev->frame = 0; | ||
1342 | mode = gspca_dev->curr_mode; | ||
1343 | gspca_dev->pixfmt = | ||
1344 | gspca_dev->cam.cam_mode[mode].pixfmt; | ||
1345 | } | ||
1346 | } | ||
1347 | #endif /*GSPCA_HLP*/ | ||
1348 | } | 1001 | } |
1349 | file->private_data = NULL; | 1002 | file->private_data = NULL; |
1350 | mutex_unlock(&gspca_dev->queue_lock); | 1003 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1370,23 +1023,38 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1370 | return 0; | 1023 | return 0; |
1371 | } | 1024 | } |
1372 | 1025 | ||
1026 | /* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */ | ||
1373 | static int vidioc_queryctrl(struct file *file, void *priv, | 1027 | static int vidioc_queryctrl(struct file *file, void *priv, |
1374 | struct v4l2_queryctrl *q_ctrl) | 1028 | struct v4l2_queryctrl *q_ctrl) |
1375 | { | 1029 | { |
1376 | struct gspca_dev *gspca_dev = priv; | 1030 | struct gspca_dev *gspca_dev = priv; |
1377 | int i; | 1031 | int i; |
1378 | 1032 | u32 id; | |
1379 | PDEBUG(D_CONF, "queryctrl"); | 1033 | |
1034 | id = q_ctrl->id; | ||
1035 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | ||
1036 | id &= V4L2_CTRL_ID_MASK; | ||
1037 | id++; | ||
1038 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1039 | if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
1040 | memcpy(q_ctrl, | ||
1041 | &gspca_dev->sd_desc->ctrls[i].qctrl, | ||
1042 | sizeof *q_ctrl); | ||
1043 | return 0; | ||
1044 | } | ||
1045 | } | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1380 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1048 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1381 | if (q_ctrl->id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | 1049 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { |
1382 | memcpy(q_ctrl, | 1050 | memcpy(q_ctrl, |
1383 | &gspca_dev->sd_desc->ctrls[i].qctrl, | 1051 | &gspca_dev->sd_desc->ctrls[i].qctrl, |
1384 | sizeof *q_ctrl); | 1052 | sizeof *q_ctrl); |
1385 | return 0; | 1053 | return 0; |
1386 | } | 1054 | } |
1387 | } | 1055 | } |
1388 | if (q_ctrl->id >= V4L2_CID_BASE | 1056 | if (id >= V4L2_CID_BASE |
1389 | && q_ctrl->id <= V4L2_CID_LASTP1) { | 1057 | && id <= V4L2_CID_LASTP1) { |
1390 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | 1058 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; |
1391 | return 0; | 1059 | return 0; |
1392 | } | 1060 | } |
@@ -1489,13 +1157,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1489 | return -EINVAL; | 1157 | return -EINVAL; |
1490 | switch (rb->memory) { | 1158 | switch (rb->memory) { |
1491 | case V4L2_MEMORY_MMAP: | 1159 | case V4L2_MEMORY_MMAP: |
1492 | break; | ||
1493 | case V4L2_MEMORY_USERPTR: | 1160 | case V4L2_MEMORY_USERPTR: |
1494 | #ifdef GSPCA_HLP | 1161 | break; |
1495 | if (hlp == 0 || hlp->gspca_dev != gspca_dev) | ||
1496 | break; | ||
1497 | #endif | ||
1498 | return -EINVAL; | ||
1499 | default: | 1162 | default: |
1500 | return -EINVAL; | 1163 | return -EINVAL; |
1501 | } | 1164 | } |
@@ -1578,7 +1241,7 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1578 | if (ret < 0) | 1241 | if (ret < 0) |
1579 | goto out; | 1242 | goto out; |
1580 | } | 1243 | } |
1581 | #ifdef GSPCA_DEBUG | 1244 | #ifdef VIDEO_ADV_DEBUG |
1582 | if (gspca_debug & D_STREAM) { | 1245 | if (gspca_debug & D_STREAM) { |
1583 | PDEBUG_MODE("stream on OK", | 1246 | PDEBUG_MODE("stream on OK", |
1584 | gspca_dev->pixfmt, | 1247 | gspca_dev->pixfmt, |
@@ -1657,7 +1320,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, | |||
1657 | { | 1320 | { |
1658 | struct gspca_dev *gspca_dev = priv; | 1321 | struct gspca_dev *gspca_dev = priv; |
1659 | 1322 | ||
1660 | memset(parm, 0, sizeof parm); | 1323 | memset(parm, 0, sizeof *parm); |
1661 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1324 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1662 | parm->parm.capture.readbuffers = gspca_dev->nbufread; | 1325 | parm->parm.capture.readbuffers = gspca_dev->nbufread; |
1663 | return 0; | 1326 | return 0; |
@@ -1677,6 +1340,12 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1677 | return 0; | 1340 | return 0; |
1678 | } | 1341 | } |
1679 | 1342 | ||
1343 | static int vidioc_s_std(struct file *filp, void *priv, | ||
1344 | v4l2_std_id *parm) | ||
1345 | { | ||
1346 | return 0; | ||
1347 | } | ||
1348 | |||
1680 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1349 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1681 | static int vidiocgmbuf(struct file *file, void *priv, | 1350 | static int vidiocgmbuf(struct file *file, void *priv, |
1682 | struct video_mbuf *mbuf) | 1351 | struct video_mbuf *mbuf) |
@@ -1686,29 +1355,32 @@ static int vidiocgmbuf(struct file *file, void *priv, | |||
1686 | 1355 | ||
1687 | PDEBUG(D_STREAM, "cgmbuf"); | 1356 | PDEBUG(D_STREAM, "cgmbuf"); |
1688 | if (gspca_dev->nframes == 0) { | 1357 | if (gspca_dev->nframes == 0) { |
1689 | struct v4l2_requestbuffers rb; | ||
1690 | int ret; | 1358 | int ret; |
1691 | __u32 pixfmt; | 1359 | |
1692 | short width, height; | 1360 | { |
1693 | 1361 | struct v4l2_format fmt; | |
1694 | /* as the final format is not yet defined, allocate | 1362 | |
1695 | buffers with the max size */ | 1363 | memset(&fmt, 0, sizeof fmt); |
1696 | pixfmt = gspca_dev->pixfmt; | 1364 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1697 | width = gspca_dev->width; | 1365 | i = gspca_dev->cam.nmodes - 1; /* highest mode */ |
1698 | height = gspca_dev->height; | 1366 | fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; |
1699 | gspca_dev->pixfmt = V4L2_PIX_FMT_BGR32; | 1367 | fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; |
1700 | gspca_dev->width = 640; | 1368 | fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; |
1701 | gspca_dev->height = 480; | 1369 | ret = vidioc_s_fmt_cap(file, priv, &fmt); |
1702 | memset(&rb, 0, sizeof rb); | 1370 | if (ret != 0) |
1703 | rb.count = 4; | 1371 | return ret; |
1704 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1372 | } |
1705 | rb.memory = V4L2_MEMORY_MMAP; | 1373 | { |
1706 | ret = vidioc_reqbufs(file, priv, &rb); | 1374 | struct v4l2_requestbuffers rb; |
1707 | gspca_dev->pixfmt = pixfmt; | 1375 | |
1708 | gspca_dev->width = width; | 1376 | memset(&rb, 0, sizeof rb); |
1709 | gspca_dev->height = height; | 1377 | rb.count = 4; |
1710 | if (ret != 0) | 1378 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1711 | return ret; | 1379 | rb.memory = V4L2_MEMORY_MMAP; |
1380 | ret = vidioc_reqbufs(file, priv, &rb); | ||
1381 | if (ret != 0) | ||
1382 | return ret; | ||
1383 | } | ||
1712 | } | 1384 | } |
1713 | mbuf->frames = gspca_dev->nframes; | 1385 | mbuf->frames = gspca_dev->nframes; |
1714 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; | 1386 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; |
@@ -1951,7 +1623,7 @@ static int vidioc_qbuf(struct file *file, void *priv, | |||
1951 | 1623 | ||
1952 | if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { | 1624 | if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { |
1953 | frame->data = frame->data_end = | 1625 | frame->data = frame->data_end = |
1954 | (unsigned char *) v4l2_buf->m.userptr; | 1626 | (__u8 *) v4l2_buf->m.userptr; |
1955 | frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; | 1627 | frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; |
1956 | frame->v4l2_buf.length = v4l2_buf->length; | 1628 | frame->v4l2_buf.length = v4l2_buf->length; |
1957 | } | 1629 | } |
@@ -2154,6 +1826,9 @@ static struct file_operations dev_fops = { | |||
2154 | .read = dev_read, | 1826 | .read = dev_read, |
2155 | .mmap = dev_mmap, | 1827 | .mmap = dev_mmap, |
2156 | .ioctl = video_ioctl2, | 1828 | .ioctl = video_ioctl2, |
1829 | #ifdef CONFIG_COMPAT | ||
1830 | .compat_ioctl = v4l_compat_ioctl32, | ||
1831 | #endif | ||
2157 | .llseek = no_llseek, | 1832 | .llseek = no_llseek, |
2158 | .poll = dev_poll, | 1833 | .poll = dev_poll, |
2159 | }; | 1834 | }; |
@@ -2186,6 +1861,7 @@ static struct video_device gspca_template = { | |||
2186 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1861 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
2187 | .vidioc_g_parm = vidioc_g_parm, | 1862 | .vidioc_g_parm = vidioc_g_parm, |
2188 | .vidioc_s_parm = vidioc_s_parm, | 1863 | .vidioc_s_parm = vidioc_s_parm, |
1864 | .vidioc_s_std = vidioc_s_std, | ||
2189 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1865 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
2190 | .vidiocgmbuf = vidiocgmbuf, | 1866 | .vidiocgmbuf = vidiocgmbuf, |
2191 | #endif | 1867 | #endif |
@@ -2207,12 +1883,8 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2207 | struct gspca_dev *gspca_dev; | 1883 | struct gspca_dev *gspca_dev; |
2208 | struct usb_device *dev = interface_to_usbdev(intf); | 1884 | struct usb_device *dev = interface_to_usbdev(intf); |
2209 | int ret; | 1885 | int ret; |
2210 | __u16 vendor; | ||
2211 | __u16 product; | ||
2212 | 1886 | ||
2213 | vendor = id->idVendor; | 1887 | PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); |
2214 | product = id->idProduct; | ||
2215 | PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product); | ||
2216 | 1888 | ||
2217 | /* we don't handle multi-config cameras */ | 1889 | /* we don't handle multi-config cameras */ |
2218 | if (dev->descriptor.bNumConfigurations != 1) | 1890 | if (dev->descriptor.bNumConfigurations != 1) |
@@ -2309,35 +1981,24 @@ EXPORT_SYMBOL(gspca_disconnect); | |||
2309 | /* -- module insert / remove -- */ | 1981 | /* -- module insert / remove -- */ |
2310 | static int __init gspca_init(void) | 1982 | static int __init gspca_init(void) |
2311 | { | 1983 | { |
2312 | #ifdef GSPCA_HLP | ||
2313 | int ret; | ||
2314 | |||
2315 | /* create /dev/gspca_hlp */ | ||
2316 | ret = misc_register(&hlp_device); | ||
2317 | if (ret < 0) | ||
2318 | err("misc_register err %d", ret); | ||
2319 | start_hlp(); /* try to start the helper process */ | ||
2320 | #endif | ||
2321 | info("main v%s registered", version); | 1984 | info("main v%s registered", version); |
2322 | return 0; | 1985 | return 0; |
2323 | } | 1986 | } |
2324 | static void __exit gspca_exit(void) | 1987 | static void __exit gspca_exit(void) |
2325 | { | 1988 | { |
2326 | #ifdef GSPCA_HLP | ||
2327 | misc_deregister(&hlp_device); | ||
2328 | #endif | ||
2329 | info("main deregistered"); | 1989 | info("main deregistered"); |
2330 | } | 1990 | } |
2331 | 1991 | ||
2332 | module_init(gspca_init); | 1992 | module_init(gspca_init); |
2333 | module_exit(gspca_exit); | 1993 | module_exit(gspca_exit); |
2334 | 1994 | ||
1995 | #ifdef VIDEO_ADV_DEBUG | ||
2335 | module_param_named(debug, gspca_debug, int, 0644); | 1996 | module_param_named(debug, gspca_debug, int, 0644); |
2336 | MODULE_PARM_DESC(debug, | 1997 | MODULE_PARM_DESC(debug, |
2337 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" | 1998 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" |
2338 | " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" | 1999 | " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" |
2339 | " 0x0100: v4l2"); | 2000 | " 0x0100: v4l2"); |
2340 | 2001 | #endif | |
2341 | module_param(comp_fac, int, 0644); | 2002 | module_param(comp_fac, int, 0644); |
2342 | MODULE_PARM_DESC(comp_fac, | 2003 | MODULE_PARM_DESC(comp_fac, |
2343 | "Buffer size ratio when compressed in percent"); | 2004 | "Buffer size ratio when compressed in percent"); |