1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
5 * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
6 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
7 * Thanks BUGabundo and Malmostoso for your amazing help!
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
16 MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
17 MODULE_LICENSE("GPL");
19 /*======================== static function declarations ====================*/
21 static void (*dev_init_settings
)(struct gspca_dev
*gspca_dev
);
23 static int sd_config(struct gspca_dev
*gspca_dev
,
24 const struct usb_device_id
*id
);
25 static int sd_init(struct gspca_dev
*gspca_dev
);
26 static int sd_isoc_init(struct gspca_dev
*gspca_dev
);
27 static int sd_start(struct gspca_dev
*gspca_dev
);
28 static void sd_stop0(struct gspca_dev
*gspca_dev
);
29 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
31 static void sd_callback(struct gspca_dev
*gspca_dev
);
33 static int gl860_guess_sensor(struct gspca_dev
*gspca_dev
,
34 u16 vendor_id
, u16 product_id
);
36 /*============================ driver options ==============================*/
38 static s32 AC50Hz
= 0xff;
39 module_param(AC50Hz
, int, 0644);
40 MODULE_PARM_DESC(AC50Hz
, " Does AC power frequency is 50Hz? (0/1)");
42 static char sensor
[7];
43 module_param_string(sensor
, sensor
, sizeof(sensor
), 0644);
44 MODULE_PARM_DESC(sensor
,
45 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
47 /*============================ webcam controls =============================*/
49 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
51 struct gspca_dev
*gspca_dev
=
52 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
53 struct sd
*sd
= (struct sd
*) gspca_dev
;
56 case V4L2_CID_BRIGHTNESS
:
57 sd
->vcur
.brightness
= ctrl
->val
;
59 case V4L2_CID_CONTRAST
:
60 sd
->vcur
.contrast
= ctrl
->val
;
62 case V4L2_CID_SATURATION
:
63 sd
->vcur
.saturation
= ctrl
->val
;
66 sd
->vcur
.hue
= ctrl
->val
;
69 sd
->vcur
.gamma
= ctrl
->val
;
72 sd
->vcur
.mirror
= ctrl
->val
;
75 sd
->vcur
.flip
= ctrl
->val
;
77 case V4L2_CID_POWER_LINE_FREQUENCY
:
78 sd
->vcur
.AC50Hz
= ctrl
->val
;
80 case V4L2_CID_WHITE_BALANCE_TEMPERATURE
:
81 sd
->vcur
.whitebal
= ctrl
->val
;
83 case V4L2_CID_SHARPNESS
:
84 sd
->vcur
.sharpness
= ctrl
->val
;
86 case V4L2_CID_BACKLIGHT_COMPENSATION
:
87 sd
->vcur
.backlight
= ctrl
->val
;
93 if (gspca_dev
->streaming
)
99 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
103 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
105 struct sd
*sd
= (struct sd
*) gspca_dev
;
106 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
108 gspca_dev
->vdev
.ctrl_handler
= hdl
;
109 v4l2_ctrl_handler_init(hdl
, 11);
111 if (sd
->vmax
.brightness
)
112 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_BRIGHTNESS
,
113 0, sd
->vmax
.brightness
, 1,
114 sd
->vcur
.brightness
);
116 if (sd
->vmax
.contrast
)
117 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_CONTRAST
,
118 0, sd
->vmax
.contrast
, 1,
121 if (sd
->vmax
.saturation
)
122 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_SATURATION
,
123 0, sd
->vmax
.saturation
, 1,
124 sd
->vcur
.saturation
);
127 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_HUE
,
128 0, sd
->vmax
.hue
, 1, sd
->vcur
.hue
);
131 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_GAMMA
,
132 0, sd
->vmax
.gamma
, 1, sd
->vcur
.gamma
);
135 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_HFLIP
,
136 0, sd
->vmax
.mirror
, 1, sd
->vcur
.mirror
);
139 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_VFLIP
,
140 0, sd
->vmax
.flip
, 1, sd
->vcur
.flip
);
143 v4l2_ctrl_new_std_menu(hdl
, &sd_ctrl_ops
,
144 V4L2_CID_POWER_LINE_FREQUENCY
,
145 sd
->vmax
.AC50Hz
, 0, sd
->vcur
.AC50Hz
);
147 if (sd
->vmax
.whitebal
)
148 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
149 V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
150 0, sd
->vmax
.whitebal
, 1, sd
->vcur
.whitebal
);
152 if (sd
->vmax
.sharpness
)
153 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
, V4L2_CID_SHARPNESS
,
154 0, sd
->vmax
.sharpness
, 1,
157 if (sd
->vmax
.backlight
)
158 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
159 V4L2_CID_BACKLIGHT_COMPENSATION
,
160 0, sd
->vmax
.backlight
, 1,
164 pr_err("Could not initialize controls\n");
171 /*==================== sud-driver structure initialisation =================*/
173 static const struct sd_desc sd_desc_mi1320
= {
177 .init_controls
= sd_init_controls
,
178 .isoc_init
= sd_isoc_init
,
181 .pkt_scan
= sd_pkt_scan
,
182 .dq_callback
= sd_callback
,
185 static const struct sd_desc sd_desc_mi2020
= {
189 .init_controls
= sd_init_controls
,
190 .isoc_init
= sd_isoc_init
,
193 .pkt_scan
= sd_pkt_scan
,
194 .dq_callback
= sd_callback
,
197 static const struct sd_desc sd_desc_ov2640
= {
201 .init_controls
= sd_init_controls
,
202 .isoc_init
= sd_isoc_init
,
205 .pkt_scan
= sd_pkt_scan
,
206 .dq_callback
= sd_callback
,
209 static const struct sd_desc sd_desc_ov9655
= {
213 .init_controls
= sd_init_controls
,
214 .isoc_init
= sd_isoc_init
,
217 .pkt_scan
= sd_pkt_scan
,
218 .dq_callback
= sd_callback
,
221 /*=========================== sub-driver image sizes =======================*/
223 static struct v4l2_pix_format mi2020_mode
[] = {
224 { 640, 480, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
226 .sizeimage
= 640 * 480,
227 .colorspace
= V4L2_COLORSPACE_SRGB
,
230 { 800, 598, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
232 .sizeimage
= 800 * 598,
233 .colorspace
= V4L2_COLORSPACE_SRGB
,
236 {1280, 1024, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
237 .bytesperline
= 1280,
238 .sizeimage
= 1280 * 1024,
239 .colorspace
= V4L2_COLORSPACE_SRGB
,
242 {1600, 1198, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
243 .bytesperline
= 1600,
244 .sizeimage
= 1600 * 1198,
245 .colorspace
= V4L2_COLORSPACE_SRGB
,
250 static struct v4l2_pix_format ov2640_mode
[] = {
251 { 640, 480, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
253 .sizeimage
= 640 * 480,
254 .colorspace
= V4L2_COLORSPACE_SRGB
,
257 { 800, 600, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
259 .sizeimage
= 800 * 600,
260 .colorspace
= V4L2_COLORSPACE_SRGB
,
263 {1280, 960, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
264 .bytesperline
= 1280,
265 .sizeimage
= 1280 * 960,
266 .colorspace
= V4L2_COLORSPACE_SRGB
,
269 {1600, 1200, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
270 .bytesperline
= 1600,
271 .sizeimage
= 1600 * 1200,
272 .colorspace
= V4L2_COLORSPACE_SRGB
,
277 static struct v4l2_pix_format mi1320_mode
[] = {
278 { 640, 480, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
280 .sizeimage
= 640 * 480,
281 .colorspace
= V4L2_COLORSPACE_SRGB
,
284 { 800, 600, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
286 .sizeimage
= 800 * 600,
287 .colorspace
= V4L2_COLORSPACE_SRGB
,
290 {1280, 960, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
291 .bytesperline
= 1280,
292 .sizeimage
= 1280 * 960,
293 .colorspace
= V4L2_COLORSPACE_SRGB
,
298 static struct v4l2_pix_format ov9655_mode
[] = {
299 { 640, 480, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
301 .sizeimage
= 640 * 480,
302 .colorspace
= V4L2_COLORSPACE_SRGB
,
305 {1280, 960, V4L2_PIX_FMT_SGBRG8
, V4L2_FIELD_NONE
,
306 .bytesperline
= 1280,
307 .sizeimage
= 1280 * 960,
308 .colorspace
= V4L2_COLORSPACE_SRGB
,
313 /*========================= sud-driver functions ===========================*/
315 /* This function is called at probe time */
316 static int sd_config(struct gspca_dev
*gspca_dev
,
317 const struct usb_device_id
*id
)
319 struct sd
*sd
= (struct sd
*) gspca_dev
;
321 u16 vendor_id
, product_id
;
323 /* Get USB VendorID and ProductID */
324 vendor_id
= id
->idVendor
;
325 product_id
= id
->idProduct
;
331 if (strcmp(sensor
, "MI1320") == 0)
332 sd
->sensor
= ID_MI1320
;
333 else if (strcmp(sensor
, "OV2640") == 0)
334 sd
->sensor
= ID_OV2640
;
335 else if (strcmp(sensor
, "OV9655") == 0)
336 sd
->sensor
= ID_OV9655
;
337 else if (strcmp(sensor
, "MI2020") == 0)
338 sd
->sensor
= ID_MI2020
;
340 /* Get sensor and set the suitable init/start/../stop functions */
341 if (gl860_guess_sensor(gspca_dev
, vendor_id
, product_id
) == -1)
344 cam
= &gspca_dev
->cam
;
346 switch (sd
->sensor
) {
348 gspca_dev
->sd_desc
= &sd_desc_mi1320
;
349 cam
->cam_mode
= mi1320_mode
;
350 cam
->nmodes
= ARRAY_SIZE(mi1320_mode
);
351 dev_init_settings
= mi1320_init_settings
;
355 gspca_dev
->sd_desc
= &sd_desc_mi2020
;
356 cam
->cam_mode
= mi2020_mode
;
357 cam
->nmodes
= ARRAY_SIZE(mi2020_mode
);
358 dev_init_settings
= mi2020_init_settings
;
362 gspca_dev
->sd_desc
= &sd_desc_ov2640
;
363 cam
->cam_mode
= ov2640_mode
;
364 cam
->nmodes
= ARRAY_SIZE(ov2640_mode
);
365 dev_init_settings
= ov2640_init_settings
;
369 gspca_dev
->sd_desc
= &sd_desc_ov9655
;
370 cam
->cam_mode
= ov9655_mode
;
371 cam
->nmodes
= ARRAY_SIZE(ov9655_mode
);
372 dev_init_settings
= ov9655_init_settings
;
376 dev_init_settings(gspca_dev
);
378 ((struct sd
*) gspca_dev
)->vcur
.AC50Hz
= AC50Hz
;
383 /* This function is called at probe time after sd_config */
384 static int sd_init(struct gspca_dev
*gspca_dev
)
386 struct sd
*sd
= (struct sd
*) gspca_dev
;
388 return sd
->dev_init_at_startup(gspca_dev
);
391 /* This function is called before to choose the alt setting */
392 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
394 struct sd
*sd
= (struct sd
*) gspca_dev
;
396 return sd
->dev_configure_alt(gspca_dev
);
399 /* This function is called to start the webcam */
400 static int sd_start(struct gspca_dev
*gspca_dev
)
402 struct sd
*sd
= (struct sd
*) gspca_dev
;
404 return sd
->dev_init_pre_alt(gspca_dev
);
407 /* This function is called to stop the webcam */
408 static void sd_stop0(struct gspca_dev
*gspca_dev
)
410 struct sd
*sd
= (struct sd
*) gspca_dev
;
412 if (!sd
->gspca_dev
.present
)
415 return sd
->dev_post_unset_alt(gspca_dev
);
418 /* This function is called when an image is being received */
419 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
422 struct sd
*sd
= (struct sd
*) gspca_dev
;
425 s32 mode
= (s32
) gspca_dev
->curr_mode
;
427 sd
->swapRB
* (gspca_dev
->cam
.cam_mode
[mode
].bytesperline
+ 1);
429 /* Test only against 0202h, so endianness does not matter */
430 switch (*(s16
*) data
) {
431 case 0x0202: /* End of frame, start a new one */
432 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
434 if (sd
->nbIm
>= 0 && sd
->nbIm
< 10)
436 gspca_frame_add(gspca_dev
, FIRST_PACKET
, NULL
, 0);
442 if (nSkipped
+ len
<= nToSkip
)
445 if (nSkipped
< nToSkip
&& nSkipped
+ len
> nToSkip
) {
446 data
+= nToSkip
- nSkipped
;
447 len
-= nToSkip
- nSkipped
;
448 nSkipped
= nToSkip
+ 1;
450 gspca_frame_add(gspca_dev
,
451 INTER_PACKET
, data
, len
);
457 /* This function is called when an image has been read */
458 /* This function is used to monitor webcam orientation */
459 static void sd_callback(struct gspca_dev
*gspca_dev
)
461 struct sd
*sd
= (struct sd
*) gspca_dev
;
467 /* Probe sensor orientation */
468 ctrl_in(gspca_dev
, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state
);
470 /* C8/40 means upside-down (looking backwards) */
471 /* D8/50 means right-up (looking onwards) */
472 upsideDown
= (state
== 0xc8 || state
== 0x40);
474 if (upsideDown
&& sd
->nbRightUp
> -4) {
475 if (sd
->nbRightUp
> 0)
477 if (sd
->nbRightUp
== -3) {
483 if (!upsideDown
&& sd
->nbRightUp
< 4) {
484 if (sd
->nbRightUp
< 0)
486 if (sd
->nbRightUp
== 3) {
495 sd
->dev_camera_settings(gspca_dev
);
498 /*=================== USB driver structure initialisation ==================*/
500 static const struct usb_device_id device_table
[] = {
501 {USB_DEVICE(0x05e3, 0x0503)},
502 {USB_DEVICE(0x05e3, 0xf191)},
506 MODULE_DEVICE_TABLE(usb
, device_table
);
508 static int sd_probe(struct usb_interface
*intf
,
509 const struct usb_device_id
*id
)
511 return gspca_dev_probe(intf
, id
,
512 &sd_desc_mi1320
, sizeof(struct sd
), THIS_MODULE
);
515 static void sd_disconnect(struct usb_interface
*intf
)
517 gspca_disconnect(intf
);
520 static struct usb_driver sd_driver
= {
522 .id_table
= device_table
,
524 .disconnect
= sd_disconnect
,
526 .suspend
= gspca_suspend
,
527 .resume
= gspca_resume
,
528 .reset_resume
= gspca_resume
,
532 /*====================== Init and Exit module functions ====================*/
534 module_usb_driver(sd_driver
);
536 /*==========================================================================*/
538 int gl860_RTx(struct gspca_dev
*gspca_dev
,
539 unsigned char pref
, u32 req
, u16 val
, u16 index
,
540 s32 len
, void *pdata
)
542 struct usb_device
*udev
= gspca_dev
->dev
;
545 if (pref
== 0x40) { /* Send */
547 memcpy(gspca_dev
->usb_buf
, pdata
, len
);
548 r
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
549 req
, pref
, val
, index
,
551 len
, 400 + 200 * (len
> 1));
553 r
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
554 req
, pref
, val
, index
, NULL
, len
, 400);
556 } else { /* Receive */
558 r
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
559 req
, pref
, val
, index
,
561 len
, 400 + 200 * (len
> 1));
562 memcpy(pdata
, gspca_dev
->usb_buf
, len
);
564 r
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
565 req
, pref
, val
, index
, NULL
, len
, 400);
570 pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n",
571 r
, pref
, req
, val
, index
, len
);
572 else if (len
> 1 && r
< len
)
573 gspca_err(gspca_dev
, "short ctrl transfer %d/%d\n", r
, len
);
580 int fetch_validx(struct gspca_dev
*gspca_dev
, struct validx
*tbl
, int len
)
584 for (n
= 0; n
< len
; n
++) {
585 if (tbl
[n
].idx
!= 0xffff)
586 ctrl_out(gspca_dev
, 0x40, 1, tbl
[n
].val
,
587 tbl
[n
].idx
, 0, NULL
);
588 else if (tbl
[n
].val
== 0xffff)
596 int keep_on_fetching_validx(struct gspca_dev
*gspca_dev
, struct validx
*tbl
,
600 if (tbl
[n
].idx
!= 0xffff)
601 ctrl_out(gspca_dev
, 0x40, 1, tbl
[n
].val
, tbl
[n
].idx
,
603 else if (tbl
[n
].val
== 0xffff)
611 void fetch_idxdata(struct gspca_dev
*gspca_dev
, struct idxdata
*tbl
, int len
)
615 for (n
= 0; n
< len
; n
++) {
616 if (memcmp(tbl
[n
].data
, "\xff\xff\xff", 3) != 0)
617 ctrl_out(gspca_dev
, 0x40, 3, 0x7a00, tbl
[n
].idx
,
624 static int gl860_guess_sensor(struct gspca_dev
*gspca_dev
,
625 u16 vendor_id
, u16 product_id
)
627 struct sd
*sd
= (struct sd
*) gspca_dev
;
628 u8 probe
, nb26
, nb96
, nOV
, ntry
;
630 if (product_id
== 0xf191)
631 sd
->sensor
= ID_MI1320
;
633 if (sd
->sensor
== 0xff) {
634 ctrl_in(gspca_dev
, 0xc0, 2, 0x0000, 0x0004, 1, &probe
);
635 ctrl_in(gspca_dev
, 0xc0, 2, 0x0000, 0x0004, 1, &probe
);
637 ctrl_out(gspca_dev
, 0x40, 1, 0x0000, 0x0000, 0, NULL
);
639 ctrl_out(gspca_dev
, 0x40, 1, 0x0010, 0x0010, 0, NULL
);
641 ctrl_out(gspca_dev
, 0x40, 1, 0x0008, 0x00c0, 0, NULL
);
643 ctrl_out(gspca_dev
, 0x40, 1, 0x0001, 0x00c1, 0, NULL
);
645 ctrl_out(gspca_dev
, 0x40, 1, 0x0001, 0x00c2, 0, NULL
);
647 ctrl_out(gspca_dev
, 0x40, 1, 0x0020, 0x0006, 0, NULL
);
649 ctrl_out(gspca_dev
, 0x40, 1, 0x006a, 0x000d, 0, NULL
);
652 gspca_dbg(gspca_dev
, D_PROBE
, "probing for sensor MI2020 or OVXXXX\n");
654 for (ntry
= 0; ntry
< 4; ntry
++) {
655 ctrl_out(gspca_dev
, 0x40, 1, 0x0040, 0x0000, 0, NULL
);
657 ctrl_out(gspca_dev
, 0x40, 1, 0x0063, 0x0006, 0, NULL
);
659 ctrl_out(gspca_dev
, 0x40, 1, 0x7a00, 0x8030, 0, NULL
);
661 ctrl_in(gspca_dev
, 0xc0, 2, 0x7a00, 0x8030, 1, &probe
);
662 gspca_dbg(gspca_dev
, D_PROBE
, "probe=0x%02x\n", probe
);
668 gspca_dbg(gspca_dev
, D_PROBE
, "0xff -> OVXXXX\n");
669 gspca_dbg(gspca_dev
, D_PROBE
, "probing for sensor OV2640 or OV9655");
672 for (ntry
= 0; ntry
< 4; ntry
++) {
673 ctrl_out(gspca_dev
, 0x40, 1, 0x0040, 0x0000,
676 ctrl_out(gspca_dev
, 0x40, 1, 0x6000, 0x800a,
680 /* Wait for 26(OV2640) or 96(OV9655) */
681 ctrl_in(gspca_dev
, 0xc0, 2, 0x6000, 0x800a,
684 if (probe
== 0x26 || probe
== 0x40) {
685 gspca_dbg(gspca_dev
, D_PROBE
,
686 "probe=0x%02x -> OV2640\n",
688 sd
->sensor
= ID_OV2640
;
692 if (probe
== 0x96 || probe
== 0x55) {
693 gspca_dbg(gspca_dev
, D_PROBE
,
694 "probe=0x%02x -> OV9655\n",
696 sd
->sensor
= ID_OV9655
;
700 gspca_dbg(gspca_dev
, D_PROBE
, "probe=0x%02x\n",
708 if (nb26
< 4 && nb96
< 4)
711 gspca_dbg(gspca_dev
, D_PROBE
, "Not any 0xff -> MI2020\n");
712 sd
->sensor
= ID_MI2020
;
717 gspca_dbg(gspca_dev
, D_PROBE
, "05e3:f191 sensor MI1320 (1.3M)\n");
718 } else if (_MI2020_
) {
719 gspca_dbg(gspca_dev
, D_PROBE
, "05e3:0503 sensor MI2020 (2.0M)\n");
720 } else if (_OV9655_
) {
721 gspca_dbg(gspca_dev
, D_PROBE
, "05e3:0503 sensor OV9655 (1.3M)\n");
722 } else if (_OV2640_
) {
723 gspca_dbg(gspca_dev
, D_PROBE
, "05e3:0503 sensor OV2640 (2.0M)\n");
725 gspca_dbg(gspca_dev
, D_PROBE
, "***** Unknown sensor *****\n");