diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/gspca/sq905.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/media/video/gspca/sq905.c')
-rw-r--r-- | drivers/media/video/gspca/sq905.c | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c new file mode 100644 index 00000000000..5ba96aff225 --- /dev/null +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -0,0 +1,448 @@ | |||
1 | /* | ||
2 | * SQ905 subdriver | ||
3 | * | ||
4 | * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore | ||
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 | * History and Acknowledgments | ||
23 | * | ||
24 | * The original Linux driver for SQ905 based cameras was written by | ||
25 | * Marcell Lengyel and furter developed by many other contributors | ||
26 | * and is available from http://sourceforge.net/projects/sqcam/ | ||
27 | * | ||
28 | * This driver takes advantage of the reverse engineering work done for | ||
29 | * that driver and for libgphoto2 but shares no code with them. | ||
30 | * | ||
31 | * This driver has used as a base the finepix driver and other gspca | ||
32 | * based drivers and may still contain code fragments taken from those | ||
33 | * drivers. | ||
34 | */ | ||
35 | |||
36 | #define MODULE_NAME "sq905" | ||
37 | |||
38 | #include <linux/workqueue.h> | ||
39 | #include <linux/slab.h> | ||
40 | #include "gspca.h" | ||
41 | |||
42 | MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, " | ||
43 | "Theodore Kilgore <kilgota@auburn.edu>"); | ||
44 | MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); | ||
45 | MODULE_LICENSE("GPL"); | ||
46 | |||
47 | /* Default timeouts, in ms */ | ||
48 | #define SQ905_CMD_TIMEOUT 500 | ||
49 | #define SQ905_DATA_TIMEOUT 1000 | ||
50 | |||
51 | /* Maximum transfer size to use. */ | ||
52 | #define SQ905_MAX_TRANSFER 0x8000 | ||
53 | #define FRAME_HEADER_LEN 64 | ||
54 | |||
55 | /* The known modes, or registers. These go in the "value" slot. */ | ||
56 | |||
57 | /* 00 is "none" obviously */ | ||
58 | |||
59 | #define SQ905_BULK_READ 0x03 /* precedes any bulk read */ | ||
60 | #define SQ905_COMMAND 0x06 /* precedes the command codes below */ | ||
61 | #define SQ905_PING 0x07 /* when reading an "idling" command */ | ||
62 | #define SQ905_READ_DONE 0xc0 /* ack bulk read completed */ | ||
63 | |||
64 | /* Any non-zero value in the bottom 2 bits of the 2nd byte of | ||
65 | * the ID appears to indicate the camera can do 640*480. If the | ||
66 | * LSB of that byte is set the image is just upside down, otherwise | ||
67 | * it is rotated 180 degrees. */ | ||
68 | #define SQ905_HIRES_MASK 0x00000300 | ||
69 | #define SQ905_ORIENTATION_MASK 0x00000100 | ||
70 | |||
71 | /* Some command codes. These go in the "index" slot. */ | ||
72 | |||
73 | #define SQ905_ID 0xf0 /* asks for model string */ | ||
74 | #define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */ | ||
75 | #define SQ905_DATA 0x30 /* accesses photo data, not used here */ | ||
76 | #define SQ905_CLEAR 0xa0 /* clear everything */ | ||
77 | #define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */ | ||
78 | #define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */ | ||
79 | #define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */ | ||
80 | /* note that the capture command also controls the output dimensions */ | ||
81 | |||
82 | /* Structure to hold all of our device specific stuff */ | ||
83 | struct sd { | ||
84 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
85 | |||
86 | /* | ||
87 | * Driver stuff | ||
88 | */ | ||
89 | struct work_struct work_struct; | ||
90 | struct workqueue_struct *work_thread; | ||
91 | }; | ||
92 | |||
93 | static struct v4l2_pix_format sq905_mode[] = { | ||
94 | { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
95 | .bytesperline = 160, | ||
96 | .sizeimage = 160 * 120, | ||
97 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
98 | .priv = 0}, | ||
99 | { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
100 | .bytesperline = 320, | ||
101 | .sizeimage = 320 * 240, | ||
102 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
103 | .priv = 0}, | ||
104 | { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
105 | .bytesperline = 640, | ||
106 | .sizeimage = 640 * 480, | ||
107 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
108 | .priv = 0} | ||
109 | }; | ||
110 | |||
111 | /* | ||
112 | * Send a command to the camera. | ||
113 | */ | ||
114 | static int sq905_command(struct gspca_dev *gspca_dev, u16 index) | ||
115 | { | ||
116 | int ret; | ||
117 | |||
118 | gspca_dev->usb_buf[0] = '\0'; | ||
119 | ret = usb_control_msg(gspca_dev->dev, | ||
120 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
121 | USB_REQ_SYNCH_FRAME, /* request */ | ||
122 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
123 | SQ905_COMMAND, index, gspca_dev->usb_buf, 1, | ||
124 | SQ905_CMD_TIMEOUT); | ||
125 | if (ret < 0) { | ||
126 | err("%s: usb_control_msg failed (%d)", | ||
127 | __func__, ret); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | ret = usb_control_msg(gspca_dev->dev, | ||
132 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
133 | USB_REQ_SYNCH_FRAME, /* request */ | ||
134 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
135 | SQ905_PING, 0, gspca_dev->usb_buf, 1, | ||
136 | SQ905_CMD_TIMEOUT); | ||
137 | if (ret < 0) { | ||
138 | err("%s: usb_control_msg failed 2 (%d)", | ||
139 | __func__, ret); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Acknowledge the end of a frame - see warning on sq905_command. | ||
148 | */ | ||
149 | static int sq905_ack_frame(struct gspca_dev *gspca_dev) | ||
150 | { | ||
151 | int ret; | ||
152 | |||
153 | gspca_dev->usb_buf[0] = '\0'; | ||
154 | ret = usb_control_msg(gspca_dev->dev, | ||
155 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
156 | USB_REQ_SYNCH_FRAME, /* request */ | ||
157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
158 | SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, | ||
159 | SQ905_CMD_TIMEOUT); | ||
160 | if (ret < 0) { | ||
161 | err("%s: usb_control_msg failed (%d)", __func__, ret); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * request and read a block of data - see warning on sq905_command. | ||
170 | */ | ||
171 | static int | ||
172 | sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) | ||
173 | { | ||
174 | int ret; | ||
175 | int act_len; | ||
176 | |||
177 | gspca_dev->usb_buf[0] = '\0'; | ||
178 | if (need_lock) | ||
179 | mutex_lock(&gspca_dev->usb_lock); | ||
180 | ret = usb_control_msg(gspca_dev->dev, | ||
181 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
182 | USB_REQ_SYNCH_FRAME, /* request */ | ||
183 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
184 | SQ905_BULK_READ, size, gspca_dev->usb_buf, | ||
185 | 1, SQ905_CMD_TIMEOUT); | ||
186 | if (need_lock) | ||
187 | mutex_unlock(&gspca_dev->usb_lock); | ||
188 | if (ret < 0) { | ||
189 | err("%s: usb_control_msg failed (%d)", __func__, ret); | ||
190 | return ret; | ||
191 | } | ||
192 | ret = usb_bulk_msg(gspca_dev->dev, | ||
193 | usb_rcvbulkpipe(gspca_dev->dev, 0x81), | ||
194 | data, size, &act_len, SQ905_DATA_TIMEOUT); | ||
195 | |||
196 | /* successful, it returns 0, otherwise negative */ | ||
197 | if (ret < 0 || act_len != size) { | ||
198 | err("bulk read fail (%d) len %d/%d", | ||
199 | ret, act_len, size); | ||
200 | return -EIO; | ||
201 | } | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | /* This function is called as a workqueue function and runs whenever the camera | ||
206 | * is streaming data. Because it is a workqueue function it is allowed to sleep | ||
207 | * so we can use synchronous USB calls. To avoid possible collisions with other | ||
208 | * threads attempting to use the camera's USB interface we take the gspca | ||
209 | * usb_lock when performing USB operations. In practice the only thing we need | ||
210 | * to protect against is the usb_set_interface call that gspca makes during | ||
211 | * stream_off as the camera doesn't provide any controls that the user could try | ||
212 | * to change. | ||
213 | */ | ||
214 | static void sq905_dostream(struct work_struct *work) | ||
215 | { | ||
216 | struct sd *dev = container_of(work, struct sd, work_struct); | ||
217 | struct gspca_dev *gspca_dev = &dev->gspca_dev; | ||
218 | int bytes_left; /* bytes remaining in current frame. */ | ||
219 | int data_len; /* size to use for the next read. */ | ||
220 | int header_read; /* true if we have already read the frame header. */ | ||
221 | int packet_type; | ||
222 | int frame_sz; | ||
223 | int ret; | ||
224 | u8 *data; | ||
225 | u8 *buffer; | ||
226 | |||
227 | buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); | ||
228 | if (!buffer) { | ||
229 | err("Couldn't allocate USB buffer"); | ||
230 | goto quit_stream; | ||
231 | } | ||
232 | |||
233 | frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage | ||
234 | + FRAME_HEADER_LEN; | ||
235 | |||
236 | while (gspca_dev->present && gspca_dev->streaming) { | ||
237 | /* request some data and then read it until we have | ||
238 | * a complete frame. */ | ||
239 | bytes_left = frame_sz; | ||
240 | header_read = 0; | ||
241 | |||
242 | /* Note we do not check for gspca_dev->streaming here, as | ||
243 | we must finish reading an entire frame, otherwise the | ||
244 | next time we stream we start reading in the middle of a | ||
245 | frame. */ | ||
246 | while (bytes_left > 0 && gspca_dev->present) { | ||
247 | data_len = bytes_left > SQ905_MAX_TRANSFER ? | ||
248 | SQ905_MAX_TRANSFER : bytes_left; | ||
249 | ret = sq905_read_data(gspca_dev, buffer, data_len, 1); | ||
250 | if (ret < 0) | ||
251 | goto quit_stream; | ||
252 | PDEBUG(D_PACK, | ||
253 | "Got %d bytes out of %d for frame", | ||
254 | data_len, bytes_left); | ||
255 | bytes_left -= data_len; | ||
256 | data = buffer; | ||
257 | if (!header_read) { | ||
258 | packet_type = FIRST_PACKET; | ||
259 | /* The first 64 bytes of each frame are | ||
260 | * a header full of FF 00 bytes */ | ||
261 | data += FRAME_HEADER_LEN; | ||
262 | data_len -= FRAME_HEADER_LEN; | ||
263 | header_read = 1; | ||
264 | } else if (bytes_left == 0) { | ||
265 | packet_type = LAST_PACKET; | ||
266 | } else { | ||
267 | packet_type = INTER_PACKET; | ||
268 | } | ||
269 | gspca_frame_add(gspca_dev, packet_type, | ||
270 | data, data_len); | ||
271 | /* If entire frame fits in one packet we still | ||
272 | need to add a LAST_PACKET */ | ||
273 | if (packet_type == FIRST_PACKET && | ||
274 | bytes_left == 0) | ||
275 | gspca_frame_add(gspca_dev, LAST_PACKET, | ||
276 | NULL, 0); | ||
277 | } | ||
278 | if (gspca_dev->present) { | ||
279 | /* acknowledge the frame */ | ||
280 | mutex_lock(&gspca_dev->usb_lock); | ||
281 | ret = sq905_ack_frame(gspca_dev); | ||
282 | mutex_unlock(&gspca_dev->usb_lock); | ||
283 | if (ret < 0) | ||
284 | goto quit_stream; | ||
285 | } | ||
286 | } | ||
287 | quit_stream: | ||
288 | if (gspca_dev->present) { | ||
289 | mutex_lock(&gspca_dev->usb_lock); | ||
290 | sq905_command(gspca_dev, SQ905_CLEAR); | ||
291 | mutex_unlock(&gspca_dev->usb_lock); | ||
292 | } | ||
293 | kfree(buffer); | ||
294 | } | ||
295 | |||
296 | /* This function is called at probe time just before sd_init */ | ||
297 | static int sd_config(struct gspca_dev *gspca_dev, | ||
298 | const struct usb_device_id *id) | ||
299 | { | ||
300 | struct cam *cam = &gspca_dev->cam; | ||
301 | struct sd *dev = (struct sd *) gspca_dev; | ||
302 | |||
303 | /* We don't use the buffer gspca allocates so make it small. */ | ||
304 | cam->bulk = 1; | ||
305 | cam->bulk_size = 64; | ||
306 | |||
307 | INIT_WORK(&dev->work_struct, sq905_dostream); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | /* called on streamoff with alt==0 and on disconnect */ | ||
313 | /* the usb_lock is held at entry - restore on exit */ | ||
314 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
315 | { | ||
316 | struct sd *dev = (struct sd *) gspca_dev; | ||
317 | |||
318 | /* wait for the work queue to terminate */ | ||
319 | mutex_unlock(&gspca_dev->usb_lock); | ||
320 | /* This waits for sq905_dostream to finish */ | ||
321 | destroy_workqueue(dev->work_thread); | ||
322 | dev->work_thread = NULL; | ||
323 | mutex_lock(&gspca_dev->usb_lock); | ||
324 | } | ||
325 | |||
326 | /* this function is called at probe and resume time */ | ||
327 | static int sd_init(struct gspca_dev *gspca_dev) | ||
328 | { | ||
329 | u32 ident; | ||
330 | int ret; | ||
331 | |||
332 | /* connect to the camera and read | ||
333 | * the model ID and process that and put it away. | ||
334 | */ | ||
335 | ret = sq905_command(gspca_dev, SQ905_CLEAR); | ||
336 | if (ret < 0) | ||
337 | return ret; | ||
338 | ret = sq905_command(gspca_dev, SQ905_ID); | ||
339 | if (ret < 0) | ||
340 | return ret; | ||
341 | ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0); | ||
342 | if (ret < 0) | ||
343 | return ret; | ||
344 | /* usb_buf is allocated with kmalloc so is aligned. | ||
345 | * Camera model number is the right way round if we assume this | ||
346 | * reverse engineered ID is supposed to be big endian. */ | ||
347 | ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf); | ||
348 | ret = sq905_command(gspca_dev, SQ905_CLEAR); | ||
349 | if (ret < 0) | ||
350 | return ret; | ||
351 | PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident); | ||
352 | gspca_dev->cam.cam_mode = sq905_mode; | ||
353 | gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode); | ||
354 | if (!(ident & SQ905_HIRES_MASK)) | ||
355 | gspca_dev->cam.nmodes--; | ||
356 | |||
357 | if (ident & SQ905_ORIENTATION_MASK) | ||
358 | gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP; | ||
359 | else | ||
360 | gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP | | ||
361 | V4L2_IN_ST_HFLIP; | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | /* Set up for getting frames. */ | ||
366 | static int sd_start(struct gspca_dev *gspca_dev) | ||
367 | { | ||
368 | struct sd *dev = (struct sd *) gspca_dev; | ||
369 | int ret; | ||
370 | |||
371 | /* "Open the shutter" and set size, to start capture */ | ||
372 | switch (gspca_dev->curr_mode) { | ||
373 | default: | ||
374 | /* case 2: */ | ||
375 | PDEBUG(D_STREAM, "Start streaming at high resolution"); | ||
376 | ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH); | ||
377 | break; | ||
378 | case 1: | ||
379 | PDEBUG(D_STREAM, "Start streaming at medium resolution"); | ||
380 | ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED); | ||
381 | break; | ||
382 | case 0: | ||
383 | PDEBUG(D_STREAM, "Start streaming at low resolution"); | ||
384 | ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW); | ||
385 | } | ||
386 | |||
387 | if (ret < 0) { | ||
388 | PDEBUG(D_ERR, "Start streaming command failed"); | ||
389 | return ret; | ||
390 | } | ||
391 | /* Start the workqueue function to do the streaming */ | ||
392 | dev->work_thread = create_singlethread_workqueue(MODULE_NAME); | ||
393 | queue_work(dev->work_thread, &dev->work_struct); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | /* Table of supported USB devices */ | ||
399 | static const struct usb_device_id device_table[] = { | ||
400 | {USB_DEVICE(0x2770, 0x9120)}, | ||
401 | {} | ||
402 | }; | ||
403 | |||
404 | MODULE_DEVICE_TABLE(usb, device_table); | ||
405 | |||
406 | /* sub-driver description */ | ||
407 | static const struct sd_desc sd_desc = { | ||
408 | .name = MODULE_NAME, | ||
409 | .config = sd_config, | ||
410 | .init = sd_init, | ||
411 | .start = sd_start, | ||
412 | .stop0 = sd_stop0, | ||
413 | }; | ||
414 | |||
415 | /* -- device connect -- */ | ||
416 | static int sd_probe(struct usb_interface *intf, | ||
417 | const struct usb_device_id *id) | ||
418 | { | ||
419 | return gspca_dev_probe(intf, id, | ||
420 | &sd_desc, | ||
421 | sizeof(struct sd), | ||
422 | THIS_MODULE); | ||
423 | } | ||
424 | |||
425 | static struct usb_driver sd_driver = { | ||
426 | .name = MODULE_NAME, | ||
427 | .id_table = device_table, | ||
428 | .probe = sd_probe, | ||
429 | .disconnect = gspca_disconnect, | ||
430 | #ifdef CONFIG_PM | ||
431 | .suspend = gspca_suspend, | ||
432 | .resume = gspca_resume, | ||
433 | #endif | ||
434 | }; | ||
435 | |||
436 | /* -- module insert / remove -- */ | ||
437 | static int __init sd_mod_init(void) | ||
438 | { | ||
439 | return usb_register(&sd_driver); | ||
440 | } | ||
441 | |||
442 | static void __exit sd_mod_exit(void) | ||
443 | { | ||
444 | usb_deregister(&sd_driver); | ||
445 | } | ||
446 | |||
447 | module_init(sd_mod_init); | ||
448 | module_exit(sd_mod_exit); | ||