xref: /openbmc/linux/drivers/media/usb/gspca/jeilinj.c (revision fd9871f7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Jeilinj subdriver
4  *
5  * Supports some Jeilin dual-mode cameras which use bulk transport and
6  * download raw JPEG data.
7  *
8  * Copyright (C) 2009 Theodore Kilgore
9  *
10  * Sportscam DV15 support and control settings are
11  * Copyright (C) 2011 Patrice Chotard
12  */
13 
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 
16 #define MODULE_NAME "jeilinj"
17 
18 #include <linux/slab.h>
19 #include "gspca.h"
20 #include "jpeg.h"
21 
22 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
23 MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
24 MODULE_LICENSE("GPL");
25 
26 /* Default timeouts, in ms */
27 #define JEILINJ_CMD_TIMEOUT 500
28 #define JEILINJ_CMD_DELAY 160
29 #define JEILINJ_DATA_TIMEOUT 1000
30 
31 /* Maximum transfer size to use. */
32 #define JEILINJ_MAX_TRANSFER 0x200
33 #define FRAME_HEADER_LEN 0x10
34 #define FRAME_START 0xFFFFFFFF
35 
36 enum {
37 	SAKAR_57379,
38 	SPORTSCAM_DV15,
39 };
40 
41 #define CAMQUALITY_MIN 0	/* highest cam quality */
42 #define CAMQUALITY_MAX 97	/* lowest cam quality  */
43 
44 /* Structure to hold all of our device specific stuff */
45 struct sd {
46 	struct gspca_dev gspca_dev;	/* !! must be the first item */
47 	int blocks_left;
48 	const struct v4l2_pix_format *cap_mode;
49 	struct v4l2_ctrl *freq;
50 	struct v4l2_ctrl *jpegqual;
51 	/* Driver stuff */
52 	u8 type;
53 	u8 quality;				 /* image quality */
54 #define QUALITY_MIN 35
55 #define QUALITY_MAX 85
56 #define QUALITY_DEF 85
57 	u8 jpeg_hdr[JPEG_HDR_SZ];
58 };
59 
60 struct jlj_command {
61 	unsigned char instruction[2];
62 	unsigned char ack_wanted;
63 	unsigned char delay;
64 };
65 
66 /* AFAICT these cameras will only do 320x240. */
67 static 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,
72 		.priv = 0},
73 	{ 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
74 		.bytesperline = 640,
75 		.sizeimage = 640 * 480,
76 		.colorspace = V4L2_COLORSPACE_JPEG,
77 		.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 */
jlj_write2(struct gspca_dev * gspca_dev,unsigned char * command)86 static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
87 {
88 	int retval;
89 
90 	if (gspca_dev->usb_err < 0)
91 		return;
92 	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);
96 	if (retval < 0) {
97 		pr_err("command write [%02x] error %d\n",
98 		       gspca_dev->usb_buf[0], retval);
99 		gspca_dev->usb_err = retval;
100 	}
101 }
102 
103 /* Responses are one byte only */
jlj_read1(struct gspca_dev * gspca_dev,unsigned char * response)104 static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char *response)
105 {
106 	int retval;
107 
108 	if (gspca_dev->usb_err < 0)
109 		return;
110 	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];
114 	if (retval < 0) {
115 		pr_err("read command [%02x] error %d\n",
116 		       gspca_dev->usb_buf[0], retval);
117 		gspca_dev->usb_err = retval;
118 	}
119 }
120 
setfreq(struct gspca_dev * gspca_dev,s32 val)121 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
122 {
123 	u8 freq_commands[][2] = {
124 		{0x71, 0x80},
125 		{0x70, 0x07}
126 	};
127 
128 	freq_commands[0][1] |= val >> 1;
129 
130 	jlj_write2(gspca_dev, freq_commands[0]);
131 	jlj_write2(gspca_dev, freq_commands[1]);
132 }
133 
setcamquality(struct gspca_dev * gspca_dev,s32 val)134 static void setcamquality(struct gspca_dev *gspca_dev, s32 val)
135 {
136 	u8 quality_commands[][2] = {
137 		{0x71, 0x1E},
138 		{0x70, 0x06}
139 	};
140 	u8 camquality;
141 
142 	/* adapt camera quality from jpeg quality */
143 	camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX)
144 		/ (QUALITY_MAX - QUALITY_MIN);
145 	quality_commands[0][1] += camquality;
146 
147 	jlj_write2(gspca_dev, quality_commands[0]);
148 	jlj_write2(gspca_dev, quality_commands[1]);
149 }
150 
setautogain(struct gspca_dev * gspca_dev,s32 val)151 static void setautogain(struct gspca_dev *gspca_dev, s32 val)
152 {
153 	u8 autogain_commands[][2] = {
154 		{0x94, 0x02},
155 		{0xcf, 0x00}
156 	};
157 
158 	autogain_commands[1][1] = val << 4;
159 
160 	jlj_write2(gspca_dev, autogain_commands[0]);
161 	jlj_write2(gspca_dev, autogain_commands[1]);
162 }
163 
setred(struct gspca_dev * gspca_dev,s32 val)164 static void setred(struct gspca_dev *gspca_dev, s32 val)
165 {
166 	u8 setred_commands[][2] = {
167 		{0x94, 0x02},
168 		{0xe6, 0x00}
169 	};
170 
171 	setred_commands[1][1] = val;
172 
173 	jlj_write2(gspca_dev, setred_commands[0]);
174 	jlj_write2(gspca_dev, setred_commands[1]);
175 }
176 
setgreen(struct gspca_dev * gspca_dev,s32 val)177 static void setgreen(struct gspca_dev *gspca_dev, s32 val)
178 {
179 	u8 setgreen_commands[][2] = {
180 		{0x94, 0x02},
181 		{0xe7, 0x00}
182 	};
183 
184 	setgreen_commands[1][1] = val;
185 
186 	jlj_write2(gspca_dev, setgreen_commands[0]);
187 	jlj_write2(gspca_dev, setgreen_commands[1]);
188 }
189 
setblue(struct gspca_dev * gspca_dev,s32 val)190 static void setblue(struct gspca_dev *gspca_dev, s32 val)
191 {
192 	u8 setblue_commands[][2] = {
193 		{0x94, 0x02},
194 		{0xe9, 0x00}
195 	};
196 
197 	setblue_commands[1][1] = val;
198 
199 	jlj_write2(gspca_dev, setblue_commands[0]);
200 	jlj_write2(gspca_dev, setblue_commands[1]);
201 }
202 
jlj_start(struct gspca_dev * gspca_dev)203 static int jlj_start(struct gspca_dev *gspca_dev)
204 {
205 	int i;
206 	int start_commands_size;
207 	u8 response = 0xff;
208 	struct sd *sd = (struct sd *) gspca_dev;
209 	struct jlj_command start_commands[] = {
210 		{{0x71, 0x81}, 0, 0},
211 		{{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
212 		{{0x95, 0x70}, 1, 0},
213 		{{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
214 		{{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
215 		{{0x95, 0x70}, 1, 0},
216 		{{0x71, 0x00}, 0, 0},   /* start streaming ??*/
217 		{{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
218 		{{0x95, 0x70}, 1, 0},
219 #define SPORTSCAM_DV15_CMD_SIZE 9
220 		{{0x94, 0x02}, 0, 0},
221 		{{0xde, 0x24}, 0, 0},
222 		{{0x94, 0x02}, 0, 0},
223 		{{0xdd, 0xf0}, 0, 0},
224 		{{0x94, 0x02}, 0, 0},
225 		{{0xe3, 0x2c}, 0, 0},
226 		{{0x94, 0x02}, 0, 0},
227 		{{0xe4, 0x00}, 0, 0},
228 		{{0x94, 0x02}, 0, 0},
229 		{{0xe5, 0x00}, 0, 0},
230 		{{0x94, 0x02}, 0, 0},
231 		{{0xe6, 0x2c}, 0, 0},
232 		{{0x94, 0x03}, 0, 0},
233 		{{0xaa, 0x00}, 0, 0}
234 	};
235 
236 	sd->blocks_left = 0;
237 	/* Under Windows, USB spy shows that only the 9 first start
238 	 * commands are used for SPORTSCAM_DV15 webcam
239 	 */
240 	if (sd->type == SPORTSCAM_DV15)
241 		start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
242 	else
243 		start_commands_size = ARRAY_SIZE(start_commands);
244 
245 	for (i = 0; i < start_commands_size; i++) {
246 		jlj_write2(gspca_dev, start_commands[i].instruction);
247 		if (start_commands[i].delay)
248 			msleep(start_commands[i].delay);
249 		if (start_commands[i].ack_wanted)
250 			jlj_read1(gspca_dev, &response);
251 	}
252 	setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
253 	msleep(2);
254 	setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
255 	if (gspca_dev->usb_err < 0)
256 		gspca_err(gspca_dev, "Start streaming command failed\n");
257 	return gspca_dev->usb_err;
258 }
259 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)260 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
261 			u8 *data, int len)
262 {
263 	struct sd *sd = (struct sd *) gspca_dev;
264 	int packet_type;
265 	u32 header_marker;
266 
267 	gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
268 		  len, JEILINJ_MAX_TRANSFER);
269 	if (len != JEILINJ_MAX_TRANSFER) {
270 		gspca_dbg(gspca_dev, D_PACK, "bad length\n");
271 		goto discard;
272 	}
273 	/* check if it's start of frame */
274 	header_marker = ((u32 *)data)[0];
275 	if (header_marker == FRAME_START) {
276 		sd->blocks_left = data[0x0a] - 1;
277 		gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
278 			  sd->blocks_left);
279 		/* Start a new frame, and add the JPEG header, first thing */
280 		gspca_frame_add(gspca_dev, FIRST_PACKET,
281 				sd->jpeg_hdr, JPEG_HDR_SZ);
282 		/* Toss line 0 of data block 0, keep the rest. */
283 		gspca_frame_add(gspca_dev, INTER_PACKET,
284 				data + FRAME_HEADER_LEN,
285 				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
286 	} else if (sd->blocks_left > 0) {
287 		gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
288 			  sd->blocks_left);
289 		sd->blocks_left -= 1;
290 		if (sd->blocks_left == 0)
291 			packet_type = LAST_PACKET;
292 		else
293 			packet_type = INTER_PACKET;
294 		gspca_frame_add(gspca_dev, packet_type,
295 				data, JEILINJ_MAX_TRANSFER);
296 	} else
297 		goto discard;
298 	return;
299 discard:
300 	/* Discard data until a new frame starts. */
301 	gspca_dev->last_packet_type = DISCARD_PACKET;
302 }
303 
304 /* This function is called at probe time just before sd_init */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)305 static int sd_config(struct gspca_dev *gspca_dev,
306 		const struct usb_device_id *id)
307 {
308 	struct cam *cam = &gspca_dev->cam;
309 	struct sd *dev  = (struct sd *) gspca_dev;
310 
311 	dev->type = id->driver_info;
312 	dev->quality = QUALITY_DEF;
313 
314 	cam->cam_mode = jlj_mode;
315 	cam->nmodes = ARRAY_SIZE(jlj_mode);
316 	cam->bulk = 1;
317 	cam->bulk_nurbs = 1;
318 	cam->bulk_size = JEILINJ_MAX_TRANSFER;
319 	return 0;
320 }
321 
sd_stopN(struct gspca_dev * gspca_dev)322 static void sd_stopN(struct gspca_dev *gspca_dev)
323 {
324 	int i;
325 	u8 *buf;
326 	static u8 stop_commands[][2] = {
327 		{0x71, 0x00},
328 		{0x70, 0x09},
329 		{0x71, 0x80},
330 		{0x70, 0x05}
331 	};
332 
333 	for (;;) {
334 		/* get the image remaining blocks */
335 		usb_bulk_msg(gspca_dev->dev,
336 				gspca_dev->urb[0]->pipe,
337 				gspca_dev->urb[0]->transfer_buffer,
338 				JEILINJ_MAX_TRANSFER, NULL,
339 				JEILINJ_DATA_TIMEOUT);
340 
341 		/* search for 0xff 0xd9  (EOF for JPEG) */
342 		i = 0;
343 		buf = gspca_dev->urb[0]->transfer_buffer;
344 		while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
345 			((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
346 			i++;
347 
348 		if (i != (JEILINJ_MAX_TRANSFER - 1))
349 			/* last remaining block found */
350 			break;
351 		}
352 
353 	for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
354 		jlj_write2(gspca_dev, stop_commands[i]);
355 }
356 
357 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)358 static int sd_init(struct gspca_dev *gspca_dev)
359 {
360 	return gspca_dev->usb_err;
361 }
362 
363 /* Set up for getting frames. */
sd_start(struct gspca_dev * gspca_dev)364 static int sd_start(struct gspca_dev *gspca_dev)
365 {
366 	struct sd *dev = (struct sd *) gspca_dev;
367 
368 	/* create the JPEG header */
369 	jpeg_define(dev->jpeg_hdr, gspca_dev->pixfmt.height,
370 			gspca_dev->pixfmt.width,
371 			0x21);          /* JPEG 422 */
372 	jpeg_set_qual(dev->jpeg_hdr, dev->quality);
373 	gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
374 		  gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
375 	jlj_start(gspca_dev);
376 	return gspca_dev->usb_err;
377 }
378 
379 /* Table of supported USB devices */
380 static const struct usb_device_id device_table[] = {
381 	{USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
382 	{USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
383 	{}
384 };
385 
386 MODULE_DEVICE_TABLE(usb, device_table);
387 
sd_s_ctrl(struct v4l2_ctrl * ctrl)388 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
389 {
390 	struct gspca_dev *gspca_dev =
391 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
392 	struct sd *sd = (struct sd *)gspca_dev;
393 
394 	gspca_dev->usb_err = 0;
395 
396 	if (!gspca_dev->streaming)
397 		return 0;
398 
399 	switch (ctrl->id) {
400 	case V4L2_CID_POWER_LINE_FREQUENCY:
401 		setfreq(gspca_dev, ctrl->val);
402 		break;
403 	case V4L2_CID_RED_BALANCE:
404 		setred(gspca_dev, ctrl->val);
405 		break;
406 	case V4L2_CID_GAIN:
407 		setgreen(gspca_dev, ctrl->val);
408 		break;
409 	case V4L2_CID_BLUE_BALANCE:
410 		setblue(gspca_dev, ctrl->val);
411 		break;
412 	case V4L2_CID_AUTOGAIN:
413 		setautogain(gspca_dev, ctrl->val);
414 		break;
415 	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
416 		jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
417 		setcamquality(gspca_dev, ctrl->val);
418 		break;
419 	}
420 	return gspca_dev->usb_err;
421 }
422 
423 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
424 	.s_ctrl = sd_s_ctrl,
425 };
426 
sd_init_controls(struct gspca_dev * gspca_dev)427 static int sd_init_controls(struct gspca_dev *gspca_dev)
428 {
429 	struct sd *sd = (struct sd *)gspca_dev;
430 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
431 	static const struct v4l2_ctrl_config custom_autogain = {
432 		.ops = &sd_ctrl_ops,
433 		.id = V4L2_CID_AUTOGAIN,
434 		.type = V4L2_CTRL_TYPE_INTEGER,
435 		.name = "Automatic Gain (and Exposure)",
436 		.max = 3,
437 		.step = 1,
438 		.def = 0,
439 	};
440 
441 	gspca_dev->vdev.ctrl_handler = hdl;
442 	v4l2_ctrl_handler_init(hdl, 6);
443 	sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
444 			V4L2_CID_POWER_LINE_FREQUENCY,
445 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
446 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ);
447 	v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL);
448 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
449 			V4L2_CID_RED_BALANCE, 0, 3, 1, 2);
450 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
451 			V4L2_CID_GAIN, 0, 3, 1, 2);
452 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
453 			V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2);
454 	sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
455 			V4L2_CID_JPEG_COMPRESSION_QUALITY,
456 			QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
457 
458 	if (hdl->error) {
459 		pr_err("Could not initialize controls\n");
460 		return hdl->error;
461 	}
462 	return 0;
463 }
464 
sd_set_jcomp(struct gspca_dev * gspca_dev,const struct v4l2_jpegcompression * jcomp)465 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
466 			const struct v4l2_jpegcompression *jcomp)
467 {
468 	struct sd *sd = (struct sd *) gspca_dev;
469 
470 	v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
471 	return 0;
472 }
473 
sd_get_jcomp(struct gspca_dev * gspca_dev,struct v4l2_jpegcompression * jcomp)474 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
475 			struct v4l2_jpegcompression *jcomp)
476 {
477 	struct sd *sd = (struct sd *) gspca_dev;
478 
479 	memset(jcomp, 0, sizeof *jcomp);
480 	jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
481 	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
482 			| V4L2_JPEG_MARKER_DQT;
483 	return 0;
484 }
485 
486 
487 /* sub-driver description */
488 static const struct sd_desc sd_desc_sakar_57379 = {
489 	.name   = MODULE_NAME,
490 	.config = sd_config,
491 	.init   = sd_init,
492 	.start  = sd_start,
493 	.stopN  = sd_stopN,
494 	.pkt_scan = sd_pkt_scan,
495 };
496 
497 /* sub-driver description */
498 static const struct sd_desc sd_desc_sportscam_dv15 = {
499 	.name   = MODULE_NAME,
500 	.config = sd_config,
501 	.init   = sd_init,
502 	.init_controls = sd_init_controls,
503 	.start  = sd_start,
504 	.stopN  = sd_stopN,
505 	.pkt_scan = sd_pkt_scan,
506 	.get_jcomp = sd_get_jcomp,
507 	.set_jcomp = sd_set_jcomp,
508 };
509 
510 static const struct sd_desc *sd_desc[2] = {
511 	&sd_desc_sakar_57379,
512 	&sd_desc_sportscam_dv15
513 };
514 
515 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)516 static int sd_probe(struct usb_interface *intf,
517 		const struct usb_device_id *id)
518 {
519 	return gspca_dev_probe(intf, id,
520 			sd_desc[id->driver_info],
521 			sizeof(struct sd),
522 			THIS_MODULE);
523 }
524 
525 static struct usb_driver sd_driver = {
526 	.name       = MODULE_NAME,
527 	.id_table   = device_table,
528 	.probe      = sd_probe,
529 	.disconnect = gspca_disconnect,
530 #ifdef CONFIG_PM
531 	.suspend = gspca_suspend,
532 	.resume  = gspca_resume,
533 	.reset_resume = gspca_resume,
534 #endif
535 };
536 
537 module_usb_driver(sd_driver);
538