blob: 33de1771b1913d50969a69429b838e8e2bf9051c [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
37#define JEILINJ_DATA_TIMEOUT 1000
38
39/* Maximum transfer size to use. */
40#define JEILINJ_MAX_TRANSFER 0x200
Theodore Kilgore3040b042009-08-03 04:13:23 -030041#define FRAME_HEADER_LEN 0x10
Patrice Chotardc3d86922011-04-18 17:37:06 -030042#define FRAME_START 0xFFFFFFFF
Theodore Kilgore3040b042009-08-03 04:13:23 -030043
44/* Structure to hold all of our device specific stuff */
45struct sd {
46 struct gspca_dev gspca_dev; /* !! must be the first item */
Patrice Chotardc3d86922011-04-18 17:37:06 -030047 int blocks_left;
Theodore Kilgore3040b042009-08-03 04:13:23 -030048 const struct v4l2_pix_format *cap_mode;
49 /* Driver stuff */
Theodore Kilgore3040b042009-08-03 04:13:23 -030050 u8 quality; /* image quality */
Jean-François Moine9a731a32010-06-04 05:26:42 -030051 u8 jpeg_hdr[JPEG_HDR_SZ];
Theodore Kilgore3040b042009-08-03 04:13:23 -030052};
53
Patrice Chotardc3d86922011-04-18 17:37:06 -030054struct jlj_command {
55 unsigned char instruction[2];
56 unsigned char ack_wanted;
57};
Theodore Kilgore3040b042009-08-03 04:13:23 -030058
59/* AFAICT these cameras will only do 320x240. */
60static struct v4l2_pix_format jlj_mode[] = {
61 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
62 .bytesperline = 320,
63 .sizeimage = 320 * 240,
64 .colorspace = V4L2_COLORSPACE_JPEG,
65 .priv = 0}
66};
67
68/*
69 * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
70 * and 0x82 for bulk transfer.
71 */
72
73/* All commands are two bytes only */
74static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
75{
76 int retval;
77
78 memcpy(gspca_dev->usb_buf, command, 2);
79 retval = usb_bulk_msg(gspca_dev->dev,
80 usb_sndbulkpipe(gspca_dev->dev, 3),
81 gspca_dev->usb_buf, 2, NULL, 500);
82 if (retval < 0)
Jean-François Moine0b656322010-09-13 05:19:58 -030083 err("command write [%02x] error %d",
Theodore Kilgore3040b042009-08-03 04:13:23 -030084 gspca_dev->usb_buf[0], retval);
85 return retval;
86}
87
88/* Responses are one byte only */
89static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
90{
91 int retval;
92
93 retval = usb_bulk_msg(gspca_dev->dev,
94 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
95 gspca_dev->usb_buf, 1, NULL, 500);
96 response = gspca_dev->usb_buf[0];
97 if (retval < 0)
Jean-François Moine0b656322010-09-13 05:19:58 -030098 err("read command [%02x] error %d",
Theodore Kilgore3040b042009-08-03 04:13:23 -030099 gspca_dev->usb_buf[0], retval);
100 return retval;
101}
102
103static int jlj_start(struct gspca_dev *gspca_dev)
104{
105 int i;
106 int retval = -1;
107 u8 response = 0xff;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300108 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300109 struct jlj_command start_commands[] = {
110 {{0x71, 0x81}, 0},
111 {{0x70, 0x05}, 0},
112 {{0x95, 0x70}, 1},
113 {{0x71, 0x81}, 0},
114 {{0x70, 0x04}, 0},
115 {{0x95, 0x70}, 1},
116 {{0x71, 0x00}, 0},
117 {{0x70, 0x08}, 0},
118 {{0x95, 0x70}, 1},
119 {{0x94, 0x02}, 0},
120 {{0xde, 0x24}, 0},
121 {{0x94, 0x02}, 0},
122 {{0xdd, 0xf0}, 0},
123 {{0x94, 0x02}, 0},
124 {{0xe3, 0x2c}, 0},
125 {{0x94, 0x02}, 0},
126 {{0xe4, 0x00}, 0},
127 {{0x94, 0x02}, 0},
128 {{0xe5, 0x00}, 0},
129 {{0x94, 0x02}, 0},
130 {{0xe6, 0x2c}, 0},
131 {{0x94, 0x03}, 0},
132 {{0xaa, 0x00}, 0},
133 {{0x71, 0x1e}, 0},
134 {{0x70, 0x06}, 0},
135 {{0x71, 0x80}, 0},
136 {{0x70, 0x07}, 0}
137 };
Patrice Chotardc3d86922011-04-18 17:37:06 -0300138
139 sd->blocks_left = 0;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300140 for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
141 retval = jlj_write2(gspca_dev, start_commands[i].instruction);
142 if (retval < 0)
143 return retval;
144 if (start_commands[i].ack_wanted)
145 retval = jlj_read1(gspca_dev, response);
146 if (retval < 0)
147 return retval;
148 }
149 PDEBUG(D_ERR, "jlj_start retval is %d", retval);
150 return retval;
151}
152
Patrice Chotardc3d86922011-04-18 17:37:06 -0300153static void sd_pkt_scan(struct gspca_dev *gspca_dev,
154 u8 *data, int len)
Theodore Kilgore3040b042009-08-03 04:13:23 -0300155{
Patrice Chotardc3d86922011-04-18 17:37:06 -0300156 struct sd *sd = (struct sd *) gspca_dev;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300157 int packet_type;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300158 u32 header_marker;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300159
Patrice Chotardc3d86922011-04-18 17:37:06 -0300160 PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
161 len, JEILINJ_MAX_TRANSFER);
162 if (len != JEILINJ_MAX_TRANSFER) {
163 PDEBUG(D_PACK, "bad length");
164 goto discard;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300165 }
Patrice Chotardc3d86922011-04-18 17:37:06 -0300166 /* check if it's start of frame */
167 header_marker = ((u32 *)data)[0];
168 if (header_marker == FRAME_START) {
169 sd->blocks_left = data[0x0a] - 1;
170 PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
Hans de Goede6ca3f252009-10-09 03:58:35 -0300171 /* Start a new frame, and add the JPEG header, first thing */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300172 gspca_frame_add(gspca_dev, FIRST_PACKET,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300173 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300174 /* Toss line 0 of data block 0, keep the rest. */
175 gspca_frame_add(gspca_dev, INTER_PACKET,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300176 data + FRAME_HEADER_LEN,
Theodore Kilgore3040b042009-08-03 04:13:23 -0300177 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
Patrice Chotardc3d86922011-04-18 17:37:06 -0300178 } else if (sd->blocks_left > 0) {
179 PDEBUG(D_STREAM, "%d blocks remaining for frame",
180 sd->blocks_left);
181 sd->blocks_left -= 1;
182 if (sd->blocks_left == 0)
183 packet_type = LAST_PACKET;
184 else
185 packet_type = INTER_PACKET;
186 gspca_frame_add(gspca_dev, packet_type,
187 data, JEILINJ_MAX_TRANSFER);
188 } else
189 goto discard;
190 return;
191discard:
192 /* Discard data until a new frame starts. */
193 gspca_dev->last_packet_type = DISCARD_PACKET;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300194}
195
196/* This function is called at probe time just before sd_init */
197static int sd_config(struct gspca_dev *gspca_dev,
198 const struct usb_device_id *id)
199{
200 struct cam *cam = &gspca_dev->cam;
201 struct sd *dev = (struct sd *) gspca_dev;
202
203 dev->quality = 85;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300204 PDEBUG(D_PROBE,
205 "JEILINJ camera detected"
206 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
207 cam->cam_mode = jlj_mode;
208 cam->nmodes = 1;
209 cam->bulk = 1;
Patrice Chotardc3d86922011-04-18 17:37:06 -0300210 cam->bulk_nurbs = 1;
211 cam->bulk_size = JEILINJ_MAX_TRANSFER;
Theodore Kilgore3040b042009-08-03 04:13:23 -0300212 return 0;
213}
214
Patrice Chotardc3d86922011-04-18 17:37:06 -0300215static void sd_stopN(struct gspca_dev *gspca_dev)
Theodore Kilgore3040b042009-08-03 04:13:23 -0300216{
Patrice Chotardc3d86922011-04-18 17:37:06 -0300217 int i;
218 u8 *buf;
219 u8 stop_commands[][2] = {
220 {0x71, 0x00},
221 {0x70, 0x09},
222 {0x71, 0x80},
223 {0x70, 0x05}
224 };
Theodore Kilgore3040b042009-08-03 04:13:23 -0300225
Patrice Chotardc3d86922011-04-18 17:37:06 -0300226 for (;;) {
227 /* get the image remaining blocks */
228 usb_bulk_msg(gspca_dev->dev,
229 gspca_dev->urb[0]->pipe,
230 gspca_dev->urb[0]->transfer_buffer,
231 JEILINJ_MAX_TRANSFER, NULL,
232 JEILINJ_DATA_TIMEOUT);
233
234 /* search for 0xff 0xd9 (EOF for JPEG) */
235 i = 0;
236 buf = gspca_dev->urb[0]->transfer_buffer;
237 while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
238 ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
239 i++;
240
241 if (i != (JEILINJ_MAX_TRANSFER - 1))
242 /* last remaining block found */
243 break;
244 }
245
246 for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
247 jlj_write2(gspca_dev, stop_commands[i]);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300248}
249
250/* this function is called at probe and resume time */
251static int sd_init(struct gspca_dev *gspca_dev)
252{
253 return 0;
254}
255
256/* Set up for getting frames. */
257static int sd_start(struct gspca_dev *gspca_dev)
258{
259 struct sd *dev = (struct sd *) gspca_dev;
260 int ret;
261
262 /* create the JPEG header */
Theodore Kilgore3040b042009-08-03 04:13:23 -0300263 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
264 0x21); /* JPEG 422 */
265 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
266 PDEBUG(D_STREAM, "Start streaming at 320x240");
267 ret = jlj_start(gspca_dev);
268 if (ret < 0) {
269 PDEBUG(D_ERR, "Start streaming command failed");
270 return ret;
271 }
Theodore Kilgore3040b042009-08-03 04:13:23 -0300272 return 0;
273}
274
275/* Table of supported USB devices */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300276static const struct usb_device_id device_table[] = {
Theodore Kilgore3040b042009-08-03 04:13:23 -0300277 {USB_DEVICE(0x0979, 0x0280)},
278 {}
279};
280
281MODULE_DEVICE_TABLE(usb, device_table);
282
283/* sub-driver description */
284static const struct sd_desc sd_desc = {
285 .name = MODULE_NAME,
286 .config = sd_config,
287 .init = sd_init,
288 .start = sd_start,
Patrice Chotardc3d86922011-04-18 17:37:06 -0300289 .stopN = sd_stopN,
290 .pkt_scan = sd_pkt_scan,
Theodore Kilgore3040b042009-08-03 04:13:23 -0300291};
292
293/* -- device connect -- */
294static int sd_probe(struct usb_interface *intf,
295 const struct usb_device_id *id)
296{
297 return gspca_dev_probe(intf, id,
298 &sd_desc,
299 sizeof(struct sd),
300 THIS_MODULE);
301}
302
303static struct usb_driver sd_driver = {
304 .name = MODULE_NAME,
305 .id_table = device_table,
306 .probe = sd_probe,
307 .disconnect = gspca_disconnect,
308#ifdef CONFIG_PM
309 .suspend = gspca_suspend,
310 .resume = gspca_resume,
311#endif
312};
313
314/* -- module insert / remove -- */
315static int __init sd_mod_init(void)
316{
Jean-François Moine54826432010-09-13 04:53:03 -0300317 return usb_register(&sd_driver);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300318}
319
320static void __exit sd_mod_exit(void)
321{
322 usb_deregister(&sd_driver);
Theodore Kilgore3040b042009-08-03 04:13:23 -0300323}
324
325module_init(sd_mod_init);
326module_exit(sd_mod_exit);