1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Syntek DV4000 (STK014) subdriver
5 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #define MODULE_NAME "stk014"
15 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
16 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
17 MODULE_LICENSE("GPL");
21 /* specific webcam descriptor */
23 struct gspca_dev gspca_dev
; /* !! must be the first item */
24 u8 jpeg_hdr
[JPEG_HDR_SZ
];
27 static const struct v4l2_pix_format vga_mode
[] = {
28 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
30 .sizeimage
= 320 * 240 * 3 / 8 + 590,
31 .colorspace
= V4L2_COLORSPACE_JPEG
,
33 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
35 .sizeimage
= 640 * 480 * 3 / 8 + 590,
36 .colorspace
= V4L2_COLORSPACE_JPEG
,
40 /* -- read a register -- */
41 static u8
reg_r(struct gspca_dev
*gspca_dev
,
44 struct usb_device
*dev
= gspca_dev
->dev
;
47 if (gspca_dev
->usb_err
< 0)
49 ret
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
51 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
54 gspca_dev
->usb_buf
, 1,
57 pr_err("reg_r err %d\n", ret
);
58 gspca_dev
->usb_err
= ret
;
61 return gspca_dev
->usb_buf
[0];
64 /* -- write a register -- */
65 static void reg_w(struct gspca_dev
*gspca_dev
,
66 __u16 index
, __u16 value
)
68 struct usb_device
*dev
= gspca_dev
->dev
;
71 if (gspca_dev
->usb_err
< 0)
73 ret
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
75 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
82 pr_err("reg_w err %d\n", ret
);
83 gspca_dev
->usb_err
= ret
;
87 /* -- get a bulk value (4 bytes) -- */
88 static void rcv_val(struct gspca_dev
*gspca_dev
,
91 struct usb_device
*dev
= gspca_dev
->dev
;
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)
105 ret
= usb_bulk_msg(dev
,
106 usb_rcvbulkpipe(dev
, 0x05),
110 500); /* timeout in milliseconds */
112 pr_err("rcv_val err %d\n", ret
);
113 gspca_dev
->usb_err
= ret
;
117 /* -- send a bulk value -- */
118 static void snd_val(struct gspca_dev
*gspca_dev
,
122 struct usb_device
*dev
= gspca_dev
->dev
;
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
);
132 reg_w(gspca_dev
, 0x654, (ads
>> 16) & 0xff);
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)
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),
153 500); /* timeout in milliseconds */
155 pr_err("snd_val err %d\n", ret
);
156 gspca_dev
->usb_err
= ret
;
158 if (ads
== 0x003f08) {
161 reg_w(gspca_dev
, 0x705, seq
);
166 /* set a camera parameter */
167 static void set_par(struct gspca_dev
*gspca_dev
,
170 snd_val(gspca_dev
, 0x003f08, parval
);
173 static void setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
177 parval
= 0x06000000 /* whiteness */
179 set_par(gspca_dev
, parval
);
182 static void setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
186 parval
= 0x07000000 /* contrast */
188 set_par(gspca_dev
, parval
);
191 static void setcolors(struct gspca_dev
*gspca_dev
, s32 val
)
195 parval
= 0x08000000 /* saturation */
197 set_par(gspca_dev
, parval
);
200 static void setlightfreq(struct gspca_dev
*gspca_dev
, s32 val
)
202 set_par(gspca_dev
, val
== 1
203 ? 0x33640000 /* 50 Hz */
204 : 0x33780000); /* 60 Hz */
207 /* this function is called at probe time */
208 static int sd_config(struct gspca_dev
*gspca_dev
,
209 const struct usb_device_id
*id
)
211 gspca_dev
->cam
.cam_mode
= vga_mode
;
212 gspca_dev
->cam
.nmodes
= ARRAY_SIZE(vga_mode
);
216 /* this function is called at probe and resume time */
217 static int sd_init(struct gspca_dev
*gspca_dev
)
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) {
226 pr_err("init reg: 0x%02x\n", ret
);
227 gspca_dev
->usb_err
= -EIO
;
230 return gspca_dev
->usb_err
;
233 /* -- start the camera -- */
234 static int sd_start(struct gspca_dev
*gspca_dev
)
236 struct sd
*sd
= (struct sd
*) gspca_dev
;
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
);
245 /* work on alternate 1 */
246 usb_set_interface(gspca_dev
->dev
, gspca_dev
->iface
, 1);
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 */
255 value
= 0x4001f000; /* 320x240 */
256 set_par(gspca_dev
, value
);
257 ret
= usb_set_interface(gspca_dev
->dev
,
261 pr_err("set intf %d %d failed\n",
262 gspca_dev
->iface
, gspca_dev
->alt
);
263 gspca_dev
->usb_err
= ret
;
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 ? */
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",
287 return gspca_dev
->usb_err
;
290 static void sd_stopN(struct gspca_dev
*gspca_dev
)
292 struct usb_device
*dev
= gspca_dev
->dev
;
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");
309 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
310 u8
*data
, /* isoc packet */
311 int len
) /* iso packet length */
313 struct sd
*sd
= (struct sd
*) gspca_dev
;
314 static unsigned char ffd9
[] = {0xff, 0xd9};
316 /* a frame starts with:
318 * - 0x08 0x00 - length (little endian ?!)
319 * - 4 bytes = size of whole frame (BE - including header)
322 * - .. JPEG image with escape sequences (ff 00)
323 * (without ending - ff d9)
325 if (data
[0] == 0xff && data
[1] == 0xfe) {
326 gspca_frame_add(gspca_dev
, LAST_PACKET
,
329 /* put the JPEG 411 header */
330 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
331 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
333 /* beginning of the frame */
338 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
341 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
343 struct gspca_dev
*gspca_dev
=
344 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
346 gspca_dev
->usb_err
= 0;
348 if (!gspca_dev
->streaming
)
352 case V4L2_CID_BRIGHTNESS
:
353 setbrightness(gspca_dev
, ctrl
->val
);
355 case V4L2_CID_CONTRAST
:
356 setcontrast(gspca_dev
, ctrl
->val
);
358 case V4L2_CID_SATURATION
:
359 setcolors(gspca_dev
, ctrl
->val
);
361 case V4L2_CID_POWER_LINE_FREQUENCY
:
362 setlightfreq(gspca_dev
, ctrl
->val
);
365 return gspca_dev
->usb_err
;
368 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
372 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
374 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
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
);
390 pr_err("Could not initialize controls\n");
396 /* sub-driver description */
397 static const struct sd_desc sd_desc
= {
401 .init_controls
= sd_init_controls
,
404 .pkt_scan
= sd_pkt_scan
,
407 /* -- module initialisation -- */
408 static const struct usb_device_id device_table
[] = {
409 {USB_DEVICE(0x05e1, 0x0893)},
412 MODULE_DEVICE_TABLE(usb
, device_table
);
414 /* -- device connect -- */
415 static int sd_probe(struct usb_interface
*intf
,
416 const struct usb_device_id
*id
)
418 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
422 static struct usb_driver sd_driver
= {
424 .id_table
= device_table
,
426 .disconnect
= gspca_disconnect
,
428 .suspend
= gspca_suspend
,
429 .resume
= gspca_resume
,
430 .reset_resume
= gspca_resume
,
434 module_usb_driver(sd_driver
);