aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/Kconfig6
-rw-r--r--drivers/media/video/gspca/Kconfig9
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/stv0680.c365
-rw-r--r--include/linux/videodev2.h1
5 files changed, 382 insertions, 1 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 7ecae636e6ad..82ae85c975f5 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1016,9 +1016,13 @@ config USB_SE401
1016source "drivers/media/video/sn9c102/Kconfig" 1016source "drivers/media/video/sn9c102/Kconfig"
1017 1017
1018config USB_STV680 1018config USB_STV680
1019 tristate "USB STV680 (Pencam) Camera support" 1019 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
1020 depends on VIDEO_V4L1 1020 depends on VIDEO_V4L1
1021 ---help--- 1021 ---help---
1022 This driver is DEPRECATED please use the gspca stv0680 module
1023 instead. Note that for the gspca stv0680 module you need
1024 atleast version 0.6.3 of libv4l.
1025
1022 Say Y here if you want to connect this type of camera to your 1026 Say Y here if you want to connect this type of camera to your
1023 computer's USB port. This includes the Pencam line of cameras. 1027 computer's USB port. This includes the Pencam line of cameras.
1024 See <file:Documentation/video4linux/stv680.txt> for more information 1028 See <file:Documentation/video4linux/stv680.txt> for more information
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index cbc2367719f0..568edbbb8948 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -230,6 +230,15 @@ config USB_GSPCA_STK014
230 To compile this driver as a module, choose M here: the 230 To compile this driver as a module, choose M here: the
231 module will be called gspca_stk014. 231 module will be called gspca_stk014.
232 232
233config USB_GSPCA_STV0680
234 tristate "STV0680 USB Camera Driver"
235 depends on VIDEO_V4L2 && USB_GSPCA
236 help
237 Say Y here if you want support for cameras based on the STV0680 chip.
238
239 To compile this driver as a module, choose M here: the
240 module will be called gspca_stv0680.
241
233config USB_GSPCA_SUNPLUS 242config USB_GSPCA_SUNPLUS
234 tristate "SUNPLUS USB Camera Driver" 243 tristate "SUNPLUS USB Camera Driver"
235 depends on VIDEO_V4L2 && USB_GSPCA 244 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index b7420818037e..770b01387e99 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
22obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o 22obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
23obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o 23obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
24obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o 24obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
25obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
25obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 26obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
26obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o 27obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
27obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o 28obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
@@ -50,6 +51,7 @@ gspca_spca561-objs := spca561.o
50gspca_sq905-objs := sq905.o 51gspca_sq905-objs := sq905.o
51gspca_sq905c-objs := sq905c.o 52gspca_sq905c-objs := sq905c.o
52gspca_stk014-objs := stk014.o 53gspca_stk014-objs := stk014.o
54gspca_stv0680-objs := stv0680.o
53gspca_sunplus-objs := sunplus.o 55gspca_sunplus-objs := sunplus.o
54gspca_t613-objs := t613.o 56gspca_t613-objs := t613.o
55gspca_tv8532-objs := tv8532.o 57gspca_tv8532-objs := tv8532.o
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
new file mode 100644
index 000000000000..0981ce14235d
--- /dev/null
+++ b/drivers/media/video/gspca/stv0680.c
@@ -0,0 +1,365 @@
1/*
2 * STV0680 USB Camera Driver
3 *
4 * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 stv680 driver:
7 *
8 * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
9 *
10 * Thanks to STMicroelectronics for information on the usb commands, and
11 * to Steve Miller at STM for his help and encouragement while I was
12 * writing this driver.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#define MODULE_NAME "stv0680"
31
32#include "gspca.h"
33
34MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
35MODULE_DESCRIPTION("STV0680 USB Camera Driver");
36MODULE_LICENSE("GPL");
37
38/* specific webcam descriptor */
39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 struct v4l2_pix_format mode;
42 u8 orig_mode;
43 u8 video_mode;
44 u8 current_mode;
45};
46
47/* V4L2 controls supported by the driver */
48static struct ctrl sd_ctrls[] = {
49};
50
51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
52 int size)
53{
54 int ret = -1;
55 u8 req_type = 0;
56
57 switch (set) {
58 case 0: /* 0xc1 */
59 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
60 break;
61 case 1: /* 0x41 */
62 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
63 break;
64 case 2: /* 0x80 */
65 req_type = USB_DIR_IN | USB_RECIP_DEVICE;
66 break;
67 case 3: /* 0x40 */
68 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
69 break;
70 }
71
72 ret = usb_control_msg(gspca_dev->dev,
73 usb_rcvctrlpipe(gspca_dev->dev, 0),
74 req, req_type,
75 val, 0, gspca_dev->usb_buf, size, 500);
76
77 if ((ret < 0) && (req != 0x0a))
78 PDEBUG(D_ERR,
79 "usb_control_msg error %i, request = 0x%x, error = %i",
80 set, req, ret);
81
82 return ret;
83}
84
85static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
86{
87 stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
88 PDEBUG(D_ERR, "last error: %i, command = 0x%x",
89 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
90 return ret;
91}
92
93static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
94{
95 /* Note not sure if this init of usb_buf is really necessary */
96 memset(gspca_dev->usb_buf, 0, 8);
97 gspca_dev->usb_buf[0] = 0x0f;
98
99 if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
100 PDEBUG(D_ERR, "Get_Camera_Mode failed");
101 return stv0680_handle_error(gspca_dev, -EIO);
102 }
103
104 return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
105}
106
107static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
108{
109 struct sd *sd = (struct sd *) gspca_dev;
110
111 if (sd->current_mode == mode)
112 return 0;
113
114 memset(gspca_dev->usb_buf, 0, 8);
115 gspca_dev->usb_buf[0] = mode;
116
117 if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
118 PDEBUG(D_ERR, "Set_Camera_Mode failed");
119 return stv0680_handle_error(gspca_dev, -EIO);
120 }
121
122 /* Verify we got what we've asked for */
123 if (stv0680_get_video_mode(gspca_dev) != mode) {
124 PDEBUG(D_ERR, "Error setting camera video mode!");
125 return -EIO;
126 }
127
128 sd->current_mode = mode;
129
130 return 0;
131}
132
133/* this function is called at probe time */
134static int sd_config(struct gspca_dev *gspca_dev,
135 const struct usb_device_id *id)
136{
137 int ret;
138 struct sd *sd = (struct sd *) gspca_dev;
139 struct cam *cam = &gspca_dev->cam;
140
141 /* ping camera to be sure STV0680 is present */
142 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
143 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
144 PDEBUG(D_ERR, "STV(e): camera ping failed!!");
145 return stv0680_handle_error(gspca_dev, -ENODEV);
146 }
147
148 /* get camera descriptor */
149 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
150 return stv0680_handle_error(gspca_dev, -ENODEV);
151
152 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
153 gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
154 PDEBUG(D_ERR, "Could not get descriptor 0200.");
155 return stv0680_handle_error(gspca_dev, -ENODEV);
156 }
157 if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
158 return stv0680_handle_error(gspca_dev, -ENODEV);
159 if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
160 return stv0680_handle_error(gspca_dev, -ENODEV);
161 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
162 return stv0680_handle_error(gspca_dev, -ENODEV);
163
164 if (!(gspca_dev->usb_buf[7] & 0x09)) {
165 PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
166 return -ENODEV;
167 }
168 if (gspca_dev->usb_buf[7] & 0x01)
169 PDEBUG(D_PROBE, "Camera supports CIF mode");
170 if (gspca_dev->usb_buf[7] & 0x02)
171 PDEBUG(D_PROBE, "Camera supports VGA mode");
172 if (gspca_dev->usb_buf[7] & 0x08)
173 PDEBUG(D_PROBE, "Camera supports QVGA mode");
174
175 if (gspca_dev->usb_buf[7] & 0x01)
176 sd->video_mode = 0x00; /* CIF */
177 else
178 sd->video_mode = 0x03; /* QVGA */
179
180 /* FW rev, ASIC rev, sensor ID */
181 PDEBUG(D_PROBE, "Firmware rev is %i.%i",
182 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
183 PDEBUG(D_PROBE, "ASIC rev is %i.%i",
184 gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
185 PDEBUG(D_PROBE, "Sensor ID is %i",
186 (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
187
188
189 ret = stv0680_get_video_mode(gspca_dev);
190 if (ret < 0)
191 return ret;
192 sd->current_mode = sd->orig_mode = ret;
193
194 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
195 if (ret < 0)
196 return ret;
197
198 /* Get mode details */
199 if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
200 return stv0680_handle_error(gspca_dev, -EIO);
201
202 cam->bulk = 1;
203 cam->bulk_nurbs = 1; /* The cam cannot handle more */
204 cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
205 (gspca_dev->usb_buf[1] << 16) |
206 (gspca_dev->usb_buf[2] << 8) |
207 (gspca_dev->usb_buf[3]);
208 sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
209 (gspca_dev->usb_buf[5]); /* 322, 356, 644 */
210 sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
211 (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
212 sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
213 sd->mode.field = V4L2_FIELD_NONE;
214 sd->mode.bytesperline = sd->mode.width;
215 sd->mode.sizeimage = cam->bulk_size;
216 sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
217
218 /* origGain = gspca_dev->usb_buf[12]; */
219
220 cam->cam_mode = &sd->mode;
221 cam->nmodes = 1;
222
223
224 ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
225 if (ret < 0)
226 return ret;
227
228 if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
229 gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
230 PDEBUG(D_ERR, "Could not get descriptor 0100.");
231 return stv0680_handle_error(gspca_dev, -EIO);
232 }
233
234 return 0;
235}
236
237/* this function is called at probe and resume time */
238static int sd_init(struct gspca_dev *gspca_dev)
239{
240 return 0;
241}
242
243/* -- start the camera -- */
244static int sd_start(struct gspca_dev *gspca_dev)
245{
246 int ret;
247 struct sd *sd = (struct sd *) gspca_dev;
248
249 ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
250 if (ret < 0)
251 return ret;
252
253 if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
254 return stv0680_handle_error(gspca_dev, -EIO);
255
256 /* Start stream at:
257 0x0000 = CIF (352x288)
258 0x0100 = VGA (640x480)
259 0x0300 = QVGA (320x240) */
260 if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
261 return stv0680_handle_error(gspca_dev, -EIO);
262
263 return 0;
264}
265
266static void sd_stopN(struct gspca_dev *gspca_dev)
267{
268 /* This is a high priority command; it stops all lower order cmds */
269 if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
270 stv0680_handle_error(gspca_dev, -EIO);
271}
272
273static void sd_stop0(struct gspca_dev *gspca_dev)
274{
275 struct sd *sd = (struct sd *) gspca_dev;
276
277 if (!sd->gspca_dev.present)
278 return;
279
280 stv0680_set_video_mode(gspca_dev, sd->orig_mode);
281}
282
283static void sd_pkt_scan(struct gspca_dev *gspca_dev,
284 struct gspca_frame *frame,
285 __u8 *data,
286 int len)
287{
288 struct sd *sd = (struct sd *) gspca_dev;
289
290 /* Every now and then the camera sends a 16 byte packet, no idea
291 what it contains, but it is not image data, when this
292 happens the frame received before this packet is corrupt,
293 so discard it. */
294 if (len != sd->mode.sizeimage) {
295 gspca_dev->last_packet_type = DISCARD_PACKET;
296 return;
297 }
298
299 /* Finish the previous frame, we do this upon reception of the next
300 packet, even though it is already complete so that the strange 16
301 byte packets send after a corrupt frame can discard it. */
302 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
303
304 /* Store the just received frame */
305 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
306}
307
308/* sub-driver description */
309static const struct sd_desc sd_desc = {
310 .name = MODULE_NAME,
311 .ctrls = sd_ctrls,
312 .nctrls = ARRAY_SIZE(sd_ctrls),
313 .config = sd_config,
314 .init = sd_init,
315 .start = sd_start,
316 .stopN = sd_stopN,
317 .stop0 = sd_stop0,
318 .pkt_scan = sd_pkt_scan,
319};
320
321/* -- module initialisation -- */
322static const __devinitdata struct usb_device_id device_table[] = {
323 {USB_DEVICE(0x0553, 0x0202)},
324 {USB_DEVICE(0x041e, 0x4007)},
325 {}
326};
327MODULE_DEVICE_TABLE(usb, device_table);
328
329/* -- device connect -- */
330static int sd_probe(struct usb_interface *intf,
331 const struct usb_device_id *id)
332{
333 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
334 THIS_MODULE);
335}
336
337static struct usb_driver sd_driver = {
338 .name = MODULE_NAME,
339 .id_table = device_table,
340 .probe = sd_probe,
341 .disconnect = gspca_disconnect,
342#ifdef CONFIG_PM
343 .suspend = gspca_suspend,
344 .resume = gspca_resume,
345#endif
346};
347
348/* -- module insert / remove -- */
349static int __init sd_mod_init(void)
350{
351 int ret;
352 ret = usb_register(&sd_driver);
353 if (ret < 0)
354 return ret;
355 PDEBUG(D_PROBE, "registered");
356 return 0;
357}
358static void __exit sd_mod_exit(void)
359{
360 usb_deregister(&sd_driver);
361 PDEBUG(D_PROBE, "deregistered");
362}
363
364module_init(sd_mod_init);
365module_exit(sd_mod_exit);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index b59e78c57161..b9a799a35763 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -361,6 +361,7 @@ struct v4l2_pix_format {
361#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ 361#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
362#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ 362#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
363#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ 363#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
364#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
364 365
365/* 366/*
366 * F O R M A T E N U M E R A T I O N 367 * F O R M A T E N U M E R A T I O N