blob: da92867fb273ff2402427de5223e862b9eaa8209 [file] [log] [blame]
Theodore Kilgore3040b042009-08-03 04:13:23 -03001/*
2 * Jeilinj subdriver
3 *
4 * Supports some Jeilin dual-mode cameras which use bulk transport and
5 * download raw JPEG data.
6 *
7 * Copyright (C) 2009 Theodore Kilgore
Patrice Chotardc3d86922011-04-18 17:37:06 -03008 * Copyright (C) 2011 Patrice Chotard
Theodore Kilgore3040b042009-08-03 04:13:23 -03009 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#define MODULE_NAME "jeilinj"
26
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090027#include <linux/slab.h>
Theodore Kilgore3040b042009-08-03 04:13:23 -030028#include "gspca.h"
29#include "jpeg.h"
30
31MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
32MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
33MODULE_LICENSE("GPL");
34
35/* Default timeouts, in ms */
36#define JEILINJ_CMD_TIMEOUT 500
Patrice Chotard713b4662011-04-18 17:40:54 -030037#define JEILINJ_CMD_DELAY 160
Theodore Kilgore3040b042009-08-03 04:13:23 -030038#define JEILINJ_DATA_TIMEOUT 1000
39
40/* Maximum transfer size to use. */
41#define JEILINJ_MAX_TRANSFER 0x200
Theodore Kilgore3040b042009-08-03 04:13:23 -030042#define FRAME_HEADER_LEN 0x10
Patrice Chotardc3d86922011-04-18 17:37:06 -030043#define FRAME_START 0xFFFFFFFF
Theodore Kilgore3040b042009-08-03 04:13:23 -030044
Patrice Chotard713b4662011-04-18 17:40:54 -030045enum {
46 SAKAR_57379,
47 SPORTSCAM_DV15,
48};
Theodore Kilgore3040b042009-08-03 04:13:23 -030049/* Structure to hold all of our device specific stuff */
50struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */
Patrice Chotardc3d86922011-04-18 17:37:06 -030052 int blocks_left;
Theodore Kilgore3040b042009-08-03 04:13:23 -030053 const struct v4l2_pix_format *cap_mode;
54 /* Driver stuff */
Patrice Chotard713b4662011-04-18 17:40:54 -030055 u8 type;
Theodore Kilgore3040b042009-08-03 04:13:23 -030056 u8 quality; /* image quality */
Jean-François Moine9a731a32010-06-04 05:26:42 -030057 u8 jpeg_hdr[JPEG_HDR_SZ];
Theodore Kilgore3040b042009-08-03 04:13:23 -030058};
59
Patrice Chotardc3d86922011-04-18 17:37:06 -030060struct jlj_command {
61 unsigned char instruction[2];
62 unsigned char ack_wanted;
Patrice Chotard713b4662011-04-18 17:40:54 -030063 unsigned char delay;
Patrice Chotardc3d86922011-04-18 17:37:06 -030064};
Theodore Kilgore3040b042009-08-03 04:13:23 -030065
66/* AFAICT these cameras will only do 320x240. */
67static struct v4l2_pix_format jlj_mode[] = {
68 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
69 .bytesperline = 320,
70 .sizeimage = 320 * 240,
71 .colorspace = V4L2_COLORSPACE_JPEG,
Patrice Chotard6f8efcf2011-04-18 17:39:38 -030072 .priv = 0},
73 { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
74 .bytesperline = 640,
75 .sizeimage = 640 * 480,
76 .colorspace = V4L2_COLORSPACE_JPEG,
Theodore Kilgore3040b042009-08-03 04:13:23 -030077 .priv = 0}
78};
79
80/*
81 * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
82 * and 0x82 for bulk transfer.
83 */
84
85/* All commands are two bytes only */
Patrice Chotard8715b162011-04-18 17:38:37 -030086static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
Theodore Kilgore3040b042009-08-03 04:13:23 -030087{
88 int retval;
89
Patrice Chotard8715b162011-04-18 17:38:37 -030090 if (gspca_dev->usb_err < 0)
91 return;
Theodore Kilgore3040b042009-08-03 04:13:23 -030092 memcpy(gspca_dev->usb_buf, command, 2);
93 retval = usb_bulk_msg(gspca_dev->dev,
94 usb_sndbulkpipe(gspca_dev->dev, 3),
95 gspca_dev->usb_buf, 2, NULL, 500);
Patrice Chotard8715b162011-04-18 17:38:37 -030096 if (retval < 0) {
Jean-François Moine0b656322010-09-13 05:19:58 -030097 err("command write [%02x] error %d",
Theodore Kilgore3040b042009-08-03 04:13:23 -030098 gspca_dev->usb_buf[0], retval);
Patrice Chotard8715b162011-04-18 17:38:37 -030099 gspca_dev->usb_err = retval;
100 }
Theodore Kilgore3040b042009-08-03 04:13:23 -0300101}
102
103/* Responses are one byte only */
Patrice Chotard8715b162011-04-18 17:38:37 -0300104static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
Theodore Kilgore3040b042009-08-03 04:13:23 -0300105{
106 int retval;
107
Patrice Chotard8715b162011-04-18 17:38:37 -0300108 if (gspca_dev->usb_err < 0)
109 return;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300110 retval = usb_bulk_msg(gspca_dev->dev,
111 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
112 gspca_dev->usb_buf, 1, NULL, 500);
113 response = gspca_dev->usb_buf[0];
Patrice Chotard8715b162011-04-18 17:38:37 -0300114 if (retval < 0) {
Jean-François Moine0b656322010-09-13 05:19:58 -0300115 err("read command [%02x] error %d",
Theodore Kilgore3040b042009-08-03 04:13:23 -0300116 gspca_dev->usb_buf[0], retval);
Patrice Chotard8715b162011-04-18 17:38:37 -0300117 gspca_dev->usb_err = retval;
118 }
Theodore Kilgore3040b042009-08-03 04:13:23 -0300119}
120
121static int jlj_start(struct gspca_dev *gspca_dev)
122{
123 int i;
Patrice Chotard713b4662011-04-18 17:40:54 -0300124 int start_commands_size;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300125 u8 response = 0xff;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300126 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300127 struct jlj_command start_commands[] = {
Patrice Chotard713b4662011-04-18 17:40:54 -0300128 {{0x71, 0x81}, 0, 0},
129 {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
130 {{0x95, 0x70}, 1, 0},
131 {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
132 {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
133 {{0x95, 0x70}, 1, 0},
134 {{0x71, 0x00}, 0, 0}, /* start streaming ??*/
135 {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
136 {{0x95, 0x70}, 1, 0},
137#define SPORTSCAM_DV15_CMD_SIZE 9
138 {{0x94, 0x02}, 0, 0},
139 {{0xde, 0x24}, 0, 0},
140 {{0x94, 0x02}, 0, 0},
141 {{0xdd, 0xf0}, 0, 0},
142 {{0x94, 0x02}, 0, 0},
143 {{0xe3, 0x2c}, 0, 0},
144 {{0x94, 0x02}, 0, 0},
145 {{0xe4, 0x00}, 0, 0},
146 {{0x94, 0x02}, 0, 0},
147 {{0xe5, 0x00}, 0, 0},
148 {{0x94, 0x02}, 0, 0},
149 {{0xe6, 0x2c}, 0, 0},
150 {{0x94, 0x03}, 0, 0},
151 {{0xaa, 0x00}, 0, 0},
152 {{0x71, 0x1e}, 0, 0},
153 {{0x70, 0x06}, 0, 0},
154 {{0x71, 0x80}, 0, 0},
155 {{0x70, 0x07}, 0, 0}
Theodore Kilgore3040b042009-08-03 04:13:23 -0300156 };
Patrice Chotardc3d86922011-04-18 17:37:06 -0300157
158 sd->blocks_left = 0;
Patrice Chotard713b4662011-04-18 17:40:54 -0300159 /* Under Windows, USB spy shows that only the 9 first start
160 * commands are used for SPORTSCAM_DV15 webcam
161 */
162 if (sd->type == SPORTSCAM_DV15)
163 start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
164 else
165 start_commands_size = ARRAY_SIZE(start_commands);
166
167 for (i = 0; i < start_commands_size; i++) {
Patrice Chotard8715b162011-04-18 17:38:37 -0300168 jlj_write2(gspca_dev, start_commands[i].instruction);
Patrice Chotard713b4662011-04-18 17:40:54 -0300169 if (start_commands[i].delay)
170 msleep(start_commands[i].delay);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300171 if (start_commands[i].ack_wanted)
Patrice Chotard8715b162011-04-18 17:38:37 -0300172 jlj_read1(gspca_dev, response);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300173 }
Patrice Chotard8715b162011-04-18 17:38:37 -0300174 if (gspca_dev->usb_err < 0)
175 PDEBUG(D_ERR, "Start streaming command failed");
176 return gspca_dev->usb_err;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300177}
178
Patrice Chotardc3d86922011-04-18 17:37:06 -0300179static void sd_pkt_scan(struct gspca_dev *gspca_dev,
180 u8 *data, int len)
Theodore Kilgore3040b042009-08-03 04:13:23 -0300181{
Patrice Chotardc3d86922011-04-18 17:37:06 -0300182 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300183 int packet_type;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300184 u32 header_marker;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300185
Patrice Chotardc3d86922011-04-18 17:37:06 -0300186 PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
187 len, JEILINJ_MAX_TRANSFER);
188 if (len != JEILINJ_MAX_TRANSFER) {
189 PDEBUG(D_PACK, "bad length");
190 goto discard;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300191 }
Patrice Chotardc3d86922011-04-18 17:37:06 -0300192 /* check if it's start of frame */
193 header_marker = ((u32 *)data)[0];
194 if (header_marker == FRAME_START) {
195 sd->blocks_left = data[0x0a] - 1;
196 PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
Hans de Goede6ca3f252009-10-09 03:58:35 -0300197 /* Start a new frame, and add the JPEG header, first thing */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300198 gspca_frame_add(gspca_dev, FIRST_PACKET,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300199 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300200 /* Toss line 0 of data block 0, keep the rest. */
201 gspca_frame_add(gspca_dev, INTER_PACKET,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300202 data + FRAME_HEADER_LEN,
Theodore Kilgore3040b042009-08-03 04:13:23 -0300203 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
Patrice Chotardc3d86922011-04-18 17:37:06 -0300204 } else if (sd->blocks_left > 0) {
205 PDEBUG(D_STREAM, "%d blocks remaining for frame",
206 sd->blocks_left);
207 sd->blocks_left -= 1;
208 if (sd->blocks_left == 0)
209 packet_type = LAST_PACKET;
210 else
211 packet_type = INTER_PACKET;
212 gspca_frame_add(gspca_dev, packet_type,
213 data, JEILINJ_MAX_TRANSFER);
214 } else
215 goto discard;
216 return;
217discard:
218 /* Discard data until a new frame starts. */
219 gspca_dev->last_packet_type = DISCARD_PACKET;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300220}
221
222/* This function is called at probe time just before sd_init */
223static int sd_config(struct gspca_dev *gspca_dev,
224 const struct usb_device_id *id)
225{
226 struct cam *cam = &gspca_dev->cam;
227 struct sd *dev = (struct sd *) gspca_dev;
228
Patrice Chotard713b4662011-04-18 17:40:54 -0300229 dev->type = id->driver_info;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300230 dev->quality = 85;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300231 PDEBUG(D_PROBE,
232 "JEILINJ camera detected"
233 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
234 cam->cam_mode = jlj_mode;
Patrice Chotard6f8efcf2011-04-18 17:39:38 -0300235 cam->nmodes = ARRAY_SIZE(jlj_mode);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300236 cam->bulk = 1;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300237 cam->bulk_nurbs = 1;
238 cam->bulk_size = JEILINJ_MAX_TRANSFER;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300239 return 0;
240}
241
Patrice Chotardc3d86922011-04-18 17:37:06 -0300242static void sd_stopN(struct gspca_dev *gspca_dev)
Theodore Kilgore3040b042009-08-03 04:13:23 -0300243{
Patrice Chotardc3d86922011-04-18 17:37:06 -0300244 int i;
245 u8 *buf;
246 u8 stop_commands[][2] = {
247 {0x71, 0x00},
248 {0x70, 0x09},
249 {0x71, 0x80},
250 {0x70, 0x05}
251 };
Theodore Kilgore3040b042009-08-03 04:13:23 -0300252
Patrice Chotardc3d86922011-04-18 17:37:06 -0300253 for (;;) {
254 /* get the image remaining blocks */
255 usb_bulk_msg(gspca_dev->dev,
256 gspca_dev->urb[0]->pipe,
257 gspca_dev->urb[0]->transfer_buffer,
258 JEILINJ_MAX_TRANSFER, NULL,
259 JEILINJ_DATA_TIMEOUT);
260
261 /* search for 0xff 0xd9 (EOF for JPEG) */
262 i = 0;
263 buf = gspca_dev->urb[0]->transfer_buffer;
264 while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
265 ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
266 i++;
267
268 if (i != (JEILINJ_MAX_TRANSFER - 1))
269 /* last remaining block found */
270 break;
271 }
272
273 for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
274 jlj_write2(gspca_dev, stop_commands[i]);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300275}
276
277/* this function is called at probe and resume time */
278static int sd_init(struct gspca_dev *gspca_dev)
279{
Patrice Chotard8715b162011-04-18 17:38:37 -0300280 return gspca_dev->usb_err;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300281}
282
283/* Set up for getting frames. */
284static int sd_start(struct gspca_dev *gspca_dev)
285{
286 struct sd *dev = (struct sd *) gspca_dev;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300287
288 /* create the JPEG header */
Theodore Kilgore3040b042009-08-03 04:13:23 -0300289 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
290 0x21); /* JPEG 422 */
291 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
Patrice Chotard6f8efcf2011-04-18 17:39:38 -0300292 PDEBUG(D_STREAM, "Start streaming at %dx%d",
293 gspca_dev->height, gspca_dev->width);
Patrice Chotard8715b162011-04-18 17:38:37 -0300294 jlj_start(gspca_dev);
295 return gspca_dev->usb_err;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300296}
297
298/* Table of supported USB devices */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300299static const struct usb_device_id device_table[] = {
Patrice Chotard713b4662011-04-18 17:40:54 -0300300 {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
301 {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
Theodore Kilgore3040b042009-08-03 04:13:23 -0300302 {}
303};
304
305MODULE_DEVICE_TABLE(usb, device_table);
306
307/* sub-driver description */
Patrice Chotard713b4662011-04-18 17:40:54 -0300308static const struct sd_desc sd_desc_sakar_57379 = {
Theodore Kilgore3040b042009-08-03 04:13:23 -0300309 .name = MODULE_NAME,
310 .config = sd_config,
311 .init = sd_init,
312 .start = sd_start,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300313 .stopN = sd_stopN,
314 .pkt_scan = sd_pkt_scan,
Theodore Kilgore3040b042009-08-03 04:13:23 -0300315};
316
Patrice Chotard713b4662011-04-18 17:40:54 -0300317/* sub-driver description */
318static const struct sd_desc sd_desc_sportscam_dv15 = {
319 .name = MODULE_NAME,
320 .config = sd_config,
321 .init = sd_init,
322 .start = sd_start,
323 .stopN = sd_stopN,
324 .pkt_scan = sd_pkt_scan,
325};
326
327static const struct sd_desc *sd_desc[2] = {
328 &sd_desc_sakar_57379,
329 &sd_desc_sportscam_dv15
330};
331
Theodore Kilgore3040b042009-08-03 04:13:23 -0300332/* -- device connect -- */
333static int sd_probe(struct usb_interface *intf,
334 const struct usb_device_id *id)
335{
336 return gspca_dev_probe(intf, id,
Patrice Chotard713b4662011-04-18 17:40:54 -0300337 sd_desc[id->driver_info],
Theodore Kilgore3040b042009-08-03 04:13:23 -0300338 sizeof(struct sd),
339 THIS_MODULE);
340}
341
342static struct usb_driver sd_driver = {
343 .name = MODULE_NAME,
344 .id_table = device_table,
345 .probe = sd_probe,
346 .disconnect = gspca_disconnect,
347#ifdef CONFIG_PM
348 .suspend = gspca_suspend,
349 .resume = gspca_resume,
350#endif
351};
352
353/* -- module insert / remove -- */
354static int __init sd_mod_init(void)
355{
Jean-François Moine54826432010-09-13 04:53:03 -0300356 return usb_register(&sd_driver);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300357}
358
359static void __exit sd_mod_exit(void)
360{
361 usb_deregister(&sd_driver);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300362}
363
364module_init(sd_mod_init);
365module_exit(sd_mod_exit);