aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/video4linux/gspca.txt238
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/gspca/Kconfig13
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/gspca.c1750
-rw-r--r--drivers/media/video/gspca/gspca.h178
-rw-r--r--drivers/media/video/gspca/jpeg.h301
-rw-r--r--drivers/media/video/gspca/stk014.c562
8 files changed, 3048 insertions, 0 deletions
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
new file mode 100644
index 000000000000..9c404b56dbb3
--- /dev/null
+++ b/Documentation/video4linux/gspca.txt
@@ -0,0 +1,238 @@
1Here the list of the known working cameras with gspca.
2
3The modules are:
4 gspca_main main driver
5 gspca_xxxx subdriver module with xxxx as follows
6
7xxxx vend:prod
8----
9conex 0572:0041 Creative Notebook cx11646
10etoms 102c:6151 Qcam Sangha CIF
11etoms 102c:6251 Qcam xxxxxx VGA
12mars 093a:050f Mars-Semi Pc-Camera
13ov519 041e:4052 Creative Live! VISTA IM
14ov519 041e:405f Creative Live! VISTA VF0330
15ov519 041e:4060 Creative Live! VISTA VF0350
16ov519 041e:4061 Creative Live! VISTA VF0400
17ov519 041e:4064 Creative Live! VISTA VF0420
18ov519 041e:4068 Creative Live! VISTA VF0470
19ov519 045e:028c Micro$oft xbox cam
20ov519 054c:0154 Sonny toy4
21ov519 054c:0155 Sonny toy5
22ov519 05a9:0519 OmniVision
23ov519 05a9:4519 OmniVision
24ov519 05a9:8519 OmniVision
25ov519 05a9:0530 OmniVision
26pac207 041e:4028 Creative Webcam Vista Plus
27pac207 093a:2460 PAC207 Qtec Webcam 100
28pac207 093a:2463 Philips spc200nc pac207
29pac207 093a:2464 Labtec Webcam 1200
30pac207 093a:2468 PAC207
31pac207 093a:2470 Genius GF112
32pac207 093a:2471 PAC207 Genius VideoCam ge111
33pac207 093a:2472 PAC207 Genius VideoCam ge110
34pac7311 093a:2600 PAC7311 Typhoon
35pac7311 093a:2601 PAC7311 Phillips SPC610NC
36pac7311 093a:2603 PAC7312
37pac7311 093a:2608 PAC7311 Trust WB-3300p
38pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
39pac7311 093a:260f PAC7311 SnakeCam
40sonixb 0c45:6001 Genius VideoCAM NB
41sonixb 0c45:6005 Sweex Tas5110
42sonixb 0c45:6007 Sonix sn9c101 + Tas5110D
43sonixb 0c45:6009 spcaCam@120
44sonixb 0c45:600d spcaCam@120
45sonixb 0c45:6011 MAX Webcam (Microdia - OV6650 - SN9C101G)
46sonixb 0c45:6019 Generic Sonix OV7630
47sonixb 0c45:6024 Generic Sonix Tas5130c
48sonixb 0c45:6025 Xcam Shanga
49sonixb 0c45:6028 Sonix Btc Pc380
50sonixb 0c45:6029 spcaCam@150
51sonixb 0c45:602c Generic Sonix OV7630
52sonixb 0c45:602d LIC-200 LG
53sonixb 0c45:602e Genius VideoCam Messenger
54sonixj 0458:7025 Genius Eye 311Q
55sonixj 045e:00f5 MicroSoft VX3000
56sonixj 045e:00f7 MicroSoft VX1000
57sonixj 0471:0327 Philips SPC 600 NC
58sonixj 0471:0328 Philips SPC 700 NC
59sonixj 0471:0330 Philips SPC 710NC
60sonixj 0c45:6040 Speed NVC 350K
61sonixj 0c45:607c Sonix sn9c102p Hv7131R
62sonixj 0c45:60c0 Sangha Sn535
63sonixj 0c45:60ec SN9C105+MO4000
64sonixj 0c45:60fb Surfer NoName
65sonixj 0c45:60fc LG-LIC300
66sonixj 0c45:612a Avant Camera
67sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
68sonixj 0c45:6130 Sonix Pccam
69sonixj 0c45:6138 Sn9c120 Mo4000
70sonixj 0c45:613b Surfer SN-206
71sonixj 0c45:613c Sonix Pccam168
72spca500 040a:0300 Kodak EZ200
73spca500 041e:400a Creative PC-CAM 300
74spca500 046d:0890 Logitech QuickCam traveler
75spca500 046d:0900 Logitech Inc. ClickSmart 310
76spca500 046d:0901 Logitech Inc. ClickSmart 510
77spca500 04a5:300c Benq DC1016
78spca500 04fc:7333 PalmPixDC85
79spca500 055f:c200 Mustek Gsmart 300
80spca500 055f:c220 Gsmart Mini
81spca500 06bd:0404 Agfa CL20
82spca500 06be:0800 Optimedia
83spca500 084d:0003 D-Link DSC-350
84spca500 08ca:0103 Aiptek PocketDV
85spca500 2899:012c Toptro Industrial
86spca500 8086:0630 Intel Pocket PC Camera
87spca501 040a:0002 Kodak DVC-325
88spca501 0497:c001 Smile International
89spca501 0506:00df 3Com HomeConnect Lite
90spca501 0733:0401 Intel Create and Share
91spca501 0733:0402 ViewQuest M318B
92spca501 1776:501c Arowana 300K CMOS Camera
93spca501 0000:0000 MystFromOri Unknow Camera
94spca505 041e:401d Creative Webcam NX ULTRA
95spca505 0733:0430 Intel PC Camera Pro
96spca506 06e1:a190 ADS Instant VCD
97spca506 0734:043b 3DeMon USB Capture aka
98spca506 99fa:8988 Grandtec V.cap
99spca506 99fa:8988 Grandtec V.cap
100spca508 041e:4018 Creative Webcam Vista (PD1100)
101spca508 0461:0815 Micro Innovation IC200
102spca508 0733:0110 ViewQuest VQ110
103spca508 0af9:0010 Hama USB Sightcam 100
104spca508 0af9:0011 Hama USB Sightcam 100
105spca508 8086:0110 Intel Easy PC Camera
106spca561 041e:401a Creative Webcam Vista (PD1100)
107spca561 041e:403b Creative Webcam Vista (VF0010)
108spca561 0458:7004 Genius VideoCAM Express V2
109spca561 046d:0928 Logitech QC Express Etch2
110spca561 046d:0929 Labtec Webcam Elch2
111spca561 046d:092a Logitech QC for Notebook
112spca561 046d:092b Labtec Webcam Plus
113spca561 046d:092c Logitech QC chat Elch2
114spca561 046d:092d Logitech QC Elch2
115spca561 046d:092e Logitech QC Elch2
116spca561 046d:092f Logitech QC Elch2
117spca561 04fc:0561 Flexcam 100
118spca561 060b:a001 Maxell Compact Pc PM3
119spca561 10fd:7e50 FlyCam Usb 100
120spca561 abcd:cdee Petcam
121stk014 05e1:0893 Syntek DV4000
122sunplus 041e:400b Creative PC-CAM 600
123sunplus 041e:4012 PC-Cam350
124sunplus 041e:4013 Creative Pccam750
125sunplus 0458:7006 Genius Dsc 1.3 Smart
126sunplus 046d:0905 Logitech ClickSmart 820
127sunplus 046d:0960 Logitech ClickSmart 420
128sunplus 0471:0322 Philips DMVC1300K
129sunplus 04a5:3003 Benq DC 1300
130sunplus 04a5:3008 Benq DC 1500
131sunplus 04a5:300a Benq DC3410
132sunplus 04f1:1001 JVC GC A50
133sunplus 04fc:500c Sunplus CA500C
134sunplus 04fc:504a Aiptek Mini PenCam 1.3
135sunplus 04fc:504b Maxell MaxPocket LE 1.3
136sunplus 04fc:5330 Digitrex 2110
137sunplus 04fc:5360 Sunplus Generic
138sunplus 04fc:ffff Pure DigitalDakota
139sunplus 052b:1513 Megapix V4
140sunplus 0546:3155 Polaroid PDC3070
141sunplus 0546:3191 Polaroid Ion 80
142sunplus 0546:3273 Polaroid PDC2030
143sunplus 055f:c211 Kowa Bs888e Microcamera
144sunplus 055f:c230 Mustek Digicam 330K
145sunplus 055f:c232 Mustek MDC3500
146sunplus 055f:c360 Mustek DV4000 Mpeg4
147sunplus 055f:c420 Mustek gSmart Mini 2
148sunplus 055f:c430 Mustek Gsmart LCD 2
149sunplus 055f:c440 Mustek DV 3000
150sunplus 055f:c520 Mustek gSmart Mini 3
151sunplus 055f:c530 Mustek Gsmart LCD 3
152sunplus 055f:c540 Gsmart D30
153sunplus 055f:c630 Mustek MDC4000
154sunplus 055f:c650 Mustek MDC5500Z
155sunplus 05da:1018 Digital Dream Enigma 1.3
156sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
157sunplus 0733:1311 Digital Dream Epsilon 1.3
158sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam
159sunplus 0733:2211 Jenoptik jdc 21 LCD
160sunplus 0733:2221 Mercury Digital Pro 3.1p
161sunplus 0733:3261 Concord 3045 spca536a
162sunplus 0733:3281 Cyberpix S550V
163sunplus 08ca:0104 Aiptek PocketDVII 1.3
164sunplus 08ca:0106 Aiptek Pocket DV3100+
165sunplus 08ca:2008 Aiptek Mini PenCam 2 M
166sunplus 08ca:2010 Aiptek PocketCam 3M
167sunplus 08ca:2016 Aiptek PocketCam 2 Mega
168sunplus 08ca:2018 Aiptek Pencam SD 2M
169sunplus 08ca:2020 Aiptek Slim 3000F
170sunplus 08ca:2022 Aiptek Slim 3200
171sunplus 08ca:2024 Aiptek DV3500 Mpeg4
172sunplus 08ca:2028 Aiptek PocketCam4M
173sunplus 08ca:2040 Aiptek PocketDV4100M
174sunplus 08ca:2042 Aiptek PocketDV5100
175sunplus 08ca:2060 Aiptek PocketDV5300
176sunplus 0d64:0303 Sunplus FashionCam DXG
177tv8532 046d:0920 QC Express
178tv8532 046d:0921 Labtec Webcam
179tv8532 0545:808b Veo Stingray
180tv8532 0545:8333 Veo Stingray
181tv8532 0923:010f ICM532 cams
182vc032x 046d:0892 Logitech Orbicam
183vc032x 046d:0896 Logitech Orbicam
184vc032x 0ac8:0321 Vimicro generic vc0321
185vc032x 0ac8:0323 Vimicro Vc0323
186vc032x 0ac8:0328 A4Tech PK-130MG
187vc032x 0ac8:c001 Sony embedded vimicro
188vc032x 0ac8:c002 Sony embedded vimicro
189vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
190zc3xx 041e:041e Creative WebCam Live!
191zc3xx 041e:4017 Creative Webcam Mobile PD1090
192zc3xx 041e:401c Creative NX
193zc3xx 041e:401e Creative Nx Pro
194zc3xx 041e:401f Creative Webcam Notebook PD1171
195zc3xx 041e:4029 Creative WebCam Vista Pro
196zc3xx 041e:4034 Creative Instant P0620
197zc3xx 041e:4035 Creative Instant P0620D
198zc3xx 041e:4036 Creative Live !
199zc3xx 041e:403a Creative Nx Pro 2
200zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
201zc3xx 041e:4053 Creative Live!Cam Video IM
202zc3xx 0458:7007 Genius VideoCam V2
203zc3xx 0458:700c Genius VideoCam V3
204zc3xx 0458:700f Genius VideoCam Web V2
205zc3xx 0461:0a00 MicroInnovation WebCam320
206zc3xx 046d:08a0 Logitech QC IM
207zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound
208zc3xx 046d:08a2 Labtec Webcam Pro
209zc3xx 046d:08a3 Logitech QC Chat
210zc3xx 046d:08a6 Logitech QCim
211zc3xx 046d:08a7 Logitech QuickCam Image
212zc3xx 046d:08a9 Logitech Notebook Deluxe
213zc3xx 046d:08aa Labtec Webcam Notebook
214zc3xx 046d:08ac Logitech QuickCam Cool
215zc3xx 046d:08ad Logitech QCCommunicate STX
216zc3xx 046d:08ae Logitech QuickCam for Notebooks
217zc3xx 046d:08af Logitech QuickCam Cool
218zc3xx 046d:08b9 Logitech QC IM ???
219zc3xx 046d:08d7 Logitech QCam STX
220zc3xx 046d:08d9 Logitech QuickCam IM/Connect
221zc3xx 046d:08d8 Logitech Notebook Deluxe
222zc3xx 046d:08da Logitech QuickCam Messenger
223zc3xx 046d:08dd Logitech QuickCam for Notebooks
224zc3xx 0471:0325 Philips SPC 200 NC
225zc3xx 0471:0326 Philips SPC 300 NC
226zc3xx 0471:032d Philips spc210nc
227zc3xx 0471:032e Philips spc315nc
228zc3xx 055f:c005 Mustek Wcam300A
229zc3xx 055f:d003 Mustek WCam300A
230zc3xx 055f:d004 Mustek WCam300 AN
231zc3xx 0698:2003 CTX M730V built in
232zc3xx 0ac8:0302 Z-star Vimicro zc0302
233zc3xx 0ac8:301b Z-Star zc301b
234zc3xx 0ac8:303b Vimicro 0x303b
235zc3xx 0ac8:305b Z-star Vimicro zc0305b
236zc3xx 0ac8:307b Ldlc VC302+Ov7620
237zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
238zc3xx 10fd:8050 Typhoon Webshot II USB 300k
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 8fca90b75e79..a6fbee4d41b7 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -801,6 +801,8 @@ config USB_VIDEO_CLASS
801 801
802 For more information see: <http://linux-uvc.berlios.de/> 802 For more information see: <http://linux-uvc.berlios.de/>
803 803
804source "drivers/media/video/gspca/Kconfig"
805
804source "drivers/media/video/pvrusb2/Kconfig" 806source "drivers/media/video/pvrusb2/Kconfig"
805 807
806source "drivers/media/video/em28xx/Kconfig" 808source "drivers/media/video/em28xx/Kconfig"
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
new file mode 100644
index 000000000000..a04e413e1258
--- /dev/null
+++ b/drivers/media/video/gspca/Kconfig
@@ -0,0 +1,13 @@
1config USB_GSPCA
2 tristate "USB GSPCA driver"
3 depends on VIDEO_V4L2
4 ---help---
5 Say Y here if you want support for various USB cameras.
6
7 See <file:Documentation/video4linux/gspca.txt> for more info.
8
9 This driver uses the Video For Linux API. You must say Y or M to
10 "Video For Linux" to use this driver.
11
12 To compile this driver as modules, choose M here: the
13 modules will be called gspca_xxxx.
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
new file mode 100644
index 000000000000..885d4454d8e5
--- /dev/null
+++ b/drivers/media/video/gspca/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_GSPCA) += gspca_main.o gspca_stk014.o
2
3gspca_main-objs := gspca.o
4gspca_stk014-objs := stk014.o
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
new file mode 100644
index 000000000000..4fe082ff7074
--- /dev/null
+++ b/drivers/media/video/gspca/gspca.c
@@ -0,0 +1,1750 @@
1/*
2 * Main USB camera driver
3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#define MODULE_NAME "gspca"
22
23#include <linux/init.h>
24#include <linux/fs.h>
25#include <linux/vmalloc.h>
26#include <linux/sched.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/string.h>
30#include <linux/pagemap.h>
31#include <asm/io.h>
32#include <asm/page.h>
33#include <asm/uaccess.h>
34#include <linux/jiffies.h>
35
36#include "gspca.h"
37
38MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
39MODULE_DESCRIPTION("GSPCA USB Camera Driver");
40MODULE_LICENSE("GPL");
41
42#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 26)
43static const char version[] = "0.0.26";
44
45static int video_nr = -1;
46
47static int comp_fac = 30; /* Buffer size ratio when compressed in % */
48
49#ifdef GSPCA_DEBUG
50int gspca_debug = D_ERR | D_PROBE;
51EXPORT_SYMBOL(gspca_debug);
52
53static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)
54{
55 if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {
56 PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d",
57 txt,
58 pixfmt & 0xff,
59 (pixfmt >> 8) & 0xff,
60 (pixfmt >> 16) & 0xff,
61 pixfmt >> 24,
62 w, h);
63 } else {
64 PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d",
65 txt,
66 pixfmt,
67 w, h);
68 }
69}
70#else
71#define PDEBUG_MODE(txt, pixfmt, w, h)
72#endif
73
74/*
75 * VMA operations.
76 */
77static void gspca_vm_open(struct vm_area_struct *vma)
78{
79 struct gspca_frame *frame = vma->vm_private_data;
80
81 frame->vma_use_count++;
82 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED;
83}
84
85static void gspca_vm_close(struct vm_area_struct *vma)
86{
87 struct gspca_frame *frame = vma->vm_private_data;
88
89 if (--frame->vma_use_count <= 0)
90 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;
91}
92
93static struct vm_operations_struct gspca_vm_ops = {
94 .open = gspca_vm_open,
95 .close = gspca_vm_close,
96};
97
98/*
99 * ISOC message interrupt from the USB device
100 *
101 * Analyse each packet and call the subdriver for doing the copy
102 * to the frame buffer.
103 */
104static void isoc_irq(struct urb *urb)
105{
106 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
107 struct gspca_frame *frame;
108 unsigned char *data; /* address of data in the iso message */
109 int i, j, len, st;
110 cam_pkt_op pkt_scan;
111
112 PDEBUG(D_PACK, "isoc irq");
113 if (!gspca_dev->streaming)
114 return;
115 pkt_scan = gspca_dev->sd_desc->pkt_scan;
116 for (i = 0; i < urb->number_of_packets; i++) {
117
118 /* check the availability of the frame buffer */
119 j = gspca_dev->fr_i;
120 j = gspca_dev->fr_queue[j];
121 frame = &gspca_dev->frame[j];
122 if ((frame->v4l2_buf.flags
123 & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
124 != V4L2_BUF_FLAG_QUEUED) {
125 gspca_dev->last_packet_type = DISCARD_PACKET;
126 break;
127 }
128
129 /* check the packet status and length */
130 len = urb->iso_frame_desc[i].actual_length;
131 st = urb->iso_frame_desc[i].status;
132 if (st) {
133 PDEBUG(D_ERR, "ISOC data error: [%d] len=%d, status=%d",
134 i, len, st);
135 gspca_dev->last_packet_type = DISCARD_PACKET;
136 continue;
137 }
138 if (len == 0)
139 continue;
140
141 /* let the packet be analyzed by the subdriver */
142 PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
143 i, urb->iso_frame_desc[i].offset, len);
144 data = (unsigned char *) urb->transfer_buffer
145 + urb->iso_frame_desc[i].offset;
146 pkt_scan(gspca_dev, frame, data, len);
147 }
148
149 /* resubmit the URB */
150 urb->status = 0;
151 st = usb_submit_urb(urb, GFP_ATOMIC);
152 if (st < 0)
153 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
154}
155
156/*
157 * add data to the current frame
158 *
159 * This function is called by the subdrivers at interrupt level.
160 * To build a frame, these ones must add
161 * - one FIRST_PACKET
162 * - 0 or many INTER_PACKETs
163 * - one LAST_PACKET
164 * DISCARD_PACKET invalidates the whole frame.
165 * On LAST_PACKET, a new frame is returned.
166 */
167struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
168 int packet_type,
169 struct gspca_frame *frame,
170 unsigned char *data,
171 int len)
172{
173 int i, j;
174
175 PDEBUG(D_PACK, "add t:%d l:%d %02x %02x %02x %02x...",
176 packet_type, len, data[0], data[1], data[2], data[3]);
177
178 /* when start of a new frame, if the current frame buffer
179 * is not queued, discard the whole frame */
180 if (packet_type == FIRST_PACKET) {
181 if ((frame->v4l2_buf.flags
182 & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
183 != V4L2_BUF_FLAG_QUEUED) {
184 gspca_dev->last_packet_type = DISCARD_PACKET;
185 return frame;
186 }
187 frame->data_end = frame->data;
188 jiffies_to_timeval(get_jiffies_64(),
189 &frame->v4l2_buf.timestamp);
190 frame->v4l2_buf.sequence = ++gspca_dev->sequence;
191 } else if (gspca_dev->last_packet_type == DISCARD_PACKET)
192 return frame;
193
194 /* append the packet in the frame buffer */
195 if (len > 0) {
196 if (frame->data_end - frame->data + len
197 > frame->v4l2_buf.length) {
198 PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
199 frame->data_end - frame->data + len,
200 frame->v4l2_buf.length);
201 packet_type = DISCARD_PACKET;
202 } else {
203 if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR)
204 memcpy(frame->data_end, data, len);
205 else
206 copy_to_user(frame->data_end, data, len);
207 frame->data_end += len;
208 }
209 }
210 gspca_dev->last_packet_type = packet_type;
211
212 /* if last packet, wake the application and advance in the queue */
213 if (packet_type == LAST_PACKET) {
214 frame->v4l2_buf.bytesused = frame->data_end - frame->data;
215 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
216 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
217 atomic_inc(&gspca_dev->nevent);
218 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
219 i = gspca_dev->fr_i;
220 i = (i + 1) % gspca_dev->nframes;
221 PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
222 frame->v4l2_buf.bytesused,
223 gspca_dev->fr_q,
224 i,
225 gspca_dev->fr_o);
226 j = gspca_dev->fr_queue[i];
227 frame = &gspca_dev->frame[j];
228 gspca_dev->fr_i = i;
229 }
230 return frame;
231}
232EXPORT_SYMBOL(gspca_frame_add);
233
234static int gspca_is_compressed(__u32 format)
235{
236 switch (format) {
237 case V4L2_PIX_FMT_MJPEG:
238 case V4L2_PIX_FMT_JPEG:
239 return 1;
240 }
241 return 0;
242}
243
244static void *rvmalloc(unsigned long size)
245{
246 void *mem;
247 unsigned long adr;
248
249 size = PAGE_ALIGN(size);
250 mem = vmalloc_32(size);
251 if (mem != 0) {
252 memset(mem, 0, size);
253 adr = (unsigned long) mem;
254 while ((long) size > 0) {
255 SetPageReserved(vmalloc_to_page((void *) adr));
256 adr += PAGE_SIZE;
257 size -= PAGE_SIZE;
258 }
259 }
260 return mem;
261}
262
263static void rvfree(void *mem, unsigned long size)
264{
265 unsigned long adr;
266
267 if (!mem)
268 return;
269 adr = (unsigned long) mem;
270 while ((long) size > 0) {
271 ClearPageReserved(vmalloc_to_page((void *) adr));
272 adr += PAGE_SIZE;
273 size -= PAGE_SIZE;
274 }
275 vfree(mem);
276}
277
278static int frame_alloc(struct gspca_dev *gspca_dev,
279 unsigned int count,
280 unsigned int frsz,
281 enum v4l2_memory memory)
282{
283 int i, ret = 0;
284
285 PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
286 if (gspca_dev->nframes != 0) {
287 PDEBUG(D_ERR|D_STREAM, "alloc frame already done");
288 return -EBUSY;
289 }
290 if (count > GSPCA_MAX_FRAMES)
291 count = GSPCA_MAX_FRAMES;
292 /* if compressed, reduce the buffer size */
293 if (gspca_is_compressed(gspca_dev->pixfmt))
294 frsz = (frsz * comp_fac) / 100;
295 frsz = PAGE_ALIGN(frsz);
296 PDEBUG(D_STREAM, "new fr_sz: %d", frsz);
297 gspca_dev->frsz = frsz;
298 if (memory == V4L2_MEMORY_MMAP) {
299 gspca_dev->frbuf = rvmalloc(frsz * count);
300 if (!gspca_dev->frbuf) {
301 err("frame alloc failed");
302 return -ENOMEM;
303 }
304 }
305 gspca_dev->nframes = count;
306 for (i = 0; i < count; i++) {
307 gspca_dev->frame[i].v4l2_buf.index = i;
308 gspca_dev->frame[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
309 gspca_dev->frame[i].v4l2_buf.flags = 0;
310 gspca_dev->frame[i].v4l2_buf.field = V4L2_FIELD_NONE;
311 gspca_dev->frame[i].v4l2_buf.length = frsz;
312 gspca_dev->frame[i].v4l2_buf.memory = memory;
313 if (memory == V4L2_MEMORY_MMAP) {
314 gspca_dev->frame[i].data
315 = gspca_dev->frame[i].data_end
316 = gspca_dev->frbuf + i * frsz;
317 gspca_dev->frame[i].v4l2_buf.m.offset = i * frsz;
318 }
319 gspca_dev->frame[i].v4l2_buf.flags = 0; /* buf in app space */
320 }
321 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
322 gspca_dev->last_packet_type = DISCARD_PACKET;
323 gspca_dev->sequence = 0;
324 atomic_set(&gspca_dev->nevent, 0);
325 return ret;
326}
327
328static void frame_free(struct gspca_dev *gspca_dev)
329{
330 int i;
331
332 PDEBUG(D_STREAM, "frame free");
333 if (gspca_dev->frbuf != 0) {
334 rvfree(gspca_dev->frbuf,
335 gspca_dev->nframes * gspca_dev->frsz);
336 gspca_dev->frbuf = NULL;
337 for (i = 0; i < gspca_dev->nframes; i++)
338 gspca_dev->frame[i].data = NULL;
339 }
340 gspca_dev->nframes = 0;
341}
342
343static int gspca_kill_transfer(struct gspca_dev *gspca_dev)
344{
345 struct urb *urb;
346 unsigned int i;
347
348 PDEBUG(D_STREAM, "kill transfer");
349 gspca_dev->streaming = 0;
350 for (i = 0; i < NURBS; ++i) {
351 urb = gspca_dev->pktbuf[i].urb;
352 if (urb == NULL)
353 continue;
354
355 gspca_dev->pktbuf[i].urb = NULL;
356 usb_kill_urb(urb);
357
358 /* urb->transfer_buffer_length is not touched by USB core,
359 * so we can use it here as the buffer length */
360 if (gspca_dev->pktbuf[i].data) {
361 usb_buffer_free(gspca_dev->dev,
362 urb->transfer_buffer_length,
363 gspca_dev->pktbuf[i].data,
364 urb->transfer_dma);
365 gspca_dev->pktbuf[i].data = NULL;
366 }
367 usb_free_urb(urb);
368 }
369 return 0;
370}
371
372/*
373 * search an input isochronous endpoint in an alternate setting
374 */
375static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
376 __u8 epaddr)
377{
378 struct usb_host_endpoint *ep;
379 int i, attr;
380
381 epaddr |= USB_DIR_IN;
382 for (i = 0; i < alt->desc.bNumEndpoints; i++) {
383 ep = &alt->endpoint[i];
384 if (ep->desc.bEndpointAddress == epaddr) {
385 attr = ep->desc.bmAttributes
386 & USB_ENDPOINT_XFERTYPE_MASK;
387 if (attr == USB_ENDPOINT_XFER_ISOC)
388 return ep;
389 break;
390 }
391 }
392 return NULL;
393}
394
395/*
396 * search an input isochronous endpoint
397 *
398 * The endpoint is defined by the subdriver.
399 * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep).
400 * This routine may be called many times when the bandwidth is too small
401 * (the bandwidth is checked on urb submit).
402 */
403struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
404{
405 struct usb_interface *intf;
406 struct usb_host_endpoint *ep;
407 int i, ret;
408
409 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
410 i = gspca_dev->alt; /* previous alt setting */
411 while (--i > 0) { /* alt 0 is unusable */
412 ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr);
413 if (ep)
414 break;
415 }
416 if (i <= 0) {
417 err("no ISOC endpoint found");
418 return NULL;
419 }
420 PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x",
421 i, ep->desc.bEndpointAddress);
422 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
423 if (ret < 0) {
424 err("set interface err %d", ret);
425 return NULL;
426 }
427 gspca_dev->alt = i;
428 return ep;
429}
430
431/*
432 * create the isochronous URBs
433 */
434static int create_urbs(struct gspca_dev *gspca_dev,
435 struct usb_host_endpoint *ep)
436{
437 struct urb *urb;
438 int n, i, psize, npkt, bsize;
439
440 /* calculate the packet size and the number of packets */
441 /* the URB buffer size must be a power of 2 */
442 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
443 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
444 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
445 npkt = ISO_MAX_SIZE / psize;
446 if (npkt > ISO_MAX_PKT)
447 npkt = ISO_MAX_PKT;
448 bsize = psize * npkt;
449 for (n = ISO_MAX_SIZE; n > 0; n >>= 1) {
450 if (n & bsize) /* !! assume ISO_MAX_SIZE is a power of 2 */
451 break;
452 }
453 if (n != 0) {
454 npkt = n / psize;
455 bsize = psize * npkt;
456 }
457 PDEBUG(D_STREAM,
458 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize);
459 for (n = 0; n < NURBS; n++) {
460 urb = usb_alloc_urb(npkt, GFP_KERNEL);
461 if (!urb) {
462 err("usb_alloc_urb failed");
463 return -ENOMEM;
464 }
465 gspca_dev->pktbuf[n].data = usb_buffer_alloc(gspca_dev->dev,
466 bsize,
467 GFP_KERNEL,
468 &urb->transfer_dma);
469
470 if (gspca_dev->pktbuf[n].data == NULL) {
471 usb_free_urb(urb);
472 gspca_kill_transfer(gspca_dev);
473 err("usb_buffer_urb failed");
474 return -ENOMEM;
475 }
476 gspca_dev->pktbuf[n].urb = urb;
477 urb->dev = gspca_dev->dev;
478 urb->context = gspca_dev;
479 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
480 ep->desc.bEndpointAddress);
481 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
482 urb->interval = ep->desc.bInterval;
483 urb->transfer_buffer = gspca_dev->pktbuf[n].data;
484 urb->complete = isoc_irq;
485 urb->number_of_packets = npkt;
486 urb->transfer_buffer_length = bsize;
487 for (i = 0; i < npkt; i++) {
488 urb->iso_frame_desc[i].length = psize;
489 urb->iso_frame_desc[i].offset = psize * i;
490 }
491 }
492 return 0;
493}
494
495/*
496 * start the USB transfer
497 */
498static int gspca_init_transfer(struct gspca_dev *gspca_dev)
499{
500 struct usb_interface *intf;
501 struct usb_host_endpoint *ep;
502 int n, ret;
503
504 ret = mutex_lock_interruptible(&gspca_dev->usb_lock);
505 if (ret < 0)
506 return ret;
507
508 /* set the max alternate setting and loop until urb submit succeeds */
509 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
510 gspca_dev->alt = intf->num_altsetting;
511 for (;;) {
512 PDEBUG(D_STREAM, "init transfer nbalt %d", gspca_dev->alt);
513 ep = get_isoc_ep(gspca_dev);
514 if (ep == NULL) {
515 ret = -EIO;
516 goto out;
517 }
518 ret = create_urbs(gspca_dev, ep);
519 if (ret < 0)
520 goto out;
521
522 /* start the cam */
523 gspca_dev->sd_desc->start(gspca_dev);
524 gspca_dev->streaming = 1;
525 atomic_set(&gspca_dev->nevent, 0);
526
527 /* submit the URBs */
528 for (n = 0; n < NURBS; n++) {
529 ret = usb_submit_urb(gspca_dev->pktbuf[n].urb,
530 GFP_KERNEL);
531 if (ret < 0) {
532 PDEBUG(D_ERR|D_STREAM,
533 "usb_submit_urb [%d] err %d", n, ret);
534 gspca_kill_transfer(gspca_dev);
535 if (ret == -ENOSPC)
536 break; /* try the previous alt */
537 goto out;
538 }
539 }
540 if (ret >= 0)
541 break;
542 }
543out:
544 mutex_unlock(&gspca_dev->usb_lock);
545 return ret;
546}
547
548static int gspca_set_alt0(struct gspca_dev *gspca_dev)
549{
550 int ret;
551
552 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
553 if (ret < 0)
554 PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret);
555 return ret;
556}
557
558static void gspca_stream_off(struct gspca_dev *gspca_dev)
559{
560 mutex_lock_interruptible(&gspca_dev->usb_lock);
561 gspca_dev->streaming = 0;
562 if (gspca_dev->present) {
563 gspca_dev->sd_desc->stopN(gspca_dev);
564 gspca_kill_transfer(gspca_dev);
565 gspca_set_alt0(gspca_dev);
566 gspca_dev->sd_desc->stop0(gspca_dev);
567 PDEBUG(D_STREAM, "stream off OK");
568 } else {
569 gspca_kill_transfer(gspca_dev);
570 atomic_inc(&gspca_dev->nevent);
571 wake_up_interruptible(&gspca_dev->wq);
572 PDEBUG(D_ERR|D_STREAM, "stream off no device ??");
573 }
574 mutex_unlock(&gspca_dev->usb_lock);
575}
576
577static int gspca_set_default_mode(struct gspca_dev *gspca_dev)
578{
579 int i;
580
581 i = gspca_dev->cam.nmodes - 1; /* take the highest mode */
582 gspca_dev->curr_mode = i;
583 gspca_dev->width = gspca_dev->cam.cam_mode[i].width;
584 gspca_dev->height = gspca_dev->cam.cam_mode[i].height;
585 gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt;
586 return 0;
587}
588
589static int wxh_to_mode(struct gspca_dev *gspca_dev,
590 int width, int height)
591{
592 int i;
593
594 for (i = gspca_dev->cam.nmodes - 1; --i >= 0; ) {
595 if (width > gspca_dev->cam.cam_mode[i].width)
596 break;
597 }
598 i++;
599 while (i < gspca_dev->cam.nmodes - 1
600 && width == gspca_dev->cam.cam_mode[i + 1].width
601 && height < gspca_dev->cam.cam_mode[i + 1].height)
602 i++;
603 return i;
604}
605
606static __u32 get_v4l2_depth(__u32 pixfmt)
607{
608 switch (pixfmt) {
609 case V4L2_PIX_FMT_BGR32:
610 case V4L2_PIX_FMT_RGB32:
611 return 32;
612 case V4L2_PIX_FMT_RGB24:
613 case V4L2_PIX_FMT_BGR24:
614 return 24;
615 case V4L2_PIX_FMT_RGB565:
616 case V4L2_PIX_FMT_YUYV: /* packed 4.2.2 */
617 case V4L2_PIX_FMT_YYUV:
618 return 16;
619 case V4L2_PIX_FMT_YUV420: /* planar 4.2.0 */
620 return 12;
621 case V4L2_PIX_FMT_MJPEG:
622 case V4L2_PIX_FMT_JPEG:
623 case V4L2_PIX_FMT_SBGGR8: /* Bayer */
624 return 8;
625 }
626 PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c",
627 pixfmt & 0xff,
628 (pixfmt >> 8) & 0xff,
629 (pixfmt >> 16) & 0xff,
630 pixfmt >> 24);
631 return -EINVAL;
632}
633
634/*
635 * search a mode with the right pixel format
636 */
637static int gspca_get_mode(struct gspca_dev *gspca_dev,
638 int mode,
639 int pixfmt)
640{
641 int modeU, modeD;
642
643 modeU = modeD = mode;
644 while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) {
645 if (--modeD >= 0) {
646 if (gspca_dev->cam.cam_mode[modeD].pixfmt == pixfmt)
647 return modeD;
648 }
649 if (++modeU < gspca_dev->cam.nmodes) {
650 if (gspca_dev->cam.cam_mode[modeU].pixfmt == pixfmt)
651 return modeU;
652 }
653 }
654 return -EINVAL;
655}
656
657static int vidioc_enum_fmt_cap(struct file *file, void *priv,
658 struct v4l2_fmtdesc *fmtdesc)
659{
660 struct gspca_dev *gspca_dev = priv;
661 int i, j, index;
662 __u32 fmt_tb[8];
663
664 PDEBUG(D_CONF, "enum fmt cap");
665
666 /* give an index to each format */
667 index = 0;
668 j = 0;
669 for (i = gspca_dev->cam.nmodes; --i >= 0; ) {
670 fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixfmt;
671 j = 0;
672 for (;;) {
673 if (fmt_tb[j] == fmt_tb[index])
674 break;
675 j++;
676 }
677 if (j == index) {
678 if (fmtdesc->index == index)
679 break; /* new format */
680 index++;
681 if (index >= sizeof fmt_tb / sizeof fmt_tb[0])
682 return -EINVAL;
683 }
684 }
685 if (i < 0)
686 return -EINVAL; /* no more format */
687
688 fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
689 fmtdesc->pixelformat = fmt_tb[index];
690 if (gspca_is_compressed(fmt_tb[index]))
691 fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
692 fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
693 fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
694 fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
695 fmtdesc->description[3] = fmtdesc->pixelformat >> 24;
696 fmtdesc->description[4] = '\0';
697 return 0;
698}
699
700static int gspca_get_buff_size(struct gspca_dev *gspca_dev)
701{
702 unsigned int size;
703
704 size = gspca_dev->width * gspca_dev->height
705 * get_v4l2_depth(gspca_dev->pixfmt) / 8;
706 if (!size)
707 return -ENOMEM;
708 return size;
709}
710
711static int vidioc_g_fmt_cap(struct file *file, void *priv,
712 struct v4l2_format *fmt)
713{
714 struct gspca_dev *gspca_dev = priv;
715
716 fmt->fmt.pix.width = gspca_dev->width;
717 fmt->fmt.pix.height = gspca_dev->height;
718 fmt->fmt.pix.pixelformat = gspca_dev->pixfmt;
719#ifdef GSPCA_DEBUG
720 if (gspca_debug & D_CONF) {
721 PDEBUG_MODE("get fmt cap",
722 fmt->fmt.pix.pixelformat,
723 fmt->fmt.pix.width,
724 fmt->fmt.pix.height);
725 }
726#endif
727 fmt->fmt.pix.field = V4L2_FIELD_NONE;
728 fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat)
729 * fmt->fmt.pix.width / 8;
730 fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline
731 * fmt->fmt.pix.height;
732/* (should be in the subdriver) */
733 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
734 fmt->fmt.pix.priv = 0;
735 return 0;
736}
737
738static int try_fmt_cap(struct file *file,
739 void *priv,
740 struct v4l2_format *fmt)
741{
742 struct gspca_dev *gspca_dev = priv;
743 int w, h, mode, mode2, frsz;
744
745 w = (int) fmt->fmt.pix.width;
746 h = (int) fmt->fmt.pix.height;
747#ifdef GSPCA_DEBUG
748 if (gspca_debug & D_CONF)
749 PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
750#endif
751 /* search the closest mode for width and height */
752 mode = wxh_to_mode(gspca_dev, w, h);
753
754 /* OK if right palette */
755 if (gspca_dev->cam.cam_mode[mode].pixfmt != fmt->fmt.pix.pixelformat) {
756
757 /* else, search the closest mode with the same pixel format */
758 mode2 = gspca_get_mode(gspca_dev, mode,
759 fmt->fmt.pix.pixelformat);
760 if (mode2 >= 0)
761 mode = mode2;
762 else {
763
764 /* no chance, return this mode */
765 fmt->fmt.pix.pixelformat
766 = gspca_dev->cam.cam_mode[mode].pixfmt;
767#ifdef GSPCA_DEBUG
768 if (gspca_debug & D_CONF) {
769 PDEBUG_MODE("new format",
770 fmt->fmt.pix.pixelformat,
771 gspca_dev->cam.cam_mode[mode].width,
772 gspca_dev->cam.cam_mode[mode].height);
773 }
774#endif
775 }
776 }
777 fmt->fmt.pix.width = gspca_dev->cam.cam_mode[mode].width;
778 fmt->fmt.pix.height = gspca_dev->cam.cam_mode[mode].height;
779 fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat)
780 * fmt->fmt.pix.width / 8;
781 frsz = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
782 if (gspca_is_compressed(fmt->fmt.pix.pixelformat))
783 frsz = (frsz * comp_fac) / 100;
784 fmt->fmt.pix.sizeimage = frsz;
785 return mode; /* used when s_fmt */
786}
787
788static int vidioc_try_fmt_cap(struct file *file,
789 void *priv,
790 struct v4l2_format *fmt)
791{
792 int ret;
793
794/* mutex_lock_interruptible(&gspca_dev->queue_lock); */
795 ret = try_fmt_cap(file, priv, fmt);
796/* mutex_unlock(&gspca_dev->queue_lock); */
797 if (ret < 0)
798 return ret;
799 return 0;
800}
801
802static int vidioc_s_fmt_cap(struct file *file, void *priv,
803 struct v4l2_format *fmt)
804{
805 struct gspca_dev *gspca_dev = priv;
806 int ret, was_streaming;
807
808#ifdef GSPCA_DEBUG
809 if (gspca_debug & D_CONF) {
810 PDEBUG_MODE("set fmt cap",
811 fmt->fmt.pix.pixelformat,
812 fmt->fmt.pix.width, fmt->fmt.pix.height);
813 }
814#endif
815 mutex_lock_interruptible(&gspca_dev->queue_lock);
816 ret = try_fmt_cap(file, priv, fmt);
817 if (ret < 0)
818 goto out;
819
820 if (ret == gspca_dev->curr_mode)
821 goto out; /* same mode */
822 was_streaming = gspca_dev->streaming;
823 if (was_streaming != 0)
824 gspca_stream_off(gspca_dev);
825 gspca_dev->width = (int) fmt->fmt.pix.width;
826 gspca_dev->height = (int) fmt->fmt.pix.height;
827 gspca_dev->pixfmt = fmt->fmt.pix.pixelformat;
828 gspca_dev->curr_mode = ret;
829 if (was_streaming)
830 ret = gspca_init_transfer(gspca_dev);
831out:
832 mutex_unlock(&gspca_dev->queue_lock);
833 return ret;
834}
835
836static int dev_open(struct inode *inode, struct file *file)
837{
838 struct gspca_dev *gspca_dev;
839 int ret;
840
841 PDEBUG(D_STREAM, "opening");
842 gspca_dev = (struct gspca_dev *) video_devdata(file);
843 ret = mutex_lock_interruptible(&gspca_dev->queue_lock);
844 if (ret < 0)
845 return ret;
846 if (!gspca_dev->present) {
847 ret = -ENODEV;
848 goto out;
849 }
850
851 /* if not done yet, initialize the sensor */
852 if (gspca_dev->users == 0) {
853 ret = mutex_lock_interruptible(&gspca_dev->usb_lock);
854 if (ret < 0)
855 goto out;
856 ret = gspca_dev->sd_desc->open(gspca_dev);
857 mutex_unlock(&gspca_dev->usb_lock);
858 if (ret != 0) {
859 PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
860 goto out;
861 }
862 } else if (gspca_dev->users > 8) { /* (arbitrary value) */
863 ret = -EBUSY;
864 goto out;
865 }
866 gspca_dev->users++;
867 file->private_data = gspca_dev;
868#ifdef GSPCA_DEBUG
869 /* activate the v4l2 debug */
870 if (gspca_debug & D_CONF)
871 gspca_dev->vdev.debug |= 3;
872 else
873 gspca_dev->vdev.debug &= ~3;
874#endif
875out:
876 mutex_unlock(&gspca_dev->queue_lock);
877 if (ret != 0)
878 PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret);
879 else
880 PDEBUG(D_STREAM, "open OK");
881 return ret;
882}
883
884static int dev_close(struct inode *inode, struct file *file)
885{
886 struct gspca_dev *gspca_dev = file->private_data;
887
888 PDEBUG(D_STREAM, "closing");
889 if (gspca_dev->streaming) {
890 mutex_lock_interruptible(&gspca_dev->queue_lock);
891 gspca_stream_off(gspca_dev);
892 mutex_unlock(&gspca_dev->queue_lock);
893 }
894 mutex_lock_interruptible(&gspca_dev->usb_lock);
895 gspca_dev->sd_desc->close(gspca_dev);
896 mutex_unlock(&gspca_dev->usb_lock);
897 atomic_inc(&gspca_dev->nevent);
898 wake_up_interruptible(&gspca_dev->wq); /* wake blocked processes */
899 schedule();
900 mutex_lock_interruptible(&gspca_dev->queue_lock);
901 frame_free(gspca_dev);
902 file->private_data = NULL;
903 gspca_dev->users--;
904 mutex_unlock(&gspca_dev->queue_lock);
905 PDEBUG(D_STREAM, "closed");
906 return 0;
907}
908
909static int vidioc_querycap(struct file *file, void *priv,
910 struct v4l2_capability *cap)
911{
912 struct gspca_dev *gspca_dev = priv;
913
914 PDEBUG(D_CONF, "querycap");
915 memset(cap, 0, sizeof *cap);
916 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
917 strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
918 strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
919 sizeof cap->bus_info);
920 cap->version = DRIVER_VERSION_NUMBER;
921 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
922 | V4L2_CAP_STREAMING
923 | V4L2_CAP_READWRITE;
924 return 0;
925}
926
927static int vidioc_queryctrl(struct file *file, void *priv,
928 struct v4l2_queryctrl *q_ctrl)
929{
930 struct gspca_dev *gspca_dev = priv;
931 int i;
932
933 PDEBUG(D_CONF, "queryctrl");
934 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
935 if (q_ctrl->id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
936 memcpy(q_ctrl,
937 &gspca_dev->sd_desc->ctrls[i].qctrl,
938 sizeof *q_ctrl);
939 return 0;
940 }
941 }
942 if (q_ctrl->id >= V4L2_CID_BASE
943 && q_ctrl->id <= V4L2_CID_LASTP1) {
944 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
945 return 0;
946 }
947 return -EINVAL;
948}
949
950static int vidioc_s_ctrl(struct file *file, void *priv,
951 struct v4l2_control *ctrl)
952{
953 struct gspca_dev *gspca_dev = priv;
954 struct ctrl *ctrls;
955 int i, ret;
956
957 PDEBUG(D_CONF, "set ctrl");
958 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
959 i < gspca_dev->sd_desc->nctrls;
960 i++, ctrls++) {
961 if (ctrl->id != ctrls->qctrl.id)
962 continue;
963 if (ctrl->value < ctrls->qctrl.minimum
964 && ctrl->value > ctrls->qctrl.maximum)
965 return -ERANGE;
966 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
967 mutex_lock_interruptible(&gspca_dev->usb_lock);
968 ret = ctrls->set(gspca_dev, ctrl->value);
969 mutex_unlock(&gspca_dev->usb_lock);
970 return ret;
971 }
972 return -EINVAL;
973}
974
975static int vidioc_g_ctrl(struct file *file, void *priv,
976 struct v4l2_control *ctrl)
977{
978 struct gspca_dev *gspca_dev = priv;
979
980 struct ctrl *ctrls;
981 int i, ret;
982
983 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
984 i < gspca_dev->sd_desc->nctrls;
985 i++, ctrls++) {
986 if (ctrl->id != ctrls->qctrl.id)
987 continue;
988 mutex_lock_interruptible(&gspca_dev->usb_lock);
989 ret = ctrls->get(gspca_dev, &ctrl->value);
990 mutex_unlock(&gspca_dev->usb_lock);
991 return ret;
992 }
993 return -EINVAL;
994}
995
996static int vidioc_querymenu(struct file *file, void *priv,
997 struct v4l2_querymenu *qmenu)
998{
999 struct gspca_dev *gspca_dev = priv;
1000
1001 if (!gspca_dev->sd_desc->querymenu)
1002 return -EINVAL;
1003 return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);
1004}
1005
1006static int vidioc_enum_input(struct file *file, void *priv,
1007 struct v4l2_input *input)
1008{
1009 struct gspca_dev *gspca_dev = priv;
1010
1011 if (input->index != 0)
1012 return -EINVAL;
1013 memset(input, 0, sizeof *input);
1014 input->type = V4L2_INPUT_TYPE_CAMERA;
1015 strncpy(input->name, gspca_dev->sd_desc->name,
1016 sizeof input->name);
1017 return 0;
1018}
1019
1020static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1021{
1022 *i = 0;
1023 return 0;
1024}
1025
1026static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1027{
1028 if (i > 0)
1029 return -EINVAL;
1030 return (0);
1031}
1032
1033static int vidioc_reqbufs(struct file *file, void *priv,
1034 struct v4l2_requestbuffers *rb)
1035{
1036 struct gspca_dev *gspca_dev = priv;
1037 int frsz, ret;
1038
1039 PDEBUG(D_STREAM, "reqbufs %d", rb->count);
1040 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1041 return -EINVAL;
1042 if (rb->memory != V4L2_MEMORY_MMAP
1043 && rb->memory != V4L2_MEMORY_USERPTR)
1044 return -EINVAL;
1045 if (rb->count == 0)
1046 return -EINVAL;
1047 frsz = gspca_get_buff_size(gspca_dev);
1048 if (frsz < 0)
1049 return frsz;
1050 ret = mutex_lock_interruptible(&gspca_dev->queue_lock);
1051 if (ret < 0)
1052 return ret;
1053 ret = frame_alloc(gspca_dev,
1054 rb->count,
1055 (unsigned int) frsz,
1056 rb->memory);
1057 if (ret == 0)
1058 rb->count = gspca_dev->nframes;
1059 mutex_unlock(&gspca_dev->queue_lock);
1060 PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);
1061 return ret;
1062}
1063
1064static int vidioc_querybuf(struct file *file, void *priv,
1065 struct v4l2_buffer *v4l2_buf)
1066{
1067 struct gspca_dev *gspca_dev = priv;
1068 struct gspca_frame *frame;
1069
1070 PDEBUG(D_STREAM, "querybuf");
1071 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1072 || v4l2_buf->index < 0
1073 || v4l2_buf->index >= gspca_dev->nframes)
1074 return -EINVAL;
1075
1076 frame = &gspca_dev->frame[v4l2_buf->index];
1077 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
1078 return 0;
1079}
1080
1081static int vidioc_streamon(struct file *file, void *priv,
1082 enum v4l2_buf_type buf_type)
1083{
1084 struct gspca_dev *gspca_dev = priv;
1085 int ret;
1086
1087 PDEBUG(D_STREAM, "stream on");
1088 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1089 return -EINVAL;
1090 ret = mutex_lock_interruptible(&gspca_dev->queue_lock);
1091 if (ret < 0)
1092 return ret;
1093 if (!gspca_dev->present) {
1094 ret = -ENODEV;
1095 goto out;
1096 }
1097 if (gspca_dev->nframes == 0) {
1098 ret = -EINVAL;
1099 goto out;
1100 }
1101 if (!gspca_dev->streaming) {
1102 ret = gspca_init_transfer(gspca_dev);
1103 if (ret < 0)
1104 goto out;
1105 }
1106#ifdef GSPCA_DEBUG
1107 if (gspca_debug & D_STREAM) {
1108 PDEBUG_MODE("stream on OK",
1109 gspca_dev->pixfmt,
1110 gspca_dev->width,
1111 gspca_dev->height);
1112 }
1113#endif
1114out:
1115 mutex_unlock(&gspca_dev->queue_lock);
1116 return ret;
1117}
1118
1119static int vidioc_streamoff(struct file *file, void *priv,
1120 enum v4l2_buf_type buf_type)
1121{
1122 struct gspca_dev *gspca_dev = priv;
1123
1124 PDEBUG(D_STREAM, "stream off");
1125 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1126 return -EINVAL;
1127 if (gspca_dev->streaming) {
1128 mutex_lock_interruptible(&gspca_dev->queue_lock);
1129 gspca_stream_off(gspca_dev);
1130 mutex_unlock(&gspca_dev->queue_lock);
1131 }
1132 return 0;
1133}
1134
1135static int vidioc_g_jpegcomp(struct file *file, void *priv,
1136 struct v4l2_jpegcompression *jpegcomp)
1137{
1138 struct gspca_dev *gspca_dev = priv;
1139 int ret;
1140
1141 if (!gspca_dev->sd_desc->get_jcomp)
1142 return -EINVAL;
1143 mutex_lock_interruptible(&gspca_dev->usb_lock);
1144 ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
1145 mutex_unlock(&gspca_dev->usb_lock);
1146 return ret;
1147}
1148
1149static int vidioc_s_jpegcomp(struct file *file, void *priv,
1150 struct v4l2_jpegcompression *jpegcomp)
1151{
1152 struct gspca_dev *gspca_dev = priv;
1153 int ret;
1154
1155 mutex_lock_interruptible(&gspca_dev->usb_lock);
1156 if (!gspca_dev->sd_desc->set_jcomp)
1157 return -EINVAL;
1158 ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
1159 mutex_unlock(&gspca_dev->usb_lock);
1160 return ret;
1161}
1162
1163static int vidioc_g_parm(struct file *filp, void *priv,
1164 struct v4l2_streamparm *parm)
1165{
1166 struct gspca_dev *gspca_dev = priv;
1167
1168 memset(parm, 0, sizeof parm);
1169 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1170 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1171 return 0;
1172}
1173
1174static int vidioc_s_parm(struct file *filp, void *priv,
1175 struct v4l2_streamparm *parm)
1176{
1177 struct gspca_dev *gspca_dev = priv;
1178 int n;
1179
1180 mutex_lock_interruptible(&gspca_dev->usb_lock);
1181 n = parm->parm.capture.readbuffers;
1182 if (n == 0 || n > GSPCA_MAX_FRAMES)
1183 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1184 else
1185 gspca_dev->nbufread = n;
1186 mutex_unlock(&gspca_dev->usb_lock);
1187 return 0;
1188}
1189
1190#ifdef CONFIG_VIDEO_V4L1_COMPAT
1191static int vidiocgmbuf(struct file *file, void *priv,
1192 struct video_mbuf *mbuf)
1193{
1194 struct gspca_dev *gspca_dev = file->private_data;
1195 int i;
1196
1197 PDEBUG(D_STREAM, "cgmbuf");
1198 if (gspca_dev->nframes == 0) {
1199 struct v4l2_requestbuffers rb;
1200 int ret;
1201
1202 memset(&rb, 0, sizeof rb);
1203 rb.count = 4;
1204 rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1205 rb.memory = V4L2_MEMORY_MMAP;
1206 ret = vidioc_reqbufs(file, priv, &rb);
1207 if (ret != 0)
1208 return ret;
1209 }
1210 mbuf->frames = gspca_dev->nframes;
1211 mbuf->size = gspca_dev->frsz * gspca_dev->nframes;
1212 for (i = 0; i < mbuf->frames; i++)
1213 mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset;
1214 return 0;
1215}
1216#endif
1217
1218static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1219{
1220 struct gspca_dev *gspca_dev = file->private_data;
1221 struct gspca_frame *frame = 0;
1222 struct page *page;
1223 unsigned long addr, start, size;
1224 int i, ret;
1225#ifdef CONFIG_VIDEO_V4L1_COMPAT
1226 int compat = 0;
1227#endif
1228
1229 start = vma->vm_start;
1230 size = vma->vm_end - vma->vm_start;
1231 PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
1232
1233 ret = mutex_lock_interruptible(&gspca_dev->queue_lock);
1234 if (ret < 0)
1235 return ret;
1236/* sanity check disconnect, in use, no memory available */
1237 if (!gspca_dev->present) {
1238 ret = -ENODEV;
1239 goto done;
1240 }
1241
1242 for (i = 0; i < gspca_dev->nframes; ++i) {
1243 if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {
1244 PDEBUG(D_STREAM, "mmap bad memory type");
1245 break;
1246 }
1247 if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)
1248 == vma->vm_pgoff) {
1249 frame = &gspca_dev->frame[i];
1250 break;
1251 }
1252 }
1253 if (frame == 0) {
1254 PDEBUG(D_STREAM, "mmap no frame buffer found");
1255 ret = -EINVAL;
1256 goto done;
1257 }
1258#ifdef CONFIG_VIDEO_V4L1_COMPAT
1259 if (i == 0 && size == frame->v4l2_buf.length * gspca_dev->nframes)
1260 compat = 1;
1261 else
1262#endif
1263 if (size != frame->v4l2_buf.length) {
1264 PDEBUG(D_STREAM, "mmap bad size");
1265 ret = -EINVAL;
1266 goto done;
1267 }
1268
1269 /*
1270 * - VM_IO marks the area as being a mmaped region for I/O to a
1271 * device. It also prevents the region from being core dumped.
1272 */
1273 vma->vm_flags |= VM_IO;
1274
1275 addr = (unsigned long) frame->data;
1276 while (size > 0) {
1277 page = vmalloc_to_page((void *) addr);
1278 ret = vm_insert_page(vma, start, page);
1279 if (ret < 0)
1280 goto done;
1281 start += PAGE_SIZE;
1282 addr += PAGE_SIZE;
1283 size -= PAGE_SIZE;
1284 }
1285
1286 vma->vm_ops = &gspca_vm_ops;
1287 vma->vm_private_data = frame;
1288 gspca_vm_open(vma);
1289#ifdef CONFIG_VIDEO_V4L1_COMPAT
1290 if (compat) {
1291/*fixme: ugly*/
1292 for (i = 1; i < gspca_dev->nframes; ++i)
1293 gspca_dev->frame[i].v4l2_buf.flags |=
1294 V4L2_BUF_FLAG_MAPPED;
1295 }
1296#endif
1297done:
1298 mutex_unlock(&gspca_dev->queue_lock);
1299 return ret;
1300}
1301
1302static unsigned int dev_poll(struct file *file, poll_table * wait)
1303{
1304 struct gspca_dev *gspca_dev = file->private_data;
1305 int i, ret;
1306
1307 PDEBUG(D_FRAM, "poll");
1308
1309 poll_wait(file, &gspca_dev->wq, wait);
1310
1311 if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
1312 return POLLERR;
1313 if (gspca_dev->dev == 0
1314 || !gspca_dev->streaming) /* if not streaming */
1315 ret = POLLERR;
1316 else {
1317 i = gspca_dev->fr_o;
1318 i = gspca_dev->fr_queue[i];
1319 if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
1320 ret = POLLIN | POLLRDNORM; /* something to read */
1321 else
1322 ret = 0;
1323 }
1324 mutex_unlock(&gspca_dev->queue_lock);
1325 return ret;
1326}
1327
1328/*
1329 * wait for a video frame
1330 *
1331 * If a frame is ready, its index is returned.
1332 */
1333static int gspca_frame_wait(struct gspca_dev *gspca_dev,
1334 int nonblock_ing)
1335{
1336 struct gspca_frame *frame;
1337 int i, j, ret;
1338
1339 i = gspca_dev->fr_o;
1340 j = gspca_dev->fr_queue[i];
1341 frame = &gspca_dev->frame[j];
1342 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
1343 goto ok;
1344 if (nonblock_ing) /* no frame yet */
1345 return -EAGAIN;
1346
1347 /* wait till a frame is ready */
1348 for (;;) {
1349 ret = wait_event_interruptible(gspca_dev->wq,
1350 atomic_read(&gspca_dev->nevent) > 0);
1351 if (ret != 0)
1352 return ret;
1353 i = gspca_dev->fr_o;
1354 j = gspca_dev->fr_queue[i];
1355 frame = &gspca_dev->frame[j];
1356 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
1357 break;
1358 }
1359
1360ok:
1361 atomic_dec(&gspca_dev->nevent);
1362 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
1363 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
1364 gspca_dev->fr_q,
1365 gspca_dev->fr_i,
1366 gspca_dev->fr_o);
1367 return j;
1368}
1369
1370/*
1371 * dequeue a video buffer
1372 *
1373 * If nonblock_ing is false, block until a buffer is available.
1374 */
1375static int vidioc_dqbuf(struct file *file, void *priv,
1376 struct v4l2_buffer *v4l2_buf)
1377{
1378 struct gspca_dev *gspca_dev = priv;
1379 struct gspca_frame *frame;
1380 int i, ret;
1381
1382 PDEBUG(D_FRAM, "dqbuf");
1383 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1384 || (v4l2_buf->memory != V4L2_MEMORY_MMAP
1385 && v4l2_buf->memory != V4L2_MEMORY_USERPTR))
1386 return -EINVAL;
1387 if (!gspca_dev->streaming)
1388 return -EINVAL;
1389
1390 /* only one read */
1391 if (mutex_lock_interruptible(&gspca_dev->read_lock))
1392 return -ERESTARTSYS;
1393
1394 ret = gspca_frame_wait(gspca_dev, file->f_flags & O_NONBLOCK);
1395 if (ret < 0)
1396 goto done;
1397 i = ret; /* frame index */
1398 frame = &gspca_dev->frame[i];
1399 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
1400 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
1401 PDEBUG(D_FRAM, "dqbuf %d", i);
1402 ret = 0;
1403done:
1404 mutex_unlock(&gspca_dev->read_lock);
1405 return ret;
1406}
1407
1408/*
1409 * queue a video buffer
1410 *
1411 * Attempting to queue a buffer that has already been
1412 * queued will return -EINVAL.
1413 */
1414static int vidioc_qbuf(struct file *file, void *priv,
1415 struct v4l2_buffer *v4l2_buf)
1416{
1417 struct gspca_dev *gspca_dev = priv;
1418 struct gspca_frame *frame;
1419 int i, index, ret;
1420
1421 PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
1422 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1423 return -EINVAL;
1424
1425 index = v4l2_buf->index;
1426 if ((unsigned) index >= gspca_dev->nframes) {
1427 PDEBUG(D_STREAM,
1428 "qbuf idx %d >= %d", index, gspca_dev->nframes);
1429 return -EINVAL;
1430 }
1431 frame = &gspca_dev->frame[index];
1432
1433 if (v4l2_buf->memory != frame->v4l2_buf.memory) {
1434 PDEBUG(D_STREAM, "qbuf bad memory type");
1435 return -EINVAL;
1436 }
1437
1438 ret = mutex_lock_interruptible(&gspca_dev->queue_lock);
1439 if (ret < 0)
1440 return ret;
1441 if (frame->v4l2_buf.flags
1442 & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) {
1443 PDEBUG(D_STREAM, "qbuf bad state");
1444 ret = -EINVAL;
1445 goto out;
1446 }
1447
1448 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
1449 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
1450
1451 if (v4l2_buf->memory == V4L2_MEMORY_USERPTR) {
1452 frame->data = frame->data_end =
1453 (unsigned char *) v4l2_buf->m.userptr;
1454 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
1455 frame->v4l2_buf.length = v4l2_buf->length;
1456 }
1457
1458 /* put the buffer in the 'queued' queue */
1459 i = gspca_dev->fr_q;
1460 gspca_dev->fr_queue[i] = index;
1461 gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
1462 PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
1463 gspca_dev->fr_q,
1464 gspca_dev->fr_i,
1465 gspca_dev->fr_o);
1466
1467 v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
1468 v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;
1469 ret = 0;
1470out:
1471 mutex_unlock(&gspca_dev->queue_lock);
1472 return ret;
1473}
1474
1475static ssize_t dev_read(struct file *file, char __user *data,
1476 size_t count, loff_t *ppos)
1477{
1478 struct gspca_dev *gspca_dev = file->private_data;
1479 struct gspca_frame *frame;
1480 struct v4l2_buffer v4l2_buf;
1481 struct timeval timestamp;
1482 int i, ret, ret2;
1483
1484 PDEBUG(D_FRAM, "read (%p, %d)", data, count);
1485 if (gspca_dev->nframes == 0) {
1486 struct v4l2_requestbuffers rb;
1487
1488 memset(&rb, 0, sizeof rb);
1489 rb.count = gspca_dev->nbufread;
1490 rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1491 rb.memory = V4L2_MEMORY_MMAP;
1492 ret = vidioc_reqbufs(file, gspca_dev, &rb);
1493 if (ret != 0) {
1494 PDEBUG(D_STREAM, "read reqbuf err: %d", ret);
1495 return ret;
1496 }
1497 memset(&v4l2_buf, 0, sizeof v4l2_buf);
1498 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1499 v4l2_buf.memory = V4L2_MEMORY_MMAP;
1500 for (i = 0; i < gspca_dev->nbufread; i++) {
1501 v4l2_buf.index = i;
1502/*fixme: ugly!*/
1503 gspca_dev->frame[i].v4l2_buf.flags |=
1504 V4L2_BUF_FLAG_MAPPED;
1505 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
1506 if (ret != 0) {
1507 PDEBUG(D_STREAM, "read qbuf err: %d", ret);
1508 return ret;
1509 }
1510 }
1511 }
1512 if (!gspca_dev->streaming) {
1513 ret = vidioc_streamon(file, gspca_dev,
1514 V4L2_BUF_TYPE_VIDEO_CAPTURE);
1515 if (ret != 0) {
1516 PDEBUG(D_STREAM, "read streamon err %d", ret);
1517 return ret;
1518 }
1519 }
1520
1521 /* get a frame */
1522 jiffies_to_timeval(get_jiffies_64(), &timestamp);
1523 timestamp.tv_sec--;
1524 for (i = 0; i < 2; i++) {
1525 memset(&v4l2_buf, 0, sizeof v4l2_buf);
1526 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1527 v4l2_buf.memory = V4L2_MEMORY_MMAP;
1528 ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
1529 if (ret != 0) {
1530 PDEBUG(D_STREAM, "read dqbuf err %d", ret);
1531 return ret;
1532 }
1533
1534 /* if the process slept for more than 1 second,
1535 * get a brand new frame */
1536 frame = &gspca_dev->frame[v4l2_buf.index];
1537 if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
1538 break;
1539 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
1540 if (ret != 0) {
1541 PDEBUG(D_STREAM, "read qbuf err %d", ret);
1542 return ret;
1543 }
1544 }
1545
1546 /* copy the frame */
1547 if (count < frame->v4l2_buf.bytesused) {
1548 PDEBUG(D_STREAM, "read bad count: %d < %d",
1549 count, frame->v4l2_buf.bytesused);
1550/*fixme: special errno?*/
1551 ret = -EINVAL;
1552 goto out;
1553 }
1554 count = frame->v4l2_buf.bytesused;
1555 ret = copy_to_user(data, frame->data, count);
1556 if (ret != 0) {
1557 PDEBUG(D_ERR|D_STREAM,
1558 "read cp to user lack %d / %d", ret, count);
1559 ret = -EFAULT;
1560 goto out;
1561 }
1562 ret = count;
1563out:
1564 /* in each case, requeue the buffer */
1565 ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
1566 if (ret2 != 0)
1567 return ret2;
1568 return ret;
1569}
1570
1571static void gspca_dev_release(struct video_device *vfd)
1572{
1573 /* nothing */
1574}
1575
1576static struct file_operations dev_fops = {
1577 .owner = THIS_MODULE,
1578 .open = dev_open,
1579 .release = dev_close,
1580 .read = dev_read,
1581 .mmap = dev_mmap,
1582 .ioctl = video_ioctl2,
1583 .llseek = no_llseek,
1584 .poll = dev_poll,
1585};
1586
1587static struct video_device gspca_template = {
1588 .name = "gspca main driver",
1589 .type = VID_TYPE_CAPTURE,
1590 .fops = &dev_fops,
1591 .release = gspca_dev_release, /* mandatory */
1592 .minor = -1,
1593 .vidioc_querycap = vidioc_querycap,
1594 .vidioc_dqbuf = vidioc_dqbuf,
1595 .vidioc_qbuf = vidioc_qbuf,
1596 .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
1597 .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
1598 .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
1599 .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
1600 .vidioc_streamon = vidioc_streamon,
1601 .vidioc_queryctrl = vidioc_queryctrl,
1602 .vidioc_g_ctrl = vidioc_g_ctrl,
1603 .vidioc_s_ctrl = vidioc_s_ctrl,
1604 .vidioc_querymenu = vidioc_querymenu,
1605 .vidioc_enum_input = vidioc_enum_input,
1606 .vidioc_g_input = vidioc_g_input,
1607 .vidioc_s_input = vidioc_s_input,
1608 .vidioc_reqbufs = vidioc_reqbufs,
1609 .vidioc_querybuf = vidioc_querybuf,
1610 .vidioc_streamoff = vidioc_streamoff,
1611 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1612 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1613 .vidioc_g_parm = vidioc_g_parm,
1614 .vidioc_s_parm = vidioc_s_parm,
1615#ifdef CONFIG_VIDEO_V4L1_COMPAT
1616 .vidiocgmbuf = vidiocgmbuf,
1617#endif
1618};
1619
1620/*
1621 * probe and create a new gspca device
1622 *
1623 * This function must be called by the sub-driver when it is
1624 * called for probing a new device.
1625 */
1626int gspca_dev_probe(struct usb_interface *intf,
1627 const struct usb_device_id *id,
1628 const struct sd_desc *sd_desc,
1629 int dev_size)
1630{
1631 struct usb_interface_descriptor *interface;
1632 struct gspca_dev *gspca_dev;
1633 struct usb_device *dev = interface_to_usbdev(intf);
1634 int ret;
1635 __u16 vendor;
1636 __u16 product;
1637
1638 vendor = le16_to_cpu(dev->descriptor.idVendor);
1639 product = le16_to_cpu(dev->descriptor.idProduct);
1640 PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product);
1641
1642 /* we don't handle multi-config cameras */
1643 if (dev->descriptor.bNumConfigurations != 1)
1644 return -ENODEV;
1645 interface = &intf->cur_altsetting->desc;
1646 if (interface->bInterfaceNumber > 0)
1647 return -ENODEV;
1648
1649 /* create the device */
1650 if (dev_size < sizeof *gspca_dev)
1651 dev_size = sizeof *gspca_dev;
1652 gspca_dev = kzalloc(dev_size, GFP_KERNEL);
1653 if (gspca_dev == NULL) {
1654 err("couldn't kzalloc gspca struct");
1655 return -EIO;
1656 }
1657 gspca_dev->dev = dev;
1658 gspca_dev->iface = interface->bInterfaceNumber;
1659 gspca_dev->sd_desc = sd_desc;
1660/* gspca_dev->users = 0; (done by kzalloc) */
1661 gspca_dev->nbufread = 2;
1662
1663 /* configure the subdriver */
1664 ret = gspca_dev->sd_desc->config(gspca_dev, id);
1665 if (ret < 0)
1666 goto out;
1667 ret = gspca_set_alt0(gspca_dev);
1668 if (ret < 0)
1669 goto out;
1670 gspca_set_default_mode(gspca_dev);
1671
1672 mutex_init(&gspca_dev->usb_lock);
1673 mutex_init(&gspca_dev->read_lock);
1674 mutex_init(&gspca_dev->queue_lock);
1675 init_waitqueue_head(&gspca_dev->wq);
1676
1677 /* init video stuff */
1678 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1679 gspca_dev->vdev.dev = &dev->dev;
1680 ret = video_register_device(&gspca_dev->vdev,
1681 VFL_TYPE_GRABBER,
1682 video_nr);
1683 if (ret < 0) {
1684 err("video_register_device err %d", ret);
1685 goto out;
1686 }
1687
1688 gspca_dev->present = 1;
1689 usb_set_intfdata(intf, gspca_dev);
1690 PDEBUG(D_PROBE, "probe ok");
1691 return 0;
1692out:
1693 kfree(gspca_dev);
1694 return ret;
1695}
1696EXPORT_SYMBOL(gspca_dev_probe);
1697
1698/*
1699 * USB disconnection
1700 *
1701 * This function must be called by the sub-driver
1702 * when the device disconnects, after the specific resources are freed.
1703 */
1704void gspca_disconnect(struct usb_interface *intf)
1705{
1706 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1707
1708 if (!gspca_dev)
1709 return;
1710 gspca_dev->present = 0;
1711 mutex_lock_interruptible(&gspca_dev->queue_lock);
1712 mutex_lock_interruptible(&gspca_dev->usb_lock);
1713 gspca_kill_transfer(gspca_dev);
1714 mutex_unlock(&gspca_dev->queue_lock);
1715 mutex_unlock(&gspca_dev->usb_lock);
1716 while (gspca_dev->users != 0) { /* wait until fully closed */
1717 atomic_inc(&gspca_dev->nevent);
1718 wake_up_interruptible(&gspca_dev->wq); /* wake processes */
1719 schedule();
1720 }
1721/* We don't want people trying to open up the device */
1722 video_unregister_device(&gspca_dev->vdev);
1723/* Free the memory */
1724 kfree(gspca_dev);
1725 PDEBUG(D_PROBE, "disconnect complete");
1726}
1727EXPORT_SYMBOL(gspca_disconnect);
1728
1729/* -- module insert / remove -- */
1730static int __init gspca_init(void)
1731{
1732 info("main v%s registered", version);
1733 return 0;
1734}
1735static void __exit gspca_exit(void)
1736{
1737 info("main deregistered");
1738}
1739
1740module_init(gspca_init);
1741module_exit(gspca_exit);
1742
1743module_param_named(debug, gspca_debug, int, 0644);
1744MODULE_PARM_DESC(debug,
1745 "Debug (bit) 0x01:error 0x02:probe 0x04:config"
1746 " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout");
1747
1748module_param(comp_fac, int, 0644);
1749MODULE_PARM_DESC(comp_fac,
1750 "Buffer size ratio when compressed in percent");
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
new file mode 100644
index 000000000000..1394ab13f1f4
--- /dev/null
+++ b/drivers/media/video/gspca/gspca.h
@@ -0,0 +1,178 @@
1#ifndef GSPCAV2_H
2#define GSPCAV2_H
3
4#include <linux/module.h>
5#include <linux/version.h>
6#include <linux/kernel.h>
7#include <linux/usb.h>
8#include <linux/videodev2.h>
9#include <media/v4l2-common.h>
10#include <linux/mutex.h>
11
12#ifdef GSPCA_DEBUG
13/* GSPCA our debug messages */
14extern int gspca_debug;
15#define PDEBUG(level, fmt, args...) \
16 do {\
17 if (gspca_debug & (level)) \
18 printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
19 } while (0)
20#define D_ERR 0x01
21#define D_PROBE 0x02
22#define D_CONF 0x04
23#define D_STREAM 0x08
24#define D_FRAM 0x10
25#define D_PACK 0x20
26#define D_USBI 0x40
27#define D_USBO 0x80
28#else
29#define PDEBUG(level, fmt, args...)
30#endif
31#undef err
32#define err(fmt, args...) \
33 do {\
34 printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
35 } while (0)
36#undef info
37#define info(fmt, args...) \
38 do {\
39 printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
40 } while (0)
41#undef warn
42#define warn(fmt, args...) \
43 do {\
44 printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
45 } while (0)
46
47#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
48/* ISOC transfers */
49#define NURBS 4 /* number of URBs */
50#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
51#define ISO_MAX_SIZE 0x10000 /* max size of one URB buffer (64 Kb) */
52
53/* device information - set at probe time */
54struct cam_mode {
55 __u32 pixfmt;
56 short width;
57 short height;
58 short mode; /* subdriver value */
59 short reserved; /* subdriver value */
60};
61struct cam {
62 char *dev_name;
63 struct cam_mode *cam_mode; /* size nmodes */
64 char nmodes;
65 __u8 epaddr;
66};
67
68struct gspca_dev;
69struct gspca_frame;
70
71/* subdriver operations */
72typedef int (*cam_op) (struct gspca_dev *);
73typedef void (*cam_v_op) (struct gspca_dev *);
74typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
75typedef int (*cam_jpg_op) (struct gspca_dev *,
76 struct v4l2_jpegcompression *);
77typedef int (*cam_qmnu_op) (struct gspca_dev *,
78 struct v4l2_querymenu *);
79typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
80 struct gspca_frame *frame,
81 unsigned char *data,
82 int len);
83
84struct ctrl {
85 struct v4l2_queryctrl qctrl;
86 int (*set)(struct gspca_dev *, __s32);
87 int (*get)(struct gspca_dev *, __s32 *);
88};
89
90/* subdriver description */
91struct sd_desc {
92/* information */
93 char *name; /* sub-driver name */
94/* controls */
95 struct ctrl *ctrls;
96 int nctrls;
97/* operations */
98 cam_cf_op config; /* called on probe */
99 cam_op open; /* called on open */
100 cam_v_op start; /* called on stream on */
101 cam_v_op stopN; /* called on stream off - main alt */
102 cam_v_op stop0; /* called on stream off - alt 0 */
103 cam_v_op close; /* called on close */
104 cam_pkt_op pkt_scan;
105 cam_jpg_op get_jcomp;
106 cam_jpg_op set_jcomp;
107 cam_qmnu_op querymenu;
108};
109
110struct gspca_pktbuf {
111 char *data;
112 struct urb *urb;
113};
114
115/* packet types when moving from iso buf to frame buf */
116#define DISCARD_PACKET 0
117#define FIRST_PACKET 1
118#define INTER_PACKET 2
119#define LAST_PACKET 3
120
121struct gspca_frame {
122 unsigned char *data; /* frame buffer */
123 unsigned char *data_end; /* current end of frame while filling */
124 int vma_use_count;
125 struct v4l2_buffer v4l2_buf;
126};
127
128struct gspca_dev {
129 struct video_device vdev; /* !! must be the first item */
130 struct usb_device *dev;
131
132 struct cam cam; /* device information */
133 const struct sd_desc *sd_desc; /* subdriver description */
134
135 struct gspca_pktbuf pktbuf[NURBS];
136
137 __u8 *frbuf; /* buffer for nframes */
138 struct gspca_frame frame[GSPCA_MAX_FRAMES];
139 unsigned int frsz; /* frame size */
140 char nframes; /* number of frames */
141 char fr_i; /* frame being filled */
142 char fr_q; /* next frame to queue */
143 char fr_o; /* next frame to dequeue */
144 signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
145 char last_packet_type;
146
147 __u8 iface; /* USB interface number */
148 __u8 alt; /* USB alternate setting */
149 char curr_mode; /* current camera mode */
150 __u32 pixfmt; /* current mode parameters */
151 short width;
152 short height;
153
154 atomic_t nevent; /* number of frames done */
155 wait_queue_head_t wq; /* wait queue */
156 struct mutex usb_lock; /* usb exchange protection */
157 struct mutex read_lock; /* read protection */
158 struct mutex queue_lock; /* ISOC queue protection */
159 __u32 sequence; /* frame sequence number */
160 signed char streaming;
161 char users; /* # open */
162 char present; /* device connected */
163 char nbufread; /* number of buffers for read() */
164};
165
166int gspca_dev_probe(struct usb_interface *intf,
167 const struct usb_device_id *id,
168 const struct sd_desc *sd_desc,
169 int dev_size);
170int gspca_dev_init(struct gspca_dev *gspca_dev,
171 struct usb_interface *intf);
172void gspca_disconnect(struct usb_interface *intf);
173struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
174 int packet_type,
175 struct gspca_frame *frame,
176 unsigned char *data,
177 int len);
178#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
new file mode 100644
index 000000000000..c4087c0ebc46
--- /dev/null
+++ b/drivers/media/video/gspca/jpeg.h
@@ -0,0 +1,301 @@
1#ifndef JPEG_H
2#define JPEG_H 1
3/*
4 * Insert a JPEG header at start of frame
5 *
6 * This module is used by the gspca subdrivers.
7 * A special case is done for Conexant webcams.
8 *
9 * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* start of jpeg frame + quantization table */
28static const unsigned char quant[][0x88] = {
29/* index 0 - Q40*/
30 {
31 0xff, 0xd8, /* jpeg */
32 0xff, 0xdb, 0x00, 0x84, /* DQT */
330, /* quantization table part 1 */
34 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
35 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
36 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
37 109,
38 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
39 126, 129, 124,
401, /* quantization table part 2 */
41 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
42 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
43 124, 124, 124,
44 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
45 124, 124, 124,
46 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
47 124, 124, 124},
48/* index 1 - Q50 */
49 {
50 0xff, 0xd8,
51 0xff, 0xdb, 0x00, 0x84, /* DQT */
520,
53 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
54 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
55 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
56 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
57 103, 99,
581,
59 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
60 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
61 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
62 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
63/* index 2 Q60 */
64 {
65 0xff, 0xd8,
66 0xff, 0xdb, 0x00, 0x84, /* DQT */
670,
68 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
69 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
70 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
71 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
721,
73 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
74 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
75 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
76 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
77/* index 3 - Q70 */
78 {
79 0xff, 0xd8,
80 0xff, 0xdb, 0x00, 0x84, /* DQT */
810,
82 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
83 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
84 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
85 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
861,
87 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
88 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
89 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
90 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
91/* index 4 - Q80 */
92 {
93 0xff, 0xd8,
94 0xff, 0xdb, 0x00, 0x84, /* DQT */
950,
96 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
97 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
98 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
99 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
1001,
101 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
102 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
103 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
104 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
105/* index 5 - Q85 */
106 {
107 0xff, 0xd8,
108 0xff, 0xdb, 0x00, 0x84, /* DQT */
1090,
110 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
111 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
112 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
113 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
1141,
115 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
116 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
117 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
118 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
119/* index 6 - 86 */
120{
121 0xff, 0xd8,
122 0xff, 0xdb, 0x00, 0x84, /* DQT */
1230,
124 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
125 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
126 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
127 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
128 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
129 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
130 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
131 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
1321,
133 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
134 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
135 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
136 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
137 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
138 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
139 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
140 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
141 },
142/* index 7 - 88 */
143{
144 0xff, 0xd8,
145 0xff, 0xdb, 0x00, 0x84, /* DQT */
1460,
147 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
148 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
149 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
150 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
151 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
152 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
153 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
154 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
1551,
156 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
157 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
158 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
159 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
160 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
161 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
162 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
163 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
164},
165/* index 8 - ?? */
166{
167 0xff, 0xd8,
168 0xff, 0xdb, 0x00, 0x84, /* DQT */
1690,
170 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
171 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
172 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
173 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
174 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
175 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
176 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
177 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
1781,
179 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
180 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
181 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
182 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
183 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
184 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
185 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
186 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
187}
188};
189
190/* huffman table + start of SOF0 */
191static unsigned char huffman[] = {
192 0xff, 0xc4, 0x01, 0xa2,
193 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
194 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
196 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
197 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
198 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
199 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
200 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03,
201 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
202 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
203 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
204 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81,
205 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
206 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82,
207 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
208 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
209 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
210 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
211 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
212 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
213 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86,
214 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
215 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
216 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
217 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
218 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
219 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
220 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
221 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
222 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
223 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
224 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
225 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
226 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
227 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
228 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
229 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
230 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28,
231 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
232 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
233 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
234 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
235 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
236 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
237 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
238 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
239 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
240 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
241 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
242 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
243 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2,
244 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
245#ifdef CONEX_CAM
246/* the Conexant frames start with SOF0 */
247#else
248 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
249 0x08, /* data precision */
250#endif
251};
252
253#ifndef CONEX_CAM
254/* variable part:
255 * 0x01, 0xe0, height
256 * 0x02, 0x80, width
257 * 0x03, component number
258 * 0x01,
259 * 0x21, samples Y
260 */
261
262/* end of header */
263static unsigned char eoh[] = {
264 0x00, /* quant Y */
265 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
266 0x03, 0x11, 0x01,
267
268 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan */
269 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
270};
271#endif
272
273/* -- output the JPEG header -- */
274static void jpeg_put_header(struct gspca_dev *gspca_dev,
275 struct gspca_frame *frame,
276 int qindex,
277 int samplesY)
278{
279#ifndef CONEX_CAM
280 unsigned char tmpbuf[8];
281#endif
282
283 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
284 (unsigned char *) quant[qindex], sizeof quant[0]);
285 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
286 (unsigned char *) huffman, sizeof huffman);
287#ifndef CONEX_CAM
288 tmpbuf[0] = gspca_dev->height >> 8;
289 tmpbuf[1] = gspca_dev->height & 0xff;
290 tmpbuf[2] = gspca_dev->width >> 8;
291 tmpbuf[3] = gspca_dev->width & 0xff;
292 tmpbuf[4] = 0x03; /* component number */
293 tmpbuf[5] = 0x01; /* first component */
294 tmpbuf[6] = samplesY;
295 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
296 tmpbuf, 7);
297 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
298 eoh, sizeof eoh);
299#endif
300}
301#endif
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
new file mode 100644
index 000000000000..8fd4ff01362e
--- /dev/null
+++ b/drivers/media/video/gspca/stk014.c
@@ -0,0 +1,562 @@
1/*
2 * Syntek DV4000 (STK014) subdriver
3 *
4 * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#define MODULE_NAME "stk014"
23
24#include "gspca.h"
25#include "jpeg.h"
26
27#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 22)
28static const char version[] = "0.0.22";
29
30MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
31MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
38 unsigned char brightness;
39 unsigned char contrast;
40 unsigned char colors;
41};
42
43/* global parameters */
44static int lightfreq = 50;
45static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
46
47/* V4L2 controls supported by the driver */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54
55static struct ctrl sd_ctrls[] = {
56#define SD_BRIGHTNESS 0
57 {
58 {
59 .id = V4L2_CID_BRIGHTNESS,
60 .type = V4L2_CTRL_TYPE_INTEGER,
61 .name = "Brightness",
62 .minimum = 0,
63 .maximum = 255,
64 .step = 1,
65 .default_value = 127,
66 },
67 .set = sd_setbrightness,
68 .get = sd_getbrightness,
69 },
70#define SD_CONTRAST 1
71 {
72 {
73 .id = V4L2_CID_CONTRAST,
74 .type = V4L2_CTRL_TYPE_INTEGER,
75 .name = "Contrast",
76 .minimum = 0,
77 .maximum = 255,
78 .step = 1,
79 .default_value = 127,
80 },
81 .set = sd_setcontrast,
82 .get = sd_getcontrast,
83 },
84#define SD_COLOR 2
85 {
86 {
87 .id = V4L2_CID_SATURATION,
88 .type = V4L2_CTRL_TYPE_INTEGER,
89 .name = "Saturation",
90 .minimum = 0,
91 .maximum = 255,
92 .step = 1,
93 .default_value = 127,
94 },
95 .set = sd_setcolors,
96 .get = sd_getcolors,
97 },
98};
99
100static struct cam_mode vga_mode[] = {
101 {V4L2_PIX_FMT_JPEG, 320, 240},
102 {V4L2_PIX_FMT_JPEG, 640, 480},
103};
104
105/* -- read a register -- */
106static int reg_read(struct gspca_dev *gspca_dev,
107 __u16 index, __u8 *buf)
108{
109 int ret;
110 struct usb_device *dev = gspca_dev->dev;
111
112 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
113 0x00,
114 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
115 0x00,
116 index,
117 buf, 1,
118 500);
119 if (ret < 0)
120 PDEBUG(D_ERR, "reg_read err %d", ret);
121 return ret;
122}
123
124/* -- write a register -- */
125static int reg_write(struct gspca_dev *gspca_dev,
126 __u16 index, __u16 value)
127{
128 struct usb_device *dev = gspca_dev->dev;
129 int ret;
130
131 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
132 0x01,
133 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
134 value,
135 index,
136 NULL,
137 0,
138 500);
139 if (ret < 0)
140 PDEBUG(D_ERR, "reg_write err %d", ret);
141 return ret;
142}
143
144/* -- get a value -- */
145static int rcv_val(struct gspca_dev *gspca_dev,
146 int ads,
147 int len)
148{
149 struct usb_device *dev = gspca_dev->dev;
150 int alen, ret;
151 unsigned char bulk_buf[4];
152
153 reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff);
154 reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff);
155 reg_write(gspca_dev, 0x636, ads & 0xff);
156 reg_write(gspca_dev, 0x637, 0);
157 reg_write(gspca_dev, 0x638, len & 0xff);
158 reg_write(gspca_dev, 0x639, len >> 8);
159 reg_write(gspca_dev, 0x63a, 0);
160 reg_write(gspca_dev, 0x63b, 0);
161 reg_write(gspca_dev, 0x630, 5);
162 if (len > sizeof bulk_buf)
163 return -1;
164 ret = usb_bulk_msg(dev,
165 usb_rcvbulkpipe(dev, 5),
166 bulk_buf,
167 len,
168 &alen,
169 500); /* timeout in milliseconds */
170 return ret;
171}
172
173/* -- send a value -- */
174static int snd_val(struct gspca_dev *gspca_dev,
175 int ads,
176 unsigned int val)
177{
178 struct usb_device *dev = gspca_dev->dev;
179 int alen, ret;
180 __u8 value, seq;
181 unsigned char bulk_buf[4];
182
183 if (ads == 0x003f08) {
184 ret = reg_read(gspca_dev, 0x0704, &value);
185 if (ret < 0)
186 goto ko;
187 ret = reg_read(gspca_dev, 0x0705, &seq);
188 if (ret < 0)
189 goto ko;
190 ret = reg_read(gspca_dev, 0x0650, &value);
191 if (ret < 0)
192 goto ko;
193 reg_write(gspca_dev, 0x654, seq);
194 } else
195 reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff);
196 reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff);
197 reg_write(gspca_dev, 0x656, ads & 0xff);
198 reg_write(gspca_dev, 0x657, 0);
199 reg_write(gspca_dev, 0x658, 0x04); /* size */
200 reg_write(gspca_dev, 0x659, 0);
201 reg_write(gspca_dev, 0x65a, 0);
202 reg_write(gspca_dev, 0x65b, 0);
203 reg_write(gspca_dev, 0x650, 5);
204 bulk_buf[0] = (val >> 24) & 0xff;
205 bulk_buf[1] = (val >> 16) & 0xff;
206 bulk_buf[2] = (val >> 8) & 0xff;
207 bulk_buf[3] = val & 0xff;
208 ret = usb_bulk_msg(dev,
209 usb_sndbulkpipe(dev, 6),
210 bulk_buf,
211 4,
212 &alen,
213 500); /* timeout in milliseconds */
214 if (ret < 0)
215 goto ko;
216 if (ads == 0x003f08) {
217 seq += 4;
218 seq &= 0x3f;
219 reg_write(gspca_dev, 0x705, seq);
220 }
221 return ret;
222ko:
223 PDEBUG(D_ERR, "snd_val err %d", ret);
224 return ret;
225}
226
227/* set a camera parameter */
228static int set_par(struct gspca_dev *gspca_dev,
229 int parval)
230{
231 return snd_val(gspca_dev, 0x003f08, parval);
232}
233
234static void setbrightness(struct gspca_dev *gspca_dev)
235{
236 struct sd *sd = (struct sd *) gspca_dev;
237 int parval;
238
239 PDEBUG(D_CONF, "brightness: %d", sd->brightness);
240 parval = 0x06000000 /* whiteness */
241 + (sd->brightness << 16);
242 set_par(gspca_dev, parval);
243}
244
245static void setcontrast(struct gspca_dev *gspca_dev)
246{
247 struct sd *sd = (struct sd *) gspca_dev;
248 int parval;
249
250 PDEBUG(D_CONF, "contrast: %d", sd->contrast);
251 parval = 0x07000000 /* contrast */
252 + (sd->contrast << 16);
253 set_par(gspca_dev, parval);
254}
255
256static void setcolors(struct gspca_dev *gspca_dev)
257{
258 struct sd *sd = (struct sd *) gspca_dev;
259 int parval;
260
261 PDEBUG(D_CONF, "saturation: %d",
262 sd->colors);
263 parval = 0x08000000 /* saturation */
264 + (sd->colors << 16);
265 set_par(gspca_dev, parval);
266}
267
268/* this function is called at probe time */
269static int sd_config(struct gspca_dev *gspca_dev,
270 const struct usb_device_id *id)
271{
272 struct sd *sd = (struct sd *) gspca_dev;
273 struct cam *cam = &gspca_dev->cam;
274
275 cam->dev_name = (char *) id->driver_info;
276 cam->epaddr = 0x02;
277 gspca_dev->cam.cam_mode = vga_mode;
278 gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0];
279 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
280 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
281 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
282 return 0;
283}
284
285/* this function is called at open time */
286static int sd_open(struct gspca_dev *gspca_dev)
287{
288 __u8 value;
289 int ret;
290
291 /* check if the device responds */
292 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
293 ret = reg_read(gspca_dev, 0x0740, &value);
294 if (ret < 0)
295 return ret;
296 if (value != 0xff) {
297 PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value);
298 return -1;
299 }
300 return 0;
301}
302
303/* -- start the camera -- */
304static void sd_start(struct gspca_dev *gspca_dev)
305{
306 __u8 dum;
307 int ret, value;
308
309 /* work on alternate 1 */
310 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
311
312 set_par(gspca_dev, 0x10000000);
313 set_par(gspca_dev, 0x00000000);
314 set_par(gspca_dev, 0x8002e001);
315 set_par(gspca_dev, 0x14000000);
316 if (gspca_dev->width > 320)
317 value = 0x8002e001; /* 640x480 */
318 else
319 value = 0x4001f000; /* 320x240 */
320 set_par(gspca_dev, value);
321 ret = usb_set_interface(gspca_dev->dev,
322 gspca_dev->iface,
323 gspca_dev->alt);
324 if (ret < 0)
325 goto out;
326 ret = reg_read(gspca_dev, 0x0630, &dum);
327 if (ret < 0)
328 goto out;
329 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */
330 ret = reg_read(gspca_dev, 0x0650, &dum);
331 if (ret < 0)
332 goto out;
333 snd_val(gspca_dev, 0x000020, 0xffffffff);
334 reg_write(gspca_dev, 0x0620, 0);
335 reg_write(gspca_dev, 0x0630, 0);
336 reg_write(gspca_dev, 0x0640, 0);
337 reg_write(gspca_dev, 0x0650, 0);
338 reg_write(gspca_dev, 0x0660, 0);
339 setbrightness(gspca_dev); /* whiteness */
340 setcontrast(gspca_dev); /* contrast */
341 setcolors(gspca_dev); /* saturation */
342 set_par(gspca_dev, 0x09800000); /* Red ? */
343 set_par(gspca_dev, 0x0a800000); /* Green ? */
344 set_par(gspca_dev, 0x0b800000); /* Blue ? */
345 set_par(gspca_dev, 0x0d030000); /* Gamma ? */
346 set_par(gspca_dev, lightfreq == 60
347 ? 0x33780000 /* 60 Hz */
348 : 0x33640000); /* 50 Hz */
349
350 /* start the video flow */
351 set_par(gspca_dev, 0x01000000);
352 set_par(gspca_dev, 0x01000000);
353 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
354 return;
355out:
356 PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
357}
358
359static void sd_stopN(struct gspca_dev *gspca_dev)
360{
361 struct usb_device *dev = gspca_dev->dev;
362 __u8 value;
363
364 set_par(gspca_dev, 0x02000000);
365 set_par(gspca_dev, 0x02000000);
366 usb_set_interface(dev, gspca_dev->iface, 1);
367 reg_read(gspca_dev, 0x0630, &value);
368 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */
369 reg_read(gspca_dev, 0x0650, &value);
370 snd_val(gspca_dev, 0x000020, 0xffffffff);
371 reg_write(gspca_dev, 0x0620, 0);
372 reg_write(gspca_dev, 0x0630, 0);
373 reg_write(gspca_dev, 0x0640, 0);
374 reg_write(gspca_dev, 0x0650, 0);
375 reg_write(gspca_dev, 0x0660, 0);
376 PDEBUG(D_STREAM, "camera stopped");
377}
378
379static void sd_stop0(struct gspca_dev *gspca_dev)
380{
381}
382
383static void sd_close(struct gspca_dev *gspca_dev)
384{
385}
386
387static void sd_pkt_scan(struct gspca_dev *gspca_dev,
388 struct gspca_frame *frame, /* target */
389 unsigned char *data, /* isoc packet */
390 int len) /* iso packet length */
391{
392 int l;
393
394 /* a frame starts with:
395 * - 0xff 0xfe
396 * - 0x08 0x00 // length (little endian ?!)
397 * - 4 bytes = size of whole frame (big endian - including header)
398 * - 0x00 0x0c
399 * - 0xff 0xd8
400 * - .. JPEG image with escape sequences (ff 00)
401 */
402 if (data[0] == 0xff && data[1] == 0xfe) {
403 if (gspca_dev->last_packet_type == INTER_PACKET) {
404 PDEBUG(D_ERR|D_FRAM, "sof actual l: %d init l: %d",
405 frame->data_end - frame->data,
406 frame->v4l2_buf.bytesused);
407 }
408
409 /* put the JPEG headaer */
410 jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
411
412 /* beginning of the frame */
413#define STKHDRSZ 12
414 l = (data[4] << 24) /* frame size */
415 + (data[5] << 16)
416 + (data[6] << 8)
417 + data[7]
418 - STKHDRSZ
419 + (frame->data_end - frame->data)
420 + 2; /* EOF (ff d9) */
421 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
422 data + STKHDRSZ, len - STKHDRSZ);
423#undef STKHDRSZ
424 frame->v4l2_buf.bytesused = l;
425 return;
426 }
427 if (gspca_dev->last_packet_type != INTER_PACKET) {
428 if (gspca_dev->last_packet_type == LAST_PACKET) {
429 PDEBUG(D_ERR|D_PACK, "mof actual l: %d init l: %d",
430 frame->data_end - frame->data,
431 frame->v4l2_buf.bytesused);
432 }
433 return;
434 }
435
436 /* intermediate packet */
437 l = frame->data_end - frame->data;
438 if (len < frame->v4l2_buf.bytesused - 2 - l) {
439 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
440 data, len);
441 return;
442 }
443
444 /* last packet */
445 if (len > frame->v4l2_buf.bytesused - 2 - l)
446 len = frame->v4l2_buf.bytesused - 2 - l;
447 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
448 gspca_frame_add(gspca_dev, LAST_PACKET, frame, "\xff\xd9", 2);
449}
450
451static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
452{
453 struct sd *sd = (struct sd *) gspca_dev;
454
455 sd->brightness = val;
456 if (gspca_dev->streaming)
457 setbrightness(gspca_dev);
458 return 0;
459}
460
461static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
462{
463 struct sd *sd = (struct sd *) gspca_dev;
464
465 *val = sd->brightness;
466 return 0;
467}
468
469static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
470{
471 struct sd *sd = (struct sd *) gspca_dev;
472
473 sd->contrast = val;
474 if (gspca_dev->streaming)
475 setcontrast(gspca_dev);
476 return 0;
477}
478
479static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
480{
481 struct sd *sd = (struct sd *) gspca_dev;
482
483 *val = sd->contrast;
484 return 0;
485}
486
487static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
488{
489 struct sd *sd = (struct sd *) gspca_dev;
490
491 sd->colors = val;
492 if (gspca_dev->streaming)
493 setcolors(gspca_dev);
494 return 0;
495}
496
497static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
498{
499 struct sd *sd = (struct sd *) gspca_dev;
500
501 *val = sd->colors;
502 return 0;
503}
504
505/* sub-driver description */
506static struct sd_desc sd_desc = {
507 .name = MODULE_NAME,
508 .ctrls = sd_ctrls,
509 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
510 .config = sd_config,
511 .open = sd_open,
512 .start = sd_start,
513 .stopN = sd_stopN,
514 .stop0 = sd_stop0,
515 .close = sd_close,
516 .pkt_scan = sd_pkt_scan,
517};
518
519/* -- module initialisation -- */
520#define DVNM(name) .driver_info = (kernel_ulong_t) name
521static __devinitdata struct usb_device_id device_table[] = {
522 {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
523 {}
524};
525MODULE_DEVICE_TABLE(usb, device_table);
526
527/* -- device connect -- */
528static int sd_probe(struct usb_interface *intf,
529 const struct usb_device_id *id)
530{
531 PDEBUG(D_PROBE, "camera probe");
532 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd));
533}
534
535static struct usb_driver sd_driver = {
536 .name = MODULE_NAME,
537 .id_table = device_table,
538 .probe = sd_probe,
539 .disconnect = gspca_disconnect,
540};
541
542/* -- module insert / remove -- */
543static int __init sd_mod_init(void)
544{
545 if (usb_register(&sd_driver) < 0)
546 return -1;
547 info("v%s registered", version);
548 return 0;
549}
550static void __exit sd_mod_exit(void)
551{
552 usb_deregister(&sd_driver);
553 info("deregistered");
554}
555
556module_init(sd_mod_init);
557module_exit(sd_mod_exit);
558
559module_param(lightfreq, int, 0644);
560MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz");
561module_param_named(quant, sd_quant, int, 0644);
562MODULE_PARM_DESC(quant, "Quantization index (0..8)");