1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Syntek DV4000 (STK014) subdriver
4  *
5  * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
6  */
7 
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 
10 #define MODULE_NAME "stk014"
11 
12 #include "gspca.h"
13 #include "jpeg.h"
14 
15 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
16 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
17 MODULE_LICENSE("GPL");
18 
19 #define QUALITY 50
20 
21 /* specific webcam descriptor */
22 struct sd {
23 	struct gspca_dev gspca_dev;	/* !! must be the first item */
24 	u8 jpeg_hdr[JPEG_HDR_SZ];
25 };
26 
27 static const struct v4l2_pix_format vga_mode[] = {
28 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
29 		.bytesperline = 320,
30 		.sizeimage = 320 * 240 * 3 / 8 + 590,
31 		.colorspace = V4L2_COLORSPACE_JPEG,
32 		.priv = 1},
33 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
34 		.bytesperline = 640,
35 		.sizeimage = 640 * 480 * 3 / 8 + 590,
36 		.colorspace = V4L2_COLORSPACE_JPEG,
37 		.priv = 0},
38 };
39 
40 /* -- read a register -- */
reg_r(struct gspca_dev * gspca_dev,__u16 index)41 static u8 reg_r(struct gspca_dev *gspca_dev,
42 			__u16 index)
43 {
44 	struct usb_device *dev = gspca_dev->dev;
45 	int ret;
46 
47 	if (gspca_dev->usb_err < 0)
48 		return 0;
49 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
50 			0x00,
51 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
52 			0x00,
53 			index,
54 			gspca_dev->usb_buf, 1,
55 			500);
56 	if (ret < 0) {
57 		pr_err("reg_r err %d\n", ret);
58 		gspca_dev->usb_err = ret;
59 		return 0;
60 	}
61 	return gspca_dev->usb_buf[0];
62 }
63 
64 /* -- write a register -- */
reg_w(struct gspca_dev * gspca_dev,__u16 index,__u16 value)65 static void reg_w(struct gspca_dev *gspca_dev,
66 			__u16 index, __u16 value)
67 {
68 	struct usb_device *dev = gspca_dev->dev;
69 	int ret;
70 
71 	if (gspca_dev->usb_err < 0)
72 		return;
73 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
74 			0x01,
75 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
76 			value,
77 			index,
78 			NULL,
79 			0,
80 			500);
81 	if (ret < 0) {
82 		pr_err("reg_w err %d\n", ret);
83 		gspca_dev->usb_err = ret;
84 	}
85 }
86 
87 /* -- get a bulk value (4 bytes) -- */
rcv_val(struct gspca_dev * gspca_dev,int ads)88 static void rcv_val(struct gspca_dev *gspca_dev,
89 			int ads)
90 {
91 	struct usb_device *dev = gspca_dev->dev;
92 	int alen, ret;
93 
94 	reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
95 	reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
96 	reg_w(gspca_dev, 0x636, ads & 0xff);
97 	reg_w(gspca_dev, 0x637, 0);
98 	reg_w(gspca_dev, 0x638, 4);	/* len & 0xff */
99 	reg_w(gspca_dev, 0x639, 0);	/* len >> 8 */
100 	reg_w(gspca_dev, 0x63a, 0);
101 	reg_w(gspca_dev, 0x63b, 0);
102 	reg_w(gspca_dev, 0x630, 5);
103 	if (gspca_dev->usb_err < 0)
104 		return;
105 	ret = usb_bulk_msg(dev,
106 			usb_rcvbulkpipe(dev, 0x05),
107 			gspca_dev->usb_buf,
108 			4,		/* length */
109 			&alen,
110 			500);		/* timeout in milliseconds */
111 	if (ret < 0) {
112 		pr_err("rcv_val err %d\n", ret);
113 		gspca_dev->usb_err = ret;
114 	}
115 }
116 
117 /* -- send a bulk value -- */
snd_val(struct gspca_dev * gspca_dev,int ads,unsigned int val)118 static void snd_val(struct gspca_dev *gspca_dev,
119 			int ads,
120 			unsigned int val)
121 {
122 	struct usb_device *dev = gspca_dev->dev;
123 	int alen, ret;
124 	__u8 seq = 0;
125 
126 	if (ads == 0x003f08) {
127 		reg_r(gspca_dev, 0x0704);
128 		seq = reg_r(gspca_dev, 0x0705);
129 		reg_r(gspca_dev, 0x0650);
130 		reg_w(gspca_dev, 0x654, seq);
131 	} else {
132 		reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
133 	}
134 	reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
135 	reg_w(gspca_dev, 0x656, ads & 0xff);
136 	reg_w(gspca_dev, 0x657, 0);
137 	reg_w(gspca_dev, 0x658, 0x04);	/* size */
138 	reg_w(gspca_dev, 0x659, 0);
139 	reg_w(gspca_dev, 0x65a, 0);
140 	reg_w(gspca_dev, 0x65b, 0);
141 	reg_w(gspca_dev, 0x650, 5);
142 	if (gspca_dev->usb_err < 0)
143 		return;
144 	gspca_dev->usb_buf[0] = val >> 24;
145 	gspca_dev->usb_buf[1] = val >> 16;
146 	gspca_dev->usb_buf[2] = val >> 8;
147 	gspca_dev->usb_buf[3] = val;
148 	ret = usb_bulk_msg(dev,
149 			usb_sndbulkpipe(dev, 6),
150 			gspca_dev->usb_buf,
151 			4,
152 			&alen,
153 			500);	/* timeout in milliseconds */
154 	if (ret < 0) {
155 		pr_err("snd_val err %d\n", ret);
156 		gspca_dev->usb_err = ret;
157 	} else {
158 		if (ads == 0x003f08) {
159 			seq += 4;
160 			seq &= 0x3f;
161 			reg_w(gspca_dev, 0x705, seq);
162 		}
163 	}
164 }
165 
166 /* set a camera parameter */
set_par(struct gspca_dev * gspca_dev,int parval)167 static void set_par(struct gspca_dev *gspca_dev,
168 		   int parval)
169 {
170 	snd_val(gspca_dev, 0x003f08, parval);
171 }
172 
setbrightness(struct gspca_dev * gspca_dev,s32 val)173 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
174 {
175 	int parval;
176 
177 	parval = 0x06000000		/* whiteness */
178 		+ (val << 16);
179 	set_par(gspca_dev, parval);
180 }
181 
setcontrast(struct gspca_dev * gspca_dev,s32 val)182 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
183 {
184 	int parval;
185 
186 	parval = 0x07000000		/* contrast */
187 		+ (val << 16);
188 	set_par(gspca_dev, parval);
189 }
190 
setcolors(struct gspca_dev * gspca_dev,s32 val)191 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
192 {
193 	int parval;
194 
195 	parval = 0x08000000		/* saturation */
196 		+ (val << 16);
197 	set_par(gspca_dev, parval);
198 }
199 
setlightfreq(struct gspca_dev * gspca_dev,s32 val)200 static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
201 {
202 	set_par(gspca_dev, val == 1
203 			? 0x33640000		/* 50 Hz */
204 			: 0x33780000);		/* 60 Hz */
205 }
206 
207 /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)208 static int sd_config(struct gspca_dev *gspca_dev,
209 			const struct usb_device_id *id)
210 {
211 	gspca_dev->cam.cam_mode = vga_mode;
212 	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
213 	return 0;
214 }
215 
216 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)217 static int sd_init(struct gspca_dev *gspca_dev)
218 {
219 	u8 ret;
220 
221 	/* check if the device responds */
222 	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
223 	ret = reg_r(gspca_dev, 0x0740);
224 	if (gspca_dev->usb_err >= 0) {
225 		if (ret != 0xff) {
226 			pr_err("init reg: 0x%02x\n", ret);
227 			gspca_dev->usb_err = -EIO;
228 		}
229 	}
230 	return gspca_dev->usb_err;
231 }
232 
233 /* -- start the camera -- */
sd_start(struct gspca_dev * gspca_dev)234 static int sd_start(struct gspca_dev *gspca_dev)
235 {
236 	struct sd *sd = (struct sd *) gspca_dev;
237 	int ret, value;
238 
239 	/* create the JPEG header */
240 	jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
241 			gspca_dev->pixfmt.width,
242 			0x22);		/* JPEG 411 */
243 	jpeg_set_qual(sd->jpeg_hdr, QUALITY);
244 
245 	/* work on alternate 1 */
246 	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
247 
248 	set_par(gspca_dev, 0x10000000);
249 	set_par(gspca_dev, 0x00000000);
250 	set_par(gspca_dev, 0x8002e001);
251 	set_par(gspca_dev, 0x14000000);
252 	if (gspca_dev->pixfmt.width > 320)
253 		value = 0x8002e001;		/* 640x480 */
254 	else
255 		value = 0x4001f000;		/* 320x240 */
256 	set_par(gspca_dev, value);
257 	ret = usb_set_interface(gspca_dev->dev,
258 					gspca_dev->iface,
259 					gspca_dev->alt);
260 	if (ret < 0) {
261 		pr_err("set intf %d %d failed\n",
262 		       gspca_dev->iface, gspca_dev->alt);
263 		gspca_dev->usb_err = ret;
264 		goto out;
265 	}
266 	reg_r(gspca_dev, 0x0630);
267 	rcv_val(gspca_dev, 0x000020);	/* << (value ff ff ff ff) */
268 	reg_r(gspca_dev, 0x0650);
269 	snd_val(gspca_dev, 0x000020, 0xffffffff);
270 	reg_w(gspca_dev, 0x0620, 0);
271 	reg_w(gspca_dev, 0x0630, 0);
272 	reg_w(gspca_dev, 0x0640, 0);
273 	reg_w(gspca_dev, 0x0650, 0);
274 	reg_w(gspca_dev, 0x0660, 0);
275 	set_par(gspca_dev, 0x09800000);		/* Red ? */
276 	set_par(gspca_dev, 0x0a800000);		/* Green ? */
277 	set_par(gspca_dev, 0x0b800000);		/* Blue ? */
278 	set_par(gspca_dev, 0x0d030000);		/* Gamma ? */
279 
280 	/* start the video flow */
281 	set_par(gspca_dev, 0x01000000);
282 	set_par(gspca_dev, 0x01000000);
283 	if (gspca_dev->usb_err >= 0)
284 		gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
285 			  gspca_dev->alt);
286 out:
287 	return gspca_dev->usb_err;
288 }
289 
sd_stopN(struct gspca_dev * gspca_dev)290 static void sd_stopN(struct gspca_dev *gspca_dev)
291 {
292 	struct usb_device *dev = gspca_dev->dev;
293 
294 	set_par(gspca_dev, 0x02000000);
295 	set_par(gspca_dev, 0x02000000);
296 	usb_set_interface(dev, gspca_dev->iface, 1);
297 	reg_r(gspca_dev, 0x0630);
298 	rcv_val(gspca_dev, 0x000020);	/* << (value ff ff ff ff) */
299 	reg_r(gspca_dev, 0x0650);
300 	snd_val(gspca_dev, 0x000020, 0xffffffff);
301 	reg_w(gspca_dev, 0x0620, 0);
302 	reg_w(gspca_dev, 0x0630, 0);
303 	reg_w(gspca_dev, 0x0640, 0);
304 	reg_w(gspca_dev, 0x0650, 0);
305 	reg_w(gspca_dev, 0x0660, 0);
306 	gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
307 }
308 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)309 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
310 			u8 *data,			/* isoc packet */
311 			int len)			/* iso packet length */
312 {
313 	struct sd *sd = (struct sd *) gspca_dev;
314 	static unsigned char ffd9[] = {0xff, 0xd9};
315 
316 	/* a frame starts with:
317 	 *	- 0xff 0xfe
318 	 *	- 0x08 0x00	- length (little endian ?!)
319 	 *	- 4 bytes = size of whole frame (BE - including header)
320 	 *	- 0x00 0x0c
321 	 *	- 0xff 0xd8
322 	 *	- ..	JPEG image with escape sequences (ff 00)
323 	 *		(without ending - ff d9)
324 	 */
325 	if (data[0] == 0xff && data[1] == 0xfe) {
326 		gspca_frame_add(gspca_dev, LAST_PACKET,
327 				ffd9, 2);
328 
329 		/* put the JPEG 411 header */
330 		gspca_frame_add(gspca_dev, FIRST_PACKET,
331 			sd->jpeg_hdr, JPEG_HDR_SZ);
332 
333 		/* beginning of the frame */
334 #define STKHDRSZ 12
335 		data += STKHDRSZ;
336 		len -= STKHDRSZ;
337 	}
338 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
339 }
340 
sd_s_ctrl(struct v4l2_ctrl * ctrl)341 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
342 {
343 	struct gspca_dev *gspca_dev =
344 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
345 
346 	gspca_dev->usb_err = 0;
347 
348 	if (!gspca_dev->streaming)
349 		return 0;
350 
351 	switch (ctrl->id) {
352 	case V4L2_CID_BRIGHTNESS:
353 		setbrightness(gspca_dev, ctrl->val);
354 		break;
355 	case V4L2_CID_CONTRAST:
356 		setcontrast(gspca_dev, ctrl->val);
357 		break;
358 	case V4L2_CID_SATURATION:
359 		setcolors(gspca_dev, ctrl->val);
360 		break;
361 	case V4L2_CID_POWER_LINE_FREQUENCY:
362 		setlightfreq(gspca_dev, ctrl->val);
363 		break;
364 	}
365 	return gspca_dev->usb_err;
366 }
367 
368 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
369 	.s_ctrl = sd_s_ctrl,
370 };
371 
sd_init_controls(struct gspca_dev * gspca_dev)372 static int sd_init_controls(struct gspca_dev *gspca_dev)
373 {
374 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
375 
376 	gspca_dev->vdev.ctrl_handler = hdl;
377 	v4l2_ctrl_handler_init(hdl, 4);
378 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
379 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
380 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
381 			V4L2_CID_CONTRAST, 0, 255, 1, 127);
382 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
383 			V4L2_CID_SATURATION, 0, 255, 1, 127);
384 	v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
385 			V4L2_CID_POWER_LINE_FREQUENCY,
386 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
387 			V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
388 
389 	if (hdl->error) {
390 		pr_err("Could not initialize controls\n");
391 		return hdl->error;
392 	}
393 	return 0;
394 }
395 
396 /* sub-driver description */
397 static const struct sd_desc sd_desc = {
398 	.name = MODULE_NAME,
399 	.config = sd_config,
400 	.init = sd_init,
401 	.init_controls = sd_init_controls,
402 	.start = sd_start,
403 	.stopN = sd_stopN,
404 	.pkt_scan = sd_pkt_scan,
405 };
406 
407 /* -- module initialisation -- */
408 static const struct usb_device_id device_table[] = {
409 	{USB_DEVICE(0x05e1, 0x0893)},
410 	{}
411 };
412 MODULE_DEVICE_TABLE(usb, device_table);
413 
414 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)415 static int sd_probe(struct usb_interface *intf,
416 			const struct usb_device_id *id)
417 {
418 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
419 				THIS_MODULE);
420 }
421 
422 static struct usb_driver sd_driver = {
423 	.name = MODULE_NAME,
424 	.id_table = device_table,
425 	.probe = sd_probe,
426 	.disconnect = gspca_disconnect,
427 #ifdef CONFIG_PM
428 	.suspend = gspca_suspend,
429 	.resume = gspca_resume,
430 	.reset_resume = gspca_resume,
431 #endif
432 };
433 
434 module_usb_driver(sd_driver);
435