diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-06-17 21:16:55 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-06-17 21:16:55 -0400 |
commit | 4b337c5f245b6587ba844ac7bb13c313a2912f7b (patch) | |
tree | 999c6a6580b76a083c8efb9dabff709d1c49fcd0 /drivers/media/video/gspca | |
parent | 492b057c426e4aa747484958e18e9da29003985d (diff) | |
parent | 3fe0344faf7fdcb158bd5c1a9aec960a8d70c8e8 (diff) |
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers/media/video/gspca')
37 files changed, 4281 insertions, 3295 deletions
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 00e6863ed666..480ec5c87d0e 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
168 | 168 | ||
169 | cam->cam_mode = fpix_mode; | 169 | cam->cam_mode = fpix_mode; |
170 | cam->nmodes = 1; | 170 | cam->nmodes = 1; |
171 | cam->bulk = 1; | ||
171 | cam->bulk_size = FPIX_MAX_TRANSFER; | 172 | cam->bulk_size = FPIX_MAX_TRANSFER; |
172 | 173 | ||
173 | INIT_WORK(&dev->work_struct, dostream); | 174 | INIT_WORK(&dev->work_struct, dostream); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index a2741d7dccfe..f7e0355ad644 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Main USB camera driver | 2 | * Main USB camera driver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) | 50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0) |
51 | 51 | ||
52 | #ifdef GSPCA_DEBUG | 52 | #ifdef GSPCA_DEBUG |
53 | int gspca_debug = D_ERR | D_PROBE; | 53 | int gspca_debug = D_ERR | D_PROBE; |
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
441 | * look for an input transfer endpoint in an alternate setting | 441 | * look for an input transfer endpoint in an alternate setting |
442 | */ | 442 | */ |
443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | 443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, |
444 | __u8 xfer) | 444 | int xfer) |
445 | { | 445 | { |
446 | struct usb_host_endpoint *ep; | 446 | struct usb_host_endpoint *ep; |
447 | int i, attr; | 447 | int i, attr; |
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | |||
449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { | 449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { |
450 | ep = &alt->endpoint[i]; | 450 | ep = &alt->endpoint[i]; |
451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
452 | if (attr == xfer) | 452 | if (attr == xfer |
453 | && ep->desc.wMaxPacketSize != 0) | ||
453 | return ep; | 454 | return ep; |
454 | } | 455 | } |
455 | return NULL; | 456 | return NULL; |
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
467 | { | 468 | { |
468 | struct usb_interface *intf; | 469 | struct usb_interface *intf; |
469 | struct usb_host_endpoint *ep; | 470 | struct usb_host_endpoint *ep; |
470 | int i, ret; | 471 | int xfer, i, ret; |
471 | 472 | ||
472 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 473 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
473 | ep = NULL; | 474 | ep = NULL; |
475 | xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK | ||
476 | : USB_ENDPOINT_XFER_ISOC; | ||
474 | i = gspca_dev->alt; /* previous alt setting */ | 477 | i = gspca_dev->alt; /* previous alt setting */ |
475 | |||
476 | /* try isoc */ | ||
477 | while (--i >= 0) { | 478 | while (--i >= 0) { |
478 | ep = alt_xfer(&intf->altsetting[i], | 479 | ep = alt_xfer(&intf->altsetting[i], xfer); |
479 | USB_ENDPOINT_XFER_ISOC); | ||
480 | if (ep) | 480 | if (ep) |
481 | break; | 481 | break; |
482 | } | 482 | } |
483 | |||
484 | /* if no isoc, try bulk (alt 0 only) */ | ||
485 | if (ep == NULL) { | 483 | if (ep == NULL) { |
486 | ep = alt_xfer(&intf->altsetting[0], | 484 | err("no transfer endpoint found"); |
487 | USB_ENDPOINT_XFER_BULK); | 485 | return NULL; |
488 | if (ep == NULL) { | ||
489 | err("no transfer endpoint found"); | ||
490 | return NULL; | ||
491 | } | ||
492 | i = 0; | ||
493 | gspca_dev->bulk = 1; | ||
494 | } | 486 | } |
495 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", | 487 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", |
496 | i, ep->desc.bEndpointAddress); | 488 | i, ep->desc.bEndpointAddress); |
497 | if (i > 0) { | 489 | if (gspca_dev->nbalt > 1) { |
498 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | 490 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); |
499 | if (ret < 0) { | 491 | if (ret < 0) { |
500 | err("set interface err %d", ret); | 492 | err("set alt %d err %d", i, ret); |
501 | return NULL; | 493 | return NULL; |
502 | } | 494 | } |
503 | } | 495 | } |
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
517 | /* calculate the packet size and the number of packets */ | 509 | /* calculate the packet size and the number of packets */ |
518 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 510 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
519 | 511 | ||
520 | if (!gspca_dev->bulk) { /* isoc */ | 512 | if (!gspca_dev->cam.bulk) { /* isoc */ |
521 | 513 | ||
522 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ | 514 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ |
523 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 515 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); |
524 | npkt = ISO_MAX_SIZE / psize; | 516 | npkt = gspca_dev->cam.npkt; |
525 | if (npkt > ISO_MAX_PKT) | 517 | if (npkt == 0) |
526 | npkt = ISO_MAX_PKT; | 518 | npkt = 32; /* default value */ |
527 | bsize = psize * npkt; | 519 | bsize = psize * npkt; |
528 | PDEBUG(D_STREAM, | 520 | PDEBUG(D_STREAM, |
529 | "isoc %d pkts size %d = bsize:%d", | 521 | "isoc %d pkts size %d = bsize:%d", |
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
617 | goto out; | 609 | goto out; |
618 | 610 | ||
619 | /* clear the bulk endpoint */ | 611 | /* clear the bulk endpoint */ |
620 | if (gspca_dev->bulk) | 612 | if (gspca_dev->cam.bulk) |
621 | usb_clear_halt(gspca_dev->dev, | 613 | usb_clear_halt(gspca_dev->dev, |
622 | gspca_dev->urb[0]->pipe); | 614 | gspca_dev->urb[0]->pipe); |
623 | 615 | ||
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
630 | gspca_dev->streaming = 1; | 622 | gspca_dev->streaming = 1; |
631 | 623 | ||
632 | /* some bulk transfers are started by the subdriver */ | 624 | /* some bulk transfers are started by the subdriver */ |
633 | if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) | 625 | if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) |
634 | break; | 626 | break; |
635 | 627 | ||
636 | /* submit the URBs */ | 628 | /* submit the URBs */ |
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) | |||
661 | { | 653 | { |
662 | int ret; | 654 | int ret; |
663 | 655 | ||
656 | if (gspca_dev->alt == 0) | ||
657 | return 0; | ||
664 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | 658 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); |
665 | if (ret < 0) | 659 | if (ret < 0) |
666 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | 660 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); |
@@ -869,6 +863,32 @@ out: | |||
869 | return ret; | 863 | return ret; |
870 | } | 864 | } |
871 | 865 | ||
866 | static int vidioc_enum_framesizes(struct file *file, void *priv, | ||
867 | struct v4l2_frmsizeenum *fsize) | ||
868 | { | ||
869 | struct gspca_dev *gspca_dev = priv; | ||
870 | int i; | ||
871 | __u32 index = 0; | ||
872 | |||
873 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { | ||
874 | if (fsize->pixel_format != | ||
875 | gspca_dev->cam.cam_mode[i].pixelformat) | ||
876 | continue; | ||
877 | |||
878 | if (fsize->index == index) { | ||
879 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
880 | fsize->discrete.width = | ||
881 | gspca_dev->cam.cam_mode[i].width; | ||
882 | fsize->discrete.height = | ||
883 | gspca_dev->cam.cam_mode[i].height; | ||
884 | return 0; | ||
885 | } | ||
886 | index++; | ||
887 | } | ||
888 | |||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
872 | static void gspca_release(struct video_device *vfd) | 892 | static void gspca_release(struct video_device *vfd) |
873 | { | 893 | { |
874 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); | 894 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); |
@@ -989,43 +1009,54 @@ out: | |||
989 | return ret; | 1009 | return ret; |
990 | } | 1010 | } |
991 | 1011 | ||
1012 | static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev, | ||
1013 | int id) | ||
1014 | { | ||
1015 | const struct ctrl *ctrls; | ||
1016 | int i; | ||
1017 | |||
1018 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | ||
1019 | i < gspca_dev->sd_desc->nctrls; | ||
1020 | i++, ctrls++) { | ||
1021 | if (gspca_dev->ctrl_dis & (1 << i)) | ||
1022 | continue; | ||
1023 | if (id == ctrls->qctrl.id) | ||
1024 | return ctrls; | ||
1025 | } | ||
1026 | return NULL; | ||
1027 | } | ||
1028 | |||
992 | static int vidioc_queryctrl(struct file *file, void *priv, | 1029 | static int vidioc_queryctrl(struct file *file, void *priv, |
993 | struct v4l2_queryctrl *q_ctrl) | 1030 | struct v4l2_queryctrl *q_ctrl) |
994 | { | 1031 | { |
995 | struct gspca_dev *gspca_dev = priv; | 1032 | struct gspca_dev *gspca_dev = priv; |
996 | int i, ix; | 1033 | const struct ctrl *ctrls; |
1034 | int i; | ||
997 | u32 id; | 1035 | u32 id; |
998 | 1036 | ||
999 | ix = -1; | 1037 | ctrls = NULL; |
1000 | id = q_ctrl->id; | 1038 | id = q_ctrl->id; |
1001 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 1039 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
1002 | id &= V4L2_CTRL_ID_MASK; | 1040 | id &= V4L2_CTRL_ID_MASK; |
1003 | id++; | 1041 | id++; |
1004 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1042 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1005 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) | 1043 | if (gspca_dev->ctrl_dis & (1 << i)) |
1006 | continue; | 1044 | continue; |
1007 | if (ix < 0) { | 1045 | if (ctrls->qctrl.id < id) |
1008 | ix = i; | ||
1009 | continue; | 1046 | continue; |
1047 | if (ctrls != NULL) { | ||
1048 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | ||
1049 | > ctrls->qctrl.id) | ||
1050 | continue; | ||
1010 | } | 1051 | } |
1011 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | 1052 | ctrls = &gspca_dev->sd_desc->ctrls[i]; |
1012 | > gspca_dev->sd_desc->ctrls[ix].qctrl.id) | ||
1013 | continue; | ||
1014 | ix = i; | ||
1015 | } | ||
1016 | } | ||
1017 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1018 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
1019 | ix = i; | ||
1020 | break; | ||
1021 | } | 1053 | } |
1054 | } else { | ||
1055 | ctrls = get_ctrl(gspca_dev, id); | ||
1022 | } | 1056 | } |
1023 | if (ix < 0) | 1057 | if (ctrls == NULL) |
1024 | return -EINVAL; | 1058 | return -EINVAL; |
1025 | memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, | 1059 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); |
1026 | sizeof *q_ctrl); | ||
1027 | if (gspca_dev->ctrl_dis & (1 << ix)) | ||
1028 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
1029 | return 0; | 1060 | return 0; |
1030 | } | 1061 | } |
1031 | 1062 | ||
@@ -1034,56 +1065,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1034 | { | 1065 | { |
1035 | struct gspca_dev *gspca_dev = priv; | 1066 | struct gspca_dev *gspca_dev = priv; |
1036 | const struct ctrl *ctrls; | 1067 | const struct ctrl *ctrls; |
1037 | int i, ret; | 1068 | int ret; |
1038 | 1069 | ||
1039 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1070 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1040 | i < gspca_dev->sd_desc->nctrls; | 1071 | if (ctrls == NULL) |
1041 | i++, ctrls++) { | 1072 | return -EINVAL; |
1042 | if (ctrl->id != ctrls->qctrl.id) | 1073 | |
1043 | continue; | 1074 | if (ctrl->value < ctrls->qctrl.minimum |
1044 | if (gspca_dev->ctrl_dis & (1 << i)) | 1075 | || ctrl->value > ctrls->qctrl.maximum) |
1045 | return -EINVAL; | 1076 | return -ERANGE; |
1046 | if (ctrl->value < ctrls->qctrl.minimum | 1077 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
1047 | || ctrl->value > ctrls->qctrl.maximum) | 1078 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1048 | return -ERANGE; | 1079 | return -ERESTARTSYS; |
1049 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1080 | if (gspca_dev->present) |
1050 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1081 | ret = ctrls->set(gspca_dev, ctrl->value); |
1051 | return -ERESTARTSYS; | 1082 | else |
1052 | if (gspca_dev->present) | 1083 | ret = -ENODEV; |
1053 | ret = ctrls->set(gspca_dev, ctrl->value); | 1084 | mutex_unlock(&gspca_dev->usb_lock); |
1054 | else | 1085 | return ret; |
1055 | ret = -ENODEV; | ||
1056 | mutex_unlock(&gspca_dev->usb_lock); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | return -EINVAL; | ||
1060 | } | 1086 | } |
1061 | 1087 | ||
1062 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1088 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1063 | struct v4l2_control *ctrl) | 1089 | struct v4l2_control *ctrl) |
1064 | { | 1090 | { |
1065 | struct gspca_dev *gspca_dev = priv; | 1091 | struct gspca_dev *gspca_dev = priv; |
1066 | |||
1067 | const struct ctrl *ctrls; | 1092 | const struct ctrl *ctrls; |
1068 | int i, ret; | 1093 | int ret; |
1069 | 1094 | ||
1070 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1095 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1071 | i < gspca_dev->sd_desc->nctrls; | 1096 | if (ctrls == NULL) |
1072 | i++, ctrls++) { | 1097 | return -EINVAL; |
1073 | if (ctrl->id != ctrls->qctrl.id) | 1098 | |
1074 | continue; | 1099 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1075 | if (gspca_dev->ctrl_dis & (1 << i)) | 1100 | return -ERESTARTSYS; |
1076 | return -EINVAL; | 1101 | if (gspca_dev->present) |
1077 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1102 | ret = ctrls->get(gspca_dev, &ctrl->value); |
1078 | return -ERESTARTSYS; | 1103 | else |
1079 | if (gspca_dev->present) | 1104 | ret = -ENODEV; |
1080 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1105 | mutex_unlock(&gspca_dev->usb_lock); |
1081 | else | 1106 | return ret; |
1082 | ret = -ENODEV; | ||
1083 | mutex_unlock(&gspca_dev->usb_lock); | ||
1084 | return ret; | ||
1085 | } | ||
1086 | return -EINVAL; | ||
1087 | } | 1107 | } |
1088 | 1108 | ||
1089 | /*fixme: have an audio flag in gspca_dev?*/ | 1109 | /*fixme: have an audio flag in gspca_dev?*/ |
@@ -1864,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
1864 | .vidioc_g_parm = vidioc_g_parm, | 1884 | .vidioc_g_parm = vidioc_g_parm, |
1865 | .vidioc_s_parm = vidioc_s_parm, | 1885 | .vidioc_s_parm = vidioc_s_parm, |
1866 | .vidioc_s_std = vidioc_s_std, | 1886 | .vidioc_s_std = vidioc_s_std, |
1887 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | ||
1867 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1888 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1868 | .vidiocgmbuf = vidiocgmbuf, | 1889 | .vidiocgmbuf = vidiocgmbuf, |
1869 | #endif | 1890 | #endif |
@@ -1943,7 +1964,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
1943 | 1964 | ||
1944 | /* init video stuff */ | 1965 | /* init video stuff */ |
1945 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); | 1966 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); |
1946 | gspca_dev->vdev.parent = &dev->dev; | 1967 | gspca_dev->vdev.parent = &intf->dev; |
1947 | gspca_dev->module = module; | 1968 | gspca_dev->module = module; |
1948 | gspca_dev->present = 1; | 1969 | gspca_dev->present = 1; |
1949 | ret = video_register_device(&gspca_dev->vdev, | 1970 | ret = video_register_device(&gspca_dev->vdev, |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 58e8ff02136a..bd1faff88644 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -44,8 +44,6 @@ extern int gspca_debug; | |||
44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ | 44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ |
45 | /* image transfers */ | 45 | /* image transfers */ |
46 | #define MAX_NURBS 4 /* max number of URBs */ | 46 | #define MAX_NURBS 4 /* max number of URBs */ |
47 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ | ||
48 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ | ||
49 | 47 | ||
50 | /* device information - set at probe time */ | 48 | /* device information - set at probe time */ |
51 | struct cam { | 49 | struct cam { |
@@ -56,6 +54,9 @@ struct cam { | |||
56 | * - cannot be > MAX_NURBS | 54 | * - cannot be > MAX_NURBS |
57 | * - when 0 and bulk_size != 0 means | 55 | * - when 0 and bulk_size != 0 means |
58 | * 1 URB and submit done by subdriver */ | 56 | * 1 URB and submit done by subdriver */ |
57 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
58 | u8 npkt; /* number of packets in an ISOC message | ||
59 | * 0 is the default value: 32 packets */ | ||
59 | u32 input_flags; /* value for ENUM_INPUT status flags */ | 60 | u32 input_flags; /* value for ENUM_INPUT status flags */ |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -168,7 +169,6 @@ struct gspca_dev { | |||
168 | __u8 iface; /* USB interface number */ | 169 | __u8 iface; /* USB interface number */ |
169 | __u8 alt; /* USB alternate setting */ | 170 | __u8 alt; /* USB alternate setting */ |
170 | __u8 nbalt; /* number of USB alternate settings */ | 171 | __u8 nbalt; /* number of USB alternate settings */ |
171 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
172 | }; | 172 | }; |
173 | 173 | ||
174 | int gspca_dev_probe(struct usb_interface *intf, | 174 | int gspca_dev_probe(struct usb_interface *intf, |
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile index 9fa3644f4869..bf7a19a1e6d1 100644 --- a/drivers/media/video/gspca/m5602/Makefile +++ b/drivers/media/video/gspca/m5602/Makefile | |||
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o | |||
2 | 2 | ||
3 | gspca_m5602-objs := m5602_core.o \ | 3 | gspca_m5602-objs := m5602_core.o \ |
4 | m5602_ov9650.o \ | 4 | m5602_ov9650.o \ |
5 | m5602_ov7660.o \ | ||
5 | m5602_mt9m111.o \ | 6 | m5602_mt9m111.o \ |
6 | m5602_po1030.o \ | 7 | m5602_po1030.o \ |
7 | m5602_s5k83a.o \ | 8 | m5602_s5k83a.o \ |
8 | m5602_s5k4aa.o | 9 | m5602_s5k4aa.o |
9 | 10 | ||
10 | EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file | 11 | EXTRA_CFLAGS += -Idrivers/media/video/gspca |
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h index 8f1cea6fd3bf..1127a405c9b2 100644 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/drivers/media/video/gspca/m5602/m5602_bridge.h | |||
@@ -45,6 +45,15 @@ | |||
45 | #define M5602_XB_SEN_CLK_DIV 0x15 | 45 | #define M5602_XB_SEN_CLK_DIV 0x15 |
46 | #define M5602_XB_AUD_CLK_CTRL 0x16 | 46 | #define M5602_XB_AUD_CLK_CTRL 0x16 |
47 | #define M5602_XB_AUD_CLK_DIV 0x17 | 47 | #define M5602_XB_AUD_CLK_DIV 0x17 |
48 | #define M5602_OB_AC_LINK_STATE 0x22 | ||
49 | #define M5602_OB_PCM_SLOT_INDEX 0x24 | ||
50 | #define M5602_OB_GPIO_SLOT_INDEX 0x25 | ||
51 | #define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28 | ||
52 | #define M5602_OB_ACRX_STATUS_DATA_L 0x29 | ||
53 | #define M5602_OB_ACRX_STATUS_DATA_H 0x2a | ||
54 | #define M5602_OB_ACTX_COMMAND_ADDRESS 0x31 | ||
55 | #define M5602_OB_ACRX_COMMAND_DATA_L 0x32 | ||
56 | #define M5602_OB_ACTX_COMMAND_DATA_H 0X33 | ||
48 | #define M5602_XB_DEVCTR1 0x41 | 57 | #define M5602_XB_DEVCTR1 0x41 |
49 | #define M5602_XB_EPSETR0 0x42 | 58 | #define M5602_XB_EPSETR0 0x42 |
50 | #define M5602_XB_EPAFCTR 0x47 | 59 | #define M5602_XB_EPAFCTR 0x47 |
@@ -77,7 +86,18 @@ | |||
77 | #define M5602_XB_GPIO_EN_L 0x75 | 86 | #define M5602_XB_GPIO_EN_L 0x75 |
78 | #define M5602_XB_GPIO_DAT 0x76 | 87 | #define M5602_XB_GPIO_DAT 0x76 |
79 | #define M5602_XB_GPIO_DIR 0x77 | 88 | #define M5602_XB_GPIO_DIR 0x77 |
80 | #define M5602_XB_MISC_CTL 0x70 | 89 | #define M5602_XB_SEN_CLK_CONTROL 0x80 |
90 | #define M5602_XB_SEN_CLK_DIVISION 0x81 | ||
91 | #define M5602_XB_CPR_CLK_CONTROL 0x82 | ||
92 | #define M5602_XB_CPR_CLK_DIVISION 0x83 | ||
93 | #define M5602_XB_MCU_CLK_CONTROL 0x84 | ||
94 | #define M5602_XB_MCU_CLK_DIVISION 0x85 | ||
95 | #define M5602_XB_DCT_CLK_CONTROL 0x86 | ||
96 | #define M5602_XB_DCT_CLK_DIVISION 0x87 | ||
97 | #define M5602_XB_EC_CLK_CONTROL 0x88 | ||
98 | #define M5602_XB_EC_CLK_DIVISION 0x89 | ||
99 | #define M5602_XB_LBUF_CLK_CONTROL 0x8a | ||
100 | #define M5602_XB_LBUF_CLK_DIVISION 0x8b | ||
81 | 101 | ||
82 | #define I2C_BUSY 0x80 | 102 | #define I2C_BUSY 0x80 |
83 | 103 | ||
@@ -128,10 +148,10 @@ struct sd { | |||
128 | }; | 148 | }; |
129 | 149 | ||
130 | int m5602_read_bridge( | 150 | int m5602_read_bridge( |
131 | struct sd *sd, u8 address, u8 *i2c_data); | 151 | struct sd *sd, const u8 address, u8 *i2c_data); |
132 | 152 | ||
133 | int m5602_write_bridge( | 153 | int m5602_write_bridge( |
134 | struct sd *sd, u8 address, u8 i2c_data); | 154 | struct sd *sd, const u8 address, const u8 i2c_data); |
135 | 155 | ||
136 | int m5602_write_sensor(struct sd *sd, const u8 address, | 156 | int m5602_write_sensor(struct sd *sd, const u8 address, |
137 | u8 *i2c_data, const u8 len); | 157 | u8 *i2c_data, const u8 len); |
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 1aac2985fee6..8a5bba16ff32 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | #include "m5602_ov7660.h" | ||
20 | #include "m5602_mt9m111.h" | 21 | #include "m5602_mt9m111.h" |
21 | #include "m5602_po1030.h" | 22 | #include "m5602_po1030.h" |
22 | #include "m5602_s5k83a.h" | 23 | #include "m5602_s5k83a.h" |
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = { | |||
35 | MODULE_DEVICE_TABLE(usb, m5602_table); | 36 | MODULE_DEVICE_TABLE(usb, m5602_table); |
36 | 37 | ||
37 | /* Reads a byte from the m5602 */ | 38 | /* Reads a byte from the m5602 */ |
38 | int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | 39 | int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) |
39 | { | 40 | { |
40 | int err; | 41 | int err; |
41 | struct usb_device *udev = sd->gspca_dev.dev; | 42 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | /* Writes a byte to to the m5602 */ | 59 | /* Writes a byte to to the m5602 */ |
59 | int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | 60 | int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) |
60 | { | 61 | { |
61 | int err; | 62 | int err; |
62 | struct usb_device *udev = sd->gspca_dev.dev; | 63 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | |||
80 | return (err < 0) ? err : 0; | 81 | return (err < 0) ? err : 0; |
81 | } | 82 | } |
82 | 83 | ||
84 | int m5602_wait_for_i2c(struct sd *sd) | ||
85 | { | ||
86 | int err; | ||
87 | u8 data; | ||
88 | |||
89 | do { | ||
90 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data); | ||
91 | } while ((data & I2C_BUSY) && !err); | ||
92 | return err; | ||
93 | } | ||
94 | |||
83 | int m5602_read_sensor(struct sd *sd, const u8 address, | 95 | int m5602_read_sensor(struct sd *sd, const u8 address, |
84 | u8 *i2c_data, const u8 len) | 96 | u8 *i2c_data, const u8 len) |
85 | { | 97 | { |
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
88 | if (!len || len > sd->sensor->i2c_regW) | 100 | if (!len || len > sd->sensor->i2c_regW) |
89 | return -EINVAL; | 101 | return -EINVAL; |
90 | 102 | ||
91 | do { | 103 | err = m5602_wait_for_i2c(sd); |
92 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); | ||
93 | } while ((*i2c_data & I2C_BUSY) && !err); | ||
94 | if (err < 0) | 104 | if (err < 0) |
95 | return err; | 105 | return err; |
96 | 106 | ||
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
103 | if (err < 0) | 113 | if (err < 0) |
104 | return err; | 114 | return err; |
105 | 115 | ||
116 | /* Sensors with registers that are of only | ||
117 | one byte width are differently read */ | ||
118 | |||
119 | /* FIXME: This works with the ov9650, but has issues with the po1030 */ | ||
106 | if (sd->sensor->i2c_regW == 1) { | 120 | if (sd->sensor->i2c_regW == 1) { |
107 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); | 121 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); |
108 | if (err < 0) | 122 | if (err < 0) |
109 | return err; | 123 | return err; |
110 | 124 | ||
111 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); | 125 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); |
112 | if (err < 0) | ||
113 | return err; | ||
114 | } else { | 126 | } else { |
115 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); | 127 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); |
116 | if (err < 0) | ||
117 | return err; | ||
118 | } | 128 | } |
119 | 129 | ||
120 | for (i = 0; (i < len) && !err; i++) { | 130 | for (i = 0; (i < len) && !err; i++) { |
131 | err = m5602_wait_for_i2c(sd); | ||
132 | if (err < 0) | ||
133 | return err; | ||
134 | |||
121 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 135 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
122 | 136 | ||
123 | PDEBUG(D_CONF, "Reading sensor register " | 137 | PDEBUG(D_CONF, "Reading sensor register " |
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd) | |||
206 | if (!sd->sensor->probe(sd)) | 220 | if (!sd->sensor->probe(sd)) |
207 | return 0; | 221 | return 0; |
208 | 222 | ||
223 | /* Try the ov7660 */ | ||
224 | sd->sensor = &ov7660; | ||
225 | if (!sd->sensor->probe(sd)) | ||
226 | return 0; | ||
227 | |||
209 | /* Try the s5k83a */ | 228 | /* Try the s5k83a */ |
210 | sd->sensor = &s5k83a; | 229 | sd->sensor = &s5k83a; |
211 | if (!sd->sensor->probe(sd)) | 230 | if (!sd->sensor->probe(sd)) |
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
409 | MODULE_LICENSE("GPL"); | 428 | MODULE_LICENSE("GPL"); |
410 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); | 429 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); |
411 | MODULE_PARM_DESC(force_sensor, | 430 | MODULE_PARM_DESC(force_sensor, |
412 | "force detection of sensor, " | 431 | "forces detection of a sensor, " |
413 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); | 432 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, " |
433 | "4 = MT9M111, 5 = PO1030, 6 = OV7660"); | ||
414 | 434 | ||
415 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); | 435 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); |
416 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); | 436 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 7d3f9e348ef4..8d071dff6944 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -18,6 +18,23 @@ | |||
18 | 18 | ||
19 | #include "m5602_mt9m111.h" | 19 | #include "m5602_mt9m111.h" |
20 | 20 | ||
21 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
28 | __s32 val); | ||
29 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
30 | __s32 *val); | ||
31 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
36 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
37 | |||
21 | static struct v4l2_pix_format mt9m111_modes[] = { | 38 | static struct v4l2_pix_format mt9m111_modes[] = { |
22 | { | 39 | { |
23 | 640, | 40 | 640, |
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = { | |||
32 | }; | 49 | }; |
33 | 50 | ||
34 | const static struct ctrl mt9m111_ctrls[] = { | 51 | const static struct ctrl mt9m111_ctrls[] = { |
52 | #define VFLIP_IDX 0 | ||
35 | { | 53 | { |
36 | { | 54 | { |
37 | .id = V4L2_CID_VFLIP, | 55 | .id = V4L2_CID_VFLIP, |
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
44 | }, | 62 | }, |
45 | .set = mt9m111_set_vflip, | 63 | .set = mt9m111_set_vflip, |
46 | .get = mt9m111_get_vflip | 64 | .get = mt9m111_get_vflip |
47 | }, { | 65 | }, |
66 | #define HFLIP_IDX 1 | ||
67 | { | ||
48 | { | 68 | { |
49 | .id = V4L2_CID_HFLIP, | 69 | .id = V4L2_CID_HFLIP, |
50 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 70 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
56 | }, | 76 | }, |
57 | .set = mt9m111_set_hflip, | 77 | .set = mt9m111_set_hflip, |
58 | .get = mt9m111_get_hflip | 78 | .get = mt9m111_get_hflip |
59 | }, { | 79 | }, |
80 | #define GAIN_IDX 2 | ||
81 | { | ||
60 | { | 82 | { |
61 | .id = V4L2_CID_GAIN, | 83 | .id = V4L2_CID_GAIN, |
62 | .type = V4L2_CTRL_TYPE_INTEGER, | 84 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
64 | .minimum = 0, | 86 | .minimum = 0, |
65 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, | 87 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, |
66 | .step = 1, | 88 | .step = 1, |
67 | .default_value = DEFAULT_GAIN, | 89 | .default_value = MT9M111_DEFAULT_GAIN, |
68 | .flags = V4L2_CTRL_FLAG_SLIDER | 90 | .flags = V4L2_CTRL_FLAG_SLIDER |
69 | }, | 91 | }, |
70 | .set = mt9m111_set_gain, | 92 | .set = mt9m111_set_gain, |
71 | .get = mt9m111_get_gain | 93 | .get = mt9m111_get_gain |
72 | } | 94 | }, |
95 | #define AUTO_WHITE_BALANCE_IDX 3 | ||
96 | { | ||
97 | { | ||
98 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
99 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
100 | .name = "auto white balance", | ||
101 | .minimum = 0, | ||
102 | .maximum = 1, | ||
103 | .step = 1, | ||
104 | .default_value = 0, | ||
105 | }, | ||
106 | .set = mt9m111_set_auto_white_balance, | ||
107 | .get = mt9m111_get_auto_white_balance | ||
108 | }, | ||
109 | #define GREEN_BALANCE_IDX 4 | ||
110 | { | ||
111 | { | ||
112 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "green balance", | ||
115 | .minimum = 0x00, | ||
116 | .maximum = 0x7ff, | ||
117 | .step = 0x1, | ||
118 | .default_value = MT9M111_GREEN_GAIN_DEFAULT, | ||
119 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
120 | }, | ||
121 | .set = mt9m111_set_green_balance, | ||
122 | .get = mt9m111_get_green_balance | ||
123 | }, | ||
124 | #define BLUE_BALANCE_IDX 5 | ||
125 | { | ||
126 | { | ||
127 | .id = V4L2_CID_BLUE_BALANCE, | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .name = "blue balance", | ||
130 | .minimum = 0x00, | ||
131 | .maximum = 0x7ff, | ||
132 | .step = 0x1, | ||
133 | .default_value = MT9M111_BLUE_GAIN_DEFAULT, | ||
134 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
135 | }, | ||
136 | .set = mt9m111_set_blue_balance, | ||
137 | .get = mt9m111_get_blue_balance | ||
138 | }, | ||
139 | #define RED_BALANCE_IDX 5 | ||
140 | { | ||
141 | { | ||
142 | .id = V4L2_CID_RED_BALANCE, | ||
143 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
144 | .name = "red balance", | ||
145 | .minimum = 0x00, | ||
146 | .maximum = 0x7ff, | ||
147 | .step = 0x1, | ||
148 | .default_value = MT9M111_RED_GAIN_DEFAULT, | ||
149 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
150 | }, | ||
151 | .set = mt9m111_set_red_balance, | ||
152 | .get = mt9m111_get_red_balance | ||
153 | }, | ||
73 | }; | 154 | }; |
74 | 155 | ||
75 | |||
76 | static void mt9m111_dump_registers(struct sd *sd); | 156 | static void mt9m111_dump_registers(struct sd *sd); |
77 | 157 | ||
78 | int mt9m111_probe(struct sd *sd) | 158 | int mt9m111_probe(struct sd *sd) |
79 | { | 159 | { |
80 | u8 data[2] = {0x00, 0x00}; | 160 | u8 data[2] = {0x00, 0x00}; |
81 | int i; | 161 | int i; |
162 | s32 *sensor_settings; | ||
82 | 163 | ||
83 | if (force_sensor) { | 164 | if (force_sensor) { |
84 | if (force_sensor == MT9M111_SENSOR) { | 165 | if (force_sensor == MT9M111_SENSOR) { |
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd) | |||
117 | return -ENODEV; | 198 | return -ENODEV; |
118 | 199 | ||
119 | sensor_found: | 200 | sensor_found: |
201 | sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), | ||
202 | GFP_KERNEL); | ||
203 | if (!sensor_settings) | ||
204 | return -ENOMEM; | ||
205 | |||
120 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; | 206 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; |
121 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); | 207 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); |
122 | sd->desc->ctrls = mt9m111_ctrls; | 208 | sd->desc->ctrls = mt9m111_ctrls; |
123 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); | 209 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); |
210 | |||
211 | for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) | ||
212 | sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; | ||
213 | sd->sensor_priv = sensor_settings; | ||
214 | |||
124 | return 0; | 215 | return 0; |
125 | } | 216 | } |
126 | 217 | ||
127 | int mt9m111_init(struct sd *sd) | 218 | int mt9m111_init(struct sd *sd) |
128 | { | 219 | { |
129 | int i, err = 0; | 220 | int i, err = 0; |
221 | s32 *sensor_settings = sd->sensor_priv; | ||
130 | 222 | ||
131 | /* Init the sensor */ | 223 | /* Init the sensor */ |
132 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { | 224 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { |
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd) | |||
147 | if (dump_sensor) | 239 | if (dump_sensor) |
148 | mt9m111_dump_registers(sd); | 240 | mt9m111_dump_registers(sd); |
149 | 241 | ||
150 | return (err < 0) ? err : 0; | 242 | err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); |
243 | if (err < 0) | ||
244 | return err; | ||
245 | |||
246 | err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | |||
250 | err = mt9m111_set_green_balance(&sd->gspca_dev, | ||
251 | sensor_settings[GREEN_BALANCE_IDX]); | ||
252 | if (err < 0) | ||
253 | return err; | ||
254 | |||
255 | err = mt9m111_set_blue_balance(&sd->gspca_dev, | ||
256 | sensor_settings[BLUE_BALANCE_IDX]); | ||
257 | if (err < 0) | ||
258 | return err; | ||
259 | |||
260 | err = mt9m111_set_red_balance(&sd->gspca_dev, | ||
261 | sensor_settings[RED_BALANCE_IDX]); | ||
262 | if (err < 0) | ||
263 | return err; | ||
264 | |||
265 | return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
151 | } | 266 | } |
152 | 267 | ||
153 | int mt9m111_power_down(struct sd *sd) | 268 | int mt9m111_start(struct sd *sd) |
154 | { | 269 | { |
155 | return 0; | 270 | int i, err = 0; |
271 | u8 data[2]; | ||
272 | struct cam *cam = &sd->gspca_dev.cam; | ||
273 | s32 *sensor_settings = sd->sensor_priv; | ||
274 | |||
275 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; | ||
276 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
277 | |||
278 | for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) { | ||
279 | if (start_mt9m111[i][0] == BRIDGE) { | ||
280 | err = m5602_write_bridge(sd, | ||
281 | start_mt9m111[i][1], | ||
282 | start_mt9m111[i][2]); | ||
283 | } else { | ||
284 | data[0] = start_mt9m111[i][2]; | ||
285 | data[1] = start_mt9m111[i][3]; | ||
286 | err = m5602_write_sensor(sd, | ||
287 | start_mt9m111[i][1], data, 2); | ||
288 | } | ||
289 | } | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
298 | if (err < 0) | ||
299 | return err; | ||
300 | |||
301 | for (i = 0; i < 2 && !err; i++) | ||
302 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
303 | if (err < 0) | ||
304 | return err; | ||
305 | |||
306 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
307 | if (err < 0) | ||
308 | return err; | ||
309 | |||
310 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
311 | if (err < 0) | ||
312 | return err; | ||
313 | |||
314 | for (i = 0; i < 2 && !err; i++) | ||
315 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | |||
319 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | ||
320 | (width >> 8) & 0xff); | ||
321 | if (err < 0) | ||
322 | return err; | ||
323 | |||
324 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff); | ||
325 | if (err < 0) | ||
326 | return err; | ||
327 | |||
328 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | |||
332 | switch (width) { | ||
333 | case 640: | ||
334 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | ||
335 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
336 | data[1] = MT9M111_RMB_ROW_SKIP_2X | | ||
337 | MT9M111_RMB_COLUMN_SKIP_2X | | ||
338 | (sensor_settings[VFLIP_IDX] << 0) | | ||
339 | (sensor_settings[HFLIP_IDX] << 1); | ||
340 | |||
341 | err = m5602_write_sensor(sd, | ||
342 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
343 | break; | ||
344 | |||
345 | case 320: | ||
346 | PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); | ||
347 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
348 | data[1] = MT9M111_RMB_ROW_SKIP_4X | | ||
349 | MT9M111_RMB_COLUMN_SKIP_4X | | ||
350 | (sensor_settings[VFLIP_IDX] << 0) | | ||
351 | (sensor_settings[HFLIP_IDX] << 1); | ||
352 | err = m5602_write_sensor(sd, | ||
353 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
354 | break; | ||
355 | } | ||
356 | return err; | ||
156 | } | 357 | } |
157 | 358 | ||
158 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 359 | void mt9m111_disconnect(struct sd *sd) |
360 | { | ||
361 | sd->sensor = NULL; | ||
362 | kfree(sd->sensor_priv); | ||
363 | } | ||
364 | |||
365 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
159 | { | 366 | { |
160 | int err; | ||
161 | u8 data[2] = {0x00, 0x00}; | ||
162 | struct sd *sd = (struct sd *) gspca_dev; | 367 | struct sd *sd = (struct sd *) gspca_dev; |
368 | s32 *sensor_settings = sd->sensor_priv; | ||
163 | 369 | ||
164 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 370 | *val = sensor_settings[VFLIP_IDX]; |
165 | data, 2); | ||
166 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; | ||
167 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 371 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
168 | 372 | ||
169 | return err; | 373 | return 0; |
170 | } | 374 | } |
171 | 375 | ||
172 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 376 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
173 | { | 377 | { |
174 | int err; | 378 | int err; |
175 | u8 data[2] = {0x00, 0x00}; | 379 | u8 data[2] = {0x00, 0x00}; |
176 | struct sd *sd = (struct sd *) gspca_dev; | 380 | struct sd *sd = (struct sd *) gspca_dev; |
381 | s32 *sensor_settings = sd->sensor_priv; | ||
177 | 382 | ||
178 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 383 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
179 | 384 | ||
385 | sensor_settings[VFLIP_IDX] = val; | ||
386 | |||
387 | /* The mt9m111 is flipped by default */ | ||
388 | val = !val; | ||
389 | |||
180 | /* Set the correct page map */ | 390 | /* Set the correct page map */ |
181 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 391 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
182 | if (err < 0) | 392 | if (err < 0) |
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
186 | if (err < 0) | 396 | if (err < 0) |
187 | return err; | 397 | return err; |
188 | 398 | ||
189 | data[0] = (data[0] & 0xfe) | val; | 399 | data[1] = (data[1] & 0xfe) | val; |
190 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 400 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
191 | data, 2); | 401 | data, 2); |
192 | return err; | 402 | return err; |
193 | } | 403 | } |
194 | 404 | ||
195 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 405 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
196 | { | 406 | { |
197 | int err; | ||
198 | u8 data[2] = {0x00, 0x00}; | ||
199 | struct sd *sd = (struct sd *) gspca_dev; | 407 | struct sd *sd = (struct sd *) gspca_dev; |
408 | s32 *sensor_settings = sd->sensor_priv; | ||
200 | 409 | ||
201 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 410 | *val = sensor_settings[HFLIP_IDX]; |
202 | data, 2); | ||
203 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; | ||
204 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 411 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
205 | 412 | ||
206 | return err; | 413 | return 0; |
207 | } | 414 | } |
208 | 415 | ||
209 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 416 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
210 | { | 417 | { |
211 | int err; | 418 | int err; |
212 | u8 data[2] = {0x00, 0x00}; | 419 | u8 data[2] = {0x00, 0x00}; |
213 | struct sd *sd = (struct sd *) gspca_dev; | 420 | struct sd *sd = (struct sd *) gspca_dev; |
421 | s32 *sensor_settings = sd->sensor_priv; | ||
214 | 422 | ||
215 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 423 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
216 | 424 | ||
425 | sensor_settings[HFLIP_IDX] = val; | ||
426 | |||
427 | /* The mt9m111 is flipped by default */ | ||
428 | val = !val; | ||
429 | |||
217 | /* Set the correct page map */ | 430 | /* Set the correct page map */ |
218 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 431 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
219 | if (err < 0) | 432 | if (err < 0) |
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
223 | if (err < 0) | 436 | if (err < 0) |
224 | return err; | 437 | return err; |
225 | 438 | ||
226 | data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); | 439 | data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02); |
227 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 440 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
228 | data, 2); | 441 | data, 2); |
229 | return err; | 442 | return err; |
230 | } | 443 | } |
231 | 444 | ||
232 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 445 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
233 | { | 446 | { |
234 | int err, tmp; | ||
235 | u8 data[2] = {0x00, 0x00}; | ||
236 | struct sd *sd = (struct sd *) gspca_dev; | 447 | struct sd *sd = (struct sd *) gspca_dev; |
448 | s32 *sensor_settings = sd->sensor_priv; | ||
237 | 449 | ||
238 | err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); | 450 | *val = sensor_settings[GAIN_IDX]; |
239 | tmp = ((data[1] << 8) | data[0]); | 451 | PDEBUG(D_V4L2, "Read gain %d", *val); |
240 | 452 | ||
241 | *val = ((tmp & (1 << 10)) * 2) | | 453 | return 0; |
242 | ((tmp & (1 << 9)) * 2) | | 454 | } |
243 | ((tmp & (1 << 8)) * 2) | | ||
244 | (tmp & 0x7f); | ||
245 | 455 | ||
246 | PDEBUG(D_V4L2, "Read gain %d", *val); | 456 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, |
457 | __s32 val) | ||
458 | { | ||
459 | struct sd *sd = (struct sd *) gspca_dev; | ||
460 | s32 *sensor_settings = sd->sensor_priv; | ||
461 | int err; | ||
462 | u8 data[2]; | ||
463 | |||
464 | err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
465 | if (err < 0) | ||
466 | return err; | ||
467 | |||
468 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; | ||
469 | data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); | ||
247 | 470 | ||
471 | err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
472 | |||
473 | PDEBUG(D_V4L2, "Set auto white balance %d", val); | ||
248 | return err; | 474 | return err; |
249 | } | 475 | } |
250 | 476 | ||
251 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 477 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, |
478 | __s32 *val) { | ||
479 | struct sd *sd = (struct sd *) gspca_dev; | ||
480 | s32 *sensor_settings = sd->sensor_priv; | ||
481 | |||
482 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
483 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
252 | { | 488 | { |
253 | int err, tmp; | 489 | int err, tmp; |
254 | u8 data[2] = {0x00, 0x00}; | 490 | u8 data[2] = {0x00, 0x00}; |
255 | struct sd *sd = (struct sd *) gspca_dev; | 491 | struct sd *sd = (struct sd *) gspca_dev; |
492 | s32 *sensor_settings = sd->sensor_priv; | ||
493 | |||
494 | sensor_settings[GAIN_IDX] = val; | ||
256 | 495 | ||
257 | /* Set the correct page map */ | 496 | /* Set the correct page map */ |
258 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 497 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
275 | else | 514 | else |
276 | tmp = val; | 515 | tmp = val; |
277 | 516 | ||
278 | data[1] = (tmp & 0xff00) >> 8; | 517 | data[1] = (tmp & 0xff); |
279 | data[0] = (tmp & 0xff); | 518 | data[0] = (tmp & 0xff00) >> 8; |
280 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, | 519 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, |
281 | data[1], data[0]); | 520 | data[1], data[0]); |
282 | 521 | ||
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
286 | return err; | 525 | return err; |
287 | } | 526 | } |
288 | 527 | ||
528 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
529 | { | ||
530 | int err; | ||
531 | u8 data[2]; | ||
532 | struct sd *sd = (struct sd *) gspca_dev; | ||
533 | s32 *sensor_settings = sd->sensor_priv; | ||
534 | |||
535 | sensor_settings[GREEN_BALANCE_IDX] = val; | ||
536 | data[1] = (val & 0xff); | ||
537 | data[0] = (val & 0xff00) >> 8; | ||
538 | |||
539 | PDEBUG(D_V4L2, "Set green balance %d", val); | ||
540 | err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, | ||
541 | data, 2); | ||
542 | if (err < 0) | ||
543 | return err; | ||
544 | |||
545 | return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN, | ||
546 | data, 2); | ||
547 | } | ||
548 | |||
549 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
550 | { | ||
551 | struct sd *sd = (struct sd *) gspca_dev; | ||
552 | s32 *sensor_settings = sd->sensor_priv; | ||
553 | |||
554 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
555 | PDEBUG(D_V4L2, "Read green balance %d", *val); | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
560 | { | ||
561 | u8 data[2]; | ||
562 | struct sd *sd = (struct sd *) gspca_dev; | ||
563 | s32 *sensor_settings = sd->sensor_priv; | ||
564 | |||
565 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
566 | data[1] = (val & 0xff); | ||
567 | data[0] = (val & 0xff00) >> 8; | ||
568 | |||
569 | PDEBUG(D_V4L2, "Set blue balance %d", val); | ||
570 | |||
571 | return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, | ||
572 | data, 2); | ||
573 | } | ||
574 | |||
575 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
576 | { | ||
577 | struct sd *sd = (struct sd *) gspca_dev; | ||
578 | s32 *sensor_settings = sd->sensor_priv; | ||
579 | |||
580 | *val = sensor_settings[BLUE_BALANCE_IDX]; | ||
581 | PDEBUG(D_V4L2, "Read blue balance %d", *val); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
586 | { | ||
587 | u8 data[2]; | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | ||
589 | s32 *sensor_settings = sd->sensor_priv; | ||
590 | |||
591 | sensor_settings[RED_BALANCE_IDX] = val; | ||
592 | data[1] = (val & 0xff); | ||
593 | data[0] = (val & 0xff00) >> 8; | ||
594 | |||
595 | PDEBUG(D_V4L2, "Set red balance %d", val); | ||
596 | |||
597 | return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, | ||
598 | data, 2); | ||
599 | } | ||
600 | |||
601 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
602 | { | ||
603 | struct sd *sd = (struct sd *) gspca_dev; | ||
604 | s32 *sensor_settings = sd->sensor_priv; | ||
605 | |||
606 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
607 | PDEBUG(D_V4L2, "Read red balance %d", *val); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
289 | static void mt9m111_dump_registers(struct sd *sd) | 611 | static void mt9m111_dump_registers(struct sd *sd) |
290 | { | 612 | { |
291 | u8 address, value[2] = {0x00, 0x00}; | 613 | u8 address, value[2] = {0x00, 0x00}; |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 00c6db02bdb7..b3de77823091 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 | 37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 |
38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 | 38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 |
39 | #define MT9M111_SC_ROW_SPEED 0x0a | 39 | #define MT9M111_SC_ROW_SPEED 0x0a |
40 | |||
41 | #define MT9M111_SC_EXTRA_DELAY 0x0b | 40 | #define MT9M111_SC_EXTRA_DELAY 0x0b |
42 | #define MT9M111_SC_SHUTTER_DELAY 0x0c | 41 | #define MT9M111_SC_SHUTTER_DELAY 0x0c |
43 | #define MT9M111_SC_RESET 0x0d | 42 | #define MT9M111_SC_RESET 0x0d |
@@ -50,9 +49,6 @@ | |||
50 | #define MT9M111_SC_GREEN_2_GAIN 0x2e | 49 | #define MT9M111_SC_GREEN_2_GAIN 0x2e |
51 | #define MT9M111_SC_GLOBAL_GAIN 0x2f | 50 | #define MT9M111_SC_GLOBAL_GAIN 0x2f |
52 | 51 | ||
53 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
54 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
55 | |||
56 | #define MT9M111_CONTEXT_CONTROL 0xc8 | 52 | #define MT9M111_CONTEXT_CONTROL 0xc8 |
57 | #define MT9M111_PAGE_MAP 0xf0 | 53 | #define MT9M111_PAGE_MAP 0xf0 |
58 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 | 54 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 |
@@ -74,8 +70,37 @@ | |||
74 | #define MT9M111_COLORPIPE 0x01 | 70 | #define MT9M111_COLORPIPE 0x01 |
75 | #define MT9M111_CAMERA_CONTROL 0x02 | 71 | #define MT9M111_CAMERA_CONTROL 0x02 |
76 | 72 | ||
73 | #define MT9M111_RESET (1 << 0) | ||
74 | #define MT9M111_RESTART (1 << 1) | ||
75 | #define MT9M111_ANALOG_STANDBY (1 << 2) | ||
76 | #define MT9M111_CHIP_ENABLE (1 << 3) | ||
77 | #define MT9M111_CHIP_DISABLE (0 << 3) | ||
78 | #define MT9M111_OUTPUT_DISABLE (1 << 4) | ||
79 | #define MT9M111_SHOW_BAD_FRAMES (1 << 0) | ||
80 | #define MT9M111_RESTART_BAD_FRAMES (1 << 1) | ||
81 | #define MT9M111_SYNCHRONIZE_CHANGES (1 << 7) | ||
82 | |||
83 | #define MT9M111_RMB_OVER_SIZED (1 << 0) | ||
84 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
85 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
86 | #define MT9M111_RMB_ROW_SKIP_2X (1 << 2) | ||
87 | #define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3) | ||
88 | #define MT9M111_RMB_ROW_SKIP_4X (1 << 4) | ||
89 | #define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5) | ||
90 | |||
91 | #define MT9M111_COLOR_MATRIX_BYPASS (1 << 4) | ||
92 | #define MT9M111_SEL_CONTEXT_B (1 << 3) | ||
93 | |||
94 | #define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1) | ||
95 | #define MT9M111_SOC_SOFT_STANDBY (1 << 0) | ||
96 | |||
97 | #define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) | ||
98 | |||
77 | #define INITIAL_MAX_GAIN 64 | 99 | #define INITIAL_MAX_GAIN 64 |
78 | #define DEFAULT_GAIN 283 | 100 | #define MT9M111_DEFAULT_GAIN 283 |
101 | #define MT9M111_GREEN_GAIN_DEFAULT 0x20 | ||
102 | #define MT9M111_BLUE_GAIN_DEFAULT 0x20 | ||
103 | #define MT9M111_RED_GAIN_DEFAULT 0x20 | ||
79 | 104 | ||
80 | /*****************************************************************************/ | 105 | /*****************************************************************************/ |
81 | 106 | ||
@@ -85,16 +110,10 @@ extern int dump_sensor; | |||
85 | 110 | ||
86 | int mt9m111_probe(struct sd *sd); | 111 | int mt9m111_probe(struct sd *sd); |
87 | int mt9m111_init(struct sd *sd); | 112 | int mt9m111_init(struct sd *sd); |
88 | int mt9m111_power_down(struct sd *sd); | 113 | int mt9m111_start(struct sd *sd); |
114 | void mt9m111_disconnect(struct sd *sd); | ||
89 | 115 | ||
90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 116 | static const struct m5602_sensor mt9m111 = { |
91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | |||
97 | const static struct m5602_sensor mt9m111 = { | ||
98 | .name = "MT9M111", | 117 | .name = "MT9M111", |
99 | 118 | ||
100 | .i2c_slave_id = 0xba, | 119 | .i2c_slave_id = 0xba, |
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = { | |||
102 | 121 | ||
103 | .probe = mt9m111_probe, | 122 | .probe = mt9m111_probe, |
104 | .init = mt9m111_init, | 123 | .init = mt9m111_init, |
105 | .power_down = mt9m111_power_down | 124 | .disconnect = mt9m111_disconnect, |
125 | .start = mt9m111_start, | ||
106 | }; | 126 | }; |
107 | 127 | ||
108 | static const unsigned char preinit_mt9m111[][4] = | 128 | static const unsigned char preinit_mt9m111[][4] = |
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] = | |||
117 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 137 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
118 | 138 | ||
119 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 139 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
120 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | 140 | {SENSOR, MT9M111_SC_RESET, |
141 | MT9M111_RESET | | ||
142 | MT9M111_RESTART | | ||
143 | MT9M111_ANALOG_STANDBY | | ||
144 | MT9M111_CHIP_DISABLE, | ||
145 | MT9M111_SHOW_BAD_FRAMES | | ||
146 | MT9M111_RESTART_BAD_FRAMES | | ||
147 | MT9M111_SYNCHRONIZE_CHANGES}, | ||
121 | 148 | ||
122 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | 149 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, |
123 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 150 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] = | |||
145 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
146 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
147 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 174 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
148 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, | ||
149 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 175 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
152 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
153 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
154 | |||
155 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
156 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
157 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
158 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xde}, | ||
159 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
160 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | ||
161 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
162 | 176 | ||
163 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
164 | |||
165 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff}, | ||
166 | |||
167 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
168 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
169 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
171 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
172 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
182 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 177 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
186 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 178 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
187 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
188 | |||
189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
192 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
193 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
194 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
195 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
196 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
197 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
198 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
199 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
200 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
201 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
203 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
204 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
205 | |||
206 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
207 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
208 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
209 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
210 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
211 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
212 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
213 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
214 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
215 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
216 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
217 | {SENSOR, 0x33, 0x03, 0x49}, | ||
218 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
219 | |||
220 | {SENSOR, 0x33, 0x03, 0x49}, | ||
221 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
222 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
223 | {SENSOR, 0x40, 0x20, 0x20}, | ||
224 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
225 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
226 | {SENSOR, 0x71, 0xff, 0x00}, | ||
227 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
228 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
229 | {SENSOR, 0x74, 0x57, 0x32}, | ||
230 | {SENSOR, 0x75, 0x56, 0x34}, | ||
231 | {SENSOR, 0x76, 0x73, 0x35}, | ||
232 | {SENSOR, 0x77, 0x30, 0x12}, | ||
233 | {SENSOR, 0x78, 0x79, 0x02}, | ||
234 | {SENSOR, 0x79, 0x75, 0x06}, | ||
235 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
236 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
237 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
238 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
239 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
240 | {SENSOR, 0x80, 0x59, 0x04}, | ||
241 | {SENSOR, 0x81, 0x59, 0x04}, | ||
242 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
243 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
244 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
245 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
246 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
247 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
248 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
249 | {SENSOR, 0x60, 0x00, 0x80}, | ||
250 | {SENSOR, 0x61, 0x00, 0x00}, | ||
251 | {SENSOR, 0x62, 0x00, 0x00}, | ||
252 | {SENSOR, 0x63, 0x00, 0x00}, | ||
253 | {SENSOR, 0x64, 0x00, 0x00}, | ||
254 | |||
255 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
256 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
257 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
258 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
259 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
260 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
261 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
262 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
263 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
264 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
265 | {SENSOR, 0x30, 0x04, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
269 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
270 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
271 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
272 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
273 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
276 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
281 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
282 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
283 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
285 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
291 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
292 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
293 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
294 | |||
295 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
296 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
297 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
299 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
300 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
301 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
302 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
303 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
304 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
305 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
307 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
308 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
309 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
310 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
311 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
312 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
314 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
315 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
316 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
319 | |||
320 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
321 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
322 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
323 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
324 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
325 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
326 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
327 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
328 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
329 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 179 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
331 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
332 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | 180 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, |
333 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
334 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
335 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | 181 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, |
336 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
337 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
338 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
339 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
340 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
341 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
342 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
343 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
344 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
345 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
346 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
347 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
348 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
349 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
350 | |||
351 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
352 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
353 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
354 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
355 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
356 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
357 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
358 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
359 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
360 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
361 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
362 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
363 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
364 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
365 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
366 | |||
367 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
368 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
369 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
370 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
371 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
372 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
373 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
374 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
375 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
376 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
377 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
378 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
379 | {SENSOR, 0x33, 0x03, 0x49}, | ||
380 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
381 | |||
382 | {SENSOR, 0x33, 0x03, 0x49}, | ||
383 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
384 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
385 | {SENSOR, 0x40, 0x20, 0x20}, | ||
386 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
387 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
388 | {SENSOR, 0x71, 0xff, 0x00}, | ||
389 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
390 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
391 | {SENSOR, 0x74, 0x57, 0x32}, | ||
392 | {SENSOR, 0x75, 0x56, 0x34}, | ||
393 | {SENSOR, 0x76, 0x73, 0x35}, | ||
394 | {SENSOR, 0x77, 0x30, 0x12}, | ||
395 | {SENSOR, 0x78, 0x79, 0x02}, | ||
396 | {SENSOR, 0x79, 0x75, 0x06}, | ||
397 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
398 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
399 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
400 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
401 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
402 | {SENSOR, 0x80, 0x59, 0x04}, | ||
403 | {SENSOR, 0x81, 0x59, 0x04}, | ||
404 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
405 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
406 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
407 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
408 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
409 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
410 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
411 | {SENSOR, 0x60, 0x00, 0x80}, | ||
412 | {SENSOR, 0x61, 0x00, 0x00}, | ||
413 | {SENSOR, 0x62, 0x00, 0x00}, | ||
414 | {SENSOR, 0x63, 0x00, 0x00}, | ||
415 | {SENSOR, 0x64, 0x00, 0x00}, | ||
416 | |||
417 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
418 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
419 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
420 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
421 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
422 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
423 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
424 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
425 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
426 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
427 | {SENSOR, 0x30, 0x04, 0x00}, | ||
428 | |||
429 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
430 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
431 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
432 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
433 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
434 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
435 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
436 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
437 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
438 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
439 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
440 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
441 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
442 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
443 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
444 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
445 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
446 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
447 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
448 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
449 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
450 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
451 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
452 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
453 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
454 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
455 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
456 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
457 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
458 | |||
459 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
460 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
461 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
462 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
463 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
464 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
465 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
466 | |||
467 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
468 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
469 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
470 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
471 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
472 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
473 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | 182 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, |
474 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
475 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
476 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, |
477 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
478 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
479 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
480 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
481 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
482 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
483 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
484 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
485 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | 184 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, |
486 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | 185 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, |
487 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
488 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
489 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | 186 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, |
490 | 187 | ||
491 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
492 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
493 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
494 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | 188 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, |
495 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
496 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | 190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, |
497 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | 191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, |
498 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | 192 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, |
193 | MT9M111_CP_OPERATING_MODE_CTL}, | ||
499 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | 194 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, |
500 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | 195 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, |
501 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | 196 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, |
197 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, | ||
198 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, | ||
502 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | 199 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, |
503 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | 200 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, |
504 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | 201 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, |
505 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | 202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, |
506 | |||
507 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
508 | {SENSOR, 0xcd, 0x00, 0x0e}, | 203 | {SENSOR, 0xcd, 0x00, 0x0e}, |
509 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
510 | {SENSOR, 0xd0, 0x00, 0x40}, | 204 | {SENSOR, 0xd0, 0x00, 0x40}, |
511 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
512 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
513 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
514 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
515 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
516 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
517 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
518 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
519 | {SENSOR, 0x33, 0x03, 0x49}, | ||
520 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
521 | |||
522 | {SENSOR, 0x33, 0x03, 0x49}, | ||
523 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
524 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
525 | {SENSOR, 0x40, 0x20, 0x20}, | ||
526 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
527 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
528 | {SENSOR, 0x71, 0xff, 0x00}, | ||
529 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
530 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
531 | {SENSOR, 0x74, 0x57, 0x32}, | ||
532 | {SENSOR, 0x75, 0x56, 0x34}, | ||
533 | {SENSOR, 0x76, 0x73, 0x35}, | ||
534 | {SENSOR, 0x77, 0x30, 0x12}, | ||
535 | {SENSOR, 0x78, 0x79, 0x02}, | ||
536 | {SENSOR, 0x79, 0x75, 0x06}, | ||
537 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
538 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
539 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
540 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
541 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
542 | {SENSOR, 0x80, 0x59, 0x04}, | ||
543 | {SENSOR, 0x81, 0x59, 0x04}, | ||
544 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
545 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
546 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
547 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
548 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
549 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
550 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
551 | {SENSOR, 0x60, 0x00, 0x80}, | ||
552 | {SENSOR, 0x61, 0x00, 0x00}, | ||
553 | {SENSOR, 0x62, 0x00, 0x00}, | ||
554 | {SENSOR, 0x63, 0x00, 0x00}, | ||
555 | {SENSOR, 0x64, 0x00, 0x00}, | ||
556 | 205 | ||
557 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
558 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
559 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
560 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
561 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
562 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
563 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
564 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
565 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
566 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
567 | {SENSOR, 0x30, 0x04, 0x00}, | ||
568 | |||
569 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
570 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
571 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
572 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
573 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
574 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
575 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
576 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
577 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
578 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
579 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
580 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
581 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
582 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
583 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
584 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
585 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
586 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
587 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
588 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
589 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
590 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
591 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
592 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
593 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
594 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
595 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
596 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
597 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
598 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
599 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
600 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
601 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
602 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
603 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
604 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
605 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
606 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
607 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
608 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
609 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
610 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
611 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
612 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
613 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
614 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
615 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
616 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
617 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
618 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
619 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
620 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
621 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
622 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
623 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
624 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
625 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
626 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
627 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
628 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
629 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
630 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
631 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
632 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
633 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
634 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
635 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
636 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
637 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
638 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
639 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
640 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
641 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
642 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
643 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
644 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
645 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
646 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
647 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
648 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
649 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
650 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
651 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
652 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
653 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
654 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
655 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
656 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
657 | |||
658 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
659 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
660 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
661 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
662 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
663 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
664 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
665 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
666 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
667 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
668 | |||
669 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
670 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
671 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
672 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
673 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
674 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
675 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
676 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
677 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | 206 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, |
678 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | 207 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, |
679 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
680 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
681 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
682 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
683 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
684 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
685 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
686 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | 208 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, |
687 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
688 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
689 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
690 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
691 | {SENSOR, 0x33, 0x03, 0x49}, | ||
692 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
693 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
694 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
695 | |||
696 | {SENSOR, 0x33, 0x03, 0x49}, | ||
697 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
698 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
699 | {SENSOR, 0x40, 0x20, 0x20}, | ||
700 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
701 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
702 | {SENSOR, 0x71, 0xff, 0x00}, | ||
703 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
704 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
705 | {SENSOR, 0x74, 0x57, 0x32}, | ||
706 | {SENSOR, 0x75, 0x56, 0x34}, | ||
707 | {SENSOR, 0x76, 0x73, 0x35}, | ||
708 | {SENSOR, 0x77, 0x30, 0x12}, | ||
709 | {SENSOR, 0x78, 0x79, 0x02}, | ||
710 | {SENSOR, 0x79, 0x75, 0x06}, | ||
711 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
712 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
713 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
714 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
715 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
716 | {SENSOR, 0x80, 0x59, 0x04}, | ||
717 | {SENSOR, 0x81, 0x59, 0x04}, | ||
718 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
719 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
720 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
721 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
722 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
723 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
724 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
725 | {SENSOR, 0x60, 0x00, 0x80}, | ||
726 | {SENSOR, 0x61, 0x00, 0x00}, | ||
727 | {SENSOR, 0x62, 0x00, 0x00}, | ||
728 | {SENSOR, 0x63, 0x00, 0x00}, | ||
729 | {SENSOR, 0x64, 0x00, 0x00}, | ||
730 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
731 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | ||
732 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | ||
733 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | ||
734 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | ||
735 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
736 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | ||
737 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
738 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | ||
739 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
740 | {SENSOR, 0x30, 0x04, 0x00}, | ||
741 | |||
742 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
743 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
744 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
745 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
746 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
747 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
748 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
749 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
750 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
751 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
752 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
753 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
754 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00}, | ||
755 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
756 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
757 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
758 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
759 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
760 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
761 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
762 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
763 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
764 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
765 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
766 | |||
767 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
768 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
769 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6}, | ||
770 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
771 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
772 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
773 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
774 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
775 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
776 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
777 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
778 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
779 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
780 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
781 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
782 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
783 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
784 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
785 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
786 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
787 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
788 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
789 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
790 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
791 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
792 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
793 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
794 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
795 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
796 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
797 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
798 | 209 | ||
799 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
800 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
801 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
802 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
803 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
804 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
805 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
806 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
807 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
808 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
809 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
810 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
811 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
812 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
813 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
814 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
815 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
816 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
817 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
818 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
819 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
820 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
821 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
822 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
823 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
824 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
825 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 210 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
826 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
827 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
828 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
829 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
830 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
831 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
832 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
833 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
834 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
835 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
836 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
837 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
838 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
839 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
840 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
841 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
842 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
843 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
844 | |||
845 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
846 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
847 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
848 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
849 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
850 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
851 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
852 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
853 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
854 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
855 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
856 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
857 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
858 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
859 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
860 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
861 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
862 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
863 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
864 | |||
865 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
866 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
867 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
868 | {SENSOR, 0x33, 0x03, 0x49}, | ||
869 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
870 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
871 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
872 | |||
873 | {SENSOR, 0x33, 0x03, 0x49}, | 211 | {SENSOR, 0x33, 0x03, 0x49}, |
874 | {SENSOR, 0x34, 0xc0, 0x19}, | 212 | {SENSOR, 0x34, 0xc0, 0x19}, |
875 | {SENSOR, 0x3f, 0x20, 0x20}, | 213 | {SENSOR, 0x3f, 0x20, 0x20}, |
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] = | |||
898 | {SENSOR, 0x85, 0x48, 0x0e}, | 236 | {SENSOR, 0x85, 0x48, 0x0e}, |
899 | {SENSOR, 0x86, 0x5b, 0x02}, | 237 | {SENSOR, 0x86, 0x5b, 0x02}, |
900 | {SENSOR, 0x87, 0x00, 0x5c}, | 238 | {SENSOR, 0x87, 0x00, 0x5c}, |
901 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | 239 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B}, |
902 | {SENSOR, 0x60, 0x00, 0x80}, | 240 | {SENSOR, 0x60, 0x00, 0x80}, |
903 | {SENSOR, 0x61, 0x00, 0x00}, | 241 | {SENSOR, 0x61, 0x00, 0x00}, |
904 | {SENSOR, 0x62, 0x00, 0x00}, | 242 | {SENSOR, 0x62, 0x00, 0x00}, |
905 | {SENSOR, 0x63, 0x00, 0x00}, | 243 | {SENSOR, 0x63, 0x00, 0x00}, |
906 | {SENSOR, 0x64, 0x00, 0x00}, | 244 | {SENSOR, 0x64, 0x00, 0x00}, |
907 | 245 | ||
908 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | 246 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */ |
909 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | 247 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */ |
910 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | 248 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */ |
911 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | 249 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */ |
912 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | 250 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */ |
913 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | 251 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */ |
914 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | 252 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */ |
915 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | 253 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */ |
916 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | 254 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */ |
917 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
918 | {SENSOR, 0x30, 0x04, 0x00}, | 255 | {SENSOR, 0x30, 0x04, 0x00}, |
256 | /* Set number of blank rows chosen to 400 */ | ||
257 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
258 | }; | ||
919 | 259 | ||
260 | static const unsigned char start_mt9m111[][4] = | ||
261 | { | ||
920 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 262 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
921 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 263 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
922 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 264 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] = | |||
928 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 270 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
929 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 271 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
930 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 272 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
931 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
932 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | ||
933 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
934 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
935 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
936 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
937 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
938 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
939 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/ | ||
940 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
941 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
942 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
943 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
944 | |||
945 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
946 | /* Set number of blank rows chosen to 400 */ | ||
947 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
948 | /* Set the global gain to 283 (of 512) */ | ||
949 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63} | ||
950 | }; | 273 | }; |
951 | 274 | ||
952 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c new file mode 100644 index 000000000000..7aafeb7cfa07 --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include "m5602_ov7660.h" | ||
20 | |||
21 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | |||
24 | const static struct ctrl ov7660_ctrls[] = { | ||
25 | #define GAIN_IDX 1 | ||
26 | { | ||
27 | { | ||
28 | .id = V4L2_CID_GAIN, | ||
29 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
30 | .name = "gain", | ||
31 | .minimum = 0x00, | ||
32 | .maximum = 0xff, | ||
33 | .step = 0x1, | ||
34 | .default_value = OV7660_DEFAULT_GAIN, | ||
35 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
36 | }, | ||
37 | .set = ov7660_set_gain, | ||
38 | .get = ov7660_get_gain | ||
39 | }, | ||
40 | }; | ||
41 | |||
42 | static struct v4l2_pix_format ov7660_modes[] = { | ||
43 | { | ||
44 | 640, | ||
45 | 480, | ||
46 | V4L2_PIX_FMT_SBGGR8, | ||
47 | V4L2_FIELD_NONE, | ||
48 | .sizeimage = | ||
49 | 640 * 480, | ||
50 | .bytesperline = 640, | ||
51 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
52 | .priv = 0 | ||
53 | } | ||
54 | }; | ||
55 | |||
56 | static void ov7660_dump_registers(struct sd *sd); | ||
57 | |||
58 | int ov7660_probe(struct sd *sd) | ||
59 | { | ||
60 | int err = 0, i; | ||
61 | u8 prod_id = 0, ver_id = 0; | ||
62 | |||
63 | s32 *sensor_settings; | ||
64 | |||
65 | if (force_sensor) { | ||
66 | if (force_sensor == OV7660_SENSOR) { | ||
67 | info("Forcing an %s sensor", ov7660.name); | ||
68 | goto sensor_found; | ||
69 | } | ||
70 | /* If we want to force another sensor, | ||
71 | don't try to probe this one */ | ||
72 | return -ENODEV; | ||
73 | } | ||
74 | |||
75 | /* Do the preinit */ | ||
76 | for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { | ||
77 | u8 data[2]; | ||
78 | |||
79 | if (preinit_ov7660[i][0] == BRIDGE) { | ||
80 | err = m5602_write_bridge(sd, | ||
81 | preinit_ov7660[i][1], | ||
82 | preinit_ov7660[i][2]); | ||
83 | } else { | ||
84 | data[0] = preinit_ov7660[i][2]; | ||
85 | err = m5602_write_sensor(sd, | ||
86 | preinit_ov7660[i][1], data, 1); | ||
87 | } | ||
88 | } | ||
89 | if (err < 0) | ||
90 | return err; | ||
91 | |||
92 | if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) | ||
96 | return -ENODEV; | ||
97 | |||
98 | info("Sensor reported 0x%x%x", prod_id, ver_id); | ||
99 | |||
100 | if ((prod_id == 0x76) && (ver_id == 0x60)) { | ||
101 | info("Detected a ov7660 sensor"); | ||
102 | goto sensor_found; | ||
103 | } | ||
104 | return -ENODEV; | ||
105 | |||
106 | sensor_found: | ||
107 | sensor_settings = kmalloc( | ||
108 | ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); | ||
109 | if (!sensor_settings) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | sd->gspca_dev.cam.cam_mode = ov7660_modes; | ||
113 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); | ||
114 | sd->desc->ctrls = ov7660_ctrls; | ||
115 | sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); | ||
116 | |||
117 | for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) | ||
118 | sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; | ||
119 | sd->sensor_priv = sensor_settings; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int ov7660_init(struct sd *sd) | ||
125 | { | ||
126 | int i, err = 0; | ||
127 | s32 *sensor_settings = sd->sensor_priv; | ||
128 | |||
129 | /* Init the sensor */ | ||
130 | for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { | ||
131 | u8 data[2]; | ||
132 | |||
133 | if (init_ov7660[i][0] == BRIDGE) { | ||
134 | err = m5602_write_bridge(sd, | ||
135 | init_ov7660[i][1], | ||
136 | init_ov7660[i][2]); | ||
137 | } else { | ||
138 | data[0] = init_ov7660[i][2]; | ||
139 | err = m5602_write_sensor(sd, | ||
140 | init_ov7660[i][1], data, 1); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (dump_sensor) | ||
145 | ov7660_dump_registers(sd); | ||
146 | |||
147 | err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
148 | if (err < 0) | ||
149 | return err; | ||
150 | |||
151 | return err; | ||
152 | } | ||
153 | |||
154 | int ov7660_start(struct sd *sd) | ||
155 | { | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int ov7660_stop(struct sd *sd) | ||
160 | { | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | void ov7660_disconnect(struct sd *sd) | ||
165 | { | ||
166 | ov7660_stop(sd); | ||
167 | |||
168 | sd->sensor = NULL; | ||
169 | kfree(sd->sensor_priv); | ||
170 | } | ||
171 | |||
172 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
173 | { | ||
174 | struct sd *sd = (struct sd *) gspca_dev; | ||
175 | s32 *sensor_settings = sd->sensor_priv; | ||
176 | |||
177 | *val = sensor_settings[GAIN_IDX]; | ||
178 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
183 | { | ||
184 | int err; | ||
185 | u8 i2c_data; | ||
186 | struct sd *sd = (struct sd *) gspca_dev; | ||
187 | s32 *sensor_settings = sd->sensor_priv; | ||
188 | |||
189 | PDEBUG(D_V4L2, "Setting gain to %d", val); | ||
190 | |||
191 | sensor_settings[GAIN_IDX] = val; | ||
192 | |||
193 | err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); | ||
194 | return err; | ||
195 | } | ||
196 | |||
197 | static void ov7660_dump_registers(struct sd *sd) | ||
198 | { | ||
199 | int address; | ||
200 | info("Dumping the ov7660 register state"); | ||
201 | for (address = 0; address < 0xa9; address++) { | ||
202 | u8 value; | ||
203 | m5602_read_sensor(sd, address, &value, 1); | ||
204 | info("register 0x%x contains 0x%x", | ||
205 | address, value); | ||
206 | } | ||
207 | |||
208 | info("ov7660 register state dump complete"); | ||
209 | |||
210 | info("Probing for which registers that are read/write"); | ||
211 | for (address = 0; address < 0xff; address++) { | ||
212 | u8 old_value, ctrl_value; | ||
213 | u8 test_value[2] = {0xff, 0xff}; | ||
214 | |||
215 | m5602_read_sensor(sd, address, &old_value, 1); | ||
216 | m5602_write_sensor(sd, address, test_value, 1); | ||
217 | m5602_read_sensor(sd, address, &ctrl_value, 1); | ||
218 | |||
219 | if (ctrl_value == test_value[0]) | ||
220 | info("register 0x%x is writeable", address); | ||
221 | else | ||
222 | info("register 0x%x is read only", address); | ||
223 | |||
224 | /* Restore original value */ | ||
225 | m5602_write_sensor(sd, address, &old_value, 1); | ||
226 | } | ||
227 | } | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h new file mode 100644 index 000000000000..3f2c169a93ea --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #ifndef M5602_OV7660_H_ | ||
20 | #define M5602_OV7660_H_ | ||
21 | |||
22 | #include "m5602_sensor.h" | ||
23 | |||
24 | #define OV7660_GAIN 0x00 | ||
25 | #define OV7660_BLUE_GAIN 0x01 | ||
26 | #define OV7660_RED_GAIN 0x02 | ||
27 | #define OV7660_VREF 0x03 | ||
28 | #define OV7660_COM1 0x04 | ||
29 | #define OV7660_BAVE 0x05 | ||
30 | #define OV7660_GEAVE 0x06 | ||
31 | #define OV7660_AECHH 0x07 | ||
32 | #define OV7660_RAVE 0x08 | ||
33 | #define OV7660_COM2 0x09 | ||
34 | #define OV7660_PID 0x0a | ||
35 | #define OV7660_VER 0x0b | ||
36 | #define OV7660_COM3 0x0c | ||
37 | #define OV7660_COM4 0x0d | ||
38 | #define OV7660_COM5 0x0e | ||
39 | #define OV7660_COM6 0x0f | ||
40 | #define OV7660_AECH 0x10 | ||
41 | #define OV7660_CLKRC 0x11 | ||
42 | #define OV7660_COM7 0x12 | ||
43 | #define OV7660_COM8 0x13 | ||
44 | #define OV7660_COM9 0x14 | ||
45 | #define OV7660_COM10 0x15 | ||
46 | #define OV7660_RSVD16 0x16 | ||
47 | #define OV7660_HSTART 0x17 | ||
48 | #define OV7660_HSTOP 0x18 | ||
49 | #define OV7660_VSTART 0x19 | ||
50 | #define OV7660_VSTOP 0x1a | ||
51 | #define OV7660_PSHFT 0x1b | ||
52 | #define OV7660_MIDH 0x1c | ||
53 | #define OV7660_MIDL 0x1d | ||
54 | #define OV7660_MVFP 0x1e | ||
55 | #define OV7660_LAEC 0x1f | ||
56 | #define OV7660_BOS 0x20 | ||
57 | #define OV7660_GBOS 0x21 | ||
58 | #define OV7660_GROS 0x22 | ||
59 | #define OV7660_ROS 0x23 | ||
60 | #define OV7660_AEW 0x24 | ||
61 | #define OV7660_AEB 0x25 | ||
62 | #define OV7660_VPT 0x26 | ||
63 | #define OV7660_BBIAS 0x27 | ||
64 | #define OV7660_GbBIAS 0x28 | ||
65 | #define OV7660_RSVD29 0x29 | ||
66 | #define OV7660_RBIAS 0x2c | ||
67 | #define OV7660_HREF 0x32 | ||
68 | #define OV7660_ADC 0x37 | ||
69 | #define OV7660_OFON 0x39 | ||
70 | #define OV7660_TSLB 0x3a | ||
71 | #define OV7660_COM12 0x3c | ||
72 | #define OV7660_COM13 0x3d | ||
73 | #define OV7660_LCC1 0x62 | ||
74 | #define OV7660_LCC2 0x63 | ||
75 | #define OV7660_LCC3 0x64 | ||
76 | #define OV7660_LCC4 0x65 | ||
77 | #define OV7660_LCC5 0x66 | ||
78 | #define OV7660_HV 0x69 | ||
79 | #define OV7660_RSVDA1 0xa1 | ||
80 | |||
81 | #define OV7660_DEFAULT_GAIN 0x0e | ||
82 | #define OV7660_DEFAULT_RED_GAIN 0x80 | ||
83 | #define OV7660_DEFAULT_BLUE_GAIN 0x80 | ||
84 | #define OV7660_DEFAULT_SATURATION 0x00 | ||
85 | #define OV7660_DEFAULT_EXPOSURE 0x20 | ||
86 | |||
87 | /* Kernel module parameters */ | ||
88 | extern int force_sensor; | ||
89 | extern int dump_sensor; | ||
90 | |||
91 | int ov7660_probe(struct sd *sd); | ||
92 | int ov7660_init(struct sd *sd); | ||
93 | int ov7660_start(struct sd *sd); | ||
94 | int ov7660_stop(struct sd *sd); | ||
95 | void ov7660_disconnect(struct sd *sd); | ||
96 | |||
97 | const static struct m5602_sensor ov7660 = { | ||
98 | .name = "ov7660", | ||
99 | .i2c_slave_id = 0x42, | ||
100 | .i2c_regW = 1, | ||
101 | .probe = ov7660_probe, | ||
102 | .init = ov7660_init, | ||
103 | .start = ov7660_start, | ||
104 | .stop = ov7660_stop, | ||
105 | .disconnect = ov7660_disconnect, | ||
106 | }; | ||
107 | |||
108 | static const unsigned char preinit_ov7660[][4] = | ||
109 | { | ||
110 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
111 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
112 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
113 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
114 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
115 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
116 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
117 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
118 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
119 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
120 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
121 | |||
122 | {SENSOR, OV7660_OFON, 0x0c}, | ||
123 | {SENSOR, OV7660_COM2, 0x11}, | ||
124 | {SENSOR, OV7660_COM7, 0x05}, | ||
125 | |||
126 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
127 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
128 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
129 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
130 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
133 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
134 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
135 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
136 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
137 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
138 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
139 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
140 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} | ||
141 | }; | ||
142 | |||
143 | static const unsigned char init_ov7660[][4] = | ||
144 | { | ||
145 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
146 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
147 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
148 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
149 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
150 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
152 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
153 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
154 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
155 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
156 | |||
157 | {SENSOR, OV7660_OFON, 0x0c}, | ||
158 | {SENSOR, OV7660_COM2, 0x11}, | ||
159 | {SENSOR, OV7660_COM7, 0x05}, | ||
160 | |||
161 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
162 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
163 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
164 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
165 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
166 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
167 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
168 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
169 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
170 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
171 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
175 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
179 | |||
180 | {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE}, | ||
181 | {SENSOR, OV7660_COM1, 0x00}, | ||
182 | |||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
186 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
187 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
188 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
189 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
190 | |||
191 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
193 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
194 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
195 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
196 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
197 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
198 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
199 | |||
200 | {SENSOR, OV7660_COM7, 0x80}, | ||
201 | {SENSOR, OV7660_CLKRC, 0x80}, | ||
202 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
203 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
204 | {SENSOR, OV7660_COM9, 0x4c}, | ||
205 | {SENSOR, OV7660_OFON, 0x43}, | ||
206 | {SENSOR, OV7660_COM12, 0x28}, | ||
207 | {SENSOR, OV7660_COM8, 0x00}, | ||
208 | {SENSOR, OV7660_COM10, 0x40}, | ||
209 | {SENSOR, OV7660_HSTART, 0x0c}, | ||
210 | {SENSOR, OV7660_HSTOP, 0x61}, | ||
211 | {SENSOR, OV7660_HREF, 0xa4}, | ||
212 | {SENSOR, OV7660_PSHFT, 0x0b}, | ||
213 | {SENSOR, OV7660_VSTART, 0x01}, | ||
214 | {SENSOR, OV7660_VSTOP, 0x7a}, | ||
215 | {SENSOR, OV7660_VREF, 0x00}, | ||
216 | {SENSOR, OV7660_COM7, 0x05}, | ||
217 | {SENSOR, OV7660_COM6, 0x4b}, | ||
218 | {SENSOR, OV7660_BBIAS, 0x98}, | ||
219 | {SENSOR, OV7660_GbBIAS, 0x98}, | ||
220 | {SENSOR, OV7660_RSVD29, 0x98}, | ||
221 | {SENSOR, OV7660_RBIAS, 0x98}, | ||
222 | {SENSOR, OV7660_COM1, 0x00}, | ||
223 | {SENSOR, OV7660_AECH, 0x00}, | ||
224 | {SENSOR, OV7660_AECHH, 0x00}, | ||
225 | {SENSOR, OV7660_ADC, 0x04}, | ||
226 | {SENSOR, OV7660_COM13, 0x00}, | ||
227 | {SENSOR, OV7660_RSVDA1, 0x23}, | ||
228 | {SENSOR, OV7660_TSLB, 0x0d}, | ||
229 | {SENSOR, OV7660_HV, 0x80}, | ||
230 | {SENSOR, OV7660_LCC1, 0x00}, | ||
231 | {SENSOR, OV7660_LCC2, 0x00}, | ||
232 | {SENSOR, OV7660_LCC3, 0x10}, | ||
233 | {SENSOR, OV7660_LCC4, 0x40}, | ||
234 | {SENSOR, OV7660_LCC5, 0x01}, | ||
235 | |||
236 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
237 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
238 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
239 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
240 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
241 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
242 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
243 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
244 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x08}, | ||
245 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
246 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
247 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */ | ||
249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
251 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */ | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */ | ||
257 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
258 | |||
259 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
261 | |||
262 | {SENSOR, OV7660_AECH, 0x20}, | ||
263 | {SENSOR, OV7660_COM1, 0x00}, | ||
264 | {SENSOR, OV7660_OFON, 0x0c}, | ||
265 | {SENSOR, OV7660_COM2, 0x11}, | ||
266 | {SENSOR, OV7660_COM7, 0x05}, | ||
267 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
268 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
269 | |||
270 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
271 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
272 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
273 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
275 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
276 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} | ||
277 | }; | ||
278 | |||
279 | #endif | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index fc4548fd441d..c2739d6605a1 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -18,44 +18,87 @@ | |||
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | 20 | ||
21 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
34 | __s32 *val); | ||
35 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
38 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
39 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
40 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
41 | |||
21 | /* Vertically and horizontally flips the image if matched, needed for machines | 42 | /* Vertically and horizontally flips the image if matched, needed for machines |
22 | where the sensor is mounted upside down */ | 43 | where the sensor is mounted upside down */ |
23 | static | 44 | static |
24 | const | 45 | const |
25 | struct dmi_system_id ov9650_flip_dmi_table[] = { | 46 | struct dmi_system_id ov9650_flip_dmi_table[] = { |
26 | { | 47 | { |
27 | .ident = "ASUS A6VC", | 48 | .ident = "ASUS A6Ja", |
28 | .matches = { | 49 | .matches = { |
29 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
30 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") |
31 | } | 52 | } |
32 | }, | 53 | }, |
33 | { | 54 | { |
34 | .ident = "ASUS A6VM", | 55 | .ident = "ASUS A6JC", |
35 | .matches = { | 56 | .matches = { |
36 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
37 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | 58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") |
38 | } | 59 | } |
39 | }, | 60 | }, |
40 | { | 61 | { |
41 | .ident = "ASUS A6JC", | 62 | .ident = "ASUS A6K", |
42 | .matches = { | 63 | .matches = { |
43 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 64 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
44 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") | 65 | DMI_MATCH(DMI_PRODUCT_NAME, "A6K") |
45 | } | 66 | } |
46 | }, | 67 | }, |
47 | { | 68 | { |
48 | .ident = "ASUS A6Ja", | 69 | .ident = "ASUS A6Kt", |
49 | .matches = { | 70 | .matches = { |
50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 71 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") | 72 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") |
52 | } | 73 | } |
53 | }, | 74 | }, |
54 | { | 75 | { |
55 | .ident = "ASUS A6Kt", | 76 | .ident = "ASUS A6VA", |
56 | .matches = { | 77 | .matches = { |
57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 78 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") | 79 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") |
80 | } | ||
81 | }, | ||
82 | { | ||
83 | |||
84 | .ident = "ASUS A6VC", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | ||
88 | } | ||
89 | }, | ||
90 | { | ||
91 | .ident = "ASUS A6VM", | ||
92 | .matches = { | ||
93 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
94 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | ||
95 | } | ||
96 | }, | ||
97 | { | ||
98 | .ident = "ASUS A7V", | ||
99 | .matches = { | ||
100 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
101 | DMI_MATCH(DMI_PRODUCT_NAME, "A7V") | ||
59 | } | 102 | } |
60 | }, | 103 | }, |
61 | { | 104 | { |
@@ -68,7 +111,7 @@ static | |||
68 | {} | 111 | {} |
69 | }; | 112 | }; |
70 | 113 | ||
71 | const static struct ctrl ov9650_ctrls[] = { | 114 | static const struct ctrl ov9650_ctrls[] = { |
72 | #define EXPOSURE_IDX 0 | 115 | #define EXPOSURE_IDX 0 |
73 | { | 116 | { |
74 | { | 117 | { |
@@ -102,6 +145,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
102 | #define RED_BALANCE_IDX 2 | 145 | #define RED_BALANCE_IDX 2 |
103 | { | 146 | { |
104 | { | 147 | { |
148 | .id = V4L2_CID_RED_BALANCE, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | 149 | .type = V4L2_CTRL_TYPE_INTEGER, |
106 | .name = "red balance", | 150 | .name = "red balance", |
107 | .minimum = 0x00, | 151 | .minimum = 0x00, |
@@ -116,6 +160,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
116 | #define BLUE_BALANCE_IDX 3 | 160 | #define BLUE_BALANCE_IDX 3 |
117 | { | 161 | { |
118 | { | 162 | { |
163 | .id = V4L2_CID_BLUE_BALANCE, | ||
119 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
120 | .name = "blue balance", | 165 | .name = "blue balance", |
121 | .minimum = 0x00, | 166 | .minimum = 0x00, |
@@ -182,7 +227,22 @@ const static struct ctrl ov9650_ctrls[] = { | |||
182 | }, | 227 | }, |
183 | .set = ov9650_set_auto_gain, | 228 | .set = ov9650_set_auto_gain, |
184 | .get = ov9650_get_auto_gain | 229 | .get = ov9650_get_auto_gain |
230 | }, | ||
231 | #define AUTO_EXPOSURE_IDX 8 | ||
232 | { | ||
233 | { | ||
234 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
235 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
236 | .name = "auto exposure", | ||
237 | .minimum = 0, | ||
238 | .maximum = 1, | ||
239 | .step = 1, | ||
240 | .default_value = 1 | ||
241 | }, | ||
242 | .set = ov9650_set_auto_exposure, | ||
243 | .get = ov9650_get_auto_exposure | ||
185 | } | 244 | } |
245 | |||
186 | }; | 246 | }; |
187 | 247 | ||
188 | static struct v4l2_pix_format ov9650_modes[] = { | 248 | static struct v4l2_pix_format ov9650_modes[] = { |
@@ -289,12 +349,6 @@ sensor_found: | |||
289 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) | 349 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) |
290 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; | 350 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; |
291 | sd->sensor_priv = sensor_settings; | 351 | sd->sensor_priv = sensor_settings; |
292 | |||
293 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { | ||
294 | info("vflip quirk active"); | ||
295 | sensor_settings[VFLIP_IDX] = 1; | ||
296 | } | ||
297 | |||
298 | return 0; | 352 | return 0; |
299 | } | 353 | } |
300 | 354 | ||
@@ -316,7 +370,8 @@ int ov9650_init(struct sd *sd) | |||
316 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); | 370 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); |
317 | } | 371 | } |
318 | 372 | ||
319 | err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); | 373 | err = ov9650_set_exposure(&sd->gspca_dev, |
374 | sensor_settings[EXPOSURE_IDX]); | ||
320 | if (err < 0) | 375 | if (err < 0) |
321 | return err; | 376 | return err; |
322 | 377 | ||
@@ -324,11 +379,13 @@ int ov9650_init(struct sd *sd) | |||
324 | if (err < 0) | 379 | if (err < 0) |
325 | return err; | 380 | return err; |
326 | 381 | ||
327 | err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); | 382 | err = ov9650_set_red_balance(&sd->gspca_dev, |
383 | sensor_settings[RED_BALANCE_IDX]); | ||
328 | if (err < 0) | 384 | if (err < 0) |
329 | return err; | 385 | return err; |
330 | 386 | ||
331 | err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); | 387 | err = ov9650_set_blue_balance(&sd->gspca_dev, |
388 | sensor_settings[BLUE_BALANCE_IDX]); | ||
332 | if (err < 0) | 389 | if (err < 0) |
333 | return err; | 390 | return err; |
334 | 391 | ||
@@ -340,11 +397,18 @@ int ov9650_init(struct sd *sd) | |||
340 | if (err < 0) | 397 | if (err < 0) |
341 | return err; | 398 | return err; |
342 | 399 | ||
343 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); | 400 | err = ov9650_set_auto_exposure(&sd->gspca_dev, |
401 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
402 | if (err < 0) | ||
403 | return err; | ||
404 | |||
405 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, | ||
406 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
344 | if (err < 0) | 407 | if (err < 0) |
345 | return err; | 408 | return err; |
346 | 409 | ||
347 | err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); | 410 | err = ov9650_set_auto_gain(&sd->gspca_dev, |
411 | sensor_settings[AUTO_GAIN_CTRL_IDX]); | ||
348 | return err; | 412 | return err; |
349 | } | 413 | } |
350 | 414 | ||
@@ -360,7 +424,10 @@ int ov9650_start(struct sd *sd) | |||
360 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | 424 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; |
361 | int hor_offs = OV9650_LEFT_OFFSET; | 425 | int hor_offs = OV9650_LEFT_OFFSET; |
362 | 426 | ||
363 | if (sensor_settings[VFLIP_IDX]) | 427 | if ((!dmi_check_system(ov9650_flip_dmi_table) && |
428 | sensor_settings[VFLIP_IDX]) || | ||
429 | (dmi_check_system(ov9650_flip_dmi_table) && | ||
430 | !sensor_settings[VFLIP_IDX])) | ||
364 | ver_offs--; | 431 | ver_offs--; |
365 | 432 | ||
366 | if (width <= 320) | 433 | if (width <= 320) |
@@ -406,6 +473,14 @@ int ov9650_start(struct sd *sd) | |||
406 | if (err < 0) | 473 | if (err < 0) |
407 | return err; | 474 | return err; |
408 | 475 | ||
476 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
477 | if (err < 0) | ||
478 | return err; | ||
479 | |||
480 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
481 | if (err < 0) | ||
482 | return err; | ||
483 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | 484 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, |
410 | (hor_offs >> 8) & 0xff); | 485 | (hor_offs >> 8) & 0xff); |
411 | if (err < 0) | 486 | if (err < 0) |
@@ -425,6 +500,10 @@ int ov9650_start(struct sd *sd) | |||
425 | if (err < 0) | 500 | if (err < 0) |
426 | return err; | 501 | return err; |
427 | 502 | ||
503 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | |||
428 | switch (width) { | 507 | switch (width) { |
429 | case 640: | 508 | case 640: |
430 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 509 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
@@ -467,32 +546,15 @@ int ov9650_stop(struct sd *sd) | |||
467 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); | 546 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); |
468 | } | 547 | } |
469 | 548 | ||
470 | int ov9650_power_down(struct sd *sd) | ||
471 | { | ||
472 | int i, err = 0; | ||
473 | for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) { | ||
474 | u8 data = power_down_ov9650[i][2]; | ||
475 | if (power_down_ov9650[i][0] == SENSOR) | ||
476 | err = m5602_write_sensor(sd, | ||
477 | power_down_ov9650[i][1], &data, 1); | ||
478 | else | ||
479 | err = m5602_write_bridge(sd, power_down_ov9650[i][1], | ||
480 | data); | ||
481 | } | ||
482 | |||
483 | return err; | ||
484 | } | ||
485 | |||
486 | void ov9650_disconnect(struct sd *sd) | 549 | void ov9650_disconnect(struct sd *sd) |
487 | { | 550 | { |
488 | ov9650_stop(sd); | 551 | ov9650_stop(sd); |
489 | ov9650_power_down(sd); | ||
490 | 552 | ||
491 | sd->sensor = NULL; | 553 | sd->sensor = NULL; |
492 | kfree(sd->sensor_priv); | 554 | kfree(sd->sensor_priv); |
493 | } | 555 | } |
494 | 556 | ||
495 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 557 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
496 | { | 558 | { |
497 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
498 | s32 *sensor_settings = sd->sensor_priv; | 560 | s32 *sensor_settings = sd->sensor_priv; |
@@ -502,7 +564,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
502 | return 0; | 564 | return 0; |
503 | } | 565 | } |
504 | 566 | ||
505 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 567 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
506 | { | 568 | { |
507 | struct sd *sd = (struct sd *) gspca_dev; | 569 | struct sd *sd = (struct sd *) gspca_dev; |
508 | s32 *sensor_settings = sd->sensor_priv; | 570 | s32 *sensor_settings = sd->sensor_priv; |
@@ -532,7 +594,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
532 | return err; | 594 | return err; |
533 | } | 595 | } |
534 | 596 | ||
535 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 597 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
536 | { | 598 | { |
537 | struct sd *sd = (struct sd *) gspca_dev; | 599 | struct sd *sd = (struct sd *) gspca_dev; |
538 | s32 *sensor_settings = sd->sensor_priv; | 600 | s32 *sensor_settings = sd->sensor_priv; |
@@ -542,7 +604,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
542 | return 0; | 604 | return 0; |
543 | } | 605 | } |
544 | 606 | ||
545 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 607 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
546 | { | 608 | { |
547 | int err; | 609 | int err; |
548 | u8 i2c_data; | 610 | u8 i2c_data; |
@@ -573,7 +635,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
573 | return err; | 635 | return err; |
574 | } | 636 | } |
575 | 637 | ||
576 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 638 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
577 | { | 639 | { |
578 | struct sd *sd = (struct sd *) gspca_dev; | 640 | struct sd *sd = (struct sd *) gspca_dev; |
579 | s32 *sensor_settings = sd->sensor_priv; | 641 | s32 *sensor_settings = sd->sensor_priv; |
@@ -583,7 +645,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
583 | return 0; | 645 | return 0; |
584 | } | 646 | } |
585 | 647 | ||
586 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 648 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
587 | { | 649 | { |
588 | int err; | 650 | int err; |
589 | u8 i2c_data; | 651 | u8 i2c_data; |
@@ -599,7 +661,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
599 | return err; | 661 | return err; |
600 | } | 662 | } |
601 | 663 | ||
602 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 664 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
603 | { | 665 | { |
604 | struct sd *sd = (struct sd *) gspca_dev; | 666 | struct sd *sd = (struct sd *) gspca_dev; |
605 | s32 *sensor_settings = sd->sensor_priv; | 667 | s32 *sensor_settings = sd->sensor_priv; |
@@ -610,7 +672,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
610 | return 0; | 672 | return 0; |
611 | } | 673 | } |
612 | 674 | ||
613 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 675 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
614 | { | 676 | { |
615 | int err; | 677 | int err; |
616 | u8 i2c_data; | 678 | u8 i2c_data; |
@@ -626,7 +688,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
626 | return err; | 688 | return err; |
627 | } | 689 | } |
628 | 690 | ||
629 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 691 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
630 | { | 692 | { |
631 | struct sd *sd = (struct sd *) gspca_dev; | 693 | struct sd *sd = (struct sd *) gspca_dev; |
632 | s32 *sensor_settings = sd->sensor_priv; | 694 | s32 *sensor_settings = sd->sensor_priv; |
@@ -636,7 +698,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
636 | return 0; | 698 | return 0; |
637 | } | 699 | } |
638 | 700 | ||
639 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 701 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
640 | { | 702 | { |
641 | int err; | 703 | int err; |
642 | u8 i2c_data; | 704 | u8 i2c_data; |
@@ -646,13 +708,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
646 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 708 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
647 | 709 | ||
648 | sensor_settings[HFLIP_IDX] = val; | 710 | sensor_settings[HFLIP_IDX] = val; |
649 | i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4); | 711 | |
712 | if (!dmi_check_system(ov9650_flip_dmi_table)) | ||
713 | i2c_data = ((val & 0x01) << 5) | | ||
714 | (sensor_settings[VFLIP_IDX] << 4); | ||
715 | else | ||
716 | i2c_data = ((val & 0x01) << 5) | | ||
717 | (!sensor_settings[VFLIP_IDX] << 4); | ||
718 | |||
650 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 719 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
651 | 720 | ||
652 | return err; | 721 | return err; |
653 | } | 722 | } |
654 | 723 | ||
655 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 724 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
656 | { | 725 | { |
657 | struct sd *sd = (struct sd *) gspca_dev; | 726 | struct sd *sd = (struct sd *) gspca_dev; |
658 | s32 *sensor_settings = sd->sensor_priv; | 727 | s32 *sensor_settings = sd->sensor_priv; |
@@ -663,7 +732,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
663 | return 0; | 732 | return 0; |
664 | } | 733 | } |
665 | 734 | ||
666 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 735 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
667 | { | 736 | { |
668 | int err; | 737 | int err; |
669 | u8 i2c_data; | 738 | u8 i2c_data; |
@@ -673,6 +742,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
673 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 742 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
674 | sensor_settings[VFLIP_IDX] = val; | 743 | sensor_settings[VFLIP_IDX] = val; |
675 | 744 | ||
745 | if (dmi_check_system(ov9650_flip_dmi_table)) | ||
746 | val = !val; | ||
747 | |||
676 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); | 748 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); |
677 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 749 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
678 | if (err < 0) | 750 | if (err < 0) |
@@ -685,48 +757,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
685 | return err; | 757 | return err; |
686 | } | 758 | } |
687 | 759 | ||
688 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 760 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
689 | { | 761 | { |
690 | struct sd *sd = (struct sd *) gspca_dev; | 762 | struct sd *sd = (struct sd *) gspca_dev; |
691 | s32 *sensor_settings = sd->sensor_priv; | 763 | s32 *sensor_settings = sd->sensor_priv; |
692 | 764 | ||
693 | *val = sensor_settings[GAIN_IDX]; | 765 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; |
694 | PDEBUG(D_V4L2, "Read gain %d", *val); | 766 | PDEBUG(D_V4L2, "Read auto exposure control %d", *val); |
695 | |||
696 | return 0; | 767 | return 0; |
697 | } | 768 | } |
698 | 769 | ||
699 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 770 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, |
771 | __s32 val) | ||
700 | { | 772 | { |
701 | int err; | 773 | int err; |
702 | u8 i2c_data; | 774 | u8 i2c_data; |
703 | struct sd *sd = (struct sd *) gspca_dev; | 775 | struct sd *sd = (struct sd *) gspca_dev; |
704 | s32 *sensor_settings = sd->sensor_priv; | 776 | s32 *sensor_settings = sd->sensor_priv; |
705 | 777 | ||
706 | PDEBUG(D_V4L2, "Set gain to %d", val); | 778 | PDEBUG(D_V4L2, "Set auto exposure control to %d", val); |
707 | |||
708 | sensor_settings[GAIN_IDX] = val; | ||
709 | 779 | ||
710 | /* Read the OV9650_VREF register first to avoid | 780 | sensor_settings[AUTO_EXPOSURE_IDX] = val; |
711 | corrupting the VREF high and low bits */ | 781 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
712 | err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
713 | if (err < 0) | ||
714 | return err; | ||
715 | |||
716 | /* Mask away all uninteresting bits */ | ||
717 | i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); | ||
718 | err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
719 | if (err < 0) | 782 | if (err < 0) |
720 | return err; | 783 | return err; |
721 | 784 | ||
722 | /* The 8 LSBs */ | 785 | i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); |
723 | i2c_data = val & 0xff; | ||
724 | err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); | ||
725 | 786 | ||
726 | return err; | 787 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
727 | } | 788 | } |
728 | 789 | ||
729 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 790 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, |
791 | __s32 *val) | ||
730 | { | 792 | { |
731 | struct sd *sd = (struct sd *) gspca_dev; | 793 | struct sd *sd = (struct sd *) gspca_dev; |
732 | s32 *sensor_settings = sd->sensor_priv; | 794 | s32 *sensor_settings = sd->sensor_priv; |
@@ -735,7 +797,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
735 | return 0; | 797 | return 0; |
736 | } | 798 | } |
737 | 799 | ||
738 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 800 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, |
801 | __s32 val) | ||
739 | { | 802 | { |
740 | int err; | 803 | int err; |
741 | u8 i2c_data; | 804 | u8 i2c_data; |
@@ -755,7 +818,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
755 | return err; | 818 | return err; |
756 | } | 819 | } |
757 | 820 | ||
758 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 821 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) |
759 | { | 822 | { |
760 | struct sd *sd = (struct sd *) gspca_dev; | 823 | struct sd *sd = (struct sd *) gspca_dev; |
761 | s32 *sensor_settings = sd->sensor_priv; | 824 | s32 *sensor_settings = sd->sensor_priv; |
@@ -765,7 +828,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
765 | return 0; | 828 | return 0; |
766 | } | 829 | } |
767 | 830 | ||
768 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 831 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) |
769 | { | 832 | { |
770 | int err; | 833 | int err; |
771 | u8 i2c_data; | 834 | u8 i2c_data; |
@@ -780,9 +843,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
780 | return err; | 843 | return err; |
781 | 844 | ||
782 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); | 845 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); |
783 | err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
784 | 846 | ||
785 | return err; | 847 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
786 | } | 848 | } |
787 | 849 | ||
788 | static void ov9650_dump_registers(struct sd *sd) | 850 | static void ov9650_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index fcc54e4c0f4f..c98c40d69e05 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -120,6 +120,10 @@ | |||
120 | #define OV9650_SOFT_SLEEP (1 << 4) | 120 | #define OV9650_SOFT_SLEEP (1 << 4) |
121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) | 121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) |
122 | 122 | ||
123 | #define OV9650_DENOISE_ENABLE (1 << 5) | ||
124 | #define OV9650_WHITE_PIXEL_ENABLE (1 << 1) | ||
125 | #define OV9650_WHITE_PIXEL_OPTION (1 << 0) | ||
126 | |||
123 | #define OV9650_LEFT_OFFSET 0x62 | 127 | #define OV9650_LEFT_OFFSET 0x62 |
124 | 128 | ||
125 | #define GAIN_DEFAULT 0x14 | 129 | #define GAIN_DEFAULT 0x14 |
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd); | |||
137 | int ov9650_init(struct sd *sd); | 141 | int ov9650_init(struct sd *sd); |
138 | int ov9650_start(struct sd *sd); | 142 | int ov9650_start(struct sd *sd); |
139 | int ov9650_stop(struct sd *sd); | 143 | int ov9650_stop(struct sd *sd); |
140 | int ov9650_power_down(struct sd *sd); | ||
141 | void ov9650_disconnect(struct sd *sd); | 144 | void ov9650_disconnect(struct sd *sd); |
142 | 145 | ||
143 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 146 | static const struct m5602_sensor ov9650 = { |
144 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
145 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
146 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
147 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
148 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
149 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
150 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
151 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
152 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
153 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
154 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
155 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
156 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
157 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
158 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
159 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
160 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
161 | |||
162 | const static struct m5602_sensor ov9650 = { | ||
163 | .name = "OV9650", | 147 | .name = "OV9650", |
164 | .i2c_slave_id = 0x60, | 148 | .i2c_slave_id = 0x60, |
165 | .i2c_regW = 1, | 149 | .i2c_regW = 1, |
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = { | |||
167 | .init = ov9650_init, | 151 | .init = ov9650_init, |
168 | .start = ov9650_start, | 152 | .start = ov9650_start, |
169 | .stop = ov9650_stop, | 153 | .stop = ov9650_stop, |
170 | .power_down = ov9650_power_down, | ||
171 | .disconnect = ov9650_disconnect, | 154 | .disconnect = ov9650_disconnect, |
172 | }; | 155 | }; |
173 | 156 | ||
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] = | |||
219 | /* Reset chip */ | 202 | /* Reset chip */ |
220 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 203 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
221 | /* One extra reset is needed in order to make the sensor behave | 204 | /* One extra reset is needed in order to make the sensor behave |
222 | properly when resuming from ram */ | 205 | properly when resuming from ram, could be a timing issue */ |
223 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 206 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
224 | 207 | ||
225 | /* Enable double clock */ | 208 | /* Enable double clock */ |
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] = | |||
229 | 212 | ||
230 | /* Set fast AGC/AEC algorithm with unlimited step size */ | 213 | /* Set fast AGC/AEC algorithm with unlimited step size */ |
231 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | | 214 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | |
232 | OV9650_AEC_UNLIM_STEP_SIZE | | 215 | OV9650_AEC_UNLIM_STEP_SIZE}, |
233 | OV9650_AWB_EN | OV9650_AGC_EN}, | ||
234 | 216 | ||
235 | {SENSOR, OV9650_CHLF, 0x10}, | 217 | {SENSOR, OV9650_CHLF, 0x10}, |
236 | {SENSOR, OV9650_ARBLM, 0xbf}, | 218 | {SENSOR, OV9650_ARBLM, 0xbf}, |
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] = | |||
301 | {SENSOR, OV9650_VREF, 0x10}, | 283 | {SENSOR, OV9650_VREF, 0x10}, |
302 | {SENSOR, OV9650_ADC, 0x04}, | 284 | {SENSOR, OV9650_ADC, 0x04}, |
303 | {SENSOR, OV9650_HV, 0x40}, | 285 | {SENSOR, OV9650_HV, 0x40}, |
286 | |||
304 | /* Enable denoise, and white-pixel erase */ | 287 | /* Enable denoise, and white-pixel erase */ |
305 | {SENSOR, OV9650_COM22, 0x23}, | 288 | {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE | |
289 | OV9650_WHITE_PIXEL_ENABLE | | ||
290 | OV9650_WHITE_PIXEL_OPTION}, | ||
306 | 291 | ||
307 | /* Enable VARIOPIXEL */ | 292 | /* Enable VARIOPIXEL */ |
308 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, | 293 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, |
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] = | |||
312 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, | 297 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, |
313 | }; | 298 | }; |
314 | 299 | ||
315 | static const unsigned char power_down_ov9650[][3] = | ||
316 | { | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
319 | {SENSOR, OV9650_COM7, 0x80}, | ||
320 | {SENSOR, OV9650_OFON, 0xf4}, | ||
321 | {SENSOR, OV9650_MVFP, 0x80}, | ||
322 | {SENSOR, OV9650_DBLV, 0x3f}, | ||
323 | {SENSOR, OV9650_RSVD36, 0x49}, | ||
324 | {SENSOR, OV9650_COM7, 0x05}, | ||
325 | |||
326 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
327 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
328 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
329 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
333 | }; | ||
334 | |||
335 | static const unsigned char res_init_ov9650[][3] = | 300 | static const unsigned char res_init_ov9650[][3] = |
336 | { | 301 | { |
337 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, | 302 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index eaddf488bad1..8d74d8065b79 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -18,6 +18,29 @@ | |||
18 | 18 | ||
19 | #include "m5602_po1030.h" | 19 | #include "m5602_po1030.h" |
20 | 20 | ||
21 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
38 | __s32 *val); | ||
39 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
40 | __s32 val); | ||
41 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, | ||
42 | __s32 *val); | ||
43 | |||
21 | static struct v4l2_pix_format po1030_modes[] = { | 44 | static struct v4l2_pix_format po1030_modes[] = { |
22 | { | 45 | { |
23 | 640, | 46 | 640, |
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = { | |||
27 | .sizeimage = 640 * 480, | 50 | .sizeimage = 640 * 480, |
28 | .bytesperline = 640, | 51 | .bytesperline = 640, |
29 | .colorspace = V4L2_COLORSPACE_SRGB, | 52 | .colorspace = V4L2_COLORSPACE_SRGB, |
30 | .priv = 0 | 53 | .priv = 2 |
31 | } | 54 | } |
32 | }; | 55 | }; |
33 | 56 | ||
34 | const static struct ctrl po1030_ctrls[] = { | 57 | static const struct ctrl po1030_ctrls[] = { |
58 | #define GAIN_IDX 0 | ||
35 | { | 59 | { |
36 | { | 60 | { |
37 | .id = V4L2_CID_GAIN, | 61 | .id = V4L2_CID_GAIN, |
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
45 | }, | 69 | }, |
46 | .set = po1030_set_gain, | 70 | .set = po1030_set_gain, |
47 | .get = po1030_get_gain | 71 | .get = po1030_get_gain |
48 | }, { | 72 | }, |
73 | #define EXPOSURE_IDX 1 | ||
74 | { | ||
49 | { | 75 | { |
50 | .id = V4L2_CID_EXPOSURE, | 76 | .id = V4L2_CID_EXPOSURE, |
51 | .type = V4L2_CTRL_TYPE_INTEGER, | 77 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
58 | }, | 84 | }, |
59 | .set = po1030_set_exposure, | 85 | .set = po1030_set_exposure, |
60 | .get = po1030_get_exposure | 86 | .get = po1030_get_exposure |
61 | }, { | 87 | }, |
88 | #define RED_BALANCE_IDX 2 | ||
89 | { | ||
62 | { | 90 | { |
63 | .id = V4L2_CID_RED_BALANCE, | 91 | .id = V4L2_CID_RED_BALANCE, |
64 | .type = V4L2_CTRL_TYPE_INTEGER, | 92 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
71 | }, | 99 | }, |
72 | .set = po1030_set_red_balance, | 100 | .set = po1030_set_red_balance, |
73 | .get = po1030_get_red_balance | 101 | .get = po1030_get_red_balance |
74 | }, { | 102 | }, |
103 | #define BLUE_BALANCE_IDX 3 | ||
104 | { | ||
75 | { | 105 | { |
76 | .id = V4L2_CID_BLUE_BALANCE, | 106 | .id = V4L2_CID_BLUE_BALANCE, |
77 | .type = V4L2_CTRL_TYPE_INTEGER, | 107 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
84 | }, | 114 | }, |
85 | .set = po1030_set_blue_balance, | 115 | .set = po1030_set_blue_balance, |
86 | .get = po1030_get_blue_balance | 116 | .get = po1030_get_blue_balance |
87 | }, { | 117 | }, |
118 | #define HFLIP_IDX 4 | ||
119 | { | ||
88 | { | 120 | { |
89 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
90 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
96 | }, | 128 | }, |
97 | .set = po1030_set_hflip, | 129 | .set = po1030_set_hflip, |
98 | .get = po1030_get_hflip | 130 | .get = po1030_get_hflip |
99 | }, { | 131 | }, |
132 | #define VFLIP_IDX 5 | ||
133 | { | ||
100 | { | 134 | { |
101 | .id = V4L2_CID_VFLIP, | 135 | .id = V4L2_CID_VFLIP, |
102 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 136 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = { | |||
108 | }, | 142 | }, |
109 | .set = po1030_set_vflip, | 143 | .set = po1030_set_vflip, |
110 | .get = po1030_get_vflip | 144 | .get = po1030_get_vflip |
111 | } | 145 | }, |
146 | #define AUTO_WHITE_BALANCE_IDX 6 | ||
147 | { | ||
148 | { | ||
149 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
150 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
151 | .name = "auto white balance", | ||
152 | .minimum = 0, | ||
153 | .maximum = 1, | ||
154 | .step = 1, | ||
155 | .default_value = 0, | ||
156 | }, | ||
157 | .set = po1030_set_auto_white_balance, | ||
158 | .get = po1030_get_auto_white_balance | ||
159 | }, | ||
160 | #define AUTO_EXPOSURE_IDX 7 | ||
161 | { | ||
162 | { | ||
163 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
164 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
165 | .name = "auto exposure", | ||
166 | .minimum = 0, | ||
167 | .maximum = 1, | ||
168 | .step = 1, | ||
169 | .default_value = 0, | ||
170 | }, | ||
171 | .set = po1030_set_auto_exposure, | ||
172 | .get = po1030_get_auto_exposure | ||
173 | }, | ||
174 | #define GREEN_BALANCE_IDX 8 | ||
175 | { | ||
176 | { | ||
177 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
178 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
179 | .name = "green balance", | ||
180 | .minimum = 0x00, | ||
181 | .maximum = 0xff, | ||
182 | .step = 0x1, | ||
183 | .default_value = PO1030_GREEN_GAIN_DEFAULT, | ||
184 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
185 | }, | ||
186 | .set = po1030_set_green_balance, | ||
187 | .get = po1030_get_green_balance | ||
188 | }, | ||
112 | }; | 189 | }; |
113 | 190 | ||
114 | static void po1030_dump_registers(struct sd *sd); | 191 | static void po1030_dump_registers(struct sd *sd); |
115 | 192 | ||
116 | int po1030_probe(struct sd *sd) | 193 | int po1030_probe(struct sd *sd) |
117 | { | 194 | { |
118 | u8 prod_id = 0, ver_id = 0, i; | 195 | u8 dev_id_h = 0, i; |
196 | s32 *sensor_settings; | ||
119 | 197 | ||
120 | if (force_sensor) { | 198 | if (force_sensor) { |
121 | if (force_sensor == PO1030_SENSOR) { | 199 | if (force_sensor == PO1030_SENSOR) { |
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd) | |||
139 | m5602_write_bridge(sd, preinit_po1030[i][1], data); | 217 | m5602_write_bridge(sd, preinit_po1030[i][1], data); |
140 | } | 218 | } |
141 | 219 | ||
142 | if (m5602_read_sensor(sd, 0x3, &prod_id, 1)) | 220 | if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) |
143 | return -ENODEV; | 221 | return -ENODEV; |
144 | 222 | ||
145 | if (m5602_read_sensor(sd, 0x4, &ver_id, 1)) | 223 | if (dev_id_h == 0x30) { |
146 | return -ENODEV; | ||
147 | |||
148 | if ((prod_id == 0x02) && (ver_id == 0xef)) { | ||
149 | info("Detected a po1030 sensor"); | 224 | info("Detected a po1030 sensor"); |
150 | goto sensor_found; | 225 | goto sensor_found; |
151 | } | 226 | } |
152 | return -ENODEV; | 227 | return -ENODEV; |
153 | 228 | ||
154 | sensor_found: | 229 | sensor_found: |
230 | sensor_settings = kmalloc( | ||
231 | ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); | ||
232 | if (!sensor_settings) | ||
233 | return -ENOMEM; | ||
234 | |||
155 | sd->gspca_dev.cam.cam_mode = po1030_modes; | 235 | sd->gspca_dev.cam.cam_mode = po1030_modes; |
156 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); | 236 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); |
157 | sd->desc->ctrls = po1030_ctrls; | 237 | sd->desc->ctrls = po1030_ctrls; |
158 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); | 238 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); |
239 | |||
240 | for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) | ||
241 | sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; | ||
242 | sd->sensor_priv = sensor_settings; | ||
243 | |||
159 | return 0; | 244 | return 0; |
160 | } | 245 | } |
161 | 246 | ||
162 | int po1030_init(struct sd *sd) | 247 | int po1030_init(struct sd *sd) |
163 | { | 248 | { |
249 | s32 *sensor_settings = sd->sensor_priv; | ||
164 | int i, err = 0; | 250 | int i, err = 0; |
165 | 251 | ||
166 | /* Init the sensor */ | 252 | /* Init the sensor */ |
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd) | |||
185 | return -EINVAL; | 271 | return -EINVAL; |
186 | } | 272 | } |
187 | } | 273 | } |
274 | if (err < 0) | ||
275 | return err; | ||
188 | 276 | ||
189 | if (dump_sensor) | 277 | if (dump_sensor) |
190 | po1030_dump_registers(sd); | 278 | po1030_dump_registers(sd); |
191 | 279 | ||
280 | err = po1030_set_exposure(&sd->gspca_dev, | ||
281 | sensor_settings[EXPOSURE_IDX]); | ||
282 | if (err < 0) | ||
283 | return err; | ||
284 | |||
285 | err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
286 | if (err < 0) | ||
287 | return err; | ||
288 | |||
289 | err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = po1030_set_red_balance(&sd->gspca_dev, | ||
298 | sensor_settings[RED_BALANCE_IDX]); | ||
299 | if (err < 0) | ||
300 | return err; | ||
301 | |||
302 | err = po1030_set_blue_balance(&sd->gspca_dev, | ||
303 | sensor_settings[BLUE_BALANCE_IDX]); | ||
304 | if (err < 0) | ||
305 | return err; | ||
306 | |||
307 | err = po1030_set_green_balance(&sd->gspca_dev, | ||
308 | sensor_settings[GREEN_BALANCE_IDX]); | ||
309 | if (err < 0) | ||
310 | return err; | ||
311 | |||
312 | err = po1030_set_auto_white_balance(&sd->gspca_dev, | ||
313 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
314 | if (err < 0) | ||
315 | return err; | ||
316 | |||
317 | err = po1030_set_auto_exposure(&sd->gspca_dev, | ||
318 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
192 | return err; | 319 | return err; |
193 | } | 320 | } |
194 | 321 | ||
195 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 322 | int po1030_start(struct sd *sd) |
196 | { | 323 | { |
197 | struct sd *sd = (struct sd *) gspca_dev; | 324 | struct cam *cam = &sd->gspca_dev.cam; |
198 | u8 i2c_data; | 325 | int i, err = 0; |
199 | int err; | 326 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; |
327 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
328 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | ||
329 | u8 data; | ||
330 | |||
331 | switch (width) { | ||
332 | case 320: | ||
333 | data = PO1030_SUBSAMPLING; | ||
334 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
335 | if (err < 0) | ||
336 | return err; | ||
337 | |||
338 | data = ((width + 3) >> 8) & 0xff; | ||
339 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | |||
343 | data = (width + 3) & 0xff; | ||
344 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
345 | if (err < 0) | ||
346 | return err; | ||
347 | |||
348 | data = ((height + 1) >> 8) & 0xff; | ||
349 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | |||
353 | data = (height + 1) & 0xff; | ||
354 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
355 | |||
356 | height += 6; | ||
357 | width -= 1; | ||
358 | break; | ||
359 | |||
360 | case 640: | ||
361 | data = 0; | ||
362 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
363 | if (err < 0) | ||
364 | return err; | ||
365 | |||
366 | data = ((width + 7) >> 8) & 0xff; | ||
367 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
368 | if (err < 0) | ||
369 | return err; | ||
370 | |||
371 | data = (width + 7) & 0xff; | ||
372 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
373 | if (err < 0) | ||
374 | return err; | ||
375 | |||
376 | data = ((height + 3) >> 8) & 0xff; | ||
377 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | data = (height + 3) & 0xff; | ||
382 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
383 | |||
384 | height += 12; | ||
385 | width -= 2; | ||
386 | break; | ||
387 | } | ||
388 | err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c); | ||
389 | if (err < 0) | ||
390 | return err; | ||
200 | 391 | ||
201 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, | 392 | err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81); |
202 | &i2c_data, 1); | ||
203 | if (err < 0) | 393 | if (err < 0) |
204 | return err; | 394 | return err; |
205 | *val = (i2c_data << 8); | ||
206 | 395 | ||
207 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, | 396 | err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82); |
208 | &i2c_data, 1); | 397 | if (err < 0) |
209 | *val |= i2c_data; | 398 | return err; |
210 | 399 | ||
211 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | 400 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01); |
401 | if (err < 0) | ||
402 | return err; | ||
403 | |||
404 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, | ||
405 | ((ver_offs >> 8) & 0xff)); | ||
406 | if (err < 0) | ||
407 | return err; | ||
408 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); | ||
410 | if (err < 0) | ||
411 | return err; | ||
412 | |||
413 | for (i = 0; i < 2 && !err; i++) | ||
414 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
415 | if (err < 0) | ||
416 | return err; | ||
417 | |||
418 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
419 | if (err < 0) | ||
420 | return err; | ||
421 | |||
422 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | for (i = 0; i < 2 && !err; i++) | ||
427 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
428 | |||
429 | for (i = 0; i < 2 && !err; i++) | ||
430 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
431 | |||
432 | for (i = 0; i < 2 && !err; i++) | ||
433 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
434 | if (err < 0) | ||
435 | return err; | ||
436 | |||
437 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff); | ||
438 | if (err < 0) | ||
439 | return err; | ||
212 | 440 | ||
441 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff)); | ||
442 | if (err < 0) | ||
443 | return err; | ||
444 | |||
445 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
213 | return err; | 446 | return err; |
214 | } | 447 | } |
215 | 448 | ||
216 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 449 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
217 | { | 450 | { |
218 | struct sd *sd = (struct sd *) gspca_dev; | 451 | struct sd *sd = (struct sd *) gspca_dev; |
452 | s32 *sensor_settings = sd->sensor_priv; | ||
453 | |||
454 | *val = sensor_settings[EXPOSURE_IDX]; | ||
455 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
460 | { | ||
461 | struct sd *sd = (struct sd *) gspca_dev; | ||
462 | s32 *sensor_settings = sd->sensor_priv; | ||
219 | u8 i2c_data; | 463 | u8 i2c_data; |
220 | int err; | 464 | int err; |
221 | 465 | ||
466 | sensor_settings[EXPOSURE_IDX] = val; | ||
222 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); | 467 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); |
223 | 468 | ||
224 | i2c_data = ((val & 0xff00) >> 8); | 469 | i2c_data = ((val & 0xff00) >> 8); |
225 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", | 470 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", |
226 | i2c_data); | 471 | i2c_data); |
227 | 472 | ||
228 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H, | 473 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_H, |
229 | &i2c_data, 1); | 474 | &i2c_data, 1); |
230 | if (err < 0) | 475 | if (err < 0) |
231 | return err; | 476 | return err; |
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
233 | i2c_data = (val & 0xff); | 478 | i2c_data = (val & 0xff); |
234 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", | 479 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", |
235 | i2c_data); | 480 | i2c_data); |
236 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M, | 481 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_M, |
237 | &i2c_data, 1); | 482 | &i2c_data, 1); |
238 | 483 | ||
239 | return err; | 484 | return err; |
240 | } | 485 | } |
241 | 486 | ||
242 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 487 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
243 | { | 488 | { |
244 | struct sd *sd = (struct sd *) gspca_dev; | 489 | struct sd *sd = (struct sd *) gspca_dev; |
245 | u8 i2c_data; | 490 | s32 *sensor_settings = sd->sensor_priv; |
246 | int err; | ||
247 | 491 | ||
248 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | 492 | *val = sensor_settings[GAIN_IDX]; |
249 | &i2c_data, 1); | ||
250 | *val = i2c_data; | ||
251 | PDEBUG(D_V4L2, "Read global gain %d", *val); | 493 | PDEBUG(D_V4L2, "Read global gain %d", *val); |
252 | 494 | return 0; | |
253 | return err; | ||
254 | } | 495 | } |
255 | 496 | ||
256 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 497 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
257 | { | 498 | { |
258 | struct sd *sd = (struct sd *) gspca_dev; | 499 | struct sd *sd = (struct sd *) gspca_dev; |
500 | s32 *sensor_settings = sd->sensor_priv; | ||
259 | u8 i2c_data; | 501 | u8 i2c_data; |
260 | int err; | 502 | int err; |
261 | 503 | ||
262 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, | 504 | sensor_settings[GAIN_IDX] = val; |
505 | |||
506 | i2c_data = val & 0xff; | ||
507 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | ||
508 | err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, | ||
263 | &i2c_data, 1); | 509 | &i2c_data, 1); |
510 | return err; | ||
511 | } | ||
264 | 512 | ||
265 | *val = (i2c_data >> 7) & 0x01 ; | 513 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
514 | { | ||
515 | struct sd *sd = (struct sd *) gspca_dev; | ||
516 | s32 *sensor_settings = sd->sensor_priv; | ||
266 | 517 | ||
518 | *val = sensor_settings[HFLIP_IDX]; | ||
267 | PDEBUG(D_V4L2, "Read hflip %d", *val); | 519 | PDEBUG(D_V4L2, "Read hflip %d", *val); |
268 | 520 | ||
269 | return err; | 521 | return 0; |
270 | } | 522 | } |
271 | 523 | ||
272 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 524 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
273 | { | 525 | { |
274 | struct sd *sd = (struct sd *) gspca_dev; | 526 | struct sd *sd = (struct sd *) gspca_dev; |
527 | s32 *sensor_settings = sd->sensor_priv; | ||
275 | u8 i2c_data; | 528 | u8 i2c_data; |
276 | int err; | 529 | int err; |
277 | 530 | ||
531 | sensor_settings[HFLIP_IDX] = val; | ||
532 | |||
278 | PDEBUG(D_V4L2, "Set hflip %d", val); | 533 | PDEBUG(D_V4L2, "Set hflip %d", val); |
279 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 534 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
280 | if (err < 0) | 535 | if (err < 0) |
281 | return err; | 536 | return err; |
282 | 537 | ||
283 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); | 538 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); |
284 | 539 | ||
285 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 540 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
286 | &i2c_data, 1); | 541 | &i2c_data, 1); |
287 | 542 | ||
288 | return err; | 543 | return err; |
289 | } | 544 | } |
290 | 545 | ||
291 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 546 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
292 | { | 547 | { |
293 | struct sd *sd = (struct sd *) gspca_dev; | 548 | struct sd *sd = (struct sd *) gspca_dev; |
294 | u8 i2c_data; | 549 | s32 *sensor_settings = sd->sensor_priv; |
295 | int err; | ||
296 | |||
297 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
298 | &i2c_data, 1); | ||
299 | |||
300 | *val = (i2c_data >> 6) & 0x01; | ||
301 | 550 | ||
551 | *val = sensor_settings[VFLIP_IDX]; | ||
302 | PDEBUG(D_V4L2, "Read vflip %d", *val); | 552 | PDEBUG(D_V4L2, "Read vflip %d", *val); |
303 | 553 | ||
304 | return err; | 554 | return 0; |
305 | } | 555 | } |
306 | 556 | ||
307 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 557 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
308 | { | 558 | { |
309 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
560 | s32 *sensor_settings = sd->sensor_priv; | ||
310 | u8 i2c_data; | 561 | u8 i2c_data; |
311 | int err; | 562 | int err; |
312 | 563 | ||
564 | sensor_settings[VFLIP_IDX] = val; | ||
565 | |||
313 | PDEBUG(D_V4L2, "Set vflip %d", val); | 566 | PDEBUG(D_V4L2, "Set vflip %d", val); |
314 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 567 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
315 | if (err < 0) | 568 | if (err < 0) |
316 | return err; | 569 | return err; |
317 | 570 | ||
318 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); | 571 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); |
319 | 572 | ||
320 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 573 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
321 | &i2c_data, 1); | 574 | &i2c_data, 1); |
322 | 575 | ||
323 | return err; | 576 | return err; |
324 | } | 577 | } |
325 | 578 | ||
326 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 579 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
580 | { | ||
581 | struct sd *sd = (struct sd *) gspca_dev; | ||
582 | s32 *sensor_settings = sd->sensor_priv; | ||
583 | |||
584 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
585 | PDEBUG(D_V4L2, "Read red gain %d", *val); | ||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
327 | { | 590 | { |
328 | struct sd *sd = (struct sd *) gspca_dev; | 591 | struct sd *sd = (struct sd *) gspca_dev; |
592 | s32 *sensor_settings = sd->sensor_priv; | ||
329 | u8 i2c_data; | 593 | u8 i2c_data; |
330 | int err; | 594 | int err; |
331 | 595 | ||
596 | sensor_settings[RED_BALANCE_IDX] = val; | ||
597 | |||
332 | i2c_data = val & 0xff; | 598 | i2c_data = val & 0xff; |
333 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | 599 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); |
334 | err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, | 600 | err = m5602_write_sensor(sd, PO1030_RED_GAIN, |
335 | &i2c_data, 1); | 601 | &i2c_data, 1); |
336 | return err; | 602 | return err; |
337 | } | 603 | } |
338 | 604 | ||
339 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 605 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
340 | { | 606 | { |
341 | struct sd *sd = (struct sd *) gspca_dev; | 607 | struct sd *sd = (struct sd *) gspca_dev; |
342 | u8 i2c_data; | 608 | s32 *sensor_settings = sd->sensor_priv; |
343 | int err; | ||
344 | 609 | ||
345 | err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, | 610 | *val = sensor_settings[BLUE_BALANCE_IDX]; |
346 | &i2c_data, 1); | 611 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
347 | *val = i2c_data; | 612 | |
348 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 613 | return 0; |
349 | return err; | ||
350 | } | 614 | } |
351 | 615 | ||
352 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 616 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
353 | { | 617 | { |
354 | struct sd *sd = (struct sd *) gspca_dev; | 618 | struct sd *sd = (struct sd *) gspca_dev; |
619 | s32 *sensor_settings = sd->sensor_priv; | ||
355 | u8 i2c_data; | 620 | u8 i2c_data; |
356 | int err; | 621 | int err; |
357 | 622 | ||
623 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
624 | |||
358 | i2c_data = val & 0xff; | 625 | i2c_data = val & 0xff; |
359 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); | 626 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); |
360 | err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, | 627 | err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, |
361 | &i2c_data, 1); | 628 | &i2c_data, 1); |
629 | |||
362 | return err; | 630 | return err; |
363 | } | 631 | } |
364 | 632 | ||
365 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 633 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) |
366 | { | 634 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 635 | struct sd *sd = (struct sd *) gspca_dev; |
636 | s32 *sensor_settings = sd->sensor_priv; | ||
637 | |||
638 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
639 | PDEBUG(D_V4L2, "Read green gain %d", *val); | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
645 | { | ||
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | s32 *sensor_settings = sd->sensor_priv; | ||
368 | u8 i2c_data; | 648 | u8 i2c_data; |
369 | int err; | 649 | int err; |
370 | 650 | ||
371 | err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, | 651 | sensor_settings[GREEN_BALANCE_IDX] = val; |
652 | i2c_data = val & 0xff; | ||
653 | PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); | ||
654 | |||
655 | err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN, | ||
656 | &i2c_data, 1); | ||
657 | if (err < 0) | ||
658 | return err; | ||
659 | |||
660 | return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN, | ||
372 | &i2c_data, 1); | 661 | &i2c_data, 1); |
373 | *val = i2c_data; | 662 | } |
374 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | ||
375 | 663 | ||
376 | return err; | 664 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, |
665 | __s32 *val) | ||
666 | { | ||
667 | struct sd *sd = (struct sd *) gspca_dev; | ||
668 | s32 *sensor_settings = sd->sensor_priv; | ||
669 | |||
670 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
671 | PDEBUG(D_V4L2, "Auto white balancing is %d", *val); | ||
672 | |||
673 | return 0; | ||
377 | } | 674 | } |
378 | 675 | ||
379 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 676 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, |
677 | __s32 val) | ||
380 | { | 678 | { |
381 | struct sd *sd = (struct sd *) gspca_dev; | 679 | struct sd *sd = (struct sd *) gspca_dev; |
680 | s32 *sensor_settings = sd->sensor_priv; | ||
382 | u8 i2c_data; | 681 | u8 i2c_data; |
383 | int err; | 682 | int err; |
384 | i2c_data = val & 0xff; | ||
385 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); | ||
386 | err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN, | ||
387 | &i2c_data, 1); | ||
388 | 683 | ||
684 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; | ||
685 | |||
686 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
687 | if (err < 0) | ||
688 | return err; | ||
689 | |||
690 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); | ||
691 | i2c_data = (i2c_data & 0xfe) | (val & 0x01); | ||
692 | err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
389 | return err; | 693 | return err; |
390 | } | 694 | } |
391 | 695 | ||
392 | int po1030_power_down(struct sd *sd) | 696 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, |
697 | __s32 *val) | ||
393 | { | 698 | { |
699 | struct sd *sd = (struct sd *) gspca_dev; | ||
700 | s32 *sensor_settings = sd->sensor_priv; | ||
701 | |||
702 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; | ||
703 | PDEBUG(D_V4L2, "Auto exposure is %d", *val); | ||
394 | return 0; | 704 | return 0; |
395 | } | 705 | } |
396 | 706 | ||
707 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
708 | __s32 val) | ||
709 | { | ||
710 | struct sd *sd = (struct sd *) gspca_dev; | ||
711 | s32 *sensor_settings = sd->sensor_priv; | ||
712 | u8 i2c_data; | ||
713 | int err; | ||
714 | |||
715 | sensor_settings[AUTO_EXPOSURE_IDX] = val; | ||
716 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
717 | if (err < 0) | ||
718 | return err; | ||
719 | |||
720 | PDEBUG(D_V4L2, "Set auto exposure to %d", val); | ||
721 | i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); | ||
722 | return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
723 | } | ||
724 | |||
725 | void po1030_disconnect(struct sd *sd) | ||
726 | { | ||
727 | sd->sensor = NULL; | ||
728 | kfree(sd->sensor_priv); | ||
729 | } | ||
730 | |||
397 | static void po1030_dump_registers(struct sd *sd) | 731 | static void po1030_dump_registers(struct sd *sd) |
398 | { | 732 | { |
399 | int address; | 733 | int address; |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index c10b12335818..1ea380b2bbe7 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -25,98 +25,123 @@ | |||
25 | 25 | ||
26 | /*****************************************************************************/ | 26 | /*****************************************************************************/ |
27 | 27 | ||
28 | #define PO1030_REG_DEVID_H 0x00 | 28 | #define PO1030_DEVID_H 0x00 |
29 | #define PO1030_REG_DEVID_L 0x01 | 29 | #define PO1030_DEVID_L 0x01 |
30 | #define PO1030_REG_FRAMEWIDTH_H 0x04 | 30 | #define PO1030_FRAMEWIDTH_H 0x04 |
31 | #define PO1030_REG_FRAMEWIDTH_L 0x05 | 31 | #define PO1030_FRAMEWIDTH_L 0x05 |
32 | #define PO1030_REG_FRAMEHEIGHT_H 0x06 | 32 | #define PO1030_FRAMEHEIGHT_H 0x06 |
33 | #define PO1030_REG_FRAMEHEIGHT_L 0x07 | 33 | #define PO1030_FRAMEHEIGHT_L 0x07 |
34 | #define PO1030_REG_WINDOWX_H 0x08 | 34 | #define PO1030_WINDOWX_H 0x08 |
35 | #define PO1030_REG_WINDOWX_L 0x09 | 35 | #define PO1030_WINDOWX_L 0x09 |
36 | #define PO1030_REG_WINDOWY_H 0x0a | 36 | #define PO1030_WINDOWY_H 0x0a |
37 | #define PO1030_REG_WINDOWY_L 0x0b | 37 | #define PO1030_WINDOWY_L 0x0b |
38 | #define PO1030_REG_WINDOWWIDTH_H 0x0c | 38 | #define PO1030_WINDOWWIDTH_H 0x0c |
39 | #define PO1030_REG_WINDOWWIDTH_L 0x0d | 39 | #define PO1030_WINDOWWIDTH_L 0x0d |
40 | #define PO1030_REG_WINDOWHEIGHT_H 0x0e | 40 | #define PO1030_WINDOWHEIGHT_H 0x0e |
41 | #define PO1030_REG_WINDOWHEIGHT_L 0x0f | 41 | #define PO1030_WINDOWHEIGHT_L 0x0f |
42 | 42 | ||
43 | #define PO1030_REG_GLOBALIBIAS 0x12 | 43 | #define PO1030_GLOBALIBIAS 0x12 |
44 | #define PO1030_REG_PIXELIBIAS 0x13 | 44 | #define PO1030_PIXELIBIAS 0x13 |
45 | 45 | ||
46 | #define PO1030_REG_GLOBALGAIN 0x15 | 46 | #define PO1030_GLOBALGAIN 0x15 |
47 | #define PO1030_REG_RED_GAIN 0x16 | 47 | #define PO1030_RED_GAIN 0x16 |
48 | #define PO1030_REG_GREEN_1_GAIN 0x17 | 48 | #define PO1030_GREEN_1_GAIN 0x17 |
49 | #define PO1030_REG_BLUE_GAIN 0x18 | 49 | #define PO1030_BLUE_GAIN 0x18 |
50 | #define PO1030_REG_GREEN_2_GAIN 0x19 | 50 | #define PO1030_GREEN_2_GAIN 0x19 |
51 | 51 | ||
52 | #define PO1030_REG_INTEGLINES_H 0x1a | 52 | #define PO1030_INTEGLINES_H 0x1a |
53 | #define PO1030_REG_INTEGLINES_M 0x1b | 53 | #define PO1030_INTEGLINES_M 0x1b |
54 | #define PO1030_REG_INTEGLINES_L 0x1c | 54 | #define PO1030_INTEGLINES_L 0x1c |
55 | 55 | ||
56 | #define PO1030_REG_CONTROL1 0x1d | 56 | #define PO1030_CONTROL1 0x1d |
57 | #define PO1030_REG_CONTROL2 0x1e | 57 | #define PO1030_CONTROL2 0x1e |
58 | #define PO1030_REG_CONTROL3 0x1f | 58 | #define PO1030_CONTROL3 0x1f |
59 | #define PO1030_REG_CONTROL4 0x20 | 59 | #define PO1030_CONTROL4 0x20 |
60 | 60 | ||
61 | #define PO1030_REG_PERIOD50_H 0x23 | 61 | #define PO1030_PERIOD50_H 0x23 |
62 | #define PO1030_REG_PERIOD50_L 0x24 | 62 | #define PO1030_PERIOD50_L 0x24 |
63 | #define PO1030_REG_PERIOD60_H 0x25 | 63 | #define PO1030_PERIOD60_H 0x25 |
64 | #define PO1030_REG_PERIOD60_L 0x26 | 64 | #define PO1030_PERIOD60_L 0x26 |
65 | #define PO1030_REG_REGCLK167 0x27 | 65 | #define PO1030_REGCLK167 0x27 |
66 | #define PO1030_REG_DELTA50 0x28 | 66 | #define PO1030_FLICKER_DELTA50 0x28 |
67 | #define PO1030_REG_DELTA60 0x29 | 67 | #define PO1030_FLICKERDELTA60 0x29 |
68 | 68 | ||
69 | #define PO1030_REG_ADCOFFSET 0x2c | 69 | #define PO1030_ADCOFFSET 0x2c |
70 | 70 | ||
71 | /* Gamma Correction Coeffs */ | 71 | /* Gamma Correction Coeffs */ |
72 | #define PO1030_REG_GC0 0x2d | 72 | #define PO1030_GC0 0x2d |
73 | #define PO1030_REG_GC1 0x2e | 73 | #define PO1030_GC1 0x2e |
74 | #define PO1030_REG_GC2 0x2f | 74 | #define PO1030_GC2 0x2f |
75 | #define PO1030_REG_GC3 0x30 | 75 | #define PO1030_GC3 0x30 |
76 | #define PO1030_REG_GC4 0x31 | 76 | #define PO1030_GC4 0x31 |
77 | #define PO1030_REG_GC5 0x32 | 77 | #define PO1030_GC5 0x32 |
78 | #define PO1030_REG_GC6 0x33 | 78 | #define PO1030_GC6 0x33 |
79 | #define PO1030_REG_GC7 0x34 | 79 | #define PO1030_GC7 0x34 |
80 | 80 | ||
81 | /* Color Transform Matrix */ | 81 | /* Color Transform Matrix */ |
82 | #define PO1030_REG_CT0 0x35 | 82 | #define PO1030_CT0 0x35 |
83 | #define PO1030_REG_CT1 0x36 | 83 | #define PO1030_CT1 0x36 |
84 | #define PO1030_REG_CT2 0x37 | 84 | #define PO1030_CT2 0x37 |
85 | #define PO1030_REG_CT3 0x38 | 85 | #define PO1030_CT3 0x38 |
86 | #define PO1030_REG_CT4 0x39 | 86 | #define PO1030_CT4 0x39 |
87 | #define PO1030_REG_CT5 0x3a | 87 | #define PO1030_CT5 0x3a |
88 | #define PO1030_REG_CT6 0x3b | 88 | #define PO1030_CT6 0x3b |
89 | #define PO1030_REG_CT7 0x3c | 89 | #define PO1030_CT7 0x3c |
90 | #define PO1030_REG_CT8 0x3d | 90 | #define PO1030_CT8 0x3d |
91 | 91 | ||
92 | #define PO1030_REG_AUTOCTRL1 0x3e | 92 | #define PO1030_AUTOCTRL1 0x3e |
93 | #define PO1030_REG_AUTOCTRL2 0x3f | 93 | #define PO1030_AUTOCTRL2 0x3f |
94 | 94 | ||
95 | #define PO1030_REG_YTARGET 0x40 | 95 | #define PO1030_YTARGET 0x40 |
96 | #define PO1030_REG_GLOBALGAINMIN 0x41 | 96 | #define PO1030_GLOBALGAINMIN 0x41 |
97 | #define PO1030_REG_GLOBALGAINMAX 0x42 | 97 | #define PO1030_GLOBALGAINMAX 0x42 |
98 | |||
99 | #define PO1030_AWB_RED_TUNING 0x47 | ||
100 | #define PO1030_AWB_BLUE_TUNING 0x48 | ||
98 | 101 | ||
99 | /* Output format control */ | 102 | /* Output format control */ |
100 | #define PO1030_REG_OUTFORMCTRL1 0x5a | 103 | #define PO1030_OUTFORMCTRL1 0x5a |
101 | #define PO1030_REG_OUTFORMCTRL2 0x5b | 104 | #define PO1030_OUTFORMCTRL2 0x5b |
102 | #define PO1030_REG_OUTFORMCTRL3 0x5c | 105 | #define PO1030_OUTFORMCTRL3 0x5c |
103 | #define PO1030_REG_OUTFORMCTRL4 0x5d | 106 | #define PO1030_OUTFORMCTRL4 0x5d |
104 | #define PO1030_REG_OUTFORMCTRL5 0x5e | 107 | #define PO1030_OUTFORMCTRL5 0x5e |
105 | 108 | ||
106 | /* Imaging coefficients */ | 109 | #define PO1030_EDGE_ENH_OFF 0x5f |
107 | #define PO1030_REG_YBRIGHT 0x73 | 110 | #define PO1030_EGA 0x60 |
108 | #define PO1030_REG_YCONTRAST 0x74 | ||
109 | #define PO1030_REG_YSATURATION 0x75 | ||
110 | 111 | ||
111 | #define PO1030_HFLIP (1 << 7) | 112 | #define PO1030_Cb_U_GAIN 0x63 |
112 | #define PO1030_VFLIP (1 << 6) | 113 | #define PO1030_Cr_V_GAIN 0x64 |
114 | |||
115 | #define PO1030_YCONTRAST 0x74 | ||
116 | #define PO1030_YSATURATION 0x75 | ||
117 | |||
118 | #define PO1030_HFLIP (1 << 7) | ||
119 | #define PO1030_VFLIP (1 << 6) | ||
120 | |||
121 | #define PO1030_HREF_ENABLE (1 << 6) | ||
122 | |||
123 | #define PO1030_RAW_RGB_BAYER 0x4 | ||
124 | |||
125 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
126 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
127 | |||
128 | #define PO1030_WEIGHT_WIN_2X (1 << 3) | ||
129 | |||
130 | #define PO1030_SHUTTER_MODE (1 << 6) | ||
131 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
132 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
133 | |||
134 | #define PO1030_SENSOR_RESET (1 << 5) | ||
135 | |||
136 | #define PO1030_SUBSAMPLING (1 << 6) | ||
113 | 137 | ||
114 | /*****************************************************************************/ | 138 | /*****************************************************************************/ |
115 | 139 | ||
116 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 | 140 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 |
117 | #define PO1030_EXPOSURE_DEFAULT 0x0085 | 141 | #define PO1030_EXPOSURE_DEFAULT 0x0085 |
118 | #define PO1030_BLUE_GAIN_DEFAULT 0x40 | 142 | #define PO1030_BLUE_GAIN_DEFAULT 0x36 |
119 | #define PO1030_RED_GAIN_DEFAULT 0x40 | 143 | #define PO1030_RED_GAIN_DEFAULT 0x36 |
144 | #define PO1030_GREEN_GAIN_DEFAULT 0x40 | ||
120 | 145 | ||
121 | /*****************************************************************************/ | 146 | /*****************************************************************************/ |
122 | 147 | ||
@@ -126,20 +151,8 @@ extern int dump_sensor; | |||
126 | 151 | ||
127 | int po1030_probe(struct sd *sd); | 152 | int po1030_probe(struct sd *sd); |
128 | int po1030_init(struct sd *sd); | 153 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 154 | int po1030_start(struct sd *sd); |
130 | 155 | void po1030_disconnect(struct sd *sd); | |
131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
133 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
134 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
135 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
136 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
137 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
138 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
139 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
140 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
141 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
142 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
143 | 156 | ||
144 | static const struct m5602_sensor po1030 = { | 157 | static const struct m5602_sensor po1030 = { |
145 | .name = "PO1030", | 158 | .name = "PO1030", |
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = { | |||
149 | 162 | ||
150 | .probe = po1030_probe, | 163 | .probe = po1030_probe, |
151 | .init = po1030_init, | 164 | .init = po1030_init, |
152 | .power_down = po1030_power_down, | 165 | .start = po1030_start, |
166 | .disconnect = po1030_disconnect, | ||
153 | }; | 167 | }; |
154 | 168 | ||
155 | static const unsigned char preinit_po1030[][3] = | 169 | static const unsigned char preinit_po1030[][3] = |
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] = | |||
159 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
160 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 174 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
161 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 175 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
162 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
163 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 176 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
164 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
165 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 177 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
166 | |||
167 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
168 | |||
169 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
171 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
174 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
179 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
180 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
181 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
182 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
191 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
193 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
197 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
198 | |||
199 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
200 | |||
201 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 179 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
202 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 180 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
203 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 181 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
204 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 182 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
205 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
184 | |||
185 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, | ||
186 | |||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 187 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 188 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
208 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 189 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
209 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 190 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
210 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
211 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 191 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
212 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 192 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
213 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} | 193 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} |
214 | }; | 194 | }; |
215 | 195 | ||
216 | static const unsigned char init_po1030[][4] = | 196 | static const unsigned char init_po1030[][3] = |
217 | { | 197 | { |
218 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 198 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
219 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 199 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
220 | /*sequence 1*/ | ||
221 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 200 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
222 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 201 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
223 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 202 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
224 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
225 | |||
226 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 203 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
227 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
228 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 204 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
229 | /*end of sequence 1*/ | ||
230 | |||
231 | /*sequence 2 (same as stop sequence)*/ | ||
232 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
233 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
234 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
235 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
236 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
237 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
238 | |||
239 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
240 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
241 | /*end of sequence 2*/ | ||
242 | 205 | ||
243 | /*sequence 5*/ | 206 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, |
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
245 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
246 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
247 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
248 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
249 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
250 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
251 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
259 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
265 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
266 | /*end of sequence 5*/ | ||
267 | |||
268 | /*sequence 2 stop */ | ||
269 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
270 | 207 | ||
271 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 208 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
272 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 209 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
273 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 210 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
211 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 212 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
275 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 213 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
276 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 214 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
277 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 215 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
278 | /*end of sequence 2 stop */ | ||
279 | |||
280 | /* --------------------------------- | ||
281 | * end of init - begin of start | ||
282 | * --------------------------------- */ | ||
283 | |||
284 | /*sequence 3*/ | ||
285 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
286 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
287 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
288 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
289 | /*end of sequence 3*/ | ||
290 | /*sequence 4*/ | ||
291 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 216 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
292 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | 217 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
293 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
295 | 218 | ||
296 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, | 219 | {SENSOR, PO1030_AUTOCTRL2, 0x04}, |
220 | |||
221 | {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER}, | ||
222 | {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X}, | ||
223 | |||
224 | {SENSOR, PO1030_CONTROL2, 0x03}, | ||
225 | {SENSOR, 0x21, 0x90}, | ||
226 | {SENSOR, PO1030_YTARGET, 0x60}, | ||
227 | {SENSOR, 0x59, 0x13}, | ||
228 | {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE}, | ||
229 | {SENSOR, PO1030_EDGE_ENH_OFF, 0x00}, | ||
230 | {SENSOR, PO1030_EGA, 0x80}, | ||
231 | {SENSOR, 0x78, 0x14}, | ||
232 | {SENSOR, 0x6f, 0x01}, | ||
233 | {SENSOR, PO1030_GLOBALGAINMAX, 0x14}, | ||
234 | {SENSOR, PO1030_Cb_U_GAIN, 0x38}, | ||
235 | {SENSOR, PO1030_Cr_V_GAIN, 0x38}, | ||
236 | {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE | | ||
237 | PO1030_AUTO_SUBSAMPLING | | ||
238 | PO1030_FRAME_EQUAL}, | ||
239 | {SENSOR, PO1030_GC0, 0x10}, | ||
240 | {SENSOR, PO1030_GC1, 0x20}, | ||
241 | {SENSOR, PO1030_GC2, 0x40}, | ||
242 | {SENSOR, PO1030_GC3, 0x60}, | ||
243 | {SENSOR, PO1030_GC4, 0x80}, | ||
244 | {SENSOR, PO1030_GC5, 0xa0}, | ||
245 | {SENSOR, PO1030_GC6, 0xc0}, | ||
246 | {SENSOR, PO1030_GC7, 0xff}, | ||
297 | 247 | ||
298 | /* Set the width to 751 */ | 248 | /* Set the width to 751 */ |
299 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | 249 | {SENSOR, PO1030_FRAMEWIDTH_H, 0x02}, |
300 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, | 250 | {SENSOR, PO1030_FRAMEWIDTH_L, 0xef}, |
301 | 251 | ||
302 | /* Set the height to 540 */ | 252 | /* Set the height to 540 */ |
303 | {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, | 253 | {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02}, |
304 | {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, | 254 | {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c}, |
305 | 255 | ||
306 | /* Set the x window to 1 */ | 256 | /* Set the x window to 1 */ |
307 | {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, | 257 | {SENSOR, PO1030_WINDOWX_H, 0x00}, |
308 | {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, | 258 | {SENSOR, PO1030_WINDOWX_L, 0x01}, |
309 | 259 | ||
310 | /* Set the y window to 1 */ | 260 | /* Set the y window to 1 */ |
311 | {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, | 261 | {SENSOR, PO1030_WINDOWY_H, 0x00}, |
312 | {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, | 262 | {SENSOR, PO1030_WINDOWY_L, 0x01}, |
313 | |||
314 | {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, | ||
315 | {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, | ||
316 | {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01}, | ||
317 | {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3}, | ||
318 | |||
319 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
320 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
321 | {SENSOR, PO1030_REG_AUTOCTRL1, 0x08}, | ||
322 | {SENSOR, PO1030_REG_CONTROL2, 0x03}, | ||
323 | {SENSOR, 0x21, 0x90}, | ||
324 | {SENSOR, PO1030_REG_YTARGET, 0x60}, | ||
325 | {SENSOR, 0x59, 0x13}, | ||
326 | {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40}, | ||
327 | {SENSOR, 0x5f, 0x00}, | ||
328 | {SENSOR, 0x60, 0x80}, | ||
329 | {SENSOR, 0x78, 0x14}, | ||
330 | {SENSOR, 0x6f, 0x01}, | ||
331 | {SENSOR, PO1030_REG_CONTROL1, 0x18}, | ||
332 | {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14}, | ||
333 | {SENSOR, 0x63, 0x38}, | ||
334 | {SENSOR, 0x64, 0x38}, | ||
335 | {SENSOR, PO1030_REG_CONTROL1, 0x58}, | ||
336 | {SENSOR, PO1030_REG_RED_GAIN, 0x30}, | ||
337 | {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30}, | ||
338 | {SENSOR, PO1030_REG_BLUE_GAIN, 0x30}, | ||
339 | {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30}, | ||
340 | {SENSOR, PO1030_REG_GC0, 0x10}, | ||
341 | {SENSOR, PO1030_REG_GC1, 0x20}, | ||
342 | {SENSOR, PO1030_REG_GC2, 0x40}, | ||
343 | {SENSOR, PO1030_REG_GC3, 0x60}, | ||
344 | {SENSOR, PO1030_REG_GC4, 0x80}, | ||
345 | {SENSOR, PO1030_REG_GC5, 0xa0}, | ||
346 | {SENSOR, PO1030_REG_GC6, 0xc0}, | ||
347 | {SENSOR, PO1030_REG_GC7, 0xff}, | ||
348 | /*end of sequence 4*/ | ||
349 | /*sequence 5*/ | ||
350 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
351 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
352 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
353 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
354 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
355 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
356 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
357 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
358 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
359 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
360 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
361 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
362 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
363 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
364 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
365 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
366 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
367 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
368 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
369 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
370 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e}, | ||
371 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
372 | /*end of sequence 5*/ | ||
373 | |||
374 | /*sequence 6*/ | ||
375 | /* Changing 40 in f0 the image becomes green in bayer mode and red in | ||
376 | * rgb mode */ | ||
377 | {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT}, | ||
378 | /* in changing 40 in f0 the image becomes green in bayer mode and red in | ||
379 | * rgb mode */ | ||
380 | {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT}, | ||
381 | 263 | ||
382 | /* with a very low lighted environment increase the exposure but | 264 | /* with a very low lighted environment increase the exposure but |
383 | * decrease the FPS (Frame Per Second) */ | 265 | * decrease the FPS (Frame Per Second) */ |
384 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 266 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
385 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 267 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
386 | 268 | ||
387 | /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in | 269 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
388 | * low lighted environment (f0 is more than ff ?)*/ | 270 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
389 | {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) | 271 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
390 | & 0xff)}, | 272 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, |
391 | |||
392 | /* Controls middle exposure, use only in high lighted environment */ | ||
393 | {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff}, | ||
394 | |||
395 | /* Controls clarity (not sure) */ | ||
396 | {SENSOR, PO1030_REG_INTEGLINES_L, 0x00}, | ||
397 | /* Controls gain (the image is more lighted) */ | ||
398 | {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT}, | ||
399 | |||
400 | /* Sets the width */ | ||
401 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | ||
402 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef} | ||
403 | /*end of sequence 6*/ | ||
404 | }; | 273 | }; |
405 | 274 | ||
406 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 4306d596056d..191bcd718979 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -18,6 +18,19 @@ | |||
18 | 18 | ||
19 | #include "m5602_s5k4aa.h" | 19 | #include "m5602_s5k4aa.h" |
20 | 20 | ||
21 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | |||
21 | static | 34 | static |
22 | const | 35 | const |
23 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { | 36 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { |
@@ -46,6 +59,18 @@ static | |||
46 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | 59 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), |
47 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") | 60 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") |
48 | } | 61 | } |
62 | }, { | ||
63 | .ident = "MSI L735", | ||
64 | .matches = { | ||
65 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
66 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X") | ||
67 | } | ||
68 | }, { | ||
69 | .ident = "Lenovo Y300", | ||
70 | .matches = { | ||
71 | DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"), | ||
72 | DMI_MATCH(DMI_PRODUCT_NAME, "Y300") | ||
73 | } | ||
49 | }, | 74 | }, |
50 | { } | 75 | { } |
51 | }; | 76 | }; |
@@ -61,10 +86,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = { | |||
61 | .bytesperline = 640, | 86 | .bytesperline = 640, |
62 | .colorspace = V4L2_COLORSPACE_SRGB, | 87 | .colorspace = V4L2_COLORSPACE_SRGB, |
63 | .priv = 0 | 88 | .priv = 0 |
89 | }, | ||
90 | { | ||
91 | 1280, | ||
92 | 1024, | ||
93 | V4L2_PIX_FMT_SBGGR8, | ||
94 | V4L2_FIELD_NONE, | ||
95 | .sizeimage = | ||
96 | 1280 * 1024, | ||
97 | .bytesperline = 1280, | ||
98 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
99 | .priv = 0 | ||
64 | } | 100 | } |
65 | }; | 101 | }; |
66 | 102 | ||
67 | const static struct ctrl s5k4aa_ctrls[] = { | 103 | static const struct ctrl s5k4aa_ctrls[] = { |
104 | #define VFLIP_IDX 0 | ||
68 | { | 105 | { |
69 | { | 106 | { |
70 | .id = V4L2_CID_VFLIP, | 107 | .id = V4L2_CID_VFLIP, |
@@ -77,8 +114,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
77 | }, | 114 | }, |
78 | .set = s5k4aa_set_vflip, | 115 | .set = s5k4aa_set_vflip, |
79 | .get = s5k4aa_get_vflip | 116 | .get = s5k4aa_get_vflip |
80 | 117 | }, | |
81 | }, { | 118 | #define HFLIP_IDX 1 |
119 | { | ||
82 | { | 120 | { |
83 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
84 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -90,8 +128,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
90 | }, | 128 | }, |
91 | .set = s5k4aa_set_hflip, | 129 | .set = s5k4aa_set_hflip, |
92 | .get = s5k4aa_get_hflip | 130 | .get = s5k4aa_get_hflip |
93 | 131 | }, | |
94 | }, { | 132 | #define GAIN_IDX 2 |
133 | { | ||
95 | { | 134 | { |
96 | .id = V4L2_CID_GAIN, | 135 | .id = V4L2_CID_GAIN, |
97 | .type = V4L2_CTRL_TYPE_INTEGER, | 136 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -99,12 +138,14 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
99 | .minimum = 0, | 138 | .minimum = 0, |
100 | .maximum = 127, | 139 | .maximum = 127, |
101 | .step = 1, | 140 | .step = 1, |
102 | .default_value = 0xa0, | 141 | .default_value = S5K4AA_DEFAULT_GAIN, |
103 | .flags = V4L2_CTRL_FLAG_SLIDER | 142 | .flags = V4L2_CTRL_FLAG_SLIDER |
104 | }, | 143 | }, |
105 | .set = s5k4aa_set_gain, | 144 | .set = s5k4aa_set_gain, |
106 | .get = s5k4aa_get_gain | 145 | .get = s5k4aa_get_gain |
107 | }, { | 146 | }, |
147 | #define EXPOSURE_IDX 3 | ||
148 | { | ||
108 | { | 149 | { |
109 | .id = V4L2_CID_EXPOSURE, | 150 | .id = V4L2_CID_EXPOSURE, |
110 | .type = V4L2_CTRL_TYPE_INTEGER, | 151 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -117,7 +158,36 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
117 | }, | 158 | }, |
118 | .set = s5k4aa_set_exposure, | 159 | .set = s5k4aa_set_exposure, |
119 | .get = s5k4aa_get_exposure | 160 | .get = s5k4aa_get_exposure |
120 | } | 161 | }, |
162 | #define NOISE_SUPP_IDX 4 | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_PRIVATE_BASE, | ||
166 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
167 | .name = "Noise suppression (smoothing)", | ||
168 | .minimum = 0, | ||
169 | .maximum = 1, | ||
170 | .step = 1, | ||
171 | .default_value = 1, | ||
172 | }, | ||
173 | .set = s5k4aa_set_noise, | ||
174 | .get = s5k4aa_get_noise | ||
175 | }, | ||
176 | #define BRIGHTNESS_IDX 5 | ||
177 | { | ||
178 | { | ||
179 | .id = V4L2_CID_BRIGHTNESS, | ||
180 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
181 | .name = "Brightness", | ||
182 | .minimum = 0, | ||
183 | .maximum = 0x1f, | ||
184 | .step = 1, | ||
185 | .default_value = S5K4AA_DEFAULT_BRIGHTNESS, | ||
186 | }, | ||
187 | .set = s5k4aa_set_brightness, | ||
188 | .get = s5k4aa_get_brightness | ||
189 | }, | ||
190 | |||
121 | }; | 191 | }; |
122 | 192 | ||
123 | static void s5k4aa_dump_registers(struct sd *sd); | 193 | static void s5k4aa_dump_registers(struct sd *sd); |
@@ -127,6 +197,7 @@ int s5k4aa_probe(struct sd *sd) | |||
127 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 197 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
128 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; | 198 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; |
129 | int i, err = 0; | 199 | int i, err = 0; |
200 | s32 *sensor_settings; | ||
130 | 201 | ||
131 | if (force_sensor) { | 202 | if (force_sensor) { |
132 | if (force_sensor == S5K4AA_SENSOR) { | 203 | if (force_sensor == S5K4AA_SENSOR) { |
@@ -185,10 +256,20 @@ int s5k4aa_probe(struct sd *sd) | |||
185 | info("Detected a s5k4aa sensor"); | 256 | info("Detected a s5k4aa sensor"); |
186 | 257 | ||
187 | sensor_found: | 258 | sensor_found: |
259 | sensor_settings = kmalloc( | ||
260 | ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); | ||
261 | if (!sensor_settings) | ||
262 | return -ENOMEM; | ||
263 | |||
188 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; | 264 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; |
189 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); | 265 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); |
190 | sd->desc->ctrls = s5k4aa_ctrls; | 266 | sd->desc->ctrls = s5k4aa_ctrls; |
191 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); | 267 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); |
268 | |||
269 | for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) | ||
270 | sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; | ||
271 | sd->sensor_priv = sensor_settings; | ||
272 | |||
192 | return 0; | 273 | return 0; |
193 | } | 274 | } |
194 | 275 | ||
@@ -197,9 +278,45 @@ int s5k4aa_start(struct sd *sd) | |||
197 | int i, err = 0; | 278 | int i, err = 0; |
198 | u8 data[2]; | 279 | u8 data[2]; |
199 | struct cam *cam = &sd->gspca_dev.cam; | 280 | struct cam *cam = &sd->gspca_dev.cam; |
281 | s32 *sensor_settings = sd->sensor_priv; | ||
282 | |||
283 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { | ||
284 | case 1280: | ||
285 | PDEBUG(D_V4L2, "Configuring camera for SXGA mode"); | ||
286 | |||
287 | for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) { | ||
288 | switch (SXGA_s5k4aa[i][0]) { | ||
289 | case BRIDGE: | ||
290 | err = m5602_write_bridge(sd, | ||
291 | SXGA_s5k4aa[i][1], | ||
292 | SXGA_s5k4aa[i][2]); | ||
293 | break; | ||
294 | |||
295 | case SENSOR: | ||
296 | data[0] = SXGA_s5k4aa[i][2]; | ||
297 | err = m5602_write_sensor(sd, | ||
298 | SXGA_s5k4aa[i][1], | ||
299 | data, 1); | ||
300 | break; | ||
301 | |||
302 | case SENSOR_LONG: | ||
303 | data[0] = SXGA_s5k4aa[i][2]; | ||
304 | data[1] = SXGA_s5k4aa[i][3]; | ||
305 | err = m5602_write_sensor(sd, | ||
306 | SXGA_s5k4aa[i][1], | ||
307 | data, 2); | ||
308 | break; | ||
309 | |||
310 | default: | ||
311 | err("Invalid stream command, exiting init"); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | } | ||
315 | err = s5k4aa_set_noise(&sd->gspca_dev, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | break; | ||
200 | 319 | ||
201 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) | ||
202 | { | ||
203 | case 640: | 320 | case 640: |
204 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 321 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
205 | 322 | ||
@@ -231,8 +348,37 @@ int s5k4aa_start(struct sd *sd) | |||
231 | return -EINVAL; | 348 | return -EINVAL; |
232 | } | 349 | } |
233 | } | 350 | } |
351 | err = s5k4aa_set_noise(&sd->gspca_dev, 1); | ||
352 | if (err < 0) | ||
353 | return err; | ||
354 | break; | ||
234 | } | 355 | } |
235 | return err; | 356 | if (err < 0) |
357 | return err; | ||
358 | |||
359 | err = s5k4aa_set_exposure(&sd->gspca_dev, | ||
360 | sensor_settings[EXPOSURE_IDX]); | ||
361 | if (err < 0) | ||
362 | return err; | ||
363 | |||
364 | err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
365 | if (err < 0) | ||
366 | return err; | ||
367 | |||
368 | err = s5k4aa_set_brightness(&sd->gspca_dev, | ||
369 | sensor_settings[BRIGHTNESS_IDX]); | ||
370 | if (err < 0) | ||
371 | return err; | ||
372 | |||
373 | err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); | ||
374 | if (err < 0) | ||
375 | return err; | ||
376 | |||
377 | err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
236 | } | 382 | } |
237 | 383 | ||
238 | int s5k4aa_init(struct sd *sd) | 384 | int s5k4aa_init(struct sd *sd) |
@@ -270,62 +416,28 @@ int s5k4aa_init(struct sd *sd) | |||
270 | if (dump_sensor) | 416 | if (dump_sensor) |
271 | s5k4aa_dump_registers(sd); | 417 | s5k4aa_dump_registers(sd); |
272 | 418 | ||
273 | if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { | 419 | return err; |
274 | u8 data = 0x02; | ||
275 | info("vertical flip quirk active"); | ||
276 | m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
277 | m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
278 | data |= S5K4AA_RM_V_FLIP; | ||
279 | data &= ~S5K4AA_RM_H_FLIP; | ||
280 | m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
281 | |||
282 | /* Decrement COLSTART to preserve color order (BGGR) */ | ||
283 | m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
284 | data--; | ||
285 | m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
286 | |||
287 | /* Increment ROWSTART to preserve color order (BGGR) */ | ||
288 | m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
289 | data++; | ||
290 | m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
291 | } | ||
292 | |||
293 | return (err < 0) ? err : 0; | ||
294 | } | ||
295 | |||
296 | int s5k4aa_power_down(struct sd *sd) | ||
297 | { | ||
298 | return 0; | ||
299 | } | 420 | } |
300 | 421 | ||
301 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 422 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
302 | { | 423 | { |
303 | struct sd *sd = (struct sd *) gspca_dev; | 424 | struct sd *sd = (struct sd *) gspca_dev; |
304 | u8 data = S5K4AA_PAGE_MAP_2; | 425 | s32 *sensor_settings = sd->sensor_priv; |
305 | int err; | ||
306 | |||
307 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
308 | if (err < 0) | ||
309 | return err; | ||
310 | 426 | ||
311 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); | 427 | *val = sensor_settings[EXPOSURE_IDX]; |
312 | if (err < 0) | ||
313 | return err; | ||
314 | |||
315 | *val = data << 8; | ||
316 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); | ||
317 | *val |= data; | ||
318 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 428 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
319 | 429 | ||
320 | return err; | 430 | return 0; |
321 | } | 431 | } |
322 | 432 | ||
323 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 433 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
324 | { | 434 | { |
325 | struct sd *sd = (struct sd *) gspca_dev; | 435 | struct sd *sd = (struct sd *) gspca_dev; |
436 | s32 *sensor_settings = sd->sensor_priv; | ||
326 | u8 data = S5K4AA_PAGE_MAP_2; | 437 | u8 data = S5K4AA_PAGE_MAP_2; |
327 | int err; | 438 | int err; |
328 | 439 | ||
440 | sensor_settings[EXPOSURE_IDX] = val; | ||
329 | PDEBUG(D_V4L2, "Set exposure to %d", val); | 441 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
330 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 442 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
331 | if (err < 0) | 443 | if (err < 0) |
@@ -340,29 +452,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
340 | return err; | 452 | return err; |
341 | } | 453 | } |
342 | 454 | ||
343 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 455 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
344 | { | 456 | { |
345 | struct sd *sd = (struct sd *) gspca_dev; | 457 | struct sd *sd = (struct sd *) gspca_dev; |
346 | u8 data = S5K4AA_PAGE_MAP_2; | 458 | s32 *sensor_settings = sd->sensor_priv; |
347 | int err; | ||
348 | |||
349 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | 459 | ||
353 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 460 | *val = sensor_settings[VFLIP_IDX]; |
354 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; | ||
355 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 461 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
356 | 462 | ||
357 | return err; | 463 | return 0; |
358 | } | 464 | } |
359 | 465 | ||
360 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 466 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
361 | { | 467 | { |
362 | struct sd *sd = (struct sd *) gspca_dev; | 468 | struct sd *sd = (struct sd *) gspca_dev; |
469 | s32 *sensor_settings = sd->sensor_priv; | ||
363 | u8 data = S5K4AA_PAGE_MAP_2; | 470 | u8 data = S5K4AA_PAGE_MAP_2; |
364 | int err; | 471 | int err; |
365 | 472 | ||
473 | sensor_settings[VFLIP_IDX] = val; | ||
474 | |||
366 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 475 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
367 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
368 | if (err < 0) | 477 | if (err < 0) |
@@ -370,56 +479,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
370 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 479 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
371 | if (err < 0) | 480 | if (err < 0) |
372 | return err; | 481 | return err; |
373 | data = ((data & ~S5K4AA_RM_V_FLIP) | 482 | |
374 | | ((val & 0x01) << 7)); | 483 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
375 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
376 | if (err < 0) | 484 | if (err < 0) |
377 | return err; | 485 | return err; |
378 | 486 | ||
379 | if (val) { | 487 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) |
380 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 488 | val = !val; |
381 | if (err < 0) | ||
382 | return err; | ||
383 | |||
384 | data++; | ||
385 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
386 | } else { | ||
387 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
388 | if (err < 0) | ||
389 | return err; | ||
390 | 489 | ||
391 | data--; | 490 | data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7)); |
392 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 491 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
393 | } | 492 | if (err < 0) |
493 | return err; | ||
394 | 494 | ||
495 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
496 | if (err < 0) | ||
497 | return err; | ||
498 | data = (data & 0xfe) | !val; | ||
499 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
395 | return err; | 500 | return err; |
396 | } | 501 | } |
397 | 502 | ||
398 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 503 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
399 | { | 504 | { |
400 | struct sd *sd = (struct sd *) gspca_dev; | 505 | struct sd *sd = (struct sd *) gspca_dev; |
401 | u8 data = S5K4AA_PAGE_MAP_2; | 506 | s32 *sensor_settings = sd->sensor_priv; |
402 | int err; | ||
403 | |||
404 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
405 | if (err < 0) | ||
406 | return err; | ||
407 | 507 | ||
408 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 508 | *val = sensor_settings[HFLIP_IDX]; |
409 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; | ||
410 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 509 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
411 | 510 | ||
412 | return err; | 511 | return 0; |
413 | } | 512 | } |
414 | 513 | ||
415 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 514 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
416 | { | 515 | { |
417 | struct sd *sd = (struct sd *) gspca_dev; | 516 | struct sd *sd = (struct sd *) gspca_dev; |
517 | s32 *sensor_settings = sd->sensor_priv; | ||
418 | u8 data = S5K4AA_PAGE_MAP_2; | 518 | u8 data = S5K4AA_PAGE_MAP_2; |
419 | int err; | 519 | int err; |
420 | 520 | ||
421 | PDEBUG(D_V4L2, "Set horizontal flip to %d", | 521 | sensor_settings[HFLIP_IDX] = val; |
422 | val); | 522 | |
523 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | ||
423 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 524 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
424 | if (err < 0) | 525 | if (err < 0) |
425 | return err; | 526 | return err; |
@@ -427,62 +528,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
427 | if (err < 0) | 528 | if (err < 0) |
428 | return err; | 529 | return err; |
429 | 530 | ||
531 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
532 | if (err < 0) | ||
533 | return err; | ||
534 | |||
535 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) | ||
536 | val = !val; | ||
537 | |||
430 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); | 538 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); |
431 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 539 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
432 | if (err < 0) | 540 | if (err < 0) |
433 | return err; | 541 | return err; |
434 | 542 | ||
435 | if (val) { | 543 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
436 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | 544 | if (err < 0) |
437 | if (err < 0) | 545 | return err; |
438 | return err; | 546 | data = (data & 0xfe) | !val; |
439 | data++; | 547 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
440 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
441 | if (err < 0) | ||
442 | return err; | ||
443 | } else { | ||
444 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
445 | if (err < 0) | ||
446 | return err; | ||
447 | data--; | ||
448 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
449 | } | ||
450 | |||
451 | return err; | 548 | return err; |
452 | } | 549 | } |
453 | 550 | ||
454 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 551 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
552 | { | ||
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | s32 *sensor_settings = sd->sensor_priv; | ||
555 | |||
556 | *val = sensor_settings[GAIN_IDX]; | ||
557 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
455 | { | 562 | { |
456 | struct sd *sd = (struct sd *) gspca_dev; | 563 | struct sd *sd = (struct sd *) gspca_dev; |
564 | s32 *sensor_settings = sd->sensor_priv; | ||
457 | u8 data = S5K4AA_PAGE_MAP_2; | 565 | u8 data = S5K4AA_PAGE_MAP_2; |
458 | int err; | 566 | int err; |
459 | 567 | ||
568 | sensor_settings[GAIN_IDX] = val; | ||
569 | |||
570 | PDEBUG(D_V4L2, "Set gain to %d", val); | ||
460 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 571 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
461 | if (err < 0) | 572 | if (err < 0) |
462 | return err; | 573 | return err; |
463 | 574 | ||
464 | err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 575 | data = val & 0xff; |
465 | *val = data; | 576 | err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1); |
466 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
467 | 577 | ||
468 | return err; | 578 | return err; |
469 | } | 579 | } |
470 | 580 | ||
471 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 581 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
582 | { | ||
583 | struct sd *sd = (struct sd *) gspca_dev; | ||
584 | s32 *sensor_settings = sd->sensor_priv; | ||
585 | |||
586 | *val = sensor_settings[BRIGHTNESS_IDX]; | ||
587 | PDEBUG(D_V4L2, "Read brightness %d", *val); | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | ||
472 | { | 592 | { |
473 | struct sd *sd = (struct sd *) gspca_dev; | 593 | struct sd *sd = (struct sd *) gspca_dev; |
594 | s32 *sensor_settings = sd->sensor_priv; | ||
474 | u8 data = S5K4AA_PAGE_MAP_2; | 595 | u8 data = S5K4AA_PAGE_MAP_2; |
475 | int err; | 596 | int err; |
476 | 597 | ||
477 | PDEBUG(D_V4L2, "Set gain to %d", val); | 598 | sensor_settings[BRIGHTNESS_IDX] = val; |
599 | |||
600 | PDEBUG(D_V4L2, "Set brightness to %d", val); | ||
478 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 601 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
479 | if (err < 0) | 602 | if (err < 0) |
480 | return err; | 603 | return err; |
481 | 604 | ||
482 | data = val & 0xff; | 605 | data = val & 0xff; |
483 | err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 606 | return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1); |
607 | } | ||
484 | 608 | ||
485 | return err; | 609 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) |
610 | { | ||
611 | struct sd *sd = (struct sd *) gspca_dev; | ||
612 | s32 *sensor_settings = sd->sensor_priv; | ||
613 | |||
614 | *val = sensor_settings[NOISE_SUPP_IDX]; | ||
615 | PDEBUG(D_V4L2, "Read noise %d", *val); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) | ||
620 | { | ||
621 | struct sd *sd = (struct sd *) gspca_dev; | ||
622 | s32 *sensor_settings = sd->sensor_priv; | ||
623 | u8 data = S5K4AA_PAGE_MAP_2; | ||
624 | int err; | ||
625 | |||
626 | sensor_settings[NOISE_SUPP_IDX] = val; | ||
627 | |||
628 | PDEBUG(D_V4L2, "Set noise to %d", val); | ||
629 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
630 | if (err < 0) | ||
631 | return err; | ||
632 | |||
633 | data = val & 0x01; | ||
634 | return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); | ||
635 | } | ||
636 | |||
637 | void s5k4aa_disconnect(struct sd *sd) | ||
638 | { | ||
639 | sd->sensor = NULL; | ||
640 | kfree(sd->sensor_priv); | ||
486 | } | 641 | } |
487 | 642 | ||
488 | static void s5k4aa_dump_registers(struct sd *sd) | 643 | static void s5k4aa_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index ca854d4f9475..4440da4e7f0f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h | |||
@@ -47,8 +47,9 @@ | |||
47 | #define S5K4AA_H_BLANK_LO__ 0x1e | 47 | #define S5K4AA_H_BLANK_LO__ 0x1e |
48 | #define S5K4AA_EXPOSURE_HI 0x17 | 48 | #define S5K4AA_EXPOSURE_HI 0x17 |
49 | #define S5K4AA_EXPOSURE_LO 0x18 | 49 | #define S5K4AA_EXPOSURE_LO 0x18 |
50 | #define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ | 50 | #define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */ |
51 | #define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ | 51 | #define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */ |
52 | #define S5K4AA_NOISE_SUPP 0x37 | ||
52 | 53 | ||
53 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 | 54 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 |
54 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 | 55 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 |
@@ -57,6 +58,9 @@ | |||
57 | #define S5K4AA_RM_H_FLIP 0x40 | 58 | #define S5K4AA_RM_H_FLIP 0x40 |
58 | #define S5K4AA_RM_V_FLIP 0x80 | 59 | #define S5K4AA_RM_V_FLIP 0x80 |
59 | 60 | ||
61 | #define S5K4AA_DEFAULT_GAIN 0x5f | ||
62 | #define S5K4AA_DEFAULT_BRIGHTNESS 0x10 | ||
63 | |||
60 | /*****************************************************************************/ | 64 | /*****************************************************************************/ |
61 | 65 | ||
62 | /* Kernel module parameters */ | 66 | /* Kernel module parameters */ |
@@ -66,25 +70,17 @@ extern int dump_sensor; | |||
66 | int s5k4aa_probe(struct sd *sd); | 70 | int s5k4aa_probe(struct sd *sd); |
67 | int s5k4aa_init(struct sd *sd); | 71 | int s5k4aa_init(struct sd *sd); |
68 | int s5k4aa_start(struct sd *sd); | 72 | int s5k4aa_start(struct sd *sd); |
69 | int s5k4aa_power_down(struct sd *sd); | 73 | void s5k4aa_disconnect(struct sd *sd); |
70 | |||
71 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
73 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
74 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
75 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
76 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
77 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
78 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
79 | 74 | ||
80 | static const struct m5602_sensor s5k4aa = { | 75 | static const struct m5602_sensor s5k4aa = { |
81 | .name = "S5K4AA", | 76 | .name = "S5K4AA", |
77 | .i2c_slave_id = 0x5a, | ||
78 | .i2c_regW = 2, | ||
79 | |||
82 | .probe = s5k4aa_probe, | 80 | .probe = s5k4aa_probe, |
83 | .init = s5k4aa_init, | 81 | .init = s5k4aa_init, |
84 | .start = s5k4aa_start, | 82 | .start = s5k4aa_start, |
85 | .power_down = s5k4aa_power_down, | 83 | .disconnect = s5k4aa_disconnect, |
86 | .i2c_slave_id = 0x5a, | ||
87 | .i2c_regW = 2, | ||
88 | }; | 84 | }; |
89 | 85 | ||
90 | static const unsigned char preinit_s5k4aa[][4] = | 86 | static const unsigned char preinit_s5k4aa[][4] = |
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] = | |||
179 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 175 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
180 | {SENSOR, 0x0c, 0x05, 0x00}, | 176 | {SENSOR, 0x0c, 0x05, 0x00}, |
181 | {SENSOR, 0x02, 0x0e, 0x00}, | 177 | {SENSOR, 0x02, 0x0e, 0x00}, |
182 | {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00}, | ||
183 | {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00}, | ||
184 | {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00}, | ||
185 | {SENSOR, 0x11, 0x00, 0x00}, | ||
186 | {SENSOR, 0x12, 0x00, 0x00}, | ||
187 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
188 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, | 178 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, |
189 | {SENSOR, 0x37, 0x00, 0x00}, | 179 | {SENSOR, 0x37, 0x00, 0x00}, |
190 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 180 | }; |
191 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | ||
192 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | ||
193 | {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00}, | ||
194 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | ||
195 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00}, | ||
196 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | ||
197 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00}, | ||
198 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | ||
199 | {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00}, | ||
200 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00}, | ||
201 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00}, | ||
202 | {SENSOR, 0x11, 0x04, 0x00}, | ||
203 | {SENSOR, 0x12, 0xc3, 0x00}, | ||
204 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
205 | 181 | ||
182 | static const unsigned char VGA_s5k4aa[][4] = | ||
183 | { | ||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 184 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 185 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
208 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 186 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] = | |||
238 | {SENSOR, 0x37, 0x01, 0x00}, | 216 | {SENSOR, 0x37, 0x01, 0x00}, |
239 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | 217 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ |
240 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 218 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
241 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 219 | {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00}, |
242 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 220 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
243 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 221 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, |
244 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 222 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ |
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] = | |||
255 | {SENSOR, 0x12, 0xc3, 0x00}, | 233 | {SENSOR, 0x12, 0xc3, 0x00}, |
256 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 234 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
257 | {SENSOR, 0x02, 0x0e, 0x00}, | 235 | {SENSOR, 0x02, 0x0e, 0x00}, |
258 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
259 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
260 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
261 | }; | 236 | }; |
262 | 237 | ||
263 | static const unsigned char VGA_s5k4aa[][4] = | 238 | static const unsigned char SXGA_s5k4aa[][4] = |
264 | { | 239 | { |
265 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 240 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
266 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 241 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] = | |||
273 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
276 | /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ | 251 | /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */ |
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, |
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | 253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
281 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 256 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
282 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | 257 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, |
283 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 258 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 259 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
285 | /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ | 260 | /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */ |
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, |
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, | 262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 263 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 264 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ | 265 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ |
291 | 266 | ||
292 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 267 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
293 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X | 268 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00}, |
294 | | S5K4AA_RM_COL_SKIP_2X, 0x00}, | ||
295 | /* 0x37 : Fix image stability when light is too bright and improves | ||
296 | * image quality in 640x480, but worsens it in 1280x1024 */ | ||
297 | {SENSOR, 0x37, 0x01, 0x00}, | 269 | {SENSOR, 0x37, 0x01, 0x00}, |
298 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | ||
299 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 270 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
300 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 271 | {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00}, |
301 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 272 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
302 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 273 | {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00}, |
303 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 274 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00}, |
304 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | 275 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00}, |
305 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00}, | ||
306 | /* window_width_hi, window_width_lo : 1280 = 0x0500 */ | ||
307 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | 276 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, |
308 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, | 277 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, |
309 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | 278 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00}, |
310 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ | 279 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, |
311 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, | 280 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, |
312 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, | 281 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, |
313 | {SENSOR, 0x11, 0x04, 0x00}, | 282 | {SENSOR, 0x11, 0x04, 0x00}, |
314 | {SENSOR, 0x12, 0xc3, 0x00}, | 283 | {SENSOR, 0x12, 0xc3, 0x00}, |
315 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 284 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
316 | {SENSOR, 0x02, 0x0e, 0x00}, | 285 | {SENSOR, 0x02, 0x0e, 0x00}, |
317 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
318 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
319 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
320 | }; | 286 | }; |
321 | 287 | ||
288 | |||
322 | #endif | 289 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index 42c86aa4dc8d..7127321ace8c 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c | |||
@@ -16,8 +16,20 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kthread.h> | ||
19 | #include "m5602_s5k83a.h" | 20 | #include "m5602_s5k83a.h" |
20 | 21 | ||
22 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
29 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
30 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
31 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
32 | |||
21 | static struct v4l2_pix_format s5k83a_modes[] = { | 33 | static struct v4l2_pix_format s5k83a_modes[] = { |
22 | { | 34 | { |
23 | 640, | 35 | 640, |
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = { | |||
32 | } | 44 | } |
33 | }; | 45 | }; |
34 | 46 | ||
35 | const static struct ctrl s5k83a_ctrls[] = { | 47 | static const struct ctrl s5k83a_ctrls[] = { |
48 | #define GAIN_IDX 0 | ||
36 | { | 49 | { |
37 | { | 50 | { |
38 | .id = V4L2_CID_BRIGHTNESS, | 51 | .id = V4L2_CID_GAIN, |
39 | .type = V4L2_CTRL_TYPE_INTEGER, | 52 | .type = V4L2_CTRL_TYPE_INTEGER, |
40 | .name = "brightness", | 53 | .name = "gain", |
41 | .minimum = 0x00, | 54 | .minimum = 0x00, |
42 | .maximum = 0xff, | 55 | .maximum = 0xff, |
43 | .step = 0x01, | 56 | .step = 0x01, |
44 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, | 57 | .default_value = S5K83A_DEFAULT_GAIN, |
45 | .flags = V4L2_CTRL_FLAG_SLIDER | 58 | .flags = V4L2_CTRL_FLAG_SLIDER |
46 | }, | 59 | }, |
47 | .set = s5k83a_set_brightness, | 60 | .set = s5k83a_set_gain, |
48 | .get = s5k83a_get_brightness | 61 | .get = s5k83a_get_gain |
49 | 62 | ||
50 | }, { | 63 | }, |
64 | #define BRIGHTNESS_IDX 1 | ||
65 | { | ||
51 | { | 66 | { |
52 | .id = V4L2_CID_WHITENESS, | 67 | .id = V4L2_CID_BRIGHTNESS, |
53 | .type = V4L2_CTRL_TYPE_INTEGER, | 68 | .type = V4L2_CTRL_TYPE_INTEGER, |
54 | .name = "whiteness", | 69 | .name = "brightness", |
55 | .minimum = 0x00, | 70 | .minimum = 0x00, |
56 | .maximum = 0xff, | 71 | .maximum = 0xff, |
57 | .step = 0x01, | 72 | .step = 0x01, |
58 | .default_value = S5K83A_DEFAULT_WHITENESS, | 73 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, |
59 | .flags = V4L2_CTRL_FLAG_SLIDER | 74 | .flags = V4L2_CTRL_FLAG_SLIDER |
60 | }, | 75 | }, |
61 | .set = s5k83a_set_whiteness, | 76 | .set = s5k83a_set_brightness, |
62 | .get = s5k83a_get_whiteness, | 77 | .get = s5k83a_get_brightness, |
63 | }, { | 78 | }, |
79 | #define EXPOSURE_IDX 2 | ||
80 | { | ||
64 | { | 81 | { |
65 | .id = V4L2_CID_GAIN, | 82 | .id = V4L2_CID_EXPOSURE, |
66 | .type = V4L2_CTRL_TYPE_INTEGER, | 83 | .type = V4L2_CTRL_TYPE_INTEGER, |
67 | .name = "gain", | 84 | .name = "exposure", |
68 | .minimum = 0x00, | 85 | .minimum = 0x00, |
69 | .maximum = S5K83A_MAXIMUM_GAIN, | 86 | .maximum = S5K83A_MAXIMUM_EXPOSURE, |
70 | .step = 0x01, | 87 | .step = 0x01, |
71 | .default_value = S5K83A_DEFAULT_GAIN, | 88 | .default_value = S5K83A_DEFAULT_EXPOSURE, |
72 | .flags = V4L2_CTRL_FLAG_SLIDER | 89 | .flags = V4L2_CTRL_FLAG_SLIDER |
73 | }, | 90 | }, |
74 | .set = s5k83a_set_gain, | 91 | .set = s5k83a_set_exposure, |
75 | .get = s5k83a_get_gain | 92 | .get = s5k83a_get_exposure |
76 | }, { | 93 | }, |
94 | #define HFLIP_IDX 3 | ||
95 | { | ||
77 | { | 96 | { |
78 | .id = V4L2_CID_HFLIP, | 97 | .id = V4L2_CID_HFLIP, |
79 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 98 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
80 | .name = "horizontal flip", | 99 | .name = "horizontal flip", |
81 | .minimum = 0, | 100 | .minimum = 0, |
82 | .maximum = 1, | 101 | .maximum = 1, |
83 | .step = 1, | 102 | .step = 1, |
84 | .default_value = 0 | 103 | .default_value = 0 |
85 | }, | 104 | }, |
86 | .set = s5k83a_set_hflip, | 105 | .set = s5k83a_set_hflip, |
87 | .get = s5k83a_get_hflip | 106 | .get = s5k83a_get_hflip |
88 | }, { | 107 | }, |
108 | #define VFLIP_IDX 4 | ||
109 | { | ||
89 | { | 110 | { |
90 | .id = V4L2_CID_VFLIP, | 111 | .id = V4L2_CID_VFLIP, |
91 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 112 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
92 | .name = "vertical flip", | 113 | .name = "vertical flip", |
93 | .minimum = 0, | 114 | .minimum = 0, |
94 | .maximum = 1, | 115 | .maximum = 1, |
95 | .step = 1, | 116 | .step = 1, |
96 | .default_value = 0 | 117 | .default_value = 0 |
97 | }, | 118 | }, |
98 | .set = s5k83a_set_vflip, | 119 | .set = s5k83a_set_vflip, |
99 | .get = s5k83a_get_vflip | 120 | .get = s5k83a_get_vflip |
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = { | |||
101 | }; | 122 | }; |
102 | 123 | ||
103 | static void s5k83a_dump_registers(struct sd *sd); | 124 | static void s5k83a_dump_registers(struct sd *sd); |
125 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); | ||
126 | static int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
127 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, | ||
128 | __s32 vflip, __s32 hflip); | ||
104 | 129 | ||
105 | int s5k83a_probe(struct sd *sd) | 130 | int s5k83a_probe(struct sd *sd) |
106 | { | 131 | { |
132 | struct s5k83a_priv *sens_priv; | ||
107 | u8 prod_id = 0, ver_id = 0; | 133 | u8 prod_id = 0, ver_id = 0; |
108 | int i, err = 0; | 134 | int i, err = 0; |
109 | 135 | ||
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd) | |||
145 | info("Detected a s5k83a sensor"); | 171 | info("Detected a s5k83a sensor"); |
146 | 172 | ||
147 | sensor_found: | 173 | sensor_found: |
174 | sens_priv = kmalloc( | ||
175 | sizeof(struct s5k83a_priv), GFP_KERNEL); | ||
176 | if (!sens_priv) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | sens_priv->settings = | ||
180 | kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); | ||
181 | if (!sens_priv->settings) | ||
182 | return -ENOMEM; | ||
183 | |||
148 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; | 184 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; |
149 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); | 185 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); |
150 | sd->desc->ctrls = s5k83a_ctrls; | 186 | sd->desc->ctrls = s5k83a_ctrls; |
151 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); | 187 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); |
188 | |||
189 | /* null the pointer! thread is't running now */ | ||
190 | sens_priv->rotation_thread = NULL; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) | ||
193 | sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; | ||
194 | |||
195 | sd->sensor_priv = sens_priv; | ||
152 | return 0; | 196 | return 0; |
153 | } | 197 | } |
154 | 198 | ||
155 | int s5k83a_init(struct sd *sd) | 199 | int s5k83a_init(struct sd *sd) |
156 | { | 200 | { |
157 | int i, err = 0; | 201 | int i, err = 0; |
202 | s32 *sensor_settings = | ||
203 | ((struct s5k83a_priv *) sd->sensor_priv)->settings; | ||
158 | 204 | ||
159 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { | 205 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { |
160 | u8 data[2] = {0x00, 0x00}; | 206 | u8 data[2] = {0x00, 0x00}; |
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd) | |||
187 | if (dump_sensor) | 233 | if (dump_sensor) |
188 | s5k83a_dump_registers(sd); | 234 | s5k83a_dump_registers(sd); |
189 | 235 | ||
190 | return (err < 0) ? err : 0; | 236 | err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); |
191 | } | 237 | if (err < 0) |
238 | return err; | ||
192 | 239 | ||
193 | int s5k83a_start(struct sd *sd) | 240 | err = s5k83a_set_brightness(&sd->gspca_dev, |
194 | { | 241 | sensor_settings[BRIGHTNESS_IDX]); |
195 | return s5k83a_set_led_indication(sd, 1); | 242 | if (err < 0) |
196 | } | 243 | return err; |
197 | 244 | ||
198 | int s5k83a_stop(struct sd *sd) | 245 | err = s5k83a_set_exposure(&sd->gspca_dev, |
199 | { | 246 | sensor_settings[EXPOSURE_IDX]); |
200 | return s5k83a_set_led_indication(sd, 0); | 247 | if (err < 0) |
248 | return err; | ||
249 | |||
250 | err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
251 | if (err < 0) | ||
252 | return err; | ||
253 | |||
254 | err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
255 | |||
256 | return err; | ||
201 | } | 257 | } |
202 | 258 | ||
203 | int s5k83a_power_down(struct sd *sd) | 259 | static int rotation_thread_function(void *data) |
204 | { | 260 | { |
261 | struct sd *sd = (struct sd *) data; | ||
262 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
263 | u8 reg, previous_rotation = 0; | ||
264 | __s32 vflip, hflip; | ||
265 | |||
266 | set_current_state(TASK_INTERRUPTIBLE); | ||
267 | while (!schedule_timeout(100)) { | ||
268 | if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock)) | ||
269 | break; | ||
270 | |||
271 | s5k83a_get_rotation(sd, ®); | ||
272 | if (previous_rotation != reg) { | ||
273 | previous_rotation = reg; | ||
274 | info("Camera was flipped"); | ||
275 | |||
276 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
277 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
278 | |||
279 | if (reg) { | ||
280 | vflip = !vflip; | ||
281 | hflip = !hflip; | ||
282 | } | ||
283 | s5k83a_set_flip_real((struct gspca_dev *) sd, | ||
284 | vflip, hflip); | ||
285 | } | ||
286 | |||
287 | mutex_unlock(&sd->gspca_dev.usb_lock); | ||
288 | set_current_state(TASK_INTERRUPTIBLE); | ||
289 | } | ||
290 | |||
291 | /* return to "front" flip */ | ||
292 | if (previous_rotation) { | ||
293 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
294 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
295 | s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); | ||
296 | } | ||
297 | |||
298 | sens_priv->rotation_thread = NULL; | ||
205 | return 0; | 299 | return 0; |
206 | } | 300 | } |
207 | 301 | ||
208 | static void s5k83a_dump_registers(struct sd *sd) | 302 | int s5k83a_start(struct sd *sd) |
209 | { | 303 | { |
210 | int address; | 304 | int i, err = 0; |
211 | u8 page, old_page; | 305 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
212 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
213 | 306 | ||
214 | for (page = 0; page < 16; page++) { | 307 | /* Create another thread, polling the GPIO ports of the camera to check |
215 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 308 | if it got rotated. This is how the windows driver does it so we have |
216 | info("Dumping the s5k83a register state for page 0x%x", page); | 309 | to assume that there is no better way of accomplishing this */ |
217 | for (address = 0; address <= 0xff; address++) { | 310 | sens_priv->rotation_thread = kthread_create(rotation_thread_function, |
218 | u8 val = 0; | 311 | sd, "rotation thread"); |
219 | m5602_read_sensor(sd, address, &val, 1); | 312 | wake_up_process(sens_priv->rotation_thread); |
220 | info("register 0x%x contains 0x%x", | 313 | |
221 | address, val); | 314 | /* Preinit the sensor */ |
222 | } | 315 | for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { |
316 | u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]}; | ||
317 | if (start_s5k83a[i][0] == SENSOR) | ||
318 | err = m5602_write_sensor(sd, start_s5k83a[i][1], | ||
319 | data, 2); | ||
320 | else | ||
321 | err = m5602_write_bridge(sd, start_s5k83a[i][1], | ||
322 | data[0]); | ||
223 | } | 323 | } |
224 | info("s5k83a register state dump complete"); | 324 | if (err < 0) |
325 | return err; | ||
225 | 326 | ||
226 | for (page = 0; page < 16; page++) { | 327 | return s5k83a_set_led_indication(sd, 1); |
227 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 328 | } |
228 | info("Probing for which registers that are read/write " | ||
229 | "for page 0x%x", page); | ||
230 | for (address = 0; address <= 0xff; address++) { | ||
231 | u8 old_val, ctrl_val, test_val = 0xff; | ||
232 | 329 | ||
233 | m5602_read_sensor(sd, address, &old_val, 1); | 330 | int s5k83a_stop(struct sd *sd) |
234 | m5602_write_sensor(sd, address, &test_val, 1); | 331 | { |
235 | m5602_read_sensor(sd, address, &ctrl_val, 1); | 332 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
236 | 333 | ||
237 | if (ctrl_val == test_val) | 334 | if (sens_priv->rotation_thread) |
238 | info("register 0x%x is writeable", address); | 335 | kthread_stop(sens_priv->rotation_thread); |
239 | else | ||
240 | info("register 0x%x is read only", address); | ||
241 | 336 | ||
242 | /* Restore original val */ | 337 | return s5k83a_set_led_indication(sd, 0); |
243 | m5602_write_sensor(sd, address, &old_val, 1); | ||
244 | } | ||
245 | } | ||
246 | info("Read/write register probing complete"); | ||
247 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
248 | } | 338 | } |
249 | 339 | ||
250 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 340 | void s5k83a_disconnect(struct sd *sd) |
251 | { | 341 | { |
252 | int err; | 342 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
253 | u8 data[2]; | ||
254 | struct sd *sd = (struct sd *) gspca_dev; | ||
255 | 343 | ||
256 | err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 344 | s5k83a_stop(sd); |
257 | if (err < 0) | 345 | |
258 | return err; | 346 | sd->sensor = NULL; |
347 | kfree(sens_priv->settings); | ||
348 | kfree(sens_priv); | ||
349 | } | ||
259 | 350 | ||
260 | data[1] = data[1] << 1; | 351 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
261 | *val = data[1]; | 352 | { |
353 | struct sd *sd = (struct sd *) gspca_dev; | ||
354 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
262 | 355 | ||
263 | return err; | 356 | *val = sens_priv->settings[GAIN_IDX]; |
357 | return 0; | ||
264 | } | 358 | } |
265 | 359 | ||
266 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 360 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
267 | { | 361 | { |
268 | int err; | 362 | int err; |
269 | u8 data[2]; | 363 | u8 data[2]; |
270 | struct sd *sd = (struct sd *) gspca_dev; | 364 | struct sd *sd = (struct sd *) gspca_dev; |
365 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
366 | |||
367 | sens_priv->settings[GAIN_IDX] = val; | ||
271 | 368 | ||
272 | data[0] = 0x00; | 369 | data[0] = 0x00; |
273 | data[1] = 0x20; | 370 | data[1] = 0x20; |
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
283 | 380 | ||
284 | /* FIXME: This is not sane, we need to figure out the composition | 381 | /* FIXME: This is not sane, we need to figure out the composition |
285 | of these registers */ | 382 | of these registers */ |
286 | data[0] = val >> 3; /* brightness, high 5 bits */ | 383 | data[0] = val >> 3; /* gain, high 5 bits */ |
287 | data[1] = val >> 1; /* brightness, high 7 bits */ | 384 | data[1] = val >> 1; /* gain, high 7 bits */ |
288 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 385 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); |
289 | 386 | ||
290 | return err; | 387 | return err; |
291 | } | 388 | } |
292 | 389 | ||
293 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) | 390 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
294 | { | 391 | { |
295 | int err; | ||
296 | u8 data; | ||
297 | struct sd *sd = (struct sd *) gspca_dev; | 392 | struct sd *sd = (struct sd *) gspca_dev; |
393 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
298 | 394 | ||
299 | err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1); | 395 | *val = sens_priv->settings[BRIGHTNESS_IDX]; |
300 | if (err < 0) | 396 | return 0; |
301 | return err; | ||
302 | |||
303 | *val = data; | ||
304 | |||
305 | return err; | ||
306 | } | 397 | } |
307 | 398 | ||
308 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) | 399 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) |
309 | { | 400 | { |
310 | int err; | 401 | int err; |
311 | u8 data[1]; | 402 | u8 data[1]; |
312 | struct sd *sd = (struct sd *) gspca_dev; | 403 | struct sd *sd = (struct sd *) gspca_dev; |
404 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
313 | 405 | ||
406 | sens_priv->settings[BRIGHTNESS_IDX] = val; | ||
314 | data[0] = val; | 407 | data[0] = val; |
315 | err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1); | 408 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); |
316 | |||
317 | return err; | 409 | return err; |
318 | } | 410 | } |
319 | 411 | ||
320 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 412 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
321 | { | 413 | { |
322 | int err; | ||
323 | u8 data[2]; | ||
324 | struct sd *sd = (struct sd *) gspca_dev; | 414 | struct sd *sd = (struct sd *) gspca_dev; |
415 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
325 | 416 | ||
326 | err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2); | 417 | *val = sens_priv->settings[EXPOSURE_IDX]; |
327 | if (err < 0) | 418 | return 0; |
328 | return err; | ||
329 | |||
330 | data[1] = data[1] & 0x3f; | ||
331 | if (data[1] > S5K83A_MAXIMUM_GAIN) | ||
332 | data[1] = S5K83A_MAXIMUM_GAIN; | ||
333 | |||
334 | *val = data[1]; | ||
335 | |||
336 | return err; | ||
337 | } | 419 | } |
338 | 420 | ||
339 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 421 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
340 | { | 422 | { |
341 | int err; | 423 | int err; |
342 | u8 data[2]; | 424 | u8 data[2]; |
343 | struct sd *sd = (struct sd *) gspca_dev; | 425 | struct sd *sd = (struct sd *) gspca_dev; |
426 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
344 | 427 | ||
428 | sens_priv->settings[EXPOSURE_IDX] = val; | ||
345 | data[0] = 0; | 429 | data[0] = 0; |
346 | data[1] = val; | 430 | data[1] = val; |
347 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); | 431 | err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); |
348 | return err; | 432 | return err; |
349 | } | 433 | } |
350 | 434 | ||
351 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 435 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
352 | { | 436 | { |
353 | int err; | ||
354 | u8 data[1]; | ||
355 | struct sd *sd = (struct sd *) gspca_dev; | 437 | struct sd *sd = (struct sd *) gspca_dev; |
438 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
356 | 439 | ||
357 | data[0] = 0x05; | 440 | *val = sens_priv->settings[VFLIP_IDX]; |
358 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 441 | return 0; |
359 | if (err < 0) | ||
360 | return err; | ||
361 | |||
362 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | ||
363 | *val = (data[0] | 0x40) ? 1 : 0; | ||
364 | |||
365 | return err; | ||
366 | } | 442 | } |
367 | 443 | ||
368 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 444 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, |
445 | __s32 vflip, __s32 hflip) | ||
369 | { | 446 | { |
370 | int err; | 447 | int err; |
371 | u8 data[1]; | 448 | u8 data[1]; |
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
376 | if (err < 0) | 453 | if (err < 0) |
377 | return err; | 454 | return err; |
378 | 455 | ||
379 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 456 | /* six bit is vflip, seven is hflip */ |
380 | if (err < 0) | 457 | data[0] = S5K83A_FLIP_MASK; |
381 | return err; | 458 | data[0] = (vflip) ? data[0] | 0x40 : data[0]; |
459 | data[0] = (hflip) ? data[0] | 0x80 : data[0]; | ||
382 | 460 | ||
383 | /* set or zero six bit, seven is hflip */ | ||
384 | data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK | ||
385 | : (data[0] & 0x80) | S5K83A_FLIP_MASK; | ||
386 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | 461 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); |
387 | if (err < 0) | 462 | if (err < 0) |
388 | return err; | 463 | return err; |
389 | 464 | ||
390 | data[0] = (val) ? 0x0b : 0x0a; | 465 | data[0] = (vflip) ? 0x0b : 0x0a; |
391 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); | 466 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); |
467 | if (err < 0) | ||
468 | return err; | ||
392 | 469 | ||
470 | data[0] = (hflip) ? 0x0a : 0x0b; | ||
471 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
393 | return err; | 472 | return err; |
394 | } | 473 | } |
395 | 474 | ||
396 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 475 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
397 | { | 476 | { |
398 | int err; | 477 | int err; |
399 | u8 data[1]; | 478 | u8 reg; |
479 | __s32 hflip; | ||
400 | struct sd *sd = (struct sd *) gspca_dev; | 480 | struct sd *sd = (struct sd *) gspca_dev; |
481 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
401 | 482 | ||
402 | data[0] = 0x05; | 483 | sens_priv->settings[VFLIP_IDX] = val; |
403 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 484 | |
485 | s5k83a_get_hflip(gspca_dev, &hflip); | ||
486 | |||
487 | err = s5k83a_get_rotation(sd, ®); | ||
404 | if (err < 0) | 488 | if (err < 0) |
405 | return err; | 489 | return err; |
490 | if (reg) { | ||
491 | val = !val; | ||
492 | hflip = !hflip; | ||
493 | } | ||
406 | 494 | ||
407 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 495 | err = s5k83a_set_flip_real(gspca_dev, val, hflip); |
408 | *val = (data[0] | 0x80) ? 1 : 0; | ||
409 | |||
410 | return err; | 496 | return err; |
411 | } | 497 | } |
412 | 498 | ||
413 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 499 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
500 | { | ||
501 | struct sd *sd = (struct sd *) gspca_dev; | ||
502 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
503 | |||
504 | *val = sens_priv->settings[HFLIP_IDX]; | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | ||
414 | { | 509 | { |
415 | int err; | 510 | int err; |
416 | u8 data[1]; | 511 | u8 reg; |
512 | __s32 vflip; | ||
417 | struct sd *sd = (struct sd *) gspca_dev; | 513 | struct sd *sd = (struct sd *) gspca_dev; |
514 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
418 | 515 | ||
419 | data[0] = 0x05; | 516 | sens_priv->settings[HFLIP_IDX] = val; |
420 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | ||
421 | if (err < 0) | ||
422 | return err; | ||
423 | 517 | ||
424 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 518 | s5k83a_get_vflip(gspca_dev, &vflip); |
425 | if (err < 0) | ||
426 | return err; | ||
427 | 519 | ||
428 | /* set or zero seven bit, six is vflip */ | 520 | err = s5k83a_get_rotation(sd, ®); |
429 | data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK | ||
430 | : (data[0] & 0x40) | S5K83A_FLIP_MASK; | ||
431 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | ||
432 | if (err < 0) | 521 | if (err < 0) |
433 | return err; | 522 | return err; |
523 | if (reg) { | ||
524 | val = !val; | ||
525 | vflip = !vflip; | ||
526 | } | ||
434 | 527 | ||
435 | data[0] = (val) ? 0x0a : 0x0b; | 528 | err = s5k83a_set_flip_real(gspca_dev, vflip, val); |
436 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
437 | |||
438 | return err; | 529 | return err; |
439 | } | 530 | } |
440 | 531 | ||
441 | int s5k83a_set_led_indication(struct sd *sd, u8 val) | 532 | static int s5k83a_set_led_indication(struct sd *sd, u8 val) |
442 | { | 533 | { |
443 | int err = 0; | 534 | int err = 0; |
444 | u8 data[1]; | 535 | u8 data[1]; |
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val) | |||
454 | 545 | ||
455 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); | 546 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); |
456 | 547 | ||
457 | return (err < 0) ? err : 0; | 548 | return err; |
549 | } | ||
550 | |||
551 | /* Get camera rotation on Acer notebooks */ | ||
552 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) | ||
553 | { | ||
554 | int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); | ||
555 | *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; | ||
556 | return err; | ||
557 | } | ||
558 | |||
559 | static void s5k83a_dump_registers(struct sd *sd) | ||
560 | { | ||
561 | int address; | ||
562 | u8 page, old_page; | ||
563 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
564 | |||
565 | for (page = 0; page < 16; page++) { | ||
566 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
567 | info("Dumping the s5k83a register state for page 0x%x", page); | ||
568 | for (address = 0; address <= 0xff; address++) { | ||
569 | u8 val = 0; | ||
570 | m5602_read_sensor(sd, address, &val, 1); | ||
571 | info("register 0x%x contains 0x%x", | ||
572 | address, val); | ||
573 | } | ||
574 | } | ||
575 | info("s5k83a register state dump complete"); | ||
576 | |||
577 | for (page = 0; page < 16; page++) { | ||
578 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
579 | info("Probing for which registers that are read/write " | ||
580 | "for page 0x%x", page); | ||
581 | for (address = 0; address <= 0xff; address++) { | ||
582 | u8 old_val, ctrl_val, test_val = 0xff; | ||
583 | |||
584 | m5602_read_sensor(sd, address, &old_val, 1); | ||
585 | m5602_write_sensor(sd, address, &test_val, 1); | ||
586 | m5602_read_sensor(sd, address, &ctrl_val, 1); | ||
587 | |||
588 | if (ctrl_val == test_val) | ||
589 | info("register 0x%x is writeable", address); | ||
590 | else | ||
591 | info("register 0x%x is read only", address); | ||
592 | |||
593 | /* Restore original val */ | ||
594 | m5602_write_sensor(sd, address, &old_val, 1); | ||
595 | } | ||
596 | } | ||
597 | info("Read/write register probing complete"); | ||
598 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
458 | } | 599 | } |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 819ab25272be..7814b078acde 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h | |||
@@ -21,20 +21,21 @@ | |||
21 | 21 | ||
22 | #include "m5602_sensor.h" | 22 | #include "m5602_sensor.h" |
23 | 23 | ||
24 | #define S5K83A_FLIP 0x01 | 24 | #define S5K83A_FLIP 0x01 |
25 | #define S5K83A_HFLIP_TUNE 0x03 | 25 | #define S5K83A_HFLIP_TUNE 0x03 |
26 | #define S5K83A_VFLIP_TUNE 0x05 | 26 | #define S5K83A_VFLIP_TUNE 0x05 |
27 | #define S5K83A_WHITENESS 0x0a | 27 | #define S5K83A_BRIGHTNESS 0x0a |
28 | #define S5K83A_GAIN 0x18 | 28 | #define S5K83A_EXPOSURE 0x18 |
29 | #define S5K83A_BRIGHTNESS 0x1b | 29 | #define S5K83A_GAIN 0x1b |
30 | #define S5K83A_PAGE_MAP 0xec | 30 | #define S5K83A_PAGE_MAP 0xec |
31 | 31 | ||
32 | #define S5K83A_DEFAULT_BRIGHTNESS 0x71 | 32 | #define S5K83A_DEFAULT_GAIN 0x71 |
33 | #define S5K83A_DEFAULT_WHITENESS 0x7e | 33 | #define S5K83A_DEFAULT_BRIGHTNESS 0x7e |
34 | #define S5K83A_DEFAULT_GAIN 0x00 | 34 | #define S5K83A_DEFAULT_EXPOSURE 0x00 |
35 | #define S5K83A_MAXIMUM_GAIN 0x3c | 35 | #define S5K83A_MAXIMUM_EXPOSURE 0x3c |
36 | #define S5K83A_FLIP_MASK 0x10 | 36 | #define S5K83A_FLIP_MASK 0x10 |
37 | #define S5K83A_GPIO_LED_MASK 0x10 | 37 | #define S5K83A_GPIO_LED_MASK 0x10 |
38 | #define S5K83A_GPIO_ROTATION_MASK 0x40 | ||
38 | 39 | ||
39 | /*****************************************************************************/ | 40 | /*****************************************************************************/ |
40 | 41 | ||
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd); | |||
46 | int s5k83a_init(struct sd *sd); | 47 | int s5k83a_init(struct sd *sd); |
47 | int s5k83a_start(struct sd *sd); | 48 | int s5k83a_start(struct sd *sd); |
48 | int s5k83a_stop(struct sd *sd); | 49 | int s5k83a_stop(struct sd *sd); |
49 | int s5k83a_power_down(struct sd *sd); | 50 | void s5k83a_disconnect(struct sd *sd); |
50 | |||
51 | int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
52 | |||
53 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
61 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
62 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
63 | 51 | ||
64 | static const struct m5602_sensor s5k83a = { | 52 | static const struct m5602_sensor s5k83a = { |
65 | .name = "S5K83A", | 53 | .name = "S5K83A", |
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = { | |||
67 | .init = s5k83a_init, | 55 | .init = s5k83a_init, |
68 | .start = s5k83a_start, | 56 | .start = s5k83a_start, |
69 | .stop = s5k83a_stop, | 57 | .stop = s5k83a_stop, |
70 | .power_down = s5k83a_power_down, | 58 | .disconnect = s5k83a_disconnect, |
71 | .i2c_slave_id = 0x5a, | 59 | .i2c_slave_id = 0x5a, |
72 | .i2c_regW = 2, | 60 | .i2c_regW = 2, |
73 | }; | 61 | }; |
74 | 62 | ||
63 | struct s5k83a_priv { | ||
64 | /* We use another thread periodically | ||
65 | probing the orientation of the camera */ | ||
66 | struct task_struct *rotation_thread; | ||
67 | s32 *settings; | ||
68 | }; | ||
69 | |||
75 | static const unsigned char preinit_s5k83a[][4] = | 70 | static const unsigned char preinit_s5k83a[][4] = |
76 | { | 71 | { |
77 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 72 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] = | |||
108 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 103 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
109 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 104 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
110 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | 105 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, |
111 | |||
112 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00} | ||
113 | }; | 106 | }; |
114 | 107 | ||
115 | /* This could probably be considerably shortened. | 108 | /* This could probably be considerably shortened. |
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] = | |||
117 | */ | 110 | */ |
118 | static const unsigned char init_s5k83a[][4] = | 111 | static const unsigned char init_s5k83a[][4] = |
119 | { | 112 | { |
120 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 113 | /* The following sequence is useless after a clean boot |
121 | {SENSOR, 0xaf, 0x01, 0x00}, | 114 | but is necessary after resume from suspend */ |
122 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
123 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
124 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
125 | {SENSOR, 0x01, 0x50, 0x00}, | ||
126 | {SENSOR, 0x12, 0x20, 0x00}, | ||
127 | {SENSOR, 0x17, 0x40, 0x00}, | ||
128 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
129 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
130 | {SENSOR, 0x02, 0x70, 0x00}, | ||
131 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
132 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
133 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
134 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
135 | |||
136 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
137 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
138 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
139 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
140 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
141 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
142 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
143 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
144 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
145 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
146 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
147 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
148 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
149 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
152 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
153 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
154 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
155 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
156 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
157 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
158 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
159 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
160 | |||
161 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
162 | {SENSOR, 0x06, 0x71, 0x00}, | ||
163 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
164 | {SENSOR, 0x08, 0x02, 0x00}, | ||
165 | {SENSOR, 0x09, 0x88, 0x00}, | ||
166 | {SENSOR, 0x14, 0x00, 0x00}, | ||
167 | {SENSOR, 0x15, 0x20, 0x00}, | ||
168 | {SENSOR, 0x19, 0x00, 0x00}, | ||
169 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
170 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
171 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
172 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
173 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
174 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
175 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
182 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
183 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
191 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
193 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
197 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
198 | |||
199 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
200 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 115 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
201 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | 116 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
202 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | 117 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, |
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] = | |||
216 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
217 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | 132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, |
218 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 133 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
219 | {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, | 134 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
220 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 135 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
221 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | 136 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, |
222 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 137 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] = | |||
225 | 140 | ||
226 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 141 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, |
227 | {SENSOR, 0xaf, 0x01, 0x00}, | 142 | {SENSOR, 0xaf, 0x01, 0x00}, |
228 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 143 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, |
229 | /* ff ( init value )is very dark) || 71 and f0 better */ | ||
230 | {SENSOR, 0x7b, 0xff, 0x00}, | 144 | {SENSOR, 0x7b, 0xff, 0x00}, |
231 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 145 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, |
232 | {SENSOR, 0x01, 0x50, 0x00}, | 146 | {SENSOR, 0x01, 0x50, 0x00}, |
233 | {SENSOR, 0x12, 0x20, 0x00}, | 147 | {SENSOR, 0x12, 0x20, 0x00}, |
234 | {SENSOR, 0x17, 0x40, 0x00}, | 148 | {SENSOR, 0x17, 0x40, 0x00}, |
235 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
236 | {SENSOR, 0x1c, 0x00, 0x00}, | 149 | {SENSOR, 0x1c, 0x00, 0x00}, |
237 | {SENSOR, 0x02, 0x70, 0x00}, | 150 | {SENSOR, 0x02, 0x70, 0x00}, |
238 | /* some values like 0x10 give a blue-purple image */ | ||
239 | {SENSOR, 0x03, 0x0b, 0x00}, | 151 | {SENSOR, 0x03, 0x0b, 0x00}, |
240 | {SENSOR, 0x04, 0xf0, 0x00}, | 152 | {SENSOR, 0x04, 0xf0, 0x00}, |
241 | {SENSOR, 0x05, 0x0b, 0x00}, | 153 | {SENSOR, 0x05, 0x0b, 0x00}, |
242 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
243 | |||
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
245 | /* under 80 don't work, highter depend on value */ | ||
246 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
247 | |||
248 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
249 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
250 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
251 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
259 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
260 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
261 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
265 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
269 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
270 | |||
271 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
272 | {SENSOR, 0x06, 0x71, 0x00}, | 154 | {SENSOR, 0x06, 0x71, 0x00}, |
273 | {SENSOR, 0x07, 0xe8, 0x00}, | 155 | {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */ |
274 | {SENSOR, 0x08, 0x02, 0x00}, | 156 | {SENSOR, 0x08, 0x02, 0x00}, |
275 | {SENSOR, 0x09, 0x88, 0x00}, | 157 | {SENSOR, 0x09, 0x88, 0x00}, /* 648 */ |
276 | {SENSOR, 0x14, 0x00, 0x00}, | 158 | {SENSOR, 0x14, 0x00, 0x00}, |
277 | {SENSOR, 0x15, 0x20, 0x00}, | 159 | {SENSOR, 0x15, 0x20, 0x00}, /* 32 */ |
278 | {SENSOR, 0x19, 0x00, 0x00}, | 160 | {SENSOR, 0x19, 0x00, 0x00}, |
279 | {SENSOR, 0x1a, 0x98, 0x00}, | 161 | {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */ |
280 | {SENSOR, 0x0f, 0x02, 0x00}, | 162 | {SENSOR, 0x0f, 0x02, 0x00}, |
281 | {SENSOR, 0x10, 0xe5, 0x00}, | 163 | {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */ |
282 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 164 | /* normal colors |
283 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | 165 | (this is value after boot, but after tries can be different) */ |
284 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | 166 | {SENSOR, 0x00, 0x06, 0x00}, |
285 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | 167 | }; |
286 | |||
287 | /* The following sequence is useless after a clean boot | ||
288 | but is necessary after resume from suspend */ | ||
289 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
290 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
291 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | ||
292 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, | ||
293 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
295 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
296 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
297 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, | ||
299 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
300 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
301 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
302 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
303 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | ||
304 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | ||
305 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | ||
307 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
308 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
309 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
310 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | ||
311 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
312 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | ||
314 | |||
315 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | ||
316 | {SENSOR, 0xaf, 0x01, 0x00}, | ||
317 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
318 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
319 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
320 | {SENSOR, 0x01, 0x50, 0x00}, | ||
321 | {SENSOR, 0x12, 0x20, 0x00}, | ||
322 | {SENSOR, 0x17, 0x40, 0x00}, | ||
323 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
324 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
325 | {SENSOR, 0x02, 0x70, 0x00}, | ||
326 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
327 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
328 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
329 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
330 | 168 | ||
169 | static const unsigned char start_s5k83a[][4] = | ||
170 | { | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 171 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
333 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 173 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] = | |||
340 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 180 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
341 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 181 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
342 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 182 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, |
343 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | 183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */ |
344 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
345 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
346 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 186 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] = | |||
348 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 188 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
349 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 189 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
350 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 190 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, |
351 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | 191 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */ |
352 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
353 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 193 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
354 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 194 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
355 | |||
356 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
357 | {SENSOR, 0x06, 0x71, 0x00}, | ||
358 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
359 | {SENSOR, 0x08, 0x02, 0x00}, | ||
360 | {SENSOR, 0x09, 0x88, 0x00}, | ||
361 | {SENSOR, 0x14, 0x00, 0x00}, | ||
362 | {SENSOR, 0x15, 0x20, 0x00}, | ||
363 | {SENSOR, 0x19, 0x00, 0x00}, | ||
364 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
365 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
366 | |||
367 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
368 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
369 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
370 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
371 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
372 | |||
373 | /* normal colors | ||
374 | (this is value after boot, but after tries can be different) */ | ||
375 | {SENSOR, 0x00, 0x06, 0x00}, | ||
376 | |||
377 | /* set default brightness */ | ||
378 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
379 | {SENSOR_LONG, 0x0d, 0x01, 0x00}, | ||
380 | {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3, | ||
381 | S5K83A_DEFAULT_BRIGHTNESS >> 1}, | ||
382 | |||
383 | /* set default whiteness */ | ||
384 | {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00}, | ||
385 | |||
386 | /* set default gain */ | ||
387 | {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN}, | ||
388 | |||
389 | /* set default flip */ | ||
390 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
391 | {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00}, | ||
392 | {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00}, | ||
393 | {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00} | ||
394 | |||
395 | }; | 195 | }; |
396 | 196 | ||
397 | #endif | 197 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 0d3026936f2e..edff4f1f586f 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/drivers/media/video/gspca/m5602/m5602_sensor.h | |||
@@ -21,13 +21,17 @@ | |||
21 | 21 | ||
22 | #include "m5602_bridge.h" | 22 | #include "m5602_bridge.h" |
23 | 23 | ||
24 | #define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0) | ||
25 | #define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1) | ||
26 | |||
24 | /* Enumerates all supported sensors */ | 27 | /* Enumerates all supported sensors */ |
25 | enum sensors { | 28 | enum sensors { |
26 | OV9650_SENSOR = 1, | 29 | OV9650_SENSOR = 1, |
27 | S5K83A_SENSOR = 2, | 30 | S5K83A_SENSOR = 2, |
28 | S5K4AA_SENSOR = 3, | 31 | S5K4AA_SENSOR = 3, |
29 | MT9M111_SENSOR = 4, | 32 | MT9M111_SENSOR = 4, |
30 | PO1030_SENSOR = 5 | 33 | PO1030_SENSOR = 5, |
34 | OV7660_SENSOR = 6, | ||
31 | }; | 35 | }; |
32 | 36 | ||
33 | /* Enumerates all possible instruction types */ | 37 | /* Enumerates all possible instruction types */ |
@@ -61,9 +65,6 @@ struct m5602_sensor { | |||
61 | 65 | ||
62 | /* Executed when the device is disconnected */ | 66 | /* Executed when the device is disconnected */ |
63 | void (*disconnect)(struct sd *sd); | 67 | void (*disconnect)(struct sd *sd); |
64 | |||
65 | /* Performs a power down sequence */ | ||
66 | int (*power_down)(struct sd *sd); | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | #endif | 70 | #endif |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 2a901a4a6f00..30132513400c 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = { | |||
321 | /* -- module initialisation -- */ | 321 | /* -- module initialisation -- */ |
322 | static const __devinitdata struct usb_device_id device_table[] = { | 322 | static const __devinitdata struct usb_device_id device_table[] = { |
323 | {USB_DEVICE(0x08ca, 0x0111)}, | 323 | {USB_DEVICE(0x08ca, 0x0111)}, |
324 | {USB_DEVICE(0x093a, 0x010f)}, | ||
324 | {} | 325 | {} |
325 | }; | 326 | }; |
326 | MODULE_DEVICE_TABLE(usb, device_table); | 327 | MODULE_DEVICE_TABLE(usb, device_table); |
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = { | |||
347 | /* -- module insert / remove -- */ | 348 | /* -- module insert / remove -- */ |
348 | static int __init sd_mod_init(void) | 349 | static int __init sd_mod_init(void) |
349 | { | 350 | { |
350 | if (usb_register(&sd_driver) < 0) | 351 | int ret; |
351 | return -1; | 352 | |
353 | ret = usb_register(&sd_driver); | ||
354 | if (ret < 0) | ||
355 | return ret; | ||
352 | PDEBUG(D_PROBE, "registered"); | 356 | PDEBUG(D_PROBE, "registered"); |
353 | return 0; | 357 | return 0; |
354 | } | 358 | } |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 1fff37b79891..188866ac6cef 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10; | |||
50 | struct sd { | 50 | struct sd { |
51 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 51 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
52 | 52 | ||
53 | char bridge; | ||
54 | #define BRIDGE_OV511 0 | ||
55 | #define BRIDGE_OV511PLUS 1 | ||
56 | #define BRIDGE_OV518 2 | ||
57 | #define BRIDGE_OV518PLUS 3 | ||
58 | #define BRIDGE_OV519 4 | ||
59 | |||
53 | /* Determined by sensor type */ | 60 | /* Determined by sensor type */ |
54 | __u8 sif; | 61 | __u8 sif; |
55 | 62 | ||
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | |||
87 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | 94 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); |
88 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | 95 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); |
89 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 96 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
97 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
98 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
99 | static void setcolors(struct gspca_dev *gspca_dev); | ||
90 | 100 | ||
91 | static struct ctrl sd_ctrls[] = { | 101 | static struct ctrl sd_ctrls[] = { |
92 | { | 102 | { |
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = { | |||
164 | }, | 174 | }, |
165 | }; | 175 | }; |
166 | 176 | ||
167 | static const struct v4l2_pix_format vga_mode[] = { | 177 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
168 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
169 | .bytesperline = 320, | 179 | .bytesperline = 320, |
170 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 180 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
176 | .colorspace = V4L2_COLORSPACE_JPEG, | 186 | .colorspace = V4L2_COLORSPACE_JPEG, |
177 | .priv = 0}, | 187 | .priv = 0}, |
178 | }; | 188 | }; |
179 | static const struct v4l2_pix_format sif_mode[] = { | 189 | static const struct v4l2_pix_format ov519_sif_mode[] = { |
180 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 190 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
181 | .bytesperline = 176, | 191 | .bytesperline = 176, |
182 | .sizeimage = 176 * 144 * 3 / 8 + 590, | 192 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
189 | .priv = 0}, | 199 | .priv = 0}, |
190 | }; | 200 | }; |
191 | 201 | ||
202 | static const struct v4l2_pix_format ov518_vga_mode[] = { | ||
203 | {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
204 | .bytesperline = 320, | ||
205 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
206 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
207 | .priv = 1}, | ||
208 | {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
209 | .bytesperline = 640, | ||
210 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
211 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
212 | .priv = 0}, | ||
213 | }; | ||
214 | static const struct v4l2_pix_format ov518_sif_mode[] = { | ||
215 | {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
216 | .bytesperline = 176, | ||
217 | .sizeimage = 40000, | ||
218 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
219 | .priv = 1}, | ||
220 | {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
221 | .bytesperline = 352, | ||
222 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
223 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
224 | .priv = 0}, | ||
225 | }; | ||
226 | |||
227 | |||
228 | /* Registers common to OV511 / OV518 */ | ||
229 | #define R51x_SYS_RESET 0x50 | ||
230 | #define R51x_SYS_INIT 0x53 | ||
231 | #define R51x_SYS_SNAP 0x52 | ||
232 | #define R51x_SYS_CUST_ID 0x5F | ||
233 | #define R51x_COMP_LUT_BEGIN 0x80 | ||
234 | |||
235 | /* OV511 Camera interface register numbers */ | ||
236 | #define R511_SYS_LED_CTL 0x55 /* OV511+ only */ | ||
237 | #define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ | ||
238 | |||
239 | /* OV518 Camera interface register numbers */ | ||
240 | #define R518_GPIO_OUT 0x56 /* OV518(+) only */ | ||
241 | #define R518_GPIO_CTL 0x57 /* OV518(+) only */ | ||
242 | |||
192 | /* OV519 Camera interface register numbers */ | 243 | /* OV519 Camera interface register numbers */ |
193 | #define OV519_R10_H_SIZE 0x10 | 244 | #define OV519_R10_H_SIZE 0x10 |
194 | #define OV519_R11_V_SIZE 0x11 | 245 | #define OV519_R11_V_SIZE 0x11 |
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
224 | 275 | ||
225 | /* OV7610 registers */ | 276 | /* OV7610 registers */ |
226 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ | 277 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ |
278 | #define OV7610_REG_BLUE 0x01 /* blue channel balance */ | ||
279 | #define OV7610_REG_RED 0x02 /* red channel balance */ | ||
227 | #define OV7610_REG_SAT 0x03 /* saturation */ | 280 | #define OV7610_REG_SAT 0x03 /* saturation */ |
228 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ | 281 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ |
229 | #define OV7610_REG_CNT 0x05 /* Y contrast */ | 282 | #define OV7610_REG_CNT 0x05 /* Y contrast */ |
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
846 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | 899 | static int reg_w(struct sd *sd, __u16 index, __u8 value) |
847 | { | 900 | { |
848 | int ret; | 901 | int ret; |
902 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; | ||
849 | 903 | ||
850 | sd->gspca_dev.usb_buf[0] = value; | 904 | sd->gspca_dev.usb_buf[0] = value; |
851 | ret = usb_control_msg(sd->gspca_dev.dev, | 905 | ret = usb_control_msg(sd->gspca_dev.dev, |
852 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 906 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
853 | 1, /* REQ_IO (ov518/519) */ | 907 | req, |
854 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 908 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
855 | 0, index, | 909 | 0, index, |
856 | sd->gspca_dev.usb_buf, 1, 500); | 910 | sd->gspca_dev.usb_buf, 1, 500); |
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) | |||
864 | static int reg_r(struct sd *sd, __u16 index) | 918 | static int reg_r(struct sd *sd, __u16 index) |
865 | { | 919 | { |
866 | int ret; | 920 | int ret; |
921 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; | ||
867 | 922 | ||
868 | ret = usb_control_msg(sd->gspca_dev.dev, | 923 | ret = usb_control_msg(sd->gspca_dev.dev, |
869 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 924 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
870 | 1, /* REQ_IO */ | 925 | req, |
871 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 926 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
872 | 0, index, sd->gspca_dev.usb_buf, 1, 500); | 927 | 0, index, sd->gspca_dev.usb_buf, 1, 500); |
873 | 928 | ||
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd, | |||
924 | } | 979 | } |
925 | 980 | ||
926 | /* | 981 | /* |
982 | * Writes multiple (n) byte value to a single register. Only valid with certain | ||
983 | * registers (0x30 and 0xc4 - 0xce). | ||
984 | */ | ||
985 | static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | ||
986 | { | ||
987 | int ret; | ||
988 | |||
989 | *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | ||
990 | |||
991 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
992 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
993 | 1 /* REG_IO */, | ||
994 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
995 | 0, index, | ||
996 | sd->gspca_dev.usb_buf, n, 500); | ||
997 | if (ret < 0) | ||
998 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /* | ||
927 | * The OV518 I2C I/O procedure is different, hence, this function. | 1004 | * The OV518 I2C I/O procedure is different, hence, this function. |
928 | * This is normally only called from i2c_w(). Note that this function | 1005 | * This is normally only called from i2c_w(). Note that this function |
929 | * always succeeds regardless of whether the sensor is present and working. | 1006 | * always succeeds regardless of whether the sensor is present and working. |
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd) | |||
1014 | { | 1091 | { |
1015 | PDEBUG(D_STREAM, "stopping"); | 1092 | PDEBUG(D_STREAM, "stopping"); |
1016 | sd->stopped = 1; | 1093 | sd->stopped = 1; |
1017 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 1094 | switch (sd->bridge) { |
1095 | case BRIDGE_OV511: | ||
1096 | case BRIDGE_OV511PLUS: | ||
1097 | return reg_w(sd, R51x_SYS_RESET, 0x3d); | ||
1098 | case BRIDGE_OV518: | ||
1099 | case BRIDGE_OV518PLUS: | ||
1100 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | ||
1101 | case BRIDGE_OV519: | ||
1102 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | ||
1103 | } | ||
1104 | |||
1105 | return 0; | ||
1018 | } | 1106 | } |
1019 | 1107 | ||
1020 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | 1108 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not |
1021 | * actually stopped (for performance). */ | 1109 | * actually stopped (for performance). */ |
1022 | static inline int ov51x_restart(struct sd *sd) | 1110 | static inline int ov51x_restart(struct sd *sd) |
1023 | { | 1111 | { |
1112 | int rc; | ||
1113 | |||
1024 | PDEBUG(D_STREAM, "restarting"); | 1114 | PDEBUG(D_STREAM, "restarting"); |
1025 | if (!sd->stopped) | 1115 | if (!sd->stopped) |
1026 | return 0; | 1116 | return 0; |
1027 | sd->stopped = 0; | 1117 | sd->stopped = 0; |
1028 | 1118 | ||
1029 | /* Reinitialize the stream */ | 1119 | /* Reinitialize the stream */ |
1030 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 1120 | switch (sd->bridge) { |
1121 | case BRIDGE_OV511: | ||
1122 | case BRIDGE_OV511PLUS: | ||
1123 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1124 | case BRIDGE_OV518: | ||
1125 | case BRIDGE_OV518PLUS: | ||
1126 | rc = reg_w(sd, 0x2f, 0x80); | ||
1127 | if (rc < 0) | ||
1128 | return rc; | ||
1129 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1130 | case BRIDGE_OV519: | ||
1131 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | ||
1132 | } | ||
1133 | |||
1134 | return 0; | ||
1031 | } | 1135 | } |
1032 | 1136 | ||
1033 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 1137 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd) | |||
1287 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1391 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
1288 | static void ov51x_led_control(struct sd *sd, int on) | 1392 | static void ov51x_led_control(struct sd *sd, int on) |
1289 | { | 1393 | { |
1290 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | 1394 | switch (sd->bridge) { |
1395 | /* OV511 has no LED control */ | ||
1396 | case BRIDGE_OV511PLUS: | ||
1397 | reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); | ||
1398 | break; | ||
1399 | case BRIDGE_OV518: | ||
1400 | case BRIDGE_OV518PLUS: | ||
1401 | reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); | ||
1402 | break; | ||
1403 | case BRIDGE_OV519: | ||
1404 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1405 | break; | ||
1406 | } | ||
1291 | } | 1407 | } |
1292 | 1408 | ||
1293 | /* this function is called at probe time */ | 1409 | /* OV518 quantization tables are 8x4 (instead of 8x8) */ |
1294 | static int sd_config(struct gspca_dev *gspca_dev, | 1410 | static int ov518_upload_quan_tables(struct sd *sd) |
1295 | const struct usb_device_id *id) | 1411 | { |
1412 | const unsigned char yQuanTable518[] = { | ||
1413 | 5, 4, 5, 6, 6, 7, 7, 7, | ||
1414 | 5, 5, 5, 5, 6, 7, 7, 7, | ||
1415 | 6, 6, 6, 6, 7, 7, 7, 8, | ||
1416 | 7, 7, 6, 7, 7, 7, 8, 8 | ||
1417 | }; | ||
1418 | |||
1419 | const unsigned char uvQuanTable518[] = { | ||
1420 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1421 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1422 | 6, 6, 6, 7, 7, 7, 7, 8, | ||
1423 | 7, 7, 7, 7, 7, 7, 8, 8 | ||
1424 | }; | ||
1425 | |||
1426 | const unsigned char *pYTable = yQuanTable518; | ||
1427 | const unsigned char *pUVTable = uvQuanTable518; | ||
1428 | unsigned char val0, val1; | ||
1429 | int i, rc, reg = R51x_COMP_LUT_BEGIN; | ||
1430 | |||
1431 | PDEBUG(D_PROBE, "Uploading quantization tables"); | ||
1432 | |||
1433 | for (i = 0; i < 16; i++) { | ||
1434 | val0 = *pYTable++; | ||
1435 | val1 = *pYTable++; | ||
1436 | val0 &= 0x0f; | ||
1437 | val1 &= 0x0f; | ||
1438 | val0 |= val1 << 4; | ||
1439 | rc = reg_w(sd, reg, val0); | ||
1440 | if (rc < 0) | ||
1441 | return rc; | ||
1442 | |||
1443 | val0 = *pUVTable++; | ||
1444 | val1 = *pUVTable++; | ||
1445 | val0 &= 0x0f; | ||
1446 | val1 &= 0x0f; | ||
1447 | val0 |= val1 << 4; | ||
1448 | rc = reg_w(sd, reg + 16, val0); | ||
1449 | if (rc < 0) | ||
1450 | return rc; | ||
1451 | |||
1452 | reg++; | ||
1453 | } | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | /* This initializes the OV518/OV518+ and the sensor */ | ||
1459 | static int ov518_configure(struct gspca_dev *gspca_dev) | ||
1296 | { | 1460 | { |
1297 | struct sd *sd = (struct sd *) gspca_dev; | 1461 | struct sd *sd = (struct sd *) gspca_dev; |
1298 | struct cam *cam; | 1462 | int rc; |
1463 | |||
1464 | /* For 518 and 518+ */ | ||
1465 | static struct ov_regvals init_518[] = { | ||
1466 | { R51x_SYS_RESET, 0x40 }, | ||
1467 | { R51x_SYS_INIT, 0xe1 }, | ||
1468 | { R51x_SYS_RESET, 0x3e }, | ||
1469 | { R51x_SYS_INIT, 0xe1 }, | ||
1470 | { R51x_SYS_RESET, 0x00 }, | ||
1471 | { R51x_SYS_INIT, 0xe1 }, | ||
1472 | { 0x46, 0x00 }, | ||
1473 | { 0x5d, 0x03 }, | ||
1474 | }; | ||
1475 | |||
1476 | static struct ov_regvals norm_518[] = { | ||
1477 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1478 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1479 | { 0x31, 0x0f }, | ||
1480 | { 0x5d, 0x03 }, | ||
1481 | { 0x24, 0x9f }, | ||
1482 | { 0x25, 0x90 }, | ||
1483 | { 0x20, 0x00 }, | ||
1484 | { 0x51, 0x04 }, | ||
1485 | { 0x71, 0x19 }, | ||
1486 | { 0x2f, 0x80 }, | ||
1487 | }; | ||
1488 | |||
1489 | static struct ov_regvals norm_518_p[] = { | ||
1490 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1491 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1492 | { 0x31, 0x0f }, | ||
1493 | { 0x5d, 0x03 }, | ||
1494 | { 0x24, 0x9f }, | ||
1495 | { 0x25, 0x90 }, | ||
1496 | { 0x20, 0x60 }, | ||
1497 | { 0x51, 0x02 }, | ||
1498 | { 0x71, 0x19 }, | ||
1499 | { 0x40, 0xff }, | ||
1500 | { 0x41, 0x42 }, | ||
1501 | { 0x46, 0x00 }, | ||
1502 | { 0x33, 0x04 }, | ||
1503 | { 0x21, 0x19 }, | ||
1504 | { 0x3f, 0x10 }, | ||
1505 | { 0x2f, 0x80 }, | ||
1506 | }; | ||
1507 | |||
1508 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ | ||
1509 | PDEBUG(D_PROBE, "Device revision %d", | ||
1510 | 0x1F & reg_r(sd, R51x_SYS_CUST_ID)); | ||
1511 | |||
1512 | rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518)); | ||
1513 | if (rc < 0) | ||
1514 | return rc; | ||
1515 | |||
1516 | /* Set LED GPIO pin to output mode */ | ||
1517 | rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); | ||
1518 | if (rc < 0) | ||
1519 | return rc; | ||
1299 | 1520 | ||
1521 | switch (sd->bridge) { | ||
1522 | case BRIDGE_OV518: | ||
1523 | rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); | ||
1524 | if (rc < 0) | ||
1525 | return rc; | ||
1526 | break; | ||
1527 | case BRIDGE_OV518PLUS: | ||
1528 | rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); | ||
1529 | if (rc < 0) | ||
1530 | return rc; | ||
1531 | break; | ||
1532 | } | ||
1533 | |||
1534 | rc = ov518_upload_quan_tables(sd); | ||
1535 | if (rc < 0) { | ||
1536 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
1537 | return rc; | ||
1538 | } | ||
1539 | |||
1540 | rc = reg_w(sd, 0x2f, 0x80); | ||
1541 | if (rc < 0) | ||
1542 | return rc; | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | static int ov519_configure(struct sd *sd) | ||
1548 | { | ||
1300 | static const struct ov_regvals init_519[] = { | 1549 | static const struct ov_regvals init_519[] = { |
1301 | { 0x5a, 0x6d }, /* EnableSystem */ | 1550 | { 0x5a, 0x6d }, /* EnableSystem */ |
1302 | { 0x53, 0x9b }, | 1551 | { 0x53, 0x9b }, |
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1313 | /* windows reads 0x55 at this point*/ | 1562 | /* windows reads 0x55 at this point*/ |
1314 | }; | 1563 | }; |
1315 | 1564 | ||
1316 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1565 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
1566 | } | ||
1567 | |||
1568 | /* this function is called at probe time */ | ||
1569 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1570 | const struct usb_device_id *id) | ||
1571 | { | ||
1572 | struct sd *sd = (struct sd *) gspca_dev; | ||
1573 | struct cam *cam; | ||
1574 | int ret = 0; | ||
1575 | |||
1576 | sd->bridge = id->driver_info; | ||
1577 | |||
1578 | switch (sd->bridge) { | ||
1579 | case BRIDGE_OV518: | ||
1580 | case BRIDGE_OV518PLUS: | ||
1581 | ret = ov518_configure(gspca_dev); | ||
1582 | break; | ||
1583 | case BRIDGE_OV519: | ||
1584 | ret = ov519_configure(sd); | ||
1585 | break; | ||
1586 | } | ||
1587 | |||
1588 | if (ret) | ||
1317 | goto error; | 1589 | goto error; |
1590 | |||
1318 | ov51x_led_control(sd, 0); /* turn LED off */ | 1591 | ov51x_led_control(sd, 0); /* turn LED off */ |
1319 | 1592 | ||
1320 | /* Test for 76xx */ | 1593 | /* Test for 76xx */ |
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1360 | } | 1633 | } |
1361 | 1634 | ||
1362 | cam = &gspca_dev->cam; | 1635 | cam = &gspca_dev->cam; |
1363 | if (!sd->sif) { | 1636 | switch (sd->bridge) { |
1364 | cam->cam_mode = vga_mode; | 1637 | case BRIDGE_OV518: |
1365 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1638 | case BRIDGE_OV518PLUS: |
1366 | } else { | 1639 | if (!sd->sif) { |
1367 | cam->cam_mode = sif_mode; | 1640 | cam->cam_mode = ov518_vga_mode; |
1368 | cam->nmodes = ARRAY_SIZE(sif_mode); | 1641 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); |
1642 | } else { | ||
1643 | cam->cam_mode = ov518_sif_mode; | ||
1644 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); | ||
1645 | } | ||
1646 | break; | ||
1647 | case BRIDGE_OV519: | ||
1648 | if (!sd->sif) { | ||
1649 | cam->cam_mode = ov519_vga_mode; | ||
1650 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
1651 | } else { | ||
1652 | cam->cam_mode = ov519_sif_mode; | ||
1653 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | ||
1654 | } | ||
1655 | break; | ||
1369 | } | 1656 | } |
1370 | sd->brightness = BRIGHTNESS_DEF; | 1657 | sd->brightness = BRIGHTNESS_DEF; |
1371 | sd->contrast = CONTRAST_DEF; | 1658 | sd->contrast = CONTRAST_DEF; |
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1422 | return 0; | 1709 | return 0; |
1423 | } | 1710 | } |
1424 | 1711 | ||
1712 | /* Sets up the OV518/OV518+ with the given image parameters | ||
1713 | * | ||
1714 | * OV518 needs a completely different approach, until we can figure out what | ||
1715 | * the individual registers do. Also, only 15 FPS is supported now. | ||
1716 | * | ||
1717 | * Do not put any sensor-specific code in here (including I2C I/O functions) | ||
1718 | */ | ||
1719 | static int ov518_mode_init_regs(struct sd *sd) | ||
1720 | { | ||
1721 | int hsegs, vsegs; | ||
1722 | |||
1723 | /******** Set the mode ********/ | ||
1724 | |||
1725 | reg_w(sd, 0x2b, 0); | ||
1726 | reg_w(sd, 0x2c, 0); | ||
1727 | reg_w(sd, 0x2d, 0); | ||
1728 | reg_w(sd, 0x2e, 0); | ||
1729 | reg_w(sd, 0x3b, 0); | ||
1730 | reg_w(sd, 0x3c, 0); | ||
1731 | reg_w(sd, 0x3d, 0); | ||
1732 | reg_w(sd, 0x3e, 0); | ||
1733 | |||
1734 | if (sd->bridge == BRIDGE_OV518) { | ||
1735 | /* Set 8-bit (YVYU) input format */ | ||
1736 | reg_w_mask(sd, 0x20, 0x08, 0x08); | ||
1737 | |||
1738 | /* Set 12-bit (4:2:0) output format */ | ||
1739 | reg_w_mask(sd, 0x28, 0x80, 0xf0); | ||
1740 | reg_w_mask(sd, 0x38, 0x80, 0xf0); | ||
1741 | } else { | ||
1742 | reg_w(sd, 0x28, 0x80); | ||
1743 | reg_w(sd, 0x38, 0x80); | ||
1744 | } | ||
1745 | |||
1746 | hsegs = sd->gspca_dev.width / 16; | ||
1747 | vsegs = sd->gspca_dev.height / 4; | ||
1748 | |||
1749 | reg_w(sd, 0x29, hsegs); | ||
1750 | reg_w(sd, 0x2a, vsegs); | ||
1751 | |||
1752 | reg_w(sd, 0x39, hsegs); | ||
1753 | reg_w(sd, 0x3a, vsegs); | ||
1754 | |||
1755 | /* Windows driver does this here; who knows why */ | ||
1756 | reg_w(sd, 0x2f, 0x80); | ||
1757 | |||
1758 | /******** Set the framerate (to 30 FPS) ********/ | ||
1759 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1760 | sd->clockdiv = 1; | ||
1761 | else | ||
1762 | sd->clockdiv = 0; | ||
1763 | |||
1764 | /* Mode independent, but framerate dependent, regs */ | ||
1765 | reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */ | ||
1766 | reg_w(sd, 0x22, 0x18); | ||
1767 | reg_w(sd, 0x23, 0xff); | ||
1768 | |||
1769 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1770 | reg_w(sd, 0x21, 0x19); | ||
1771 | else | ||
1772 | reg_w(sd, 0x71, 0x17); /* Compression-related? */ | ||
1773 | |||
1774 | /* FIXME: Sensor-specific */ | ||
1775 | /* Bit 5 is what matters here. Of course, it is "reserved" */ | ||
1776 | i2c_w(sd, 0x54, 0x23); | ||
1777 | |||
1778 | reg_w(sd, 0x2f, 0x80); | ||
1779 | |||
1780 | if (sd->bridge == BRIDGE_OV518PLUS) { | ||
1781 | reg_w(sd, 0x24, 0x94); | ||
1782 | reg_w(sd, 0x25, 0x90); | ||
1783 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1784 | ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */ | ||
1785 | ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */ | ||
1786 | ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */ | ||
1787 | ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */ | ||
1788 | ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */ | ||
1789 | ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */ | ||
1790 | ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */ | ||
1791 | ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */ | ||
1792 | } else { | ||
1793 | reg_w(sd, 0x24, 0x9f); | ||
1794 | reg_w(sd, 0x25, 0x90); | ||
1795 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1796 | ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */ | ||
1797 | ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */ | ||
1798 | ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */ | ||
1799 | ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */ | ||
1800 | ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */ | ||
1801 | ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */ | ||
1802 | ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */ | ||
1803 | ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */ | ||
1804 | } | ||
1805 | |||
1806 | reg_w(sd, 0x2f, 0x80); | ||
1807 | |||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | |||
1425 | /* Sets up the OV519 with the given image parameters | 1812 | /* Sets up the OV519 with the given image parameters |
1426 | * | 1813 | * |
1427 | * OV519 needs a completely different approach, until we can figure out what | 1814 | * OV519 needs a completely different approach, until we can figure out what |
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1740 | hwebase = 0x3a; | 2127 | hwebase = 0x3a; |
1741 | vwsbase = 0x05; | 2128 | vwsbase = 0x05; |
1742 | vwebase = 0x06; | 2129 | vwebase = 0x06; |
2130 | if (qvga) { | ||
2131 | /* HDG: this fixes U and V getting swapped */ | ||
2132 | hwsbase--; | ||
2133 | vwsbase--; | ||
2134 | } | ||
1743 | break; | 2135 | break; |
1744 | case SEN_OV7620: | 2136 | case SEN_OV7620: |
1745 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | 2137 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ |
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1855 | static int sd_start(struct gspca_dev *gspca_dev) | 2247 | static int sd_start(struct gspca_dev *gspca_dev) |
1856 | { | 2248 | { |
1857 | struct sd *sd = (struct sd *) gspca_dev; | 2249 | struct sd *sd = (struct sd *) gspca_dev; |
1858 | int ret; | 2250 | int ret = 0; |
1859 | 2251 | ||
1860 | ret = ov519_mode_init_regs(sd); | 2252 | switch (sd->bridge) { |
2253 | case BRIDGE_OV518: | ||
2254 | case BRIDGE_OV518PLUS: | ||
2255 | ret = ov518_mode_init_regs(sd); | ||
2256 | break; | ||
2257 | case BRIDGE_OV519: | ||
2258 | ret = ov519_mode_init_regs(sd); | ||
2259 | break; | ||
2260 | } | ||
1861 | if (ret < 0) | 2261 | if (ret < 0) |
1862 | goto out; | 2262 | goto out; |
2263 | |||
1863 | ret = set_ov_sensor_window(sd); | 2264 | ret = set_ov_sensor_window(sd); |
1864 | if (ret < 0) | 2265 | if (ret < 0) |
1865 | goto out; | 2266 | goto out; |
1866 | 2267 | ||
2268 | setcontrast(gspca_dev); | ||
2269 | setbrightness(gspca_dev); | ||
2270 | setcolors(gspca_dev); | ||
2271 | |||
1867 | ret = ov51x_restart(sd); | 2272 | ret = ov51x_restart(sd); |
1868 | if (ret < 0) | 2273 | if (ret < 0) |
1869 | goto out; | 2274 | goto out; |
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1882 | ov51x_led_control(sd, 0); | 2287 | ov51x_led_control(sd, 0); |
1883 | } | 2288 | } |
1884 | 2289 | ||
1885 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2290 | static void ov518_pkt_scan(struct gspca_dev *gspca_dev, |
2291 | struct gspca_frame *frame, /* target */ | ||
2292 | __u8 *data, /* isoc packet */ | ||
2293 | int len) /* iso packet length */ | ||
2294 | { | ||
2295 | PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len); | ||
2296 | |||
2297 | if (len & 7) { | ||
2298 | len--; | ||
2299 | PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]); | ||
2300 | } | ||
2301 | |||
2302 | /* A false positive here is likely, until OVT gives me | ||
2303 | * the definitive SOF/EOF format */ | ||
2304 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { | ||
2305 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); | ||
2306 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); | ||
2307 | } | ||
2308 | |||
2309 | /* intermediate packet */ | ||
2310 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
2311 | } | ||
2312 | |||
2313 | static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | ||
1886 | struct gspca_frame *frame, /* target */ | 2314 | struct gspca_frame *frame, /* target */ |
1887 | __u8 *data, /* isoc packet */ | 2315 | __u8 *data, /* isoc packet */ |
1888 | int len) /* iso packet length */ | 2316 | int len) /* iso packet length */ |
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1926 | data, len); | 2354 | data, len); |
1927 | } | 2355 | } |
1928 | 2356 | ||
2357 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2358 | struct gspca_frame *frame, /* target */ | ||
2359 | __u8 *data, /* isoc packet */ | ||
2360 | int len) /* iso packet length */ | ||
2361 | { | ||
2362 | struct sd *sd = (struct sd *) gspca_dev; | ||
2363 | |||
2364 | switch (sd->bridge) { | ||
2365 | case BRIDGE_OV511: | ||
2366 | case BRIDGE_OV511PLUS: | ||
2367 | break; | ||
2368 | case BRIDGE_OV518: | ||
2369 | case BRIDGE_OV518PLUS: | ||
2370 | ov518_pkt_scan(gspca_dev, frame, data, len); | ||
2371 | break; | ||
2372 | case BRIDGE_OV519: | ||
2373 | ov519_pkt_scan(gspca_dev, frame, data, len); | ||
2374 | break; | ||
2375 | } | ||
2376 | } | ||
2377 | |||
1929 | /* -- management routines -- */ | 2378 | /* -- management routines -- */ |
1930 | 2379 | ||
1931 | static void setbrightness(struct gspca_dev *gspca_dev) | 2380 | static void setbrightness(struct gspca_dev *gspca_dev) |
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1970 | break; | 2419 | break; |
1971 | case SEN_OV6630: | 2420 | case SEN_OV6630: |
1972 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | 2421 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); |
2422 | break; | ||
1973 | case SEN_OV8610: { | 2423 | case SEN_OV8610: { |
1974 | static const __u8 ctab[] = { | 2424 | static const __u8 ctab[] = { |
1975 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | 2425 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f |
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = { | |||
2136 | 2586 | ||
2137 | /* -- module initialisation -- */ | 2587 | /* -- module initialisation -- */ |
2138 | static const __devinitdata struct usb_device_id device_table[] = { | 2588 | static const __devinitdata struct usb_device_id device_table[] = { |
2139 | {USB_DEVICE(0x041e, 0x4052)}, | 2589 | {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, |
2140 | {USB_DEVICE(0x041e, 0x405f)}, | 2590 | {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, |
2141 | {USB_DEVICE(0x041e, 0x4060)}, | 2591 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
2142 | {USB_DEVICE(0x041e, 0x4061)}, | 2592 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
2143 | {USB_DEVICE(0x041e, 0x4064)}, | 2593 | {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 }, |
2144 | {USB_DEVICE(0x041e, 0x4068)}, | 2594 | {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 }, |
2145 | {USB_DEVICE(0x045e, 0x028c)}, | 2595 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
2146 | {USB_DEVICE(0x054c, 0x0154)}, | 2596 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
2147 | {USB_DEVICE(0x054c, 0x0155)}, | 2597 | {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, |
2148 | {USB_DEVICE(0x05a9, 0x0519)}, | 2598 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
2149 | {USB_DEVICE(0x05a9, 0x0530)}, | 2599 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
2150 | {USB_DEVICE(0x05a9, 0x4519)}, | 2600 | {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, |
2151 | {USB_DEVICE(0x05a9, 0x8519)}, | 2601 | {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, |
2602 | {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, | ||
2603 | {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, | ||
2152 | {} | 2604 | {} |
2153 | }; | 2605 | }; |
2154 | 2606 | ||
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 19e0bc60de14..4b528b372911 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -60,10 +60,23 @@ struct sd { | |||
60 | static struct ctrl sd_ctrls[] = { | 60 | static struct ctrl sd_ctrls[] = { |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static const struct v4l2_pix_format vga_mode[] = { | 63 | static const struct v4l2_pix_format vga_yuyv_mode[] = { |
64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
65 | .bytesperline = 640 * 2, | 65 | .bytesperline = 640 * 2, |
66 | .sizeimage = 640 * 480 * 2, | 66 | .sizeimage = 640 * 480 * 2, |
67 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
68 | .priv = 0}, | ||
69 | }; | ||
70 | |||
71 | static const struct v4l2_pix_format vga_jpeg_mode[] = { | ||
72 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
73 | .bytesperline = 320, | ||
74 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
75 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
76 | .priv = 1}, | ||
77 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
78 | .bytesperline = 640, | ||
79 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
67 | .colorspace = V4L2_COLORSPACE_JPEG, | 80 | .colorspace = V4L2_COLORSPACE_JPEG, |
68 | .priv = 0}, | 81 | .priv = 0}, |
69 | }; | 82 | }; |
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = { | |||
244 | }; | 257 | }; |
245 | 258 | ||
246 | static const u8 sensor_init_ov965x[][2] = { | 259 | static const u8 sensor_init_ov965x[][2] = { |
247 | {0x12, 0x80}, /* com7 - reset */ | 260 | {0x12, 0x80}, /* com7 - SSCB reset */ |
248 | {0x00, 0x00}, /* gain */ | 261 | {0x00, 0x00}, /* gain */ |
249 | {0x01, 0x80}, /* blue */ | 262 | {0x01, 0x80}, /* blue */ |
250 | {0x02, 0x80}, /* red */ | 263 | {0x02, 0x80}, /* red */ |
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = { | |||
254 | {0x0e, 0x61}, /* com5 */ | 267 | {0x0e, 0x61}, /* com5 */ |
255 | {0x0f, 0x42}, /* com6 */ | 268 | {0x0f, 0x42}, /* com6 */ |
256 | {0x11, 0x00}, /* clkrc */ | 269 | {0x11, 0x00}, /* clkrc */ |
257 | {0x12, 0x02}, /* com7 */ | 270 | {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ |
258 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 271 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
259 | {0x14, 0x28}, /* com9 */ | 272 | {0x14, 0x28}, /* com9 */ |
260 | {0x16, 0x24}, /* rsvd16 */ | 273 | {0x16, 0x24}, /* reg16 */ |
261 | {0x17, 0x1d}, /* hstart*/ | 274 | {0x17, 0x1d}, /* hstart*/ |
262 | {0x18, 0xbd}, /* hstop */ | 275 | {0x18, 0xbd}, /* hstop */ |
263 | {0x19, 0x01}, /* vstrt */ | 276 | {0x19, 0x01}, /* vstrt */ |
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = { | |||
269 | {0x27, 0x08}, /* bbias */ | 282 | {0x27, 0x08}, /* bbias */ |
270 | {0x28, 0x08}, /* gbbias */ | 283 | {0x28, 0x08}, /* gbbias */ |
271 | {0x29, 0x15}, /* gr com */ | 284 | {0x29, 0x15}, /* gr com */ |
272 | {0x2a, 0x00}, | 285 | {0x2a, 0x00}, /* exhch */ |
273 | {0x2b, 0x00}, | 286 | {0x2b, 0x00}, /* exhcl */ |
274 | {0x2c, 0x08}, /* rbias */ | 287 | {0x2c, 0x08}, /* rbias */ |
275 | {0x32, 0xff}, /* href */ | 288 | {0x32, 0xff}, /* href */ |
276 | {0x33, 0x00}, /* chlf */ | 289 | {0x33, 0x00}, /* chlf */ |
277 | {0x34, 0x3f}, /* arblm */ | 290 | {0x34, 0x3f}, /* aref1 */ |
278 | {0x35, 0x00}, /* rsvd35 */ | 291 | {0x35, 0x00}, /* aref2 */ |
279 | {0x36, 0xf8}, /* rsvd36 */ | 292 | {0x36, 0xf8}, /* aref3 */ |
280 | {0x38, 0x72}, /* acom38 */ | 293 | {0x38, 0x72}, /* adc2 */ |
281 | {0x39, 0x57}, /* ofon */ | 294 | {0x39, 0x57}, /* aref4 */ |
282 | {0x3a, 0x80}, /* tslb */ | 295 | {0x3a, 0x80}, /* tslb - yuyv */ |
283 | {0x3b, 0xc4}, | 296 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
284 | {0x3d, 0x99}, /* com13 */ | 297 | {0x3d, 0x99}, /* com13 */ |
285 | {0x3f, 0xc1}, | 298 | {0x3f, 0xc1}, /* edge */ |
286 | {0x40, 0xc0}, /* com15 */ | 299 | {0x40, 0xc0}, /* com15 */ |
287 | {0x41, 0x40}, /* com16 */ | 300 | {0x41, 0x40}, /* com16 */ |
288 | {0x42, 0xc0}, | 301 | {0x42, 0xc0}, /* com17 */ |
289 | {0x43, 0x0a}, | 302 | {0x43, 0x0a}, /* rsvd */ |
290 | {0x44, 0xf0}, | 303 | {0x44, 0xf0}, |
291 | {0x45, 0x46}, | 304 | {0x45, 0x46}, |
292 | {0x46, 0x62}, | 305 | {0x46, 0x62}, |
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = { | |||
297 | {0x4c, 0x7f}, | 310 | {0x4c, 0x7f}, |
298 | {0x4d, 0x7f}, | 311 | {0x4d, 0x7f}, |
299 | {0x4e, 0x7f}, | 312 | {0x4e, 0x7f}, |
300 | {0x4f, 0x98}, | 313 | {0x4f, 0x98}, /* matrix */ |
301 | {0x50, 0x98}, | 314 | {0x50, 0x98}, |
302 | {0x51, 0x00}, | 315 | {0x51, 0x00}, |
303 | {0x52, 0x28}, | 316 | {0x52, 0x28}, |
304 | {0x53, 0x70}, | 317 | {0x53, 0x70}, |
305 | {0x54, 0x98}, | 318 | {0x54, 0x98}, |
306 | {0x58, 0x1a}, | 319 | {0x58, 0x1a}, /* matrix coef sign */ |
307 | {0x59, 0x85}, | 320 | {0x59, 0x85}, /* AWB control */ |
308 | {0x5a, 0xa9}, | 321 | {0x5a, 0xa9}, |
309 | {0x5b, 0x64}, | 322 | {0x5b, 0x64}, |
310 | {0x5c, 0x84}, | 323 | {0x5c, 0x84}, |
311 | {0x5d, 0x53}, | 324 | {0x5d, 0x53}, |
312 | {0x5e, 0x0e}, | 325 | {0x5e, 0x0e}, |
313 | {0x5f, 0xf0}, | 326 | {0x5f, 0xf0}, /* AWB blue limit */ |
314 | {0x60, 0xf0}, | 327 | {0x60, 0xf0}, /* AWB red limit */ |
315 | {0x61, 0xf0}, | 328 | {0x61, 0xf0}, /* AWB green limit */ |
316 | {0x62, 0x00}, /* lcc1 */ | 329 | {0x62, 0x00}, /* lcc1 */ |
317 | {0x63, 0x00}, /* lcc2 */ | 330 | {0x63, 0x00}, /* lcc2 */ |
318 | {0x64, 0x02}, /* lcc3 */ | 331 | {0x64, 0x02}, /* lcc3 */ |
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = { | |||
324 | {0x6d, 0x55}, | 337 | {0x6d, 0x55}, |
325 | {0x6e, 0x00}, | 338 | {0x6e, 0x00}, |
326 | {0x6f, 0x9d}, | 339 | {0x6f, 0x9d}, |
327 | {0x70, 0x21}, | 340 | {0x70, 0x21}, /* dnsth */ |
328 | {0x71, 0x78}, | 341 | {0x71, 0x78}, |
329 | {0x72, 0x00}, | 342 | {0x72, 0x00}, /* poidx */ |
330 | {0x73, 0x01}, | 343 | {0x73, 0x01}, /* pckdv */ |
331 | {0x74, 0x3a}, | 344 | {0x74, 0x3a}, /* xindx */ |
332 | {0x75, 0x35}, | 345 | {0x75, 0x35}, /* yindx */ |
333 | {0x76, 0x01}, | 346 | {0x76, 0x01}, |
334 | {0x77, 0x02}, | 347 | {0x77, 0x02}, |
335 | {0x7a, 0x12}, | 348 | {0x7a, 0x12}, /* gamma curve */ |
336 | {0x7b, 0x08}, | 349 | {0x7b, 0x08}, |
337 | {0x7c, 0x16}, | 350 | {0x7c, 0x16}, |
338 | {0x7d, 0x30}, | 351 | {0x7d, 0x30}, |
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = { | |||
349 | {0x88, 0xe6}, | 362 | {0x88, 0xe6}, |
350 | {0x89, 0xf2}, | 363 | {0x89, 0xf2}, |
351 | {0x8a, 0x03}, | 364 | {0x8a, 0x03}, |
352 | {0x8c, 0x89}, | 365 | {0x8c, 0x89}, /* com19 */ |
353 | {0x14, 0x28}, /* com9 */ | 366 | {0x14, 0x28}, /* com9 */ |
354 | {0x90, 0x7d}, | 367 | {0x90, 0x7d}, |
355 | {0x91, 0x7b}, | 368 | {0x91, 0x7b}, |
356 | {0x9d, 0x03}, | 369 | {0x9d, 0x03}, /* lcc6 */ |
357 | {0x9e, 0x04}, | 370 | {0x9e, 0x04}, /* lcc7 */ |
358 | {0x9f, 0x7a}, | 371 | {0x9f, 0x7a}, |
359 | {0xa0, 0x79}, | 372 | {0xa0, 0x79}, |
360 | {0xa1, 0x40}, /* aechm */ | 373 | {0xa1, 0x40}, /* aechm */ |
361 | {0xa4, 0x50}, | 374 | {0xa4, 0x50}, /* com21 */ |
362 | {0xa5, 0x68}, /* com26 */ | 375 | {0xa5, 0x68}, /* com26 */ |
363 | {0xa6, 0x4a}, | 376 | {0xa6, 0x4a}, /* AWB green */ |
364 | {0xa8, 0xc1}, /* acoma8 */ | 377 | {0xa8, 0xc1}, /* refa8 */ |
365 | {0xa9, 0xef}, /* acoma9 */ | 378 | {0xa9, 0xef}, /* refa9 */ |
366 | {0xaa, 0x92}, | 379 | {0xaa, 0x92}, |
367 | {0xab, 0x04}, | 380 | {0xab, 0x04}, |
368 | {0xac, 0x80}, | 381 | {0xac, 0x80}, /* black level control */ |
369 | {0xad, 0x80}, | 382 | {0xad, 0x80}, |
370 | {0xae, 0x80}, | 383 | {0xae, 0x80}, |
371 | {0xaf, 0x80}, | 384 | {0xaf, 0x80}, |
372 | {0xb2, 0xf2}, | 385 | {0xb2, 0xf2}, |
373 | {0xb3, 0x20}, | 386 | {0xb3, 0x20}, |
374 | {0xb4, 0x20}, | 387 | {0xb4, 0x20}, /* ctrlb4 */ |
375 | {0xb5, 0x00}, | 388 | {0xb5, 0x00}, |
376 | {0xb6, 0xaf}, | 389 | {0xb6, 0xaf}, |
377 | {0xbb, 0xae}, | 390 | {0xbb, 0xae}, |
378 | {0xbc, 0x7f}, | 391 | {0xbc, 0x7f}, /* ADC channel offsets */ |
379 | {0xdb, 0x7f}, | 392 | {0xdb, 0x7f}, |
380 | {0xbe, 0x7f}, | 393 | {0xbe, 0x7f}, |
381 | {0xbf, 0x7f}, | 394 | {0xbf, 0x7f}, |
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = { | |||
384 | {0xc2, 0x01}, | 397 | {0xc2, 0x01}, |
385 | {0xc3, 0x4e}, | 398 | {0xc3, 0x4e}, |
386 | {0xc6, 0x85}, | 399 | {0xc6, 0x85}, |
387 | {0xc7, 0x80}, | 400 | {0xc7, 0x80}, /* com24 */ |
388 | {0xc9, 0xe0}, | 401 | {0xc9, 0xe0}, |
389 | {0xca, 0xe8}, | 402 | {0xca, 0xe8}, |
390 | {0xcb, 0xf0}, | 403 | {0xcb, 0xf0}, |
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = { | |||
399 | {0x58, 0x1a}, | 412 | {0x58, 0x1a}, |
400 | {0xff, 0x41}, /* read 41, write ff 00 */ | 413 | {0xff, 0x41}, /* read 41, write ff 00 */ |
401 | {0x41, 0x40}, /* com16 */ | 414 | {0x41, 0x40}, /* com16 */ |
402 | {0xc5, 0x03}, | 415 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
403 | {0x6a, 0x02}, | 416 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
404 | 417 | ||
405 | {0x12, 0x62}, /* com7 - VGA + CIF */ | 418 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ |
406 | {0x36, 0xfa}, /* rsvd36 */ | 419 | {0x36, 0xfa}, /* aref3 */ |
407 | {0x69, 0x0a}, /* hv */ | 420 | {0x69, 0x0a}, /* hv */ |
408 | {0x8c, 0x89}, /* com22 */ | 421 | {0x8c, 0x89}, /* com22 */ |
409 | {0x14, 0x28}, /* com9 */ | 422 | {0x14, 0x28}, /* com9 */ |
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = { | |||
442 | {0x52, 0x3c}, | 455 | {0x52, 0x3c}, |
443 | {0x53, 0x00}, | 456 | {0x53, 0x00}, |
444 | {0x54, 0x00}, | 457 | {0x54, 0x00}, |
445 | {0x55, 0x00}, | 458 | {0x55, 0x00}, /* brightness */ |
446 | {0x57, 0x00}, | 459 | {0x57, 0x00}, /* contrast 2 */ |
447 | {0x5c, 0x00}, | 460 | {0x5c, 0x00}, |
448 | {0x5a, 0xa0}, | 461 | {0x5a, 0xa0}, |
449 | {0x5b, 0x78}, | 462 | {0x5b, 0x78}, |
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = { | |||
489 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 502 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
490 | }; | 503 | }; |
491 | 504 | ||
505 | static const u8 sensor_start_ov965x[][2] = { | ||
506 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ | ||
507 | {0x36, 0xfa}, /* aref3 */ | ||
508 | {0x69, 0x0a}, /* hv */ | ||
509 | {0x8c, 0x89}, /* com22 */ | ||
510 | {0x14, 0x28}, /* com9 */ | ||
511 | {0x3e, 0x0c}, /* com14 */ | ||
512 | {0x41, 0x40}, /* com16 */ | ||
513 | {0x72, 0x00}, | ||
514 | {0x73, 0x00}, | ||
515 | {0x74, 0x3a}, | ||
516 | {0x75, 0x35}, | ||
517 | {0x76, 0x01}, | ||
518 | {0xc7, 0x80}, /* com24 */ | ||
519 | {0x03, 0x12}, /* vref */ | ||
520 | {0x17, 0x16}, /* hstart */ | ||
521 | {0x18, 0x02}, /* hstop */ | ||
522 | {0x19, 0x01}, /* vstrt */ | ||
523 | {0x1a, 0x3d}, /* vstop */ | ||
524 | {0x32, 0xff}, /* href */ | ||
525 | {0xc0, 0xaa}, | ||
526 | {} | ||
527 | }; | ||
528 | |||
492 | static const u8 bridge_start_ov965x[][2] = { | 529 | static const u8 bridge_start_ov965x[][2] = { |
530 | {0x94, 0xaa}, | ||
531 | {0xf1, 0x60}, | ||
532 | {0xe5, 0x04}, | ||
533 | {0xc0, 0x50}, | ||
534 | {0xc1, 0x3c}, | ||
535 | {0x8c, 0x00}, | ||
536 | {0x8d, 0x1c}, | ||
537 | {0x34, 0x05}, | ||
538 | {} | ||
539 | }; | ||
540 | |||
541 | static const u8 bridge_start_ov965x_vga[][2] = { | ||
542 | {0xc2, 0x0c}, | ||
543 | {0xc3, 0xf9}, | ||
544 | {0xda, 0x01}, | ||
545 | {0x50, 0x00}, | ||
546 | {0x51, 0xa0}, | ||
547 | {0x52, 0x3c}, | ||
548 | {0x53, 0x00}, | ||
549 | {0x54, 0x00}, | ||
550 | {0x55, 0x00}, | ||
551 | {0x57, 0x00}, | ||
552 | {0x5c, 0x00}, | ||
553 | {0x5a, 0xa0}, | ||
554 | {0x5b, 0x78}, | ||
555 | {0x35, 0x02}, | ||
556 | {0xd9, 0x10}, | ||
557 | {0x94, 0x11}, | ||
558 | {} | ||
559 | }; | ||
560 | |||
561 | static const u8 bridge_start_ov965x_cif[][2] = { | ||
493 | {0xc2, 0x4c}, | 562 | {0xc2, 0x4c}, |
494 | {0xc3, 0xf9}, | 563 | {0xc3, 0xf9}, |
564 | {0xda, 0x00}, | ||
495 | {0x50, 0x00}, | 565 | {0x50, 0x00}, |
496 | {0x51, 0xa0}, | 566 | {0x51, 0xa0}, |
497 | {0x52, 0x78}, | 567 | {0x52, 0x78}, |
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = { | |||
500 | {0x55, 0x00}, | 570 | {0x55, 0x00}, |
501 | {0x57, 0x00}, | 571 | {0x57, 0x00}, |
502 | {0x5c, 0x00}, | 572 | {0x5c, 0x00}, |
503 | {0x5a, 0x28}, | 573 | {0x5a, 0x50}, |
504 | {0x5b, 0x1e}, | 574 | {0x5b, 0x3c}, |
505 | {0x35, 0x00}, | 575 | {0x35, 0x02}, |
506 | {0xd9, 0x21}, | 576 | {0xd9, 0x10}, |
507 | {0x94, 0x11}, | 577 | {0x94, 0x11}, |
578 | {} | ||
508 | }; | 579 | }; |
509 | 580 | ||
510 | static const u8 sensor_start_ov965x[][2] = { | 581 | static const u8 sensor_start_ov965x_vga[][2] = { |
511 | {0x3b, 0xe4}, | 582 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
583 | {0x1e, 0x04}, /* mvfp */ | ||
584 | {0x13, 0xe0}, /* com8 */ | ||
585 | {0x00, 0x00}, | ||
586 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | ||
587 | {0x11, 0x03}, /* clkrc */ | ||
588 | {0x6b, 0x5a}, /* dblv */ | ||
589 | {0x6a, 0x05}, /* 50 Hz banding filter */ | ||
590 | {0xc5, 0x07}, /* 60 Hz banding filter */ | ||
591 | {0xa2, 0x4b}, /* bd50 */ | ||
592 | {0xa3, 0x3e}, /* bd60 */ | ||
593 | |||
594 | {0x2d, 0x00}, /* advfl */ | ||
595 | {} | ||
596 | }; | ||
597 | |||
598 | static const u8 sensor_start_ov965x_cif[][2] = { | ||
599 | {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ | ||
512 | {0x1e, 0x04}, /* mvfp */ | 600 | {0x1e, 0x04}, /* mvfp */ |
513 | {0x13, 0xe0}, /* com8 */ | 601 | {0x13, 0xe0}, /* com8 */ |
514 | {0x00, 0x00}, | 602 | {0x00, 0x00}, |
515 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 603 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
516 | {0x11, 0x01}, /* clkrc */ | 604 | {0x11, 0x01}, /* clkrc */ |
517 | {0x6b, 0x5a}, /* dblv */ | 605 | {0x6b, 0x5a}, /* dblv */ |
518 | {0x6a, 0x02}, | 606 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
519 | {0xc5, 0x03}, | 607 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
520 | {0xa2, 0x96}, | 608 | {0xa2, 0x96}, /* bd50 */ |
521 | {0xa3, 0x7d}, | 609 | {0xa3, 0x7d}, /* bd60 */ |
610 | |||
522 | {0xff, 0x13}, /* read 13, write ff 00 */ | 611 | {0xff, 0x13}, /* read 13, write ff 00 */ |
523 | {0x13, 0xe7}, | 612 | {0x13, 0xe7}, |
524 | {0x3a, 0x80}, | 613 | {0x3a, 0x80}, /* tslb - yuyv */ |
614 | {} | ||
615 | }; | ||
616 | |||
617 | static const u8 sensor_start_ov965x_2[][2] = { | ||
525 | {0xff, 0x42}, /* read 42, write ff 00 */ | 618 | {0xff, 0x42}, /* read 42, write ff 00 */ |
526 | {0x42, 0xc1}, | 619 | {0x42, 0xc1}, /* com17 - 50 Hz filter */ |
620 | {} | ||
527 | }; | 621 | }; |
528 | 622 | ||
529 | 623 | ||
@@ -705,11 +799,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
705 | 799 | ||
706 | cam = &gspca_dev->cam; | 800 | cam = &gspca_dev->cam; |
707 | 801 | ||
708 | cam->cam_mode = vga_mode; | 802 | if (sd->sensor == SENSOR_OV772X) { |
709 | cam->nmodes = ARRAY_SIZE(vga_mode); | 803 | cam->cam_mode = vga_yuyv_mode; |
804 | cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); | ||
710 | 805 | ||
711 | cam->bulk_size = 16384; | 806 | cam->bulk = 1; |
712 | cam->bulk_nurbs = 2; | 807 | cam->bulk_size = 16384; |
808 | cam->bulk_nurbs = 2; | ||
809 | } else { /* ov965x */ | ||
810 | cam->cam_mode = vga_jpeg_mode; | ||
811 | cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); | ||
812 | } | ||
713 | 813 | ||
714 | return 0; | 814 | return 0; |
715 | } | 815 | } |
@@ -778,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
778 | static int sd_start(struct gspca_dev *gspca_dev) | 878 | static int sd_start(struct gspca_dev *gspca_dev) |
779 | { | 879 | { |
780 | struct sd *sd = (struct sd *) gspca_dev; | 880 | struct sd *sd = (struct sd *) gspca_dev; |
881 | int mode; | ||
781 | 882 | ||
782 | switch (sd->sensor) { | 883 | switch (sd->sensor) { |
783 | case SENSOR_OV772X: | 884 | case SENSOR_OV772X: |
@@ -786,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
786 | break; | 887 | break; |
787 | default: | 888 | default: |
788 | /* case SENSOR_OV965X: */ | 889 | /* case SENSOR_OV965X: */ |
789 | reg_w_array(gspca_dev, bridge_start_ov965x, | 890 | |
790 | ARRAY_SIZE(bridge_start_ov965x)); | ||
791 | sccb_w_array(gspca_dev, sensor_start_ov965x, | 891 | sccb_w_array(gspca_dev, sensor_start_ov965x, |
792 | ARRAY_SIZE(sensor_start_ov965x)); | 892 | ARRAY_SIZE(sensor_start_ov965x)); |
893 | reg_w_array(gspca_dev, bridge_start_ov965x, | ||
894 | ARRAY_SIZE(bridge_start_ov965x)); | ||
895 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | ||
896 | if (mode != 0) { /* 320x240 */ | ||
897 | reg_w_array(gspca_dev, bridge_start_ov965x_cif, | ||
898 | ARRAY_SIZE(bridge_start_ov965x_cif)); | ||
899 | sccb_w_array(gspca_dev, sensor_start_ov965x_cif, | ||
900 | ARRAY_SIZE(sensor_start_ov965x_cif)); | ||
901 | } else { /* 640x480 */ | ||
902 | reg_w_array(gspca_dev, bridge_start_ov965x_vga, | ||
903 | ARRAY_SIZE(bridge_start_ov965x_vga)); | ||
904 | sccb_w_array(gspca_dev, sensor_start_ov965x_vga, | ||
905 | ARRAY_SIZE(sensor_start_ov965x_vga)); | ||
906 | } | ||
907 | sccb_w_array(gspca_dev, sensor_start_ov965x_2, | ||
908 | ARRAY_SIZE(sensor_start_ov965x_2)); | ||
909 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
793 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 910 | ov534_reg_write(gspca_dev, 0xe0, 0x00); |
794 | ov534_set_led(gspca_dev, 1); | 911 | ov534_set_led(gspca_dev, 1); |
795 | /*fixme: other sensor start omitted*/ | ||
796 | } | 912 | } |
797 | return 0; | 913 | return 0; |
798 | } | 914 | } |
@@ -832,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
832 | __u32 this_pts; | 948 | __u32 this_pts; |
833 | u16 this_fid; | 949 | u16 this_fid; |
834 | int remaining_len = len; | 950 | int remaining_len = len; |
951 | int payload_len; | ||
835 | 952 | ||
953 | payload_len = gspca_dev->cam.bulk ? 2048 : 2040; | ||
836 | do { | 954 | do { |
837 | len = min(remaining_len, 2040); /*fixme: was 2048*/ | 955 | len = min(remaining_len, payload_len); |
838 | 956 | ||
839 | /* Payloads are prefixed with a UVC-style header. We | 957 | /* Payloads are prefixed with a UVC-style header. We |
840 | consider a frame to start when the FID toggles, or the PTS | 958 | consider a frame to start when the FID toggles, or the PTS |
@@ -864,30 +982,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
864 | 982 | ||
865 | /* If PTS or FID has changed, start a new frame. */ | 983 | /* If PTS or FID has changed, start a new frame. */ |
866 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { | 984 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { |
867 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 985 | if (gspca_dev->last_packet_type == INTER_PACKET) |
868 | NULL, 0); | 986 | frame = gspca_frame_add(gspca_dev, |
987 | LAST_PACKET, frame, | ||
988 | NULL, 0); | ||
869 | sd->last_pts = this_pts; | 989 | sd->last_pts = this_pts; |
870 | sd->last_fid = this_fid; | 990 | sd->last_fid = this_fid; |
871 | } | 991 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |
872 | |||
873 | /* Add the data from this payload */ | ||
874 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
875 | data + 12, len - 12); | 992 | data + 12, len - 12); |
876 | |||
877 | /* If this packet is marked as EOF, end the frame */ | 993 | /* If this packet is marked as EOF, end the frame */ |
878 | if (data[1] & UVC_STREAM_EOF) { | 994 | } else if (data[1] & UVC_STREAM_EOF) { |
879 | sd->last_pts = 0; | 995 | sd->last_pts = 0; |
880 | |||
881 | if (frame->data_end - frame->data != | ||
882 | gspca_dev->width * gspca_dev->height * 2) { | ||
883 | PDEBUG(D_PACK, "short frame"); | ||
884 | goto discard; | ||
885 | } | ||
886 | |||
887 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 996 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
888 | NULL, 0); | 997 | data + 12, len - 12); |
998 | } else { | ||
999 | |||
1000 | /* Add the data from this payload */ | ||
1001 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1002 | data + 12, len - 12); | ||
889 | } | 1003 | } |
890 | 1004 | ||
1005 | |||
891 | /* Done this payload */ | 1006 | /* Done this payload */ |
892 | goto scan_next; | 1007 | goto scan_next; |
893 | 1008 | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 153d0a91d4b5..cf3af8de6e97 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
877 | cam->cam_mode = sif_mode; | 877 | cam->cam_mode = sif_mode; |
878 | cam->nmodes = ARRAY_SIZE(sif_mode); | 878 | cam->nmodes = ARRAY_SIZE(sif_mode); |
879 | } | 879 | } |
880 | cam->npkt = 36; /* 36 packets per ISOC message */ | ||
881 | |||
880 | sd->brightness = BRIGHTNESS_DEF; | 882 | sd->brightness = BRIGHTNESS_DEF; |
881 | sd->gain = GAIN_DEF; | 883 | sd->gain = GAIN_DEF; |
882 | sd->exposure = EXPOSURE_DEF; | 884 | sd->exposure = EXPOSURE_DEF; |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c72e19d3ac37..dc6a6f11354a 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -62,7 +62,6 @@ struct sd { | |||
62 | #define BRIDGE_SN9C105 1 | 62 | #define BRIDGE_SN9C105 1 |
63 | #define BRIDGE_SN9C110 2 | 63 | #define BRIDGE_SN9C110 2 |
64 | #define BRIDGE_SN9C120 3 | 64 | #define BRIDGE_SN9C120 3 |
65 | #define BRIDGE_SN9C325 4 | ||
66 | u8 sensor; /* Type of image sensor chip */ | 65 | u8 sensor; /* Type of image sensor chip */ |
67 | #define SENSOR_HV7131R 0 | 66 | #define SENSOR_HV7131R 0 |
68 | #define SENSOR_MI0360 1 | 67 | #define SENSOR_MI0360 1 |
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = { | |||
354 | 353 | ||
355 | static const u8 sn_ov7660[0x1c] = { | 354 | static const u8 sn_ov7660[0x1c] = { |
356 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 355 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
357 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, | 356 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, |
358 | /* reg8 reg9 rega regb regc regd rege regf */ | 357 | /* reg8 reg9 rega regb regc regd rege regf */ |
359 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, | 358 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
360 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | 359 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
361 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, | 360 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
362 | /* reg18 reg19 reg1a reg1b */ | 361 | /* reg18 reg19 reg1a reg1b */ |
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = { | |||
757 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 756 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
758 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 757 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
759 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ | 758 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
759 | {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
760 | /****** (some exchanges in the win trace) ******/ | 760 | /****** (some exchanges in the win trace) ******/ |
761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ | 761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
762 | /* bits[3..0]reserved */ | 762 | /* bits[3..0]reserved */ |
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1065 | struct sd *sd = (struct sd *) gspca_dev; | 1065 | struct sd *sd = (struct sd *) gspca_dev; |
1066 | const u8 *reg9a; | 1066 | const u8 *reg9a; |
1067 | static const u8 reg9a_def[] = | 1067 | static const u8 reg9a_def[] = |
1068 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 1068 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; |
1069 | static const u8 reg9a_sn9c325[] = | 1069 | static const u8 reg9a_spec[] = |
1070 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 1070 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; |
1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | 1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; |
1072 | 1072 | ||
1073 | reg_w1(gspca_dev, 0xf1, 0x00); | 1073 | reg_w1(gspca_dev, 0xf1, 0x00); |
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | 1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); |
1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ | 1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ |
1080 | switch (sd->bridge) { | 1080 | switch (sd->sensor) { |
1081 | case BRIDGE_SN9C325: | 1081 | case SENSOR_OV7660: |
1082 | reg9a = reg9a_sn9c325; | 1082 | case SENSOR_SP80708: |
1083 | reg9a = reg9a_spec; | ||
1083 | break; | 1084 | break; |
1084 | default: | 1085 | default: |
1085 | reg9a = reg9a_def; | 1086 | reg9a = reg9a_def; |
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1104 | reg_w1(gspca_dev, 0x17, 0x64); | 1105 | reg_w1(gspca_dev, 0x17, 0x64); |
1105 | reg_w1(gspca_dev, 0x01, 0x42); | 1106 | reg_w1(gspca_dev, 0x01, 0x42); |
1106 | break; | 1107 | break; |
1107 | /*jfm: from win trace */ | ||
1108 | case SENSOR_OV7630: | 1108 | case SENSOR_OV7630: |
1109 | reg_w1(gspca_dev, 0x01, 0x61); | 1109 | reg_w1(gspca_dev, 0x01, 0x61); |
1110 | reg_w1(gspca_dev, 0x17, 0xe2); | 1110 | reg_w1(gspca_dev, 0x17, 0xe2); |
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1114 | case SENSOR_OV7648: | 1114 | case SENSOR_OV7648: |
1115 | reg_w1(gspca_dev, 0x01, 0x63); | 1115 | reg_w1(gspca_dev, 0x01, 0x63); |
1116 | reg_w1(gspca_dev, 0x17, 0x20); | 1116 | reg_w1(gspca_dev, 0x17, 0x20); |
1117 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1117 | reg_w1(gspca_dev, 0x01, 0x42); | 1118 | reg_w1(gspca_dev, 0x01, 0x42); |
1118 | break; | 1119 | break; |
1119 | /*jfm: from win trace */ | ||
1120 | case SENSOR_OV7660: | 1120 | case SENSOR_OV7660: |
1121 | if (sd->bridge == BRIDGE_SN9C120) { | 1121 | reg_w1(gspca_dev, 0x01, 0x61); |
1122 | reg_w1(gspca_dev, 0x01, 0x61); | 1122 | reg_w1(gspca_dev, 0x17, 0x20); |
1123 | reg_w1(gspca_dev, 0x17, 0x20); | 1123 | reg_w1(gspca_dev, 0x01, 0x60); |
1124 | reg_w1(gspca_dev, 0x01, 0x60); | 1124 | reg_w1(gspca_dev, 0x01, 0x40); |
1125 | reg_w1(gspca_dev, 0x01, 0x40); | 1125 | break; |
1126 | break; | ||
1127 | } | ||
1128 | /* fall thru */ | ||
1129 | case SENSOR_SP80708: | 1126 | case SENSOR_SP80708: |
1130 | reg_w1(gspca_dev, 0x01, 0x63); | 1127 | reg_w1(gspca_dev, 0x01, 0x63); |
1131 | reg_w1(gspca_dev, 0x17, 0x20); | 1128 | reg_w1(gspca_dev, 0x17, 0x20); |
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1134 | mdelay(100); | 1131 | mdelay(100); |
1135 | reg_w1(gspca_dev, 0x02, 0x62); | 1132 | reg_w1(gspca_dev, 0x02, 0x62); |
1136 | break; | 1133 | break; |
1134 | /* case SENSOR_HV7131R: */ | ||
1135 | /* case SENSOR_MI0360: */ | ||
1136 | /* case SENSOR_MO4000: */ | ||
1137 | default: | 1137 | default: |
1138 | reg_w1(gspca_dev, 0x01, 0x43); | 1138 | reg_w1(gspca_dev, 0x01, 0x43); |
1139 | reg_w1(gspca_dev, 0x17, 0x61); | 1139 | reg_w1(gspca_dev, 0x17, 0x61); |
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1280 | cam = &gspca_dev->cam; | 1280 | cam = &gspca_dev->cam; |
1281 | cam->cam_mode = vga_mode; | 1281 | cam->cam_mode = vga_mode; |
1282 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1282 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1283 | cam->npkt = 24; /* 24 packets per ISOC message */ | ||
1283 | 1284 | ||
1284 | sd->bridge = id->driver_info >> 16; | 1285 | sd->bridge = id->driver_info >> 16; |
1285 | sd->sensor = id->driver_info >> 8; | 1286 | sd->sensor = id->driver_info >> 8; |
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1683 | case SENSOR_OV7648: | 1684 | case SENSOR_OV7648: |
1684 | reg17 = 0x20; | 1685 | reg17 = 0x20; |
1685 | break; | 1686 | break; |
1686 | /*jfm: from win trace */ | ||
1687 | case SENSOR_OV7660: | 1687 | case SENSOR_OV7660: |
1688 | if (sd->bridge == BRIDGE_SN9C120) { | 1688 | reg17 = 0xa0; |
1689 | reg17 = 0xa0; | 1689 | break; |
1690 | break; | ||
1691 | } | ||
1692 | /* fall thru */ | ||
1693 | default: | 1690 | default: |
1694 | reg17 = 0x60; | 1691 | reg17 = 0x60; |
1695 | break; | 1692 | break; |
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1714 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1711 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1715 | reg_w1(gspca_dev, 0x99, 0x60); | 1712 | reg_w1(gspca_dev, 0x99, 0x60); |
1716 | break; | 1713 | break; |
1714 | case SENSOR_OV7660: | ||
1715 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1716 | if (sd->bridge == BRIDGE_SN9C105) | ||
1717 | reg_w1(gspca_dev, 0x99, 0xff); | ||
1718 | else | ||
1719 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
1720 | break; | ||
1717 | case SENSOR_SP80708: | 1721 | case SENSOR_SP80708: |
1718 | reg_w1(gspca_dev, 0x9a, 0x05); | 1722 | reg_w1(gspca_dev, 0x9a, 0x05); |
1719 | reg_w1(gspca_dev, 0x99, 0x59); | 1723 | reg_w1(gspca_dev, 0x99, 0x59); |
1720 | break; | 1724 | break; |
1721 | case SENSOR_OV7660: | ||
1722 | if (sd->bridge == BRIDGE_SN9C120) { | ||
1723 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1724 | break; | ||
1725 | } | ||
1726 | /* fall thru */ | ||
1727 | default: | 1725 | default: |
1728 | reg_w1(gspca_dev, 0x9a, 0x08); | 1726 | reg_w1(gspca_dev, 0x9a, 0x08); |
1729 | reg_w1(gspca_dev, 0x99, 0x59); | 1727 | reg_w1(gspca_dev, 0x99, 0x59); |
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2193 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, | 2191 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, |
2194 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, | 2192 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, |
2195 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, | 2193 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, |
2194 | {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, | ||
2196 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, | 2195 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, |
2197 | /* bw600.inf: | 2196 | /* bw600.inf: |
2198 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ | 2197 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ |
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2211 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 2210 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
2212 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, | 2211 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, |
2213 | #endif | 2212 | #endif |
2213 | {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ | ||
2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ | 2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ |
2215 | {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ | ||
2216 | {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ | ||
2217 | {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ | ||
2218 | {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ | ||
2215 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ | 2219 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ |
2216 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ | 2220 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ |
2217 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ | 2221 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 6f38fa6d86b6..8806b2ff82be 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
906 | { | 903 | { |
907 | struct sd *sd = (struct sd *) gspca_dev; | 904 | struct sd *sd = (struct sd *) gspca_dev; |
908 | int i; | 905 | int i; |
909 | __u8 *s, *d; | ||
910 | static __u8 ffd9[] = {0xff, 0xd9}; | 906 | static __u8 ffd9[] = {0xff, 0xd9}; |
911 | 907 | ||
912 | /* frames are jpeg 4.1.1 without 0xff escape */ | 908 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
930 | } | 926 | } |
931 | 927 | ||
932 | /* add 0x00 after 0xff */ | 928 | /* add 0x00 after 0xff */ |
933 | for (i = len; --i >= 0; ) | 929 | i = 0; |
934 | if (data[i] == 0xff) | 930 | do { |
935 | break; | 931 | if (data[i] == 0xff) { |
936 | if (i < 0) { /* no 0xff */ | 932 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
937 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 933 | data, i + 1); |
938 | return; | 934 | len -= i; |
939 | } | 935 | data += i; |
940 | s = data; | 936 | *data = 0x00; |
941 | d = sd->packet; | 937 | i = 0; |
942 | for (i = 0; i < len; i++) { | 938 | } |
943 | *d++ = *s++; | 939 | i++; |
944 | if (s[-1] == 0xff) | 940 | } while (i < len); |
945 | *d++ = 0x00; | 941 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
946 | } | ||
947 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
948 | sd->packet, d - sd->packet); | ||
949 | } | 942 | } |
950 | 943 | ||
951 | static void setbrightness(struct gspca_dev *gspca_dev) | 944 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 2acec58b1b97..ea8c9fe2e961 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; | 637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; |
638 | sd->brightness = BRIGHTNESS_DEF; | 638 | sd->brightness = BRIGHTNESS_DEF; |
639 | 639 | ||
640 | if (sd->subtype == Nxultra) { | ||
641 | if (write_vector(gspca_dev, spca505b_init_data)) | ||
642 | return -EIO; | ||
643 | } else { | ||
644 | if (write_vector(gspca_dev, spca505_init_data)) | ||
645 | return -EIO; | ||
646 | } | ||
647 | return 0; | 640 | return 0; |
648 | } | 641 | } |
649 | 642 | ||
650 | /* this function is called at probe and resume time */ | 643 | /* this function is called at probe and resume time */ |
651 | static int sd_init(struct gspca_dev *gspca_dev) | 644 | static int sd_init(struct gspca_dev *gspca_dev) |
652 | { | 645 | { |
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | |||
648 | if (write_vector(gspca_dev, | ||
649 | sd->subtype == Nxultra | ||
650 | ? spca505b_init_data | ||
651 | : spca505_init_data)) | ||
652 | return -EIO; | ||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | 655 | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index adacf8437661..2ed2669bac3e 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SPCA508 chip based cameras subdriver | 2 | * SPCA508 chip based cameras subdriver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL"); | |||
30 | struct sd { | 30 | struct sd { |
31 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 31 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
32 | 32 | ||
33 | unsigned char brightness; | 33 | u8 brightness; |
34 | 34 | ||
35 | char subtype; | 35 | u8 subtype; |
36 | #define CreativeVista 0 | 36 | #define CreativeVista 0 |
37 | #define HamaUSBSightcam 1 | 37 | #define HamaUSBSightcam 1 |
38 | #define HamaUSBSightcam2 2 | 38 | #define HamaUSBSightcam2 2 |
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* Frame packet header offsets for the spca508 */ | 88 | /* Frame packet header offsets for the spca508 */ |
89 | #define SPCA508_OFFSET_TYPE 1 | ||
90 | #define SPCA508_OFFSET_COMPRESS 2 | ||
91 | #define SPCA508_OFFSET_FRAMSEQ 8 | ||
92 | #define SPCA508_OFFSET_WIN1LUM 11 | ||
93 | #define SPCA508_OFFSET_DATA 37 | 89 | #define SPCA508_OFFSET_DATA 37 |
94 | 90 | ||
95 | #define SPCA508_SNAPBIT 0x20 | ||
96 | #define SPCA508_SNAPCTRL 0x40 | ||
97 | /*************** I2c ****************/ | ||
98 | #define SPCA508_INDEX_I2C_BASE 0x8800 | ||
99 | |||
100 | /* | 91 | /* |
101 | * Initialization data: this is the first set-up data written to the | 92 | * Initialization data: this is the first set-up data written to the |
102 | * device (before the open data). | 93 | * device (before the open data). |
103 | */ | 94 | */ |
104 | static const u16 spca508_init_data[][2] = | 95 | static const u16 spca508_init_data[][2] = |
105 | { | 96 | { |
106 | /* line URB value, index */ | 97 | {0x0000, 0x870b}, |
107 | /* 44274 1804 */ {0x0000, 0x870b}, | 98 | |
108 | 99 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ | |
109 | /* 44299 1805 */ {0x0020, 0x8112}, | 100 | {0x0003, 0x8111}, /* Reset compression & memory */ |
110 | /* Video drop enable, ISO streaming disable */ | 101 | {0x0000, 0x8110}, /* Disable all outputs */ |
111 | /* 44324 1806 */ {0x0003, 0x8111}, | 102 | /* READ {0x0000, 0x8114} -> 0000: 00 */ |
112 | /* Reset compression & memory */ | 103 | {0x0000, 0x8114}, /* SW GPIO data */ |
113 | /* 44349 1807 */ {0x0000, 0x8110}, | 104 | {0x0008, 0x8110}, /* Enable charge pump output */ |
114 | /* Disable all outputs */ | 105 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
115 | /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ | 106 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ |
116 | /* 44398 1809 */ {0x0000, 0x8114}, | 107 | {0x0003, 0x8111}, /* Reset compression & memory */ |
117 | /* SW GPIO data */ | 108 | {0x0000, 0x8111}, /* Normal mode (not reset) */ |
118 | /* 44423 1810 */ {0x0008, 0x8110}, | 109 | {0x0098, 0x8110}, |
119 | /* Enable charge pump output */ | 110 | /* Enable charge pump output, sync.serial,external 2x clock */ |
120 | /* 44527 1811 */ {0x0002, 0x8116}, | 111 | {0x000d, 0x8114}, /* SW GPIO data */ |
121 | /* 200 kHz pump clock */ | 112 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
122 | /* 44555 1812 */ | 113 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
123 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ | ||
124 | /* 44590 1813 */ {0x0003, 0x8111}, | ||
125 | /* Reset compression & memory */ | ||
126 | /* 44615 1814 */ {0x0000, 0x8111}, | ||
127 | /* Normal mode (not reset) */ | ||
128 | /* 44640 1815 */ {0x0098, 0x8110}, | ||
129 | /* Enable charge pump output, sync.serial,external 2x clock */ | ||
130 | /* 44665 1816 */ {0x000d, 0x8114}, | ||
131 | /* SW GPIO data */ | ||
132 | /* 44690 1817 */ {0x0002, 0x8116}, | ||
133 | /* 200 kHz pump clock */ | ||
134 | /* 44715 1818 */ {0x0020, 0x8112}, | ||
135 | /* Video drop enable, ISO streaming disable */ | ||
136 | /* --------------------------------------- */ | 114 | /* --------------------------------------- */ |
137 | /* 44740 1819 */ {0x000f, 0x8402}, | 115 | {0x000f, 0x8402}, /* memory bank */ |
138 | /* memory bank */ | 116 | {0x0000, 0x8403}, /* ... address */ |
139 | /* 44765 1820 */ {0x0000, 0x8403}, | ||
140 | /* ... address */ | ||
141 | /* --------------------------------------- */ | 117 | /* --------------------------------------- */ |
142 | /* 0x88__ is Synchronous Serial Interface. */ | 118 | /* 0x88__ is Synchronous Serial Interface. */ |
143 | /* TBD: This table could be expressed more compactly */ | 119 | /* TBD: This table could be expressed more compactly */ |
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] = | |||
145 | /* TBD: Should see if the values in spca50x_i2c_data */ | 121 | /* TBD: Should see if the values in spca50x_i2c_data */ |
146 | /* would work with the VQ110 instead of the values */ | 122 | /* would work with the VQ110 instead of the values */ |
147 | /* below. */ | 123 | /* below. */ |
148 | /* 44790 1821 */ {0x00c0, 0x8804}, | 124 | {0x00c0, 0x8804}, /* SSI slave addr */ |
149 | /* SSI slave addr */ | 125 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
150 | /* 44815 1822 */ {0x0008, 0x8802}, | 126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
151 | /* 375 Khz SSI clock */ | 127 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
152 | /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 128 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
153 | /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 129 | {0x0012, 0x8801}, /* SSI reg addr */ |
154 | /* 44888 1825 */ {0x0008, 0x8802}, | 130 | {0x0080, 0x8800}, /* SSI data to write */ |
155 | /* 375 Khz SSI clock */ | 131 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
156 | /* 44913 1826 */ {0x0012, 0x8801}, | 132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
157 | /* SSI reg addr */ | 133 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
158 | /* 44938 1827 */ {0x0080, 0x8800}, | 134 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
159 | /* SSI data to write */ | 135 | {0x0012, 0x8801}, /* SSI reg addr */ |
160 | /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 136 | {0x0000, 0x8800}, /* SSI data to write */ |
161 | /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 137 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
162 | /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 138 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
163 | /* 45035 1831 */ {0x0008, 0x8802}, | 139 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
164 | /* 375 Khz SSI clock */ | 140 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
165 | /* 45060 1832 */ {0x0012, 0x8801}, | 141 | {0x0011, 0x8801}, /* SSI reg addr */ |
166 | /* SSI reg addr */ | 142 | {0x0040, 0x8800}, /* SSI data to write */ |
167 | /* 45085 1833 */ {0x0000, 0x8800}, | 143 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
168 | /* SSI data to write */ | 144 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
169 | /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 145 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
170 | /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 146 | {0x0008, 0x8802}, |
171 | /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 147 | {0x0013, 0x8801}, |
172 | /* 45182 1837 */ {0x0008, 0x8802}, | 148 | {0x0000, 0x8800}, |
173 | /* 375 Khz SSI clock */ | 149 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
174 | /* 45207 1838 */ {0x0011, 0x8801}, | 150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
175 | /* SSI reg addr */ | 151 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
176 | /* 45232 1839 */ {0x0040, 0x8800}, | 152 | {0x0008, 0x8802}, |
177 | /* SSI data to write */ | 153 | {0x0014, 0x8801}, |
178 | /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 154 | {0x0000, 0x8800}, |
179 | /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 155 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
180 | /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
181 | /* 45329 1843 */ {0x0008, 0x8802}, | 157 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
182 | /* 45354 1844 */ {0x0013, 0x8801}, | 158 | {0x0008, 0x8802}, |
183 | /* 45379 1845 */ {0x0000, 0x8800}, | 159 | {0x0015, 0x8801}, |
184 | /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 160 | {0x0001, 0x8800}, |
185 | /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 161 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
186 | /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 162 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
187 | /* 45476 1849 */ {0x0008, 0x8802}, | 163 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
188 | /* 45501 1850 */ {0x0014, 0x8801}, | 164 | {0x0008, 0x8802}, |
189 | /* 45526 1851 */ {0x0000, 0x8800}, | 165 | {0x0016, 0x8801}, |
190 | /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 166 | {0x0003, 0x8800}, |
191 | /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 167 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
192 | /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 168 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
193 | /* 45623 1855 */ {0x0008, 0x8802}, | 169 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
194 | /* 45648 1856 */ {0x0015, 0x8801}, | 170 | {0x0008, 0x8802}, |
195 | /* 45673 1857 */ {0x0001, 0x8800}, | 171 | {0x0017, 0x8801}, |
196 | /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 172 | {0x0036, 0x8800}, |
197 | /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 173 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
198 | /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 174 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
199 | /* 45770 1861 */ {0x0008, 0x8802}, | 175 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
200 | /* 45795 1862 */ {0x0016, 0x8801}, | 176 | {0x0008, 0x8802}, |
201 | /* 45820 1863 */ {0x0003, 0x8800}, | 177 | {0x0018, 0x8801}, |
202 | /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 178 | {0x00ec, 0x8800}, |
203 | /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 179 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
204 | /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 180 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
205 | /* 45917 1867 */ {0x0008, 0x8802}, | 181 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
206 | /* 45942 1868 */ {0x0017, 0x8801}, | 182 | {0x0008, 0x8802}, |
207 | /* 45967 1869 */ {0x0036, 0x8800}, | 183 | {0x001a, 0x8801}, |
208 | /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 184 | {0x0094, 0x8800}, |
209 | /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 185 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
210 | /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 186 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
211 | /* 46064 1873 */ {0x0008, 0x8802}, | 187 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
212 | /* 46089 1874 */ {0x0018, 0x8801}, | 188 | {0x0008, 0x8802}, |
213 | /* 46114 1875 */ {0x00ec, 0x8800}, | 189 | {0x001b, 0x8801}, |
214 | /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 190 | {0x0000, 0x8800}, |
215 | /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 191 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
216 | /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 192 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
217 | /* 46211 1879 */ {0x0008, 0x8802}, | 193 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
218 | /* 46236 1880 */ {0x001a, 0x8801}, | 194 | {0x0008, 0x8802}, |
219 | /* 46261 1881 */ {0x0094, 0x8800}, | 195 | {0x0027, 0x8801}, |
220 | /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 196 | {0x00a2, 0x8800}, |
221 | /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 197 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
222 | /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 198 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
223 | /* 46358 1885 */ {0x0008, 0x8802}, | 199 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
224 | /* 46383 1886 */ {0x001b, 0x8801}, | 200 | {0x0008, 0x8802}, |
225 | /* 46408 1887 */ {0x0000, 0x8800}, | 201 | {0x0028, 0x8801}, |
226 | /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 202 | {0x0040, 0x8800}, |
227 | /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 203 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
228 | /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 204 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
229 | /* 46505 1891 */ {0x0008, 0x8802}, | 205 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
230 | /* 46530 1892 */ {0x0027, 0x8801}, | 206 | {0x0008, 0x8802}, |
231 | /* 46555 1893 */ {0x00a2, 0x8800}, | 207 | {0x002a, 0x8801}, |
232 | /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 208 | {0x0084, 0x8800}, |
233 | /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 209 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
234 | /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 210 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
235 | /* 46652 1897 */ {0x0008, 0x8802}, | 211 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
236 | /* 46677 1898 */ {0x0028, 0x8801}, | 212 | {0x0008, 0x8802}, |
237 | /* 46702 1899 */ {0x0040, 0x8800}, | 213 | {0x002b, 0x8801}, |
238 | /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 214 | {0x00a8, 0x8800}, |
239 | /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 215 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
240 | /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 216 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
241 | /* 46799 1903 */ {0x0008, 0x8802}, | 217 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
242 | /* 46824 1904 */ {0x002a, 0x8801}, | 218 | {0x0008, 0x8802}, |
243 | /* 46849 1905 */ {0x0084, 0x8800}, | 219 | {0x002c, 0x8801}, |
244 | /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 220 | {0x00fe, 0x8800}, |
245 | /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 221 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
246 | /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 222 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
247 | /* 46946 1909 */ {0x0008, 0x8802}, | 223 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
248 | /* 46971 1910 */ {0x002b, 0x8801}, | 224 | {0x0008, 0x8802}, |
249 | /* 46996 1911 */ {0x00a8, 0x8800}, | 225 | {0x002d, 0x8801}, |
250 | /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 226 | {0x0003, 0x8800}, |
251 | /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 227 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
252 | /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 228 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
253 | /* 47093 1915 */ {0x0008, 0x8802}, | 229 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
254 | /* 47118 1916 */ {0x002c, 0x8801}, | 230 | {0x0008, 0x8802}, |
255 | /* 47143 1917 */ {0x00fe, 0x8800}, | 231 | {0x0038, 0x8801}, |
256 | /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 232 | {0x0083, 0x8800}, |
257 | /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 233 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
258 | /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 234 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
259 | /* 47240 1921 */ {0x0008, 0x8802}, | 235 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
260 | /* 47265 1922 */ {0x002d, 0x8801}, | 236 | {0x0008, 0x8802}, |
261 | /* 47290 1923 */ {0x0003, 0x8800}, | 237 | {0x0033, 0x8801}, |
262 | /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 238 | {0x0081, 0x8800}, |
263 | /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 239 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
264 | /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 240 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
265 | /* 47387 1927 */ {0x0008, 0x8802}, | 241 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
266 | /* 47412 1928 */ {0x0038, 0x8801}, | 242 | {0x0008, 0x8802}, |
267 | /* 47437 1929 */ {0x0083, 0x8800}, | 243 | {0x0034, 0x8801}, |
268 | /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 244 | {0x004a, 0x8800}, |
269 | /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 245 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
270 | /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 246 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
271 | /* 47534 1933 */ {0x0008, 0x8802}, | 247 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
272 | /* 47559 1934 */ {0x0033, 0x8801}, | 248 | {0x0008, 0x8802}, |
273 | /* 47584 1935 */ {0x0081, 0x8800}, | 249 | {0x0039, 0x8801}, |
274 | /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 250 | {0x0000, 0x8800}, |
275 | /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 251 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
276 | /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 252 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
277 | /* 47681 1939 */ {0x0008, 0x8802}, | 253 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
278 | /* 47706 1940 */ {0x0034, 0x8801}, | 254 | {0x0008, 0x8802}, |
279 | /* 47731 1941 */ {0x004a, 0x8800}, | 255 | {0x0010, 0x8801}, |
280 | /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 256 | {0x00a8, 0x8800}, |
281 | /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 257 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
282 | /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 258 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
283 | /* 47828 1945 */ {0x0008, 0x8802}, | 259 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
284 | /* 47853 1946 */ {0x0039, 0x8801}, | 260 | {0x0008, 0x8802}, |
285 | /* 47878 1947 */ {0x0000, 0x8800}, | 261 | {0x0006, 0x8801}, |
286 | /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 262 | {0x0058, 0x8800}, |
287 | /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 263 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
288 | /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 264 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
289 | /* 47975 1951 */ {0x0008, 0x8802}, | 265 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
290 | /* 48000 1952 */ {0x0010, 0x8801}, | 266 | {0x0008, 0x8802}, |
291 | /* 48025 1953 */ {0x00a8, 0x8800}, | 267 | {0x0000, 0x8801}, |
292 | /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 268 | {0x0004, 0x8800}, |
293 | /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 269 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
294 | /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 270 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
295 | /* 48122 1957 */ {0x0008, 0x8802}, | 271 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
296 | /* 48147 1958 */ {0x0006, 0x8801}, | 272 | {0x0008, 0x8802}, |
297 | /* 48172 1959 */ {0x0058, 0x8800}, | 273 | {0x0040, 0x8801}, |
298 | /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 274 | {0x0080, 0x8800}, |
299 | /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 275 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
300 | /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 276 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
301 | /* 48269 1963 */ {0x0008, 0x8802}, | 277 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
302 | /* 48294 1964 */ {0x0000, 0x8801}, | 278 | {0x0008, 0x8802}, |
303 | /* 48319 1965 */ {0x0004, 0x8800}, | 279 | {0x0041, 0x8801}, |
304 | /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 280 | {0x000c, 0x8800}, |
305 | /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 281 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
306 | /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 282 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
307 | /* 48416 1969 */ {0x0008, 0x8802}, | 283 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
308 | /* 48441 1970 */ {0x0040, 0x8801}, | 284 | {0x0008, 0x8802}, |
309 | /* 48466 1971 */ {0x0080, 0x8800}, | 285 | {0x0042, 0x8801}, |
310 | /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 286 | {0x000c, 0x8800}, |
311 | /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 287 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
312 | /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 288 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
313 | /* 48563 1975 */ {0x0008, 0x8802}, | 289 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
314 | /* 48588 1976 */ {0x0041, 0x8801}, | 290 | {0x0008, 0x8802}, |
315 | /* 48613 1977 */ {0x000c, 0x8800}, | 291 | {0x0043, 0x8801}, |
316 | /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 292 | {0x0028, 0x8800}, |
317 | /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 293 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
318 | /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 294 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
319 | /* 48710 1981 */ {0x0008, 0x8802}, | 295 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
320 | /* 48735 1982 */ {0x0042, 0x8801}, | 296 | {0x0008, 0x8802}, |
321 | /* 48760 1983 */ {0x000c, 0x8800}, | 297 | {0x0044, 0x8801}, |
322 | /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 298 | {0x0080, 0x8800}, |
323 | /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 299 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
324 | /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 300 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
325 | /* 48857 1987 */ {0x0008, 0x8802}, | 301 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
326 | /* 48882 1988 */ {0x0043, 0x8801}, | 302 | {0x0008, 0x8802}, |
327 | /* 48907 1989 */ {0x0028, 0x8800}, | 303 | {0x0045, 0x8801}, |
328 | /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 304 | {0x0020, 0x8800}, |
329 | /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 305 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
330 | /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 306 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
331 | /* 49004 1993 */ {0x0008, 0x8802}, | 307 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
332 | /* 49029 1994 */ {0x0044, 0x8801}, | 308 | {0x0008, 0x8802}, |
333 | /* 49054 1995 */ {0x0080, 0x8800}, | 309 | {0x0046, 0x8801}, |
334 | /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 310 | {0x0020, 0x8800}, |
335 | /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 311 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
336 | /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 312 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
337 | /* 49151 1999 */ {0x0008, 0x8802}, | 313 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
338 | /* 49176 2000 */ {0x0045, 0x8801}, | 314 | {0x0008, 0x8802}, |
339 | /* 49201 2001 */ {0x0020, 0x8800}, | 315 | {0x0047, 0x8801}, |
340 | /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 316 | {0x0080, 0x8800}, |
341 | /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 317 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
342 | /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 318 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
343 | /* 49298 2005 */ {0x0008, 0x8802}, | 319 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
344 | /* 49323 2006 */ {0x0046, 0x8801}, | 320 | {0x0008, 0x8802}, |
345 | /* 49348 2007 */ {0x0020, 0x8800}, | 321 | {0x0048, 0x8801}, |
346 | /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 322 | {0x004c, 0x8800}, |
347 | /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 323 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
348 | /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 324 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
349 | /* 49445 2011 */ {0x0008, 0x8802}, | 325 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
350 | /* 49470 2012 */ {0x0047, 0x8801}, | 326 | {0x0008, 0x8802}, |
351 | /* 49495 2013 */ {0x0080, 0x8800}, | 327 | {0x0049, 0x8801}, |
352 | /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 328 | {0x0084, 0x8800}, |
353 | /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 329 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
354 | /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 330 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
355 | /* 49592 2017 */ {0x0008, 0x8802}, | 331 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
356 | /* 49617 2018 */ {0x0048, 0x8801}, | 332 | {0x0008, 0x8802}, |
357 | /* 49642 2019 */ {0x004c, 0x8800}, | 333 | {0x004a, 0x8801}, |
358 | /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 334 | {0x0084, 0x8800}, |
359 | /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 335 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
360 | /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 336 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
361 | /* 49739 2023 */ {0x0008, 0x8802}, | 337 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
362 | /* 49764 2024 */ {0x0049, 0x8801}, | 338 | {0x0008, 0x8802}, |
363 | /* 49789 2025 */ {0x0084, 0x8800}, | 339 | {0x004b, 0x8801}, |
364 | /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 340 | {0x0084, 0x8800}, |
365 | /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 341 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
366 | /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
367 | /* 49886 2029 */ {0x0008, 0x8802}, | ||
368 | /* 49911 2030 */ {0x004a, 0x8801}, | ||
369 | /* 49936 2031 */ {0x0084, 0x8800}, | ||
370 | /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
371 | /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
372 | /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
373 | /* 50033 2035 */ {0x0008, 0x8802}, | ||
374 | /* 50058 2036 */ {0x004b, 0x8801}, | ||
375 | /* 50083 2037 */ {0x0084, 0x8800}, | ||
376 | /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
377 | /* --------------------------------------- */ | 342 | /* --------------------------------------- */ |
378 | /* 50132 2039 */ {0x0012, 0x8700}, | 343 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
379 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 344 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
380 | /* 50157 2040 */ {0x0000, 0x8701}, | 345 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
381 | /* CKx1 clock delay adj */ | 346 | {0x0001, 0x870c}, /* CKOx2 output */ |
382 | /* 50182 2041 */ {0x0000, 0x8701}, | ||
383 | /* CKx1 clock delay adj */ | ||
384 | /* 50207 2042 */ {0x0001, 0x870c}, | ||
385 | /* CKOx2 output */ | ||
386 | /* --------------------------------------- */ | 347 | /* --------------------------------------- */ |
387 | /* 50232 2043 */ {0x0080, 0x8600}, | 348 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
388 | /* Line memory read counter (L) */ | 349 | {0x0001, 0x8606}, /* reserved */ |
389 | /* 50257 2044 */ {0x0001, 0x8606}, | 350 | {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */ |
390 | /* reserved */ | 351 | {0x002a, 0x8601}, /* CDSP sharp interpolation mode, |
391 | /* 50282 2045 */ {0x0064, 0x8607}, | ||
392 | /* Line memory read counter (H) 0x6480=25,728 */ | ||
393 | /* 50307 2046 */ {0x002a, 0x8601}, | ||
394 | /* CDSP sharp interpolation mode, | ||
395 | * line sel for color sep, edge enhance enab */ | 352 | * line sel for color sep, edge enhance enab */ |
396 | /* 50332 2047 */ {0x0000, 0x8602}, | 353 | {0x0000, 0x8602}, /* optical black level for user settng = 0 */ |
397 | /* optical black level for user settng = 0 */ | 354 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
398 | /* 50357 2048 */ {0x0080, 0x8600}, | 355 | {0x000a, 0x8603}, /* optical black level calc mode: |
399 | /* Line memory read counter (L) */ | 356 | * auto; optical black offset = 10 */ |
400 | /* 50382 2049 */ {0x000a, 0x8603}, | 357 | {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */ |
401 | /* optical black level calc mode: auto; optical black offset = 10 */ | 358 | {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */ |
402 | /* 50407 2050 */ {0x00df, 0x865b}, | ||
403 | /* Horiz offset for valid pixels (L)=0xdf */ | ||
404 | /* 50432 2051 */ {0x0012, 0x865c}, | ||
405 | /* Vert offset for valid lines (L)=0x12 */ | ||
406 | 359 | ||
407 | /* The following two lines seem to be the "wrong" resolution. */ | 360 | /* The following two lines seem to be the "wrong" resolution. */ |
408 | /* But perhaps these indicate the actual size of the sensor */ | 361 | /* But perhaps these indicate the actual size of the sensor */ |
409 | /* rather than the size of the current video mode. */ | 362 | /* rather than the size of the current video mode. */ |
410 | /* 50457 2052 */ {0x0058, 0x865d}, | 363 | {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */ |
411 | /* Horiz valid pixels (*4) (L) = 352 */ | 364 | {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */ |
412 | /* 50482 2053 */ {0x0048, 0x865e}, | 365 | |
413 | /* Vert valid lines (*4) (L) = 288 */ | 366 | {0x0015, 0x8608}, /* A11 Coef ... */ |
414 | 367 | {0x0030, 0x8609}, | |
415 | /* 50507 2054 */ {0x0015, 0x8608}, | 368 | {0x00fb, 0x860a}, |
416 | /* A11 Coef ... */ | 369 | {0x003e, 0x860b}, |
417 | /* 50532 2055 */ {0x0030, 0x8609}, | 370 | {0x00ce, 0x860c}, |
418 | /* 50557 2056 */ {0x00fb, 0x860a}, | 371 | {0x00f4, 0x860d}, |
419 | /* 50582 2057 */ {0x003e, 0x860b}, | 372 | {0x00eb, 0x860e}, |
420 | /* 50607 2058 */ {0x00ce, 0x860c}, | 373 | {0x00dc, 0x860f}, |
421 | /* 50632 2059 */ {0x00f4, 0x860d}, | 374 | {0x0039, 0x8610}, |
422 | /* 50657 2060 */ {0x00eb, 0x860e}, | 375 | {0x0001, 0x8611}, /* R offset for white balance ... */ |
423 | /* 50682 2061 */ {0x00dc, 0x860f}, | 376 | {0x0000, 0x8612}, |
424 | /* 50707 2062 */ {0x0039, 0x8610}, | 377 | {0x0001, 0x8613}, |
425 | /* 50732 2063 */ {0x0001, 0x8611}, | 378 | {0x0000, 0x8614}, |
426 | /* R offset for white balance ... */ | 379 | {0x005b, 0x8651}, /* R gain for white balance ... */ |
427 | /* 50757 2064 */ {0x0000, 0x8612}, | 380 | {0x0040, 0x8652}, |
428 | /* 50782 2065 */ {0x0001, 0x8613}, | 381 | {0x0060, 0x8653}, |
429 | /* 50807 2066 */ {0x0000, 0x8614}, | 382 | {0x0040, 0x8654}, |
430 | /* 50832 2067 */ {0x005b, 0x8651}, | 383 | {0x0000, 0x8655}, |
431 | /* R gain for white balance ... */ | 384 | {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control, |
432 | /* 50857 2068 */ {0x0040, 0x8652}, | 385 | * lum filter disable, lum noise clip disable */ |
433 | /* 50882 2069 */ {0x0060, 0x8653}, | 386 | {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64, |
434 | /* 50907 2070 */ {0x0040, 0x8654}, | 387 | * gamma look-up disable, |
435 | /* 50932 2071 */ {0x0000, 0x8655}, | 388 | * new edge enhancement enable */ |
436 | /* 50957 2072 */ {0x0001, 0x863f}, | 389 | {0x0018, 0x8657}, /* Edge gain high thresh */ |
437 | /* Fixed gamma correction enable, USB control, | 390 | {0x0020, 0x8658}, /* Edge gain low thresh */ |
438 | * lum filter disable, lum noise clip disable */ | 391 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
439 | /* 50982 2073 */ {0x00a1, 0x8656}, | 392 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
440 | /* Window1 size 256x256, Windows2 size 64x64, | ||
441 | * gamma look-up disable, new edge enhancement enable */ | ||
442 | /* 51007 2074 */ {0x0018, 0x8657}, | ||
443 | /* Edge gain high thresh */ | ||
444 | /* 51032 2075 */ {0x0020, 0x8658}, | ||
445 | /* Edge gain low thresh */ | ||
446 | /* 51057 2076 */ {0x000a, 0x8659}, | ||
447 | /* Edge bandwidth high threshold */ | ||
448 | /* 51082 2077 */ {0x0005, 0x865a}, | ||
449 | /* Edge bandwidth low threshold */ | ||
450 | /* -------------------------------- */ | 393 | /* -------------------------------- */ |
451 | /* 51107 2078 */ {0x0030, 0x8112}, | 394 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
452 | /* Video drop enable, ISO streaming enable */ | 395 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
453 | /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 396 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
454 | /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 397 | {0xa908, 0x8802}, |
455 | /* 51180 2081 */ {0xa908, 0x8802}, | 398 | {0x0034, 0x8801}, /* SSI reg addr */ |
456 | /* 51205 2082 */ {0x0034, 0x8801}, | 399 | {0x00ca, 0x8800}, |
457 | /* SSI reg addr */ | ||
458 | /* 51230 2083 */ {0x00ca, 0x8800}, | ||
459 | /* SSI data to write */ | 400 | /* SSI data to write */ |
460 | /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 401 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
461 | /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 402 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
462 | /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 403 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
463 | /* 51327 2087 */ {0x1f08, 0x8802}, | 404 | {0x1f08, 0x8802}, |
464 | /* 51352 2088 */ {0x0006, 0x8801}, | 405 | {0x0006, 0x8801}, |
465 | /* 51377 2089 */ {0x0080, 0x8800}, | 406 | {0x0080, 0x8800}, |
466 | /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 407 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
467 | 408 | ||
468 | /* ----- Read back coefs we wrote earlier. */ | 409 | /* ----- Read back coefs we wrote earlier. */ |
469 | /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ | 410 | /* READ { 0x0000, 0x8608 } -> 0000: 15 */ |
470 | /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ | 411 | /* READ { 0x0000, 0x8609 } -> 0000: 30 */ |
471 | /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ | 412 | /* READ { 0x0000, 0x860a } -> 0000: fb */ |
472 | /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ | 413 | /* READ { 0x0000, 0x860b } -> 0000: 3e */ |
473 | /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ | 414 | /* READ { 0x0000, 0x860c } -> 0000: ce */ |
474 | /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ | 415 | /* READ { 0x0000, 0x860d } -> 0000: f4 */ |
475 | /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ | 416 | /* READ { 0x0000, 0x860e } -> 0000: eb */ |
476 | /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ | 417 | /* READ { 0x0000, 0x860f } -> 0000: dc */ |
477 | /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ | 418 | /* READ { 0x0000, 0x8610 } -> 0000: 39 */ |
478 | /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 419 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
479 | /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 420 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
480 | /* 51690 2102 */ {0xb008, 0x8802}, | 421 | {0xb008, 0x8802}, |
481 | /* 51715 2103 */ {0x0006, 0x8801}, | 422 | {0x0006, 0x8801}, |
482 | /* 51740 2104 */ {0x007d, 0x8800}, | 423 | {0x007d, 0x8800}, |
483 | /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 424 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
484 | 425 | ||
485 | 426 | ||
486 | /* This chunk is seemingly redundant with */ | 427 | /* This chunk is seemingly redundant with */ |
487 | /* earlier commands (A11 Coef...), but if I disable it, */ | 428 | /* earlier commands (A11 Coef...), but if I disable it, */ |
488 | /* the image appears too dark. Maybe there was some kind of */ | 429 | /* the image appears too dark. Maybe there was some kind of */ |
489 | /* reset since the earlier commands, so this is necessary again. */ | 430 | /* reset since the earlier commands, so this is necessary again. */ |
490 | /* 51789 2106 */ {0x0015, 0x8608}, | 431 | {0x0015, 0x8608}, |
491 | /* 51814 2107 */ {0x0030, 0x8609}, | 432 | {0x0030, 0x8609}, |
492 | /* 51839 2108 */ {0xfffb, 0x860a}, | 433 | {0xfffb, 0x860a}, |
493 | /* 51864 2109 */ {0x003e, 0x860b}, | 434 | {0x003e, 0x860b}, |
494 | /* 51889 2110 */ {0xffce, 0x860c}, | 435 | {0xffce, 0x860c}, |
495 | /* 51914 2111 */ {0xfff4, 0x860d}, | 436 | {0xfff4, 0x860d}, |
496 | /* 51939 2112 */ {0xffeb, 0x860e}, | 437 | {0xffeb, 0x860e}, |
497 | /* 51964 2113 */ {0xffdc, 0x860f}, | 438 | {0xffdc, 0x860f}, |
498 | /* 51989 2114 */ {0x0039, 0x8610}, | 439 | {0x0039, 0x8610}, |
499 | /* 52014 2115 */ {0x0018, 0x8657}, | 440 | {0x0018, 0x8657}, |
500 | 441 | ||
501 | /* 52039 2116 */ {0x0000, 0x8508}, | 442 | {0x0000, 0x8508}, /* Disable compression. */ |
502 | /* Disable compression. */ | ||
503 | /* Previous line was: | 443 | /* Previous line was: |
504 | * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ | 444 | {0x0021, 0x8508}, * Enable compression. */ |
505 | /* 52064 2117 */ {0x0032, 0x850b}, | 445 | {0x0032, 0x850b}, /* compression stuff */ |
506 | /* compression stuff */ | 446 | {0x0003, 0x8509}, /* compression stuff */ |
507 | /* 52089 2118 */ {0x0003, 0x8509}, | 447 | {0x0011, 0x850a}, /* compression stuff */ |
508 | /* compression stuff */ | 448 | {0x0021, 0x850d}, /* compression stuff */ |
509 | /* 52114 2119 */ {0x0011, 0x850a}, | 449 | {0x0010, 0x850c}, /* compression stuff */ |
510 | /* compression stuff */ | 450 | {0x0003, 0x8500}, /* *** Video mode: 160x120 */ |
511 | /* 52139 2120 */ {0x0021, 0x850d}, | 451 | {0x0001, 0x8501}, /* Hardware-dominated snap control */ |
512 | /* compression stuff */ | 452 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
513 | /* 52164 2121 */ {0x0010, 0x850c}, | 453 | * gamma look-up disable, |
514 | /* compression stuff */ | 454 | * new edge enhancement enable */ |
515 | /* 52189 2122 */ {0x0003, 0x8500}, | 455 | {0x0018, 0x8617}, /* Window1 start X (*2) */ |
516 | /* *** Video mode: 160x120 */ | 456 | {0x0008, 0x8618}, /* Window1 start Y (*2) */ |
517 | /* 52214 2123 */ {0x0001, 0x8501}, | 457 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
518 | /* Hardware-dominated snap control */ | 458 | * gamma look-up disable, |
519 | /* 52239 2124 */ {0x0061, 0x8656}, | 459 | * new edge enhancement enable */ |
520 | /* Window1 size 128x128, Windows2 size 128x128, | 460 | {0x0058, 0x8619}, /* Window2 start X (*2) */ |
521 | * gamma look-up disable, new edge enhancement enable */ | 461 | {0x0008, 0x861a}, /* Window2 start Y (*2) */ |
522 | /* 52264 2125 */ {0x0018, 0x8617}, | 462 | {0x00ff, 0x8615}, /* High lum thresh for white balance */ |
523 | /* Window1 start X (*2) */ | 463 | {0x0000, 0x8616}, /* Low lum thresh for white balance */ |
524 | /* 52289 2126 */ {0x0008, 0x8618}, | 464 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
525 | /* Window1 start Y (*2) */ | 465 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
526 | /* 52314 2127 */ {0x0061, 0x8656}, | 466 | /* READ { 0x0000, 0x8656 } -> 0000: 61 */ |
527 | /* Window1 size 128x128, Windows2 size 128x128, | 467 | {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
528 | * gamma look-up disable, new edge enhancement enable */ | 468 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
529 | /* 52339 2128 */ {0x0058, 0x8619}, | 469 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
530 | /* Window2 start X (*2) */ | 470 | {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
531 | /* 52364 2129 */ {0x0008, 0x861a}, | 471 | {0x0010, 0x8801}, /* SSI reg addr */ |
532 | /* Window2 start Y (*2) */ | 472 | {0x003e, 0x8800}, /* SSI data to write */ |
533 | /* 52389 2130 */ {0x00ff, 0x8615}, | 473 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
534 | /* High lum thresh for white balance */ | 474 | {0x0028, 0x8802}, |
535 | /* 52414 2131 */ {0x0000, 0x8616}, | 475 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
536 | /* Low lum thresh for white balance */ | 476 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
537 | /* 52439 2132 */ {0x0012, 0x8700}, | 477 | {0x1f28, 0x8802}, |
538 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 478 | {0x0000, 0x8801}, |
539 | /* 52464 2133 */ {0x0012, 0x8700}, | 479 | {0x001f, 0x8800}, |
540 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 480 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
541 | /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ | 481 | {0x0001, 0x8602}, /* optical black level for user settning = 1 */ |
542 | /* 52513 2135 */ {0x0028, 0x8802}, | ||
543 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
544 | /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
545 | /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
546 | /* 52586 2138 */ {0x1f28, 0x8802}, | ||
547 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
548 | /* 52611 2139 */ {0x0010, 0x8801}, | ||
549 | /* SSI reg addr */ | ||
550 | /* 52636 2140 */ {0x003e, 0x8800}, | ||
551 | /* SSI data to write */ | ||
552 | /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
553 | /* 52685 2142 */ {0x0028, 0x8802}, | ||
554 | /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
555 | /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
556 | /* 52758 2145 */ {0x1f28, 0x8802}, | ||
557 | /* 52783 2146 */ {0x0000, 0x8801}, | ||
558 | /* 52808 2147 */ {0x001f, 0x8800}, | ||
559 | /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
560 | /* 52857 2149 */ {0x0001, 0x8602}, | ||
561 | /* optical black level for user settning = 1 */ | ||
562 | 482 | ||
563 | /* Original: */ | 483 | /* Original: */ |
564 | /* 52882 2150 */ {0x0023, 0x8700}, | 484 | {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ |
565 | /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ | 485 | {0x000f, 0x8602}, /* optical black level for user settning = 15 */ |
566 | /* 52907 2151 */ {0x000f, 0x8602}, | 486 | |
567 | /* optical black level for user settning = 15 */ | 487 | {0x0028, 0x8802}, |
568 | 488 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ | |
569 | /* 52932 2152 */ {0x0028, 0x8802}, | 489 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
570 | /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 490 | {0x1f28, 0x8802}, |
571 | /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | 491 | {0x0010, 0x8801}, |
572 | /* 53005 2155 */ {0x1f28, 0x8802}, | 492 | {0x007b, 0x8800}, |
573 | /* 53030 2156 */ {0x0010, 0x8801}, | 493 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
574 | /* 53055 2157 */ {0x007b, 0x8800}, | 494 | {0x002f, 0x8651}, /* R gain for white balance ... */ |
575 | /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 495 | {0x0080, 0x8653}, |
576 | /* 53104 2159 */ {0x002f, 0x8651}, | 496 | /* READ { 0x0000, 0x8655 } -> 0000: 00 */ |
577 | /* R gain for white balance ... */ | 497 | {0x0000, 0x8655}, |
578 | /* 53129 2160 */ {0x0080, 0x8653}, | 498 | |
579 | /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ | 499 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
580 | /* 53178 2162 */ {0x0000, 0x8655}, | 500 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
581 | 501 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | |
582 | /* 53203 2163 */ {0x0030, 0x8112}, | ||
583 | /* Video drop enable, ISO streaming enable */ | ||
584 | /* 53228 2164 */ {0x0020, 0x8112}, | ||
585 | /* Video drop enable, ISO streaming disable */ | ||
586 | /* 53252 2165 */ | ||
587 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | ||
588 | {} | 502 | {} |
589 | }; | 503 | }; |
590 | 504 | ||
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] = | |||
592 | * Initialization data for Intel EasyPC Camera CS110 | 506 | * Initialization data for Intel EasyPC Camera CS110 |
593 | */ | 507 | */ |
594 | static const u16 spca508cs110_init_data[][2] = { | 508 | static const u16 spca508cs110_init_data[][2] = { |
595 | {0x0000, 0x870b}, /* Reset CTL3 */ | 509 | {0x0000, 0x870b}, /* Reset CTL3 */ |
596 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 510 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
597 | {0x0000, 0x8111}, /* Normal operation on reset */ | 511 | {0x0000, 0x8111}, /* Normal operation on reset */ |
598 | {0x0090, 0x8110}, | 512 | {0x0090, 0x8110}, |
599 | /* External Clock 2x & Synchronous Serial Interface Output */ | 513 | /* External Clock 2x & Synchronous Serial Interface Output */ |
600 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 514 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
601 | {0x0000, 0x8114}, /* Software GPIO output data */ | 515 | {0x0000, 0x8114}, /* Software GPIO output data */ |
602 | {0x0001, 0x8114}, | 516 | {0x0001, 0x8114}, |
603 | {0x0001, 0x8114}, | 517 | {0x0001, 0x8114}, |
604 | {0x0001, 0x8114}, | 518 | {0x0001, 0x8114}, |
605 | {0x0003, 0x8114}, | 519 | {0x0003, 0x8114}, |
606 | 520 | ||
607 | /* Initial sequence Synchronous Serial Interface */ | 521 | /* Initial sequence Synchronous Serial Interface */ |
608 | {0x000f, 0x8402}, /* Memory bank Address */ | 522 | {0x000f, 0x8402}, /* Memory bank Address */ |
609 | {0x0000, 0x8403}, /* Memory bank Address */ | 523 | {0x0000, 0x8403}, /* Memory bank Address */ |
610 | {0x00ba, 0x8804}, /* SSI Slave address */ | 524 | {0x00ba, 0x8804}, /* SSI Slave address */ |
611 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 525 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
612 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ | 526 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ |
613 | 527 | ||
614 | {0x0001, 0x8801}, | 528 | {0x0001, 0x8801}, |
615 | {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ | 529 | {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */ |
616 | {0x0000, 0x8800}, | 530 | {0x0000, 0x8800}, |
617 | {0x0010, 0x8802}, | 531 | {0x0010, 0x8802}, |
618 | 532 | ||
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = { | |||
646 | {0x0000, 0x8800}, | 560 | {0x0000, 0x8800}, |
647 | {0x0010, 0x8802}, | 561 | {0x0010, 0x8802}, |
648 | 562 | ||
649 | {0x0002, 0x8704}, /* External input CKIx1 */ | 563 | {0x0002, 0x8704}, /* External input CKIx1 */ |
650 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 564 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
651 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 565 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
652 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 566 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
653 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ | 567 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ |
654 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ | 568 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ |
655 | 569 | ||
656 | {0x0006, 0x8660}, /* Nibble data + input order */ | 570 | {0x0006, 0x8660}, /* Nibble data + input order */ |
657 | 571 | ||
658 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ | 572 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ |
659 | /* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ | 573 | {0x0000, 0x8603}, /* Optical black level Offset */ |
660 | 574 | ||
661 | /* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ | 575 | /* {0x0000, 0x8611}, * 0 R Offset for white Balance */ |
662 | /* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ | 576 | /* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */ |
663 | /* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ | 577 | /* {0x0000, 0x8613}, * 1f B Offset for white Balance */ |
664 | /* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ | 578 | /* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */ |
665 | 579 | ||
666 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ | 580 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ |
667 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ | 581 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ |
668 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ | 582 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ |
669 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ | 583 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ |
670 | {0x0041, 0x863f}, | 584 | {0x0041, 0x863f}, |
671 | /* Fixed Gamma correction enabled (makes colours look better) */ | 585 | /* Fixed Gamma correction enabled (makes colours look better) */ |
672 | 586 | ||
673 | /* 2422 */ {0x0000, 0x8655}, | 587 | {0x0000, 0x8655}, |
674 | /* High bits for white balance*****brightness control*** */ | 588 | /* High bits for white balance*****brightness control*** */ |
675 | {} | 589 | {} |
676 | }; | 590 | }; |
677 | 591 | ||
678 | static const u16 spca508_sightcam_init_data[][2] = { | 592 | static const u16 spca508_sightcam_init_data[][2] = { |
679 | /* This line seems to setup the frame/canvas */ | 593 | /* This line seems to setup the frame/canvas */ |
680 | /*368 */ {0x000f, 0x8402}, | 594 | {0x000f, 0x8402}, |
681 | 595 | ||
682 | /* Theese 6 lines are needed to startup the webcam */ | 596 | /* Theese 6 lines are needed to startup the webcam */ |
683 | /*398 */ {0x0090, 0x8110}, | 597 | {0x0090, 0x8110}, |
684 | /*399 */ {0x0001, 0x8114}, | 598 | {0x0001, 0x8114}, |
685 | /*400 */ {0x0001, 0x8114}, | 599 | {0x0001, 0x8114}, |
686 | /*401 */ {0x0001, 0x8114}, | 600 | {0x0001, 0x8114}, |
687 | /*402 */ {0x0003, 0x8114}, | 601 | {0x0003, 0x8114}, |
688 | /*403 */ {0x0080, 0x8804}, | 602 | {0x0080, 0x8804}, |
689 | 603 | ||
690 | /* This part seems to make the pictures darker? (autobrightness?) */ | 604 | /* This part seems to make the pictures darker? (autobrightness?) */ |
691 | /*436 */ {0x0001, 0x8801}, | 605 | {0x0001, 0x8801}, |
692 | /*437 */ {0x0004, 0x8800}, | 606 | {0x0004, 0x8800}, |
693 | /*439 */ {0x0003, 0x8801}, | 607 | {0x0003, 0x8801}, |
694 | /*440 */ {0x00e0, 0x8800}, | 608 | {0x00e0, 0x8800}, |
695 | /*442 */ {0x0004, 0x8801}, | 609 | {0x0004, 0x8801}, |
696 | /*443 */ {0x00b4, 0x8800}, | 610 | {0x00b4, 0x8800}, |
697 | /*445 */ {0x0005, 0x8801}, | 611 | {0x0005, 0x8801}, |
698 | /*446 */ {0x0000, 0x8800}, | 612 | {0x0000, 0x8800}, |
699 | 613 | ||
700 | /*448 */ {0x0006, 0x8801}, | 614 | {0x0006, 0x8801}, |
701 | /*449 */ {0x00e0, 0x8800}, | 615 | {0x00e0, 0x8800}, |
702 | /*451 */ {0x0007, 0x8801}, | 616 | {0x0007, 0x8801}, |
703 | /*452 */ {0x000c, 0x8800}, | 617 | {0x000c, 0x8800}, |
704 | 618 | ||
705 | /* This section is just needed, it probably | 619 | /* This section is just needed, it probably |
706 | * does something like the previous section, | 620 | * does something like the previous section, |
707 | * but the cam won't start if it's not included. | 621 | * but the cam won't start if it's not included. |
708 | */ | 622 | */ |
709 | /*484 */ {0x0014, 0x8801}, | 623 | {0x0014, 0x8801}, |
710 | /*485 */ {0x0008, 0x8800}, | 624 | {0x0008, 0x8800}, |
711 | /*487 */ {0x0015, 0x8801}, | 625 | {0x0015, 0x8801}, |
712 | /*488 */ {0x0067, 0x8800}, | 626 | {0x0067, 0x8800}, |
713 | /*490 */ {0x0016, 0x8801}, | 627 | {0x0016, 0x8801}, |
714 | /*491 */ {0x0000, 0x8800}, | 628 | {0x0000, 0x8800}, |
715 | /*493 */ {0x0017, 0x8801}, | 629 | {0x0017, 0x8801}, |
716 | /*494 */ {0x0020, 0x8800}, | 630 | {0x0020, 0x8800}, |
717 | /*496 */ {0x0018, 0x8801}, | 631 | {0x0018, 0x8801}, |
718 | /*497 */ {0x0044, 0x8800}, | 632 | {0x0044, 0x8800}, |
719 | 633 | ||
720 | /* Makes the picture darker - and the | 634 | /* Makes the picture darker - and the |
721 | * cam won't start if not included | 635 | * cam won't start if not included |
722 | */ | 636 | */ |
723 | /*505 */ {0x001e, 0x8801}, | 637 | {0x001e, 0x8801}, |
724 | /*506 */ {0x00ea, 0x8800}, | 638 | {0x00ea, 0x8800}, |
725 | /*508 */ {0x001f, 0x8801}, | 639 | {0x001f, 0x8801}, |
726 | /*509 */ {0x0001, 0x8800}, | 640 | {0x0001, 0x8800}, |
727 | /*511 */ {0x0003, 0x8801}, | 641 | {0x0003, 0x8801}, |
728 | /*512 */ {0x00e0, 0x8800}, | 642 | {0x00e0, 0x8800}, |
729 | 643 | ||
730 | /* seems to place the colors ontop of each other #1 */ | 644 | /* seems to place the colors ontop of each other #1 */ |
731 | /*517 */ {0x0006, 0x8704}, | 645 | {0x0006, 0x8704}, |
732 | /*518 */ {0x0001, 0x870c}, | 646 | {0x0001, 0x870c}, |
733 | /*519 */ {0x0016, 0x8600}, | 647 | {0x0016, 0x8600}, |
734 | /*520 */ {0x0002, 0x8606}, | 648 | {0x0002, 0x8606}, |
735 | 649 | ||
736 | /* if not included the pictures becomes _very_ dark */ | 650 | /* if not included the pictures becomes _very_ dark */ |
737 | /*521 */ {0x0064, 0x8607}, | 651 | {0x0064, 0x8607}, |
738 | /*522 */ {0x003a, 0x8601}, | 652 | {0x003a, 0x8601}, |
739 | /*523 */ {0x0000, 0x8602}, | 653 | {0x0000, 0x8602}, |
740 | 654 | ||
741 | /* seems to place the colors ontop of each other #2 */ | 655 | /* seems to place the colors ontop of each other #2 */ |
742 | /*524 */ {0x0016, 0x8600}, | 656 | {0x0016, 0x8600}, |
743 | /*525 */ {0x0018, 0x8617}, | 657 | {0x0018, 0x8617}, |
744 | /*526 */ {0x0008, 0x8618}, | 658 | {0x0008, 0x8618}, |
745 | /*527 */ {0x00a1, 0x8656}, | 659 | {0x00a1, 0x8656}, |
746 | 660 | ||
747 | /* webcam won't start if not included */ | 661 | /* webcam won't start if not included */ |
748 | /*528 */ {0x0007, 0x865b}, | 662 | {0x0007, 0x865b}, |
749 | /*529 */ {0x0001, 0x865c}, | 663 | {0x0001, 0x865c}, |
750 | /*530 */ {0x0058, 0x865d}, | 664 | {0x0058, 0x865d}, |
751 | /*531 */ {0x0048, 0x865e}, | 665 | {0x0048, 0x865e}, |
752 | 666 | ||
753 | /* adjusts the colors */ | 667 | /* adjusts the colors */ |
754 | /*541 */ {0x0049, 0x8651}, | 668 | {0x0049, 0x8651}, |
755 | /*542 */ {0x0040, 0x8652}, | 669 | {0x0040, 0x8652}, |
756 | /*543 */ {0x004c, 0x8653}, | 670 | {0x004c, 0x8653}, |
757 | /*544 */ {0x0040, 0x8654}, | 671 | {0x0040, 0x8654}, |
758 | {} | 672 | {} |
759 | }; | 673 | }; |
760 | 674 | ||
761 | static const u16 spca508_sightcam2_init_data[][2] = { | 675 | static const u16 spca508_sightcam2_init_data[][2] = { |
762 | /* 35 */ {0x0020, 0x8112}, | 676 | {0x0020, 0x8112}, |
763 | 677 | ||
764 | /* 36 */ {0x000f, 0x8402}, | 678 | {0x000f, 0x8402}, |
765 | /* 37 */ {0x0000, 0x8403}, | 679 | {0x0000, 0x8403}, |
766 | 680 | ||
767 | /* 38 */ {0x0008, 0x8201}, | 681 | {0x0008, 0x8201}, |
768 | /* 39 */ {0x0008, 0x8200}, | 682 | {0x0008, 0x8200}, |
769 | /* 40 */ {0x0001, 0x8200}, | 683 | {0x0001, 0x8200}, |
770 | /* 43 */ {0x0009, 0x8201}, | 684 | {0x0009, 0x8201}, |
771 | /* 44 */ {0x0008, 0x8200}, | 685 | {0x0008, 0x8200}, |
772 | /* 45 */ {0x0001, 0x8200}, | 686 | {0x0001, 0x8200}, |
773 | /* 48 */ {0x000a, 0x8201}, | 687 | {0x000a, 0x8201}, |
774 | /* 49 */ {0x0008, 0x8200}, | 688 | {0x0008, 0x8200}, |
775 | /* 50 */ {0x0001, 0x8200}, | 689 | {0x0001, 0x8200}, |
776 | /* 53 */ {0x000b, 0x8201}, | 690 | {0x000b, 0x8201}, |
777 | /* 54 */ {0x0008, 0x8200}, | 691 | {0x0008, 0x8200}, |
778 | /* 55 */ {0x0001, 0x8200}, | 692 | {0x0001, 0x8200}, |
779 | /* 58 */ {0x000c, 0x8201}, | 693 | {0x000c, 0x8201}, |
780 | /* 59 */ {0x0008, 0x8200}, | 694 | {0x0008, 0x8200}, |
781 | /* 60 */ {0x0001, 0x8200}, | 695 | {0x0001, 0x8200}, |
782 | /* 63 */ {0x000d, 0x8201}, | 696 | {0x000d, 0x8201}, |
783 | /* 64 */ {0x0008, 0x8200}, | 697 | {0x0008, 0x8200}, |
784 | /* 65 */ {0x0001, 0x8200}, | 698 | {0x0001, 0x8200}, |
785 | /* 68 */ {0x000e, 0x8201}, | 699 | {0x000e, 0x8201}, |
786 | /* 69 */ {0x0008, 0x8200}, | 700 | {0x0008, 0x8200}, |
787 | /* 70 */ {0x0001, 0x8200}, | 701 | {0x0001, 0x8200}, |
788 | /* 73 */ {0x0007, 0x8201}, | 702 | {0x0007, 0x8201}, |
789 | /* 74 */ {0x0008, 0x8200}, | 703 | {0x0008, 0x8200}, |
790 | /* 75 */ {0x0001, 0x8200}, | 704 | {0x0001, 0x8200}, |
791 | /* 78 */ {0x000f, 0x8201}, | 705 | {0x000f, 0x8201}, |
792 | /* 79 */ {0x0008, 0x8200}, | 706 | {0x0008, 0x8200}, |
793 | /* 80 */ {0x0001, 0x8200}, | 707 | {0x0001, 0x8200}, |
794 | 708 | ||
795 | /* 84 */ {0x0018, 0x8660}, | 709 | {0x0018, 0x8660}, |
796 | /* 85 */ {0x0010, 0x8201}, | 710 | {0x0010, 0x8201}, |
797 | 711 | ||
798 | /* 86 */ {0x0008, 0x8200}, | 712 | {0x0008, 0x8200}, |
799 | /* 87 */ {0x0001, 0x8200}, | 713 | {0x0001, 0x8200}, |
800 | /* 90 */ {0x0011, 0x8201}, | 714 | {0x0011, 0x8201}, |
801 | /* 91 */ {0x0008, 0x8200}, | 715 | {0x0008, 0x8200}, |
802 | /* 92 */ {0x0001, 0x8200}, | 716 | {0x0001, 0x8200}, |
803 | 717 | ||
804 | /* 95 */ {0x0000, 0x86b0}, | 718 | {0x0000, 0x86b0}, |
805 | /* 96 */ {0x0034, 0x86b1}, | 719 | {0x0034, 0x86b1}, |
806 | /* 97 */ {0x0000, 0x86b2}, | 720 | {0x0000, 0x86b2}, |
807 | /* 98 */ {0x0049, 0x86b3}, | 721 | {0x0049, 0x86b3}, |
808 | /* 99 */ {0x0000, 0x86b4}, | 722 | {0x0000, 0x86b4}, |
809 | /* 100 */ {0x0000, 0x86b4}, | 723 | {0x0000, 0x86b4}, |
810 | 724 | ||
811 | /* 101 */ {0x0012, 0x8201}, | 725 | {0x0012, 0x8201}, |
812 | /* 102 */ {0x0008, 0x8200}, | 726 | {0x0008, 0x8200}, |
813 | /* 103 */ {0x0001, 0x8200}, | 727 | {0x0001, 0x8200}, |
814 | /* 106 */ {0x0013, 0x8201}, | 728 | {0x0013, 0x8201}, |
815 | /* 107 */ {0x0008, 0x8200}, | 729 | {0x0008, 0x8200}, |
816 | /* 108 */ {0x0001, 0x8200}, | 730 | {0x0001, 0x8200}, |
817 | 731 | ||
818 | /* 111 */ {0x0001, 0x86b0}, | 732 | {0x0001, 0x86b0}, |
819 | /* 112 */ {0x00aa, 0x86b1}, | 733 | {0x00aa, 0x86b1}, |
820 | /* 113 */ {0x0000, 0x86b2}, | 734 | {0x0000, 0x86b2}, |
821 | /* 114 */ {0x00e4, 0x86b3}, | 735 | {0x00e4, 0x86b3}, |
822 | /* 115 */ {0x0000, 0x86b4}, | 736 | {0x0000, 0x86b4}, |
823 | /* 116 */ {0x0000, 0x86b4}, | 737 | {0x0000, 0x86b4}, |
824 | 738 | ||
825 | /* 118 */ {0x0018, 0x8660}, | 739 | {0x0018, 0x8660}, |
826 | 740 | ||
827 | /* 119 */ {0x0090, 0x8110}, | 741 | {0x0090, 0x8110}, |
828 | /* 120 */ {0x0001, 0x8114}, | 742 | {0x0001, 0x8114}, |
829 | /* 121 */ {0x0001, 0x8114}, | 743 | {0x0001, 0x8114}, |
830 | /* 122 */ {0x0001, 0x8114}, | 744 | {0x0001, 0x8114}, |
831 | /* 123 */ {0x0003, 0x8114}, | 745 | {0x0003, 0x8114}, |
832 | 746 | ||
833 | /* 124 */ {0x0080, 0x8804}, | 747 | {0x0080, 0x8804}, |
834 | /* 157 */ {0x0003, 0x8801}, | 748 | {0x0003, 0x8801}, |
835 | /* 158 */ {0x0012, 0x8800}, | 749 | {0x0012, 0x8800}, |
836 | /* 160 */ {0x0004, 0x8801}, | 750 | {0x0004, 0x8801}, |
837 | /* 161 */ {0x0005, 0x8800}, | 751 | {0x0005, 0x8800}, |
838 | /* 163 */ {0x0005, 0x8801}, | 752 | {0x0005, 0x8801}, |
839 | /* 164 */ {0x0000, 0x8800}, | 753 | {0x0000, 0x8800}, |
840 | /* 166 */ {0x0006, 0x8801}, | 754 | {0x0006, 0x8801}, |
841 | /* 167 */ {0x0000, 0x8800}, | 755 | {0x0000, 0x8800}, |
842 | /* 169 */ {0x0007, 0x8801}, | 756 | {0x0007, 0x8801}, |
843 | /* 170 */ {0x0000, 0x8800}, | 757 | {0x0000, 0x8800}, |
844 | /* 172 */ {0x0008, 0x8801}, | 758 | {0x0008, 0x8801}, |
845 | /* 173 */ {0x0005, 0x8800}, | 759 | {0x0005, 0x8800}, |
846 | /* 175 */ {0x000a, 0x8700}, | 760 | {0x000a, 0x8700}, |
847 | /* 176 */ {0x000e, 0x8801}, | 761 | {0x000e, 0x8801}, |
848 | /* 177 */ {0x0004, 0x8800}, | 762 | {0x0004, 0x8800}, |
849 | /* 179 */ {0x0005, 0x8801}, | 763 | {0x0005, 0x8801}, |
850 | /* 180 */ {0x0047, 0x8800}, | 764 | {0x0047, 0x8800}, |
851 | /* 182 */ {0x0006, 0x8801}, | 765 | {0x0006, 0x8801}, |
852 | /* 183 */ {0x0000, 0x8800}, | 766 | {0x0000, 0x8800}, |
853 | /* 185 */ {0x0007, 0x8801}, | 767 | {0x0007, 0x8801}, |
854 | /* 186 */ {0x00c0, 0x8800}, | 768 | {0x00c0, 0x8800}, |
855 | /* 188 */ {0x0008, 0x8801}, | 769 | {0x0008, 0x8801}, |
856 | /* 189 */ {0x0003, 0x8800}, | 770 | {0x0003, 0x8800}, |
857 | /* 191 */ {0x0013, 0x8801}, | 771 | {0x0013, 0x8801}, |
858 | /* 192 */ {0x0001, 0x8800}, | 772 | {0x0001, 0x8800}, |
859 | /* 194 */ {0x0009, 0x8801}, | 773 | {0x0009, 0x8801}, |
860 | /* 195 */ {0x0000, 0x8800}, | 774 | {0x0000, 0x8800}, |
861 | /* 197 */ {0x000a, 0x8801}, | 775 | {0x000a, 0x8801}, |
862 | /* 198 */ {0x0000, 0x8800}, | 776 | {0x0000, 0x8800}, |
863 | /* 200 */ {0x000b, 0x8801}, | 777 | {0x000b, 0x8801}, |
864 | /* 201 */ {0x0000, 0x8800}, | 778 | {0x0000, 0x8800}, |
865 | /* 203 */ {0x000c, 0x8801}, | 779 | {0x000c, 0x8801}, |
866 | /* 204 */ {0x0000, 0x8800}, | 780 | {0x0000, 0x8800}, |
867 | /* 206 */ {0x000e, 0x8801}, | 781 | {0x000e, 0x8801}, |
868 | /* 207 */ {0x0004, 0x8800}, | 782 | {0x0004, 0x8800}, |
869 | /* 209 */ {0x000f, 0x8801}, | 783 | {0x000f, 0x8801}, |
870 | /* 210 */ {0x0000, 0x8800}, | 784 | {0x0000, 0x8800}, |
871 | /* 212 */ {0x0010, 0x8801}, | 785 | {0x0010, 0x8801}, |
872 | /* 213 */ {0x0006, 0x8800}, | 786 | {0x0006, 0x8800}, |
873 | /* 215 */ {0x0011, 0x8801}, | 787 | {0x0011, 0x8801}, |
874 | /* 216 */ {0x0006, 0x8800}, | 788 | {0x0006, 0x8800}, |
875 | /* 218 */ {0x0012, 0x8801}, | 789 | {0x0012, 0x8801}, |
876 | /* 219 */ {0x0000, 0x8800}, | 790 | {0x0000, 0x8800}, |
877 | /* 221 */ {0x0013, 0x8801}, | 791 | {0x0013, 0x8801}, |
878 | /* 222 */ {0x0001, 0x8800}, | 792 | {0x0001, 0x8800}, |
879 | 793 | ||
880 | /* 224 */ {0x000a, 0x8700}, | 794 | {0x000a, 0x8700}, |
881 | /* 225 */ {0x0000, 0x8702}, | 795 | {0x0000, 0x8702}, |
882 | /* 226 */ {0x0000, 0x8703}, | 796 | {0x0000, 0x8703}, |
883 | /* 227 */ {0x00c2, 0x8704}, | 797 | {0x00c2, 0x8704}, |
884 | /* 228 */ {0x0001, 0x870c}, | 798 | {0x0001, 0x870c}, |
885 | 799 | ||
886 | /* 229 */ {0x0044, 0x8600}, | 800 | {0x0044, 0x8600}, |
887 | /* 230 */ {0x0002, 0x8606}, | 801 | {0x0002, 0x8606}, |
888 | /* 231 */ {0x0064, 0x8607}, | 802 | {0x0064, 0x8607}, |
889 | /* 232 */ {0x003a, 0x8601}, | 803 | {0x003a, 0x8601}, |
890 | /* 233 */ {0x0008, 0x8602}, | 804 | {0x0008, 0x8602}, |
891 | /* 234 */ {0x0044, 0x8600}, | 805 | {0x0044, 0x8600}, |
892 | /* 235 */ {0x0018, 0x8617}, | 806 | {0x0018, 0x8617}, |
893 | /* 236 */ {0x0008, 0x8618}, | 807 | {0x0008, 0x8618}, |
894 | /* 237 */ {0x00a1, 0x8656}, | 808 | {0x00a1, 0x8656}, |
895 | /* 238 */ {0x0004, 0x865b}, | 809 | {0x0004, 0x865b}, |
896 | /* 239 */ {0x0002, 0x865c}, | 810 | {0x0002, 0x865c}, |
897 | /* 240 */ {0x0058, 0x865d}, | 811 | {0x0058, 0x865d}, |
898 | /* 241 */ {0x0048, 0x865e}, | 812 | {0x0048, 0x865e}, |
899 | /* 242 */ {0x0012, 0x8608}, | 813 | {0x0012, 0x8608}, |
900 | /* 243 */ {0x002c, 0x8609}, | 814 | {0x002c, 0x8609}, |
901 | /* 244 */ {0x0002, 0x860a}, | 815 | {0x0002, 0x860a}, |
902 | /* 245 */ {0x002c, 0x860b}, | 816 | {0x002c, 0x860b}, |
903 | /* 246 */ {0x00db, 0x860c}, | 817 | {0x00db, 0x860c}, |
904 | /* 247 */ {0x00f9, 0x860d}, | 818 | {0x00f9, 0x860d}, |
905 | /* 248 */ {0x00f1, 0x860e}, | 819 | {0x00f1, 0x860e}, |
906 | /* 249 */ {0x00e3, 0x860f}, | 820 | {0x00e3, 0x860f}, |
907 | /* 250 */ {0x002c, 0x8610}, | 821 | {0x002c, 0x8610}, |
908 | /* 251 */ {0x006c, 0x8651}, | 822 | {0x006c, 0x8651}, |
909 | /* 252 */ {0x0041, 0x8652}, | 823 | {0x0041, 0x8652}, |
910 | /* 253 */ {0x0059, 0x8653}, | 824 | {0x0059, 0x8653}, |
911 | /* 254 */ {0x0040, 0x8654}, | 825 | {0x0040, 0x8654}, |
912 | /* 255 */ {0x00fa, 0x8611}, | 826 | {0x00fa, 0x8611}, |
913 | /* 256 */ {0x00ff, 0x8612}, | 827 | {0x00ff, 0x8612}, |
914 | /* 257 */ {0x00f8, 0x8613}, | 828 | {0x00f8, 0x8613}, |
915 | /* 258 */ {0x0000, 0x8614}, | 829 | {0x0000, 0x8614}, |
916 | /* 259 */ {0x0001, 0x863f}, | 830 | {0x0001, 0x863f}, |
917 | /* 260 */ {0x0000, 0x8640}, | 831 | {0x0000, 0x8640}, |
918 | /* 261 */ {0x0026, 0x8641}, | 832 | {0x0026, 0x8641}, |
919 | /* 262 */ {0x0045, 0x8642}, | 833 | {0x0045, 0x8642}, |
920 | /* 263 */ {0x0060, 0x8643}, | 834 | {0x0060, 0x8643}, |
921 | /* 264 */ {0x0075, 0x8644}, | 835 | {0x0075, 0x8644}, |
922 | /* 265 */ {0x0088, 0x8645}, | 836 | {0x0088, 0x8645}, |
923 | /* 266 */ {0x009b, 0x8646}, | 837 | {0x009b, 0x8646}, |
924 | /* 267 */ {0x00b0, 0x8647}, | 838 | {0x00b0, 0x8647}, |
925 | /* 268 */ {0x00c5, 0x8648}, | 839 | {0x00c5, 0x8648}, |
926 | /* 269 */ {0x00d2, 0x8649}, | 840 | {0x00d2, 0x8649}, |
927 | /* 270 */ {0x00dc, 0x864a}, | 841 | {0x00dc, 0x864a}, |
928 | /* 271 */ {0x00e5, 0x864b}, | 842 | {0x00e5, 0x864b}, |
929 | /* 272 */ {0x00eb, 0x864c}, | 843 | {0x00eb, 0x864c}, |
930 | /* 273 */ {0x00f0, 0x864d}, | 844 | {0x00f0, 0x864d}, |
931 | /* 274 */ {0x00f6, 0x864e}, | 845 | {0x00f6, 0x864e}, |
932 | /* 275 */ {0x00fa, 0x864f}, | 846 | {0x00fa, 0x864f}, |
933 | /* 276 */ {0x00ff, 0x8650}, | 847 | {0x00ff, 0x8650}, |
934 | /* 277 */ {0x0060, 0x8657}, | 848 | {0x0060, 0x8657}, |
935 | /* 278 */ {0x0010, 0x8658}, | 849 | {0x0010, 0x8658}, |
936 | /* 279 */ {0x0018, 0x8659}, | 850 | {0x0018, 0x8659}, |
937 | /* 280 */ {0x0005, 0x865a}, | 851 | {0x0005, 0x865a}, |
938 | /* 281 */ {0x0018, 0x8660}, | 852 | {0x0018, 0x8660}, |
939 | /* 282 */ {0x0003, 0x8509}, | 853 | {0x0003, 0x8509}, |
940 | /* 283 */ {0x0011, 0x850a}, | 854 | {0x0011, 0x850a}, |
941 | /* 284 */ {0x0032, 0x850b}, | 855 | {0x0032, 0x850b}, |
942 | /* 285 */ {0x0010, 0x850c}, | 856 | {0x0010, 0x850c}, |
943 | /* 286 */ {0x0021, 0x850d}, | 857 | {0x0021, 0x850d}, |
944 | /* 287 */ {0x0001, 0x8500}, | 858 | {0x0001, 0x8500}, |
945 | /* 288 */ {0x0000, 0x8508}, | 859 | {0x0000, 0x8508}, |
946 | /* 289 */ {0x0012, 0x8608}, | 860 | {0x0012, 0x8608}, |
947 | /* 290 */ {0x002c, 0x8609}, | 861 | {0x002c, 0x8609}, |
948 | /* 291 */ {0x0002, 0x860a}, | 862 | {0x0002, 0x860a}, |
949 | /* 292 */ {0x0039, 0x860b}, | 863 | {0x0039, 0x860b}, |
950 | /* 293 */ {0x00d0, 0x860c}, | 864 | {0x00d0, 0x860c}, |
951 | /* 294 */ {0x00f7, 0x860d}, | 865 | {0x00f7, 0x860d}, |
952 | /* 295 */ {0x00ed, 0x860e}, | 866 | {0x00ed, 0x860e}, |
953 | /* 296 */ {0x00db, 0x860f}, | 867 | {0x00db, 0x860f}, |
954 | /* 297 */ {0x0039, 0x8610}, | 868 | {0x0039, 0x8610}, |
955 | /* 298 */ {0x0012, 0x8657}, | 869 | {0x0012, 0x8657}, |
956 | /* 299 */ {0x000c, 0x8619}, | 870 | {0x000c, 0x8619}, |
957 | /* 300 */ {0x0004, 0x861a}, | 871 | {0x0004, 0x861a}, |
958 | /* 301 */ {0x00a1, 0x8656}, | 872 | {0x00a1, 0x8656}, |
959 | /* 302 */ {0x00c8, 0x8615}, | 873 | {0x00c8, 0x8615}, |
960 | /* 303 */ {0x0032, 0x8616}, | 874 | {0x0032, 0x8616}, |
961 | 875 | ||
962 | /* 306 */ {0x0030, 0x8112}, | 876 | {0x0030, 0x8112}, |
963 | /* 313 */ {0x0020, 0x8112}, | 877 | {0x0020, 0x8112}, |
964 | /* 314 */ {0x0020, 0x8112}, | 878 | {0x0020, 0x8112}, |
965 | /* 315 */ {0x000f, 0x8402}, | 879 | {0x000f, 0x8402}, |
966 | /* 316 */ {0x0000, 0x8403}, | 880 | {0x0000, 0x8403}, |
967 | 881 | ||
968 | /* 317 */ {0x0090, 0x8110}, | 882 | {0x0090, 0x8110}, |
969 | /* 318 */ {0x0001, 0x8114}, | 883 | {0x0001, 0x8114}, |
970 | /* 319 */ {0x0001, 0x8114}, | 884 | {0x0001, 0x8114}, |
971 | /* 320 */ {0x0001, 0x8114}, | 885 | {0x0001, 0x8114}, |
972 | /* 321 */ {0x0003, 0x8114}, | 886 | {0x0003, 0x8114}, |
973 | /* 322 */ {0x0080, 0x8804}, | 887 | {0x0080, 0x8804}, |
974 | 888 | ||
975 | /* 355 */ {0x0003, 0x8801}, | 889 | {0x0003, 0x8801}, |
976 | /* 356 */ {0x0012, 0x8800}, | 890 | {0x0012, 0x8800}, |
977 | /* 358 */ {0x0004, 0x8801}, | 891 | {0x0004, 0x8801}, |
978 | /* 359 */ {0x0005, 0x8800}, | 892 | {0x0005, 0x8800}, |
979 | /* 361 */ {0x0005, 0x8801}, | 893 | {0x0005, 0x8801}, |
980 | /* 362 */ {0x0047, 0x8800}, | 894 | {0x0047, 0x8800}, |
981 | /* 364 */ {0x0006, 0x8801}, | 895 | {0x0006, 0x8801}, |
982 | /* 365 */ {0x0000, 0x8800}, | 896 | {0x0000, 0x8800}, |
983 | /* 367 */ {0x0007, 0x8801}, | 897 | {0x0007, 0x8801}, |
984 | /* 368 */ {0x00c0, 0x8800}, | 898 | {0x00c0, 0x8800}, |
985 | /* 370 */ {0x0008, 0x8801}, | 899 | {0x0008, 0x8801}, |
986 | /* 371 */ {0x0003, 0x8800}, | 900 | {0x0003, 0x8800}, |
987 | /* 373 */ {0x000a, 0x8700}, | 901 | {0x000a, 0x8700}, |
988 | /* 374 */ {0x000e, 0x8801}, | 902 | {0x000e, 0x8801}, |
989 | /* 375 */ {0x0004, 0x8800}, | 903 | {0x0004, 0x8800}, |
990 | /* 377 */ {0x0005, 0x8801}, | 904 | {0x0005, 0x8801}, |
991 | /* 378 */ {0x0047, 0x8800}, | 905 | {0x0047, 0x8800}, |
992 | /* 380 */ {0x0006, 0x8801}, | 906 | {0x0006, 0x8801}, |
993 | /* 381 */ {0x0000, 0x8800}, | 907 | {0x0000, 0x8800}, |
994 | /* 383 */ {0x0007, 0x8801}, | 908 | {0x0007, 0x8801}, |
995 | /* 384 */ {0x00c0, 0x8800}, | 909 | {0x00c0, 0x8800}, |
996 | /* 386 */ {0x0008, 0x8801}, | 910 | {0x0008, 0x8801}, |
997 | /* 387 */ {0x0003, 0x8800}, | 911 | {0x0003, 0x8800}, |
998 | /* 389 */ {0x0013, 0x8801}, | 912 | {0x0013, 0x8801}, |
999 | /* 390 */ {0x0001, 0x8800}, | 913 | {0x0001, 0x8800}, |
1000 | /* 392 */ {0x0009, 0x8801}, | 914 | {0x0009, 0x8801}, |
1001 | /* 393 */ {0x0000, 0x8800}, | 915 | {0x0000, 0x8800}, |
1002 | /* 395 */ {0x000a, 0x8801}, | 916 | {0x000a, 0x8801}, |
1003 | /* 396 */ {0x0000, 0x8800}, | 917 | {0x0000, 0x8800}, |
1004 | /* 398 */ {0x000b, 0x8801}, | 918 | {0x000b, 0x8801}, |
1005 | /* 399 */ {0x0000, 0x8800}, | 919 | {0x0000, 0x8800}, |
1006 | /* 401 */ {0x000c, 0x8801}, | 920 | {0x000c, 0x8801}, |
1007 | /* 402 */ {0x0000, 0x8800}, | 921 | {0x0000, 0x8800}, |
1008 | /* 404 */ {0x000e, 0x8801}, | 922 | {0x000e, 0x8801}, |
1009 | /* 405 */ {0x0004, 0x8800}, | 923 | {0x0004, 0x8800}, |
1010 | /* 407 */ {0x000f, 0x8801}, | 924 | {0x000f, 0x8801}, |
1011 | /* 408 */ {0x0000, 0x8800}, | 925 | {0x0000, 0x8800}, |
1012 | /* 410 */ {0x0010, 0x8801}, | 926 | {0x0010, 0x8801}, |
1013 | /* 411 */ {0x0006, 0x8800}, | 927 | {0x0006, 0x8800}, |
1014 | /* 413 */ {0x0011, 0x8801}, | 928 | {0x0011, 0x8801}, |
1015 | /* 414 */ {0x0006, 0x8800}, | 929 | {0x0006, 0x8800}, |
1016 | /* 416 */ {0x0012, 0x8801}, | 930 | {0x0012, 0x8801}, |
1017 | /* 417 */ {0x0000, 0x8800}, | 931 | {0x0000, 0x8800}, |
1018 | /* 419 */ {0x0013, 0x8801}, | 932 | {0x0013, 0x8801}, |
1019 | /* 420 */ {0x0001, 0x8800}, | 933 | {0x0001, 0x8800}, |
1020 | /* 422 */ {0x000a, 0x8700}, | 934 | {0x000a, 0x8700}, |
1021 | /* 423 */ {0x0000, 0x8702}, | 935 | {0x0000, 0x8702}, |
1022 | /* 424 */ {0x0000, 0x8703}, | 936 | {0x0000, 0x8703}, |
1023 | /* 425 */ {0x00c2, 0x8704}, | 937 | {0x00c2, 0x8704}, |
1024 | /* 426 */ {0x0001, 0x870c}, | 938 | {0x0001, 0x870c}, |
1025 | /* 427 */ {0x0044, 0x8600}, | 939 | {0x0044, 0x8600}, |
1026 | /* 428 */ {0x0002, 0x8606}, | 940 | {0x0002, 0x8606}, |
1027 | /* 429 */ {0x0064, 0x8607}, | 941 | {0x0064, 0x8607}, |
1028 | /* 430 */ {0x003a, 0x8601}, | 942 | {0x003a, 0x8601}, |
1029 | /* 431 */ {0x0008, 0x8602}, | 943 | {0x0008, 0x8602}, |
1030 | /* 432 */ {0x0044, 0x8600}, | 944 | {0x0044, 0x8600}, |
1031 | /* 433 */ {0x0018, 0x8617}, | 945 | {0x0018, 0x8617}, |
1032 | /* 434 */ {0x0008, 0x8618}, | 946 | {0x0008, 0x8618}, |
1033 | /* 435 */ {0x00a1, 0x8656}, | 947 | {0x00a1, 0x8656}, |
1034 | /* 436 */ {0x0004, 0x865b}, | 948 | {0x0004, 0x865b}, |
1035 | /* 437 */ {0x0002, 0x865c}, | 949 | {0x0002, 0x865c}, |
1036 | /* 438 */ {0x0058, 0x865d}, | 950 | {0x0058, 0x865d}, |
1037 | /* 439 */ {0x0048, 0x865e}, | 951 | {0x0048, 0x865e}, |
1038 | /* 440 */ {0x0012, 0x8608}, | 952 | {0x0012, 0x8608}, |
1039 | /* 441 */ {0x002c, 0x8609}, | 953 | {0x002c, 0x8609}, |
1040 | /* 442 */ {0x0002, 0x860a}, | 954 | {0x0002, 0x860a}, |
1041 | /* 443 */ {0x002c, 0x860b}, | 955 | {0x002c, 0x860b}, |
1042 | /* 444 */ {0x00db, 0x860c}, | 956 | {0x00db, 0x860c}, |
1043 | /* 445 */ {0x00f9, 0x860d}, | 957 | {0x00f9, 0x860d}, |
1044 | /* 446 */ {0x00f1, 0x860e}, | 958 | {0x00f1, 0x860e}, |
1045 | /* 447 */ {0x00e3, 0x860f}, | 959 | {0x00e3, 0x860f}, |
1046 | /* 448 */ {0x002c, 0x8610}, | 960 | {0x002c, 0x8610}, |
1047 | /* 449 */ {0x006c, 0x8651}, | 961 | {0x006c, 0x8651}, |
1048 | /* 450 */ {0x0041, 0x8652}, | 962 | {0x0041, 0x8652}, |
1049 | /* 451 */ {0x0059, 0x8653}, | 963 | {0x0059, 0x8653}, |
1050 | /* 452 */ {0x0040, 0x8654}, | 964 | {0x0040, 0x8654}, |
1051 | /* 453 */ {0x00fa, 0x8611}, | 965 | {0x00fa, 0x8611}, |
1052 | /* 454 */ {0x00ff, 0x8612}, | 966 | {0x00ff, 0x8612}, |
1053 | /* 455 */ {0x00f8, 0x8613}, | 967 | {0x00f8, 0x8613}, |
1054 | /* 456 */ {0x0000, 0x8614}, | 968 | {0x0000, 0x8614}, |
1055 | /* 457 */ {0x0001, 0x863f}, | 969 | {0x0001, 0x863f}, |
1056 | /* 458 */ {0x0000, 0x8640}, | 970 | {0x0000, 0x8640}, |
1057 | /* 459 */ {0x0026, 0x8641}, | 971 | {0x0026, 0x8641}, |
1058 | /* 460 */ {0x0045, 0x8642}, | 972 | {0x0045, 0x8642}, |
1059 | /* 461 */ {0x0060, 0x8643}, | 973 | {0x0060, 0x8643}, |
1060 | /* 462 */ {0x0075, 0x8644}, | 974 | {0x0075, 0x8644}, |
1061 | /* 463 */ {0x0088, 0x8645}, | 975 | {0x0088, 0x8645}, |
1062 | /* 464 */ {0x009b, 0x8646}, | 976 | {0x009b, 0x8646}, |
1063 | /* 465 */ {0x00b0, 0x8647}, | 977 | {0x00b0, 0x8647}, |
1064 | /* 466 */ {0x00c5, 0x8648}, | 978 | {0x00c5, 0x8648}, |
1065 | /* 467 */ {0x00d2, 0x8649}, | 979 | {0x00d2, 0x8649}, |
1066 | /* 468 */ {0x00dc, 0x864a}, | 980 | {0x00dc, 0x864a}, |
1067 | /* 469 */ {0x00e5, 0x864b}, | 981 | {0x00e5, 0x864b}, |
1068 | /* 470 */ {0x00eb, 0x864c}, | 982 | {0x00eb, 0x864c}, |
1069 | /* 471 */ {0x00f0, 0x864d}, | 983 | {0x00f0, 0x864d}, |
1070 | /* 472 */ {0x00f6, 0x864e}, | 984 | {0x00f6, 0x864e}, |
1071 | /* 473 */ {0x00fa, 0x864f}, | 985 | {0x00fa, 0x864f}, |
1072 | /* 474 */ {0x00ff, 0x8650}, | 986 | {0x00ff, 0x8650}, |
1073 | /* 475 */ {0x0060, 0x8657}, | 987 | {0x0060, 0x8657}, |
1074 | /* 476 */ {0x0010, 0x8658}, | 988 | {0x0010, 0x8658}, |
1075 | /* 477 */ {0x0018, 0x8659}, | 989 | {0x0018, 0x8659}, |
1076 | /* 478 */ {0x0005, 0x865a}, | 990 | {0x0005, 0x865a}, |
1077 | /* 479 */ {0x0018, 0x8660}, | 991 | {0x0018, 0x8660}, |
1078 | /* 480 */ {0x0003, 0x8509}, | 992 | {0x0003, 0x8509}, |
1079 | /* 481 */ {0x0011, 0x850a}, | 993 | {0x0011, 0x850a}, |
1080 | /* 482 */ {0x0032, 0x850b}, | 994 | {0x0032, 0x850b}, |
1081 | /* 483 */ {0x0010, 0x850c}, | 995 | {0x0010, 0x850c}, |
1082 | /* 484 */ {0x0021, 0x850d}, | 996 | {0x0021, 0x850d}, |
1083 | /* 485 */ {0x0001, 0x8500}, | 997 | {0x0001, 0x8500}, |
1084 | /* 486 */ {0x0000, 0x8508}, | 998 | {0x0000, 0x8508}, |
1085 | 999 | ||
1086 | /* 487 */ {0x0012, 0x8608}, | 1000 | {0x0012, 0x8608}, |
1087 | /* 488 */ {0x002c, 0x8609}, | 1001 | {0x002c, 0x8609}, |
1088 | /* 489 */ {0x0002, 0x860a}, | 1002 | {0x0002, 0x860a}, |
1089 | /* 490 */ {0x0039, 0x860b}, | 1003 | {0x0039, 0x860b}, |
1090 | /* 491 */ {0x00d0, 0x860c}, | 1004 | {0x00d0, 0x860c}, |
1091 | /* 492 */ {0x00f7, 0x860d}, | 1005 | {0x00f7, 0x860d}, |
1092 | /* 493 */ {0x00ed, 0x860e}, | 1006 | {0x00ed, 0x860e}, |
1093 | /* 494 */ {0x00db, 0x860f}, | 1007 | {0x00db, 0x860f}, |
1094 | /* 495 */ {0x0039, 0x8610}, | 1008 | {0x0039, 0x8610}, |
1095 | /* 496 */ {0x0012, 0x8657}, | 1009 | {0x0012, 0x8657}, |
1096 | /* 497 */ {0x0064, 0x8619}, | 1010 | {0x0064, 0x8619}, |
1097 | 1011 | ||
1098 | /* This line starts it all, it is not needed here */ | 1012 | /* This line starts it all, it is not needed here */ |
1099 | /* since it has been build into the driver */ | 1013 | /* since it has been build into the driver */ |
1100 | /* jfm: don't start now */ | 1014 | /* jfm: don't start now */ |
1101 | /* 590 * {0x0030, 0x8112}, */ | 1015 | /* {0x0030, 0x8112}, */ |
1102 | {} | 1016 | {} |
1103 | }; | 1017 | }; |
1104 | 1018 | ||
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1109 | {0x0008, 0x8200}, /* Clear register */ | 1023 | {0x0008, 0x8200}, /* Clear register */ |
1110 | {0x0000, 0x870b}, /* Reset CTL3 */ | 1024 | {0x0000, 0x870b}, /* Reset CTL3 */ |
1111 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 1025 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
1112 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 1026 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
1113 | {0x0000, 0x8110}, /* Disable everything */ | 1027 | {0x0000, 0x8110}, /* Disable everything */ |
1114 | {0x0000, 0x8114}, /* Software GPIO output data */ | 1028 | {0x0000, 0x8114}, /* Software GPIO output data */ |
1115 | {0x0000, 0x8114}, | 1029 | {0x0000, 0x8114}, |
1116 | 1030 | ||
1117 | {0x0003, 0x8111}, | 1031 | {0x0003, 0x8111}, |
1118 | {0x0000, 0x8111}, | 1032 | {0x0000, 0x8111}, |
1119 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ | 1033 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ |
1120 | {0x0020, 0x8112}, | 1034 | {0x0020, 0x8112}, |
1121 | {0x0000, 0x8114}, | 1035 | {0x0000, 0x8114}, |
1122 | {0x0001, 0x8114}, | 1036 | {0x0001, 0x8114}, |
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1129 | {0x00ba, 0x8804}, /* SSI Slave address */ | 1043 | {0x00ba, 0x8804}, /* SSI Slave address */ |
1130 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 1044 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
1131 | 1045 | ||
1132 | /* READ { 0, 0x0001, 0x8803 } -> | 1046 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1133 | 0000: 00 */ | 1047 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1134 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1135 | 0000: 10 */ | ||
1136 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ | 1048 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ |
1137 | {0x0020, 0x8801}, /* Register address for SSI read/write */ | 1049 | {0x0020, 0x8801}, /* Register address for SSI read/write */ |
1138 | {0x0044, 0x8805}, /* DATA2 */ | 1050 | {0x0044, 0x8805}, /* DATA2 */ |
1139 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ | 1051 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ |
1140 | /* READ { 0, 0x0001, 0x8803 } -> | 1052 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1141 | 0000: 00 */ | ||
1142 | 1053 | ||
1143 | /* READ { 0, 0x0001, 0x8803 } -> | 1054 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1144 | 0000: 00 */ | 1055 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1145 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1146 | 0000: 10 */ | ||
1147 | {0x0010, 0x8802}, | 1056 | {0x0010, 0x8802}, |
1148 | {0x0009, 0x8801}, | 1057 | {0x0009, 0x8801}, |
1149 | {0x0042, 0x8805}, | 1058 | {0x0042, 0x8805}, |
1150 | {0x0001, 0x8800}, | 1059 | {0x0001, 0x8800}, |
1151 | /* READ { 0, 0x0001, 0x8803 } -> | 1060 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1152 | 0000: 00 */ | ||
1153 | 1061 | ||
1154 | /* READ { 0, 0x0001, 0x8803 } -> | 1062 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1155 | 0000: 00 */ | 1063 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1156 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1157 | 0000: 10 */ | ||
1158 | {0x0010, 0x8802}, | 1064 | {0x0010, 0x8802}, |
1159 | {0x003c, 0x8801}, | 1065 | {0x003c, 0x8801}, |
1160 | {0x0001, 0x8805}, | 1066 | {0x0001, 0x8805}, |
1161 | {0x0000, 0x8800}, | 1067 | {0x0000, 0x8800}, |
1162 | /* READ { 0, 0x0001, 0x8803 } -> | 1068 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1163 | 0000: 00 */ | ||
1164 | 1069 | ||
1165 | /* READ { 0, 0x0001, 0x8803 } -> | 1070 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1166 | 0000: 00 */ | 1071 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1167 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1168 | 0000: 10 */ | ||
1169 | {0x0010, 0x8802}, | 1072 | {0x0010, 0x8802}, |
1170 | {0x0001, 0x8801}, | 1073 | {0x0001, 0x8801}, |
1171 | {0x000a, 0x8805}, | 1074 | {0x000a, 0x8805}, |
1172 | {0x0000, 0x8800}, | 1075 | {0x0000, 0x8800}, |
1173 | /* READ { 0, 0x0001, 0x8803 } -> | 1076 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1174 | 0000: 00 */ | ||
1175 | 1077 | ||
1176 | /* READ { 0, 0x0001, 0x8803 } -> | 1078 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1177 | 0000: 00 */ | 1079 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1178 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1179 | 0000: 10 */ | ||
1180 | {0x0010, 0x8802}, | 1080 | {0x0010, 0x8802}, |
1181 | {0x0002, 0x8801}, | 1081 | {0x0002, 0x8801}, |
1182 | {0x0000, 0x8805}, | 1082 | {0x0000, 0x8805}, |
1183 | {0x0000, 0x8800}, | 1083 | {0x0000, 0x8800}, |
1184 | /* READ { 0, 0x0001, 0x8803 } -> | 1084 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1185 | 0000: 00 */ | ||
1186 | 1085 | ||
1187 | /* READ { 0, 0x0001, 0x8803 } -> | 1086 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1188 | 0000: 00 */ | 1087 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1189 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1190 | 0000: 10 */ | ||
1191 | {0x0010, 0x8802}, | 1088 | {0x0010, 0x8802}, |
1192 | {0x0003, 0x8801}, | 1089 | {0x0003, 0x8801}, |
1193 | {0x0027, 0x8805}, | 1090 | {0x0027, 0x8805}, |
1194 | {0x0001, 0x8800}, | 1091 | {0x0001, 0x8800}, |
1195 | /* READ { 0, 0x0001, 0x8803 } -> | 1092 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1196 | 0000: 00 */ | ||
1197 | 1093 | ||
1198 | /* READ { 0, 0x0001, 0x8803 } -> | 1094 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1199 | 0000: 00 */ | 1095 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1200 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1201 | 0000: 10 */ | ||
1202 | {0x0010, 0x8802}, | 1096 | {0x0010, 0x8802}, |
1203 | {0x0004, 0x8801}, | 1097 | {0x0004, 0x8801}, |
1204 | {0x0065, 0x8805}, | 1098 | {0x0065, 0x8805}, |
1205 | {0x0001, 0x8800}, | 1099 | {0x0001, 0x8800}, |
1206 | /* READ { 0, 0x0001, 0x8803 } -> | 1100 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1207 | 0000: 00 */ | ||
1208 | 1101 | ||
1209 | /* READ { 0, 0x0001, 0x8803 } -> | 1102 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1210 | 0000: 00 */ | 1103 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1211 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1212 | 0000: 10 */ | ||
1213 | {0x0010, 0x8802}, | 1104 | {0x0010, 0x8802}, |
1214 | {0x0005, 0x8801}, | 1105 | {0x0005, 0x8801}, |
1215 | {0x0003, 0x8805}, | 1106 | {0x0003, 0x8805}, |
1216 | {0x0000, 0x8800}, | 1107 | {0x0000, 0x8800}, |
1217 | /* READ { 0, 0x0001, 0x8803 } -> | 1108 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1218 | 0000: 00 */ | ||
1219 | 1109 | ||
1220 | /* READ { 0, 0x0001, 0x8803 } -> | 1110 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1221 | 0000: 00 */ | 1111 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1222 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1223 | 0000: 10 */ | ||
1224 | {0x0010, 0x8802}, | 1112 | {0x0010, 0x8802}, |
1225 | {0x0006, 0x8801}, | 1113 | {0x0006, 0x8801}, |
1226 | {0x001c, 0x8805}, | 1114 | {0x001c, 0x8805}, |
1227 | {0x0000, 0x8800}, | 1115 | {0x0000, 0x8800}, |
1228 | /* READ { 0, 0x0001, 0x8803 } -> | 1116 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1229 | 0000: 00 */ | ||
1230 | 1117 | ||
1231 | /* READ { 0, 0x0001, 0x8803 } -> | 1118 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1232 | 0000: 00 */ | 1119 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1233 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1234 | 0000: 10 */ | ||
1235 | {0x0010, 0x8802}, | 1120 | {0x0010, 0x8802}, |
1236 | {0x0007, 0x8801}, | 1121 | {0x0007, 0x8801}, |
1237 | {0x002a, 0x8805}, | 1122 | {0x002a, 0x8805}, |
1238 | {0x0000, 0x8800}, | 1123 | {0x0000, 0x8800}, |
1239 | /* READ { 0, 0x0001, 0x8803 } -> | 1124 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1240 | 0000: 00 */ | ||
1241 | 1125 | ||
1242 | /* READ { 0, 0x0001, 0x8803 } -> | 1126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1243 | 0000: 00 */ | 1127 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1244 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1245 | 0000: 10 */ | ||
1246 | {0x0010, 0x8802}, | 1128 | {0x0010, 0x8802}, |
1247 | {0x000e, 0x8801}, | 1129 | {0x000e, 0x8801}, |
1248 | {0x0000, 0x8805}, | 1130 | {0x0000, 0x8805}, |
1249 | {0x0000, 0x8800}, | 1131 | {0x0000, 0x8800}, |
1250 | /* READ { 0, 0x0001, 0x8803 } -> | 1132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1251 | 0000: 00 */ | ||
1252 | 1133 | ||
1253 | /* READ { 0, 0x0001, 0x8803 } -> | 1134 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1254 | 0000: 00 */ | 1135 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1255 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1256 | 0000: 10 */ | ||
1257 | {0x0010, 0x8802}, | 1136 | {0x0010, 0x8802}, |
1258 | {0x0028, 0x8801}, | 1137 | {0x0028, 0x8801}, |
1259 | {0x002e, 0x8805}, | 1138 | {0x002e, 0x8805}, |
1260 | {0x0000, 0x8800}, | 1139 | {0x0000, 0x8800}, |
1261 | /* READ { 0, 0x0001, 0x8803 } -> | 1140 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1262 | 0000: 00 */ | ||
1263 | 1141 | ||
1264 | /* READ { 0, 0x0001, 0x8803 } -> | 1142 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1265 | 0000: 00 */ | 1143 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1266 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1267 | 0000: 10 */ | ||
1268 | {0x0010, 0x8802}, | 1144 | {0x0010, 0x8802}, |
1269 | {0x0039, 0x8801}, | 1145 | {0x0039, 0x8801}, |
1270 | {0x0013, 0x8805}, | 1146 | {0x0013, 0x8805}, |
1271 | {0x0000, 0x8800}, | 1147 | {0x0000, 0x8800}, |
1272 | /* READ { 0, 0x0001, 0x8803 } -> | 1148 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1273 | 0000: 00 */ | ||
1274 | 1149 | ||
1275 | /* READ { 0, 0x0001, 0x8803 } -> | 1150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1276 | 0000: 00 */ | 1151 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1277 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1278 | 0000: 10 */ | ||
1279 | {0x0010, 0x8802}, | 1152 | {0x0010, 0x8802}, |
1280 | {0x003b, 0x8801}, | 1153 | {0x003b, 0x8801}, |
1281 | {0x000c, 0x8805}, | 1154 | {0x000c, 0x8805}, |
1282 | {0x0000, 0x8800}, | 1155 | {0x0000, 0x8800}, |
1283 | /* READ { 0, 0x0001, 0x8803 } -> | 1156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1284 | 0000: 00 */ | ||
1285 | 1157 | ||
1286 | /* READ { 0, 0x0001, 0x8803 } -> | 1158 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1287 | 0000: 00 */ | 1159 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1288 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1289 | 0000: 10 */ | ||
1290 | {0x0010, 0x8802}, | 1160 | {0x0010, 0x8802}, |
1291 | {0x0035, 0x8801}, | 1161 | {0x0035, 0x8801}, |
1292 | {0x0028, 0x8805}, | 1162 | {0x0028, 0x8805}, |
1293 | {0x0000, 0x8800}, | 1163 | {0x0000, 0x8800}, |
1294 | /* READ { 0, 0x0001, 0x8803 } -> | 1164 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1295 | 0000: 00 */ | ||
1296 | 1165 | ||
1297 | /* READ { 0, 0x0001, 0x8803 } -> | 1166 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1298 | 0000: 00 */ | 1167 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1299 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1300 | 0000: 10 */ | ||
1301 | {0x0010, 0x8802}, | 1168 | {0x0010, 0x8802}, |
1302 | {0x0009, 0x8801}, | 1169 | {0x0009, 0x8801}, |
1303 | {0x0042, 0x8805}, | 1170 | {0x0042, 0x8805}, |
1304 | {0x0001, 0x8800}, | 1171 | {0x0001, 0x8800}, |
1305 | /* READ { 0, 0x0001, 0x8803 } -> | 1172 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1306 | 0000: 00 */ | ||
1307 | 1173 | ||
1308 | {0x0050, 0x8703}, | 1174 | {0x0050, 0x8703}, |
1309 | {0x0002, 0x8704}, /* External input CKIx1 */ | 1175 | {0x0002, 0x8704}, /* External input CKIx1 */ |
1310 | {0x0001, 0x870c}, /* Select CKOx2 output */ | 1176 | {0x0001, 0x870c}, /* Select CKOx2 output */ |
1311 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 1177 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
1312 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 1178 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
1313 | {0x0023, 0x8601}, | 1179 | {0x0023, 0x8601}, |
1314 | {0x0010, 0x8602}, | 1180 | {0x0010, 0x8602}, |
1315 | {0x000a, 0x8603}, | 1181 | {0x000a, 0x8603}, |
1316 | {0x009A, 0x8600}, | 1182 | {0x009a, 0x8600}, |
1317 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 1183 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
1318 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ | 1184 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ |
1319 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ | 1185 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ |
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1329 | {0x0005, 0x860a}, /* ... */ | 1195 | {0x0005, 0x860a}, /* ... */ |
1330 | {0x0025, 0x860b}, | 1196 | {0x0025, 0x860b}, |
1331 | {0x00e1, 0x860c}, | 1197 | {0x00e1, 0x860c}, |
1332 | {0x00fa, 0x860D}, | 1198 | {0x00fa, 0x860d}, |
1333 | {0x00f4, 0x860e}, | 1199 | {0x00f4, 0x860e}, |
1334 | {0x00e8, 0x860f}, | 1200 | {0x00e8, 0x860f}, |
1335 | {0x0025, 0x8610}, /* A33 Coef. */ | 1201 | {0x0025, 0x8610}, /* A33 Coef. */ |
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1344 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ | 1210 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ |
1345 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ | 1211 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ |
1346 | 1212 | ||
1347 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ | 1213 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128, |
1348 | /* UV division: UV no change, Enable New edge enhancement */ | 1214 | * UV division: UV no change, |
1215 | * Enable New edge enhancement */ | ||
1349 | {0x0018, 0x8657}, /* Edge gain high threshold */ | 1216 | {0x0018, 0x8657}, /* Edge gain high threshold */ |
1350 | {0x0020, 0x8658}, /* Edge gain low threshold */ | 1217 | {0x0020, 0x8658}, /* Edge gain low threshold */ |
1351 | {0x000A, 0x8659}, /* Edge bandwidth high threshold */ | 1218 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
1352 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ | 1219 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
1353 | {0x0064, 0x8607}, /* UV filter enable */ | 1220 | {0x0064, 0x8607}, /* UV filter enable */ |
1354 | 1221 | ||
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1384 | {0x0000, 0x86b4}, | 1251 | {0x0000, 0x86b4}, |
1385 | {0x001e, 0x8660}, | 1252 | {0x001e, 0x8660}, |
1386 | 1253 | ||
1387 | /* READ { 0, 0x0000, 0x8608 } -> | 1254 | /* READ { 0x0000, 0x8608 } -> 0000: 13 */ |
1388 | 0000: 13 */ | 1255 | /* READ { 0x0000, 0x8609 } -> 0000: 28 */ |
1389 | /* READ { 0, 0x0000, 0x8609 } -> | 1256 | /* READ { 0x0000, 0x8610 } -> 0000: 05 */ |
1390 | 0000: 28 */ | 1257 | /* READ { 0x0000, 0x8611 } -> 0000: 25 */ |
1391 | /* READ { 0, 0x0000, 0x8610 } -> | 1258 | /* READ { 0x0000, 0x8612 } -> 0000: e1 */ |
1392 | 0000: 05 */ | 1259 | /* READ { 0x0000, 0x8613 } -> 0000: fa */ |
1393 | /* READ { 0, 0x0000, 0x8611 } -> | 1260 | /* READ { 0x0000, 0x8614 } -> 0000: f4 */ |
1394 | 0000: 25 */ | 1261 | /* READ { 0x0000, 0x8615 } -> 0000: e8 */ |
1395 | /* READ { 0, 0x0000, 0x8612 } -> | 1262 | /* READ { 0x0000, 0x8616 } -> 0000: 25 */ |
1396 | 0000: e1 */ | ||
1397 | /* READ { 0, 0x0000, 0x8613 } -> | ||
1398 | 0000: fa */ | ||
1399 | /* READ { 0, 0x0000, 0x8614 } -> | ||
1400 | 0000: f4 */ | ||
1401 | /* READ { 0, 0x0000, 0x8615 } -> | ||
1402 | 0000: e8 */ | ||
1403 | /* READ { 0, 0x0000, 0x8616 } -> | ||
1404 | 0000: 25 */ | ||
1405 | {} | 1263 | {} |
1406 | }; | 1264 | }; |
1407 | 1265 | ||
1408 | static int reg_write(struct usb_device *dev, | 1266 | static int reg_write(struct usb_device *dev, |
1409 | __u16 index, __u16 value) | 1267 | u16 index, u16 value) |
1410 | { | 1268 | { |
1411 | int ret; | 1269 | int ret; |
1412 | 1270 | ||
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev, | |||
1425 | /* read 1 byte */ | 1283 | /* read 1 byte */ |
1426 | /* returns: negative is error, pos or zero is data */ | 1284 | /* returns: negative is error, pos or zero is data */ |
1427 | static int reg_read(struct gspca_dev *gspca_dev, | 1285 | static int reg_read(struct gspca_dev *gspca_dev, |
1428 | __u16 index) /* wIndex */ | 1286 | u16 index) /* wIndex */ |
1429 | { | 1287 | { |
1430 | int ret; | 1288 | int ret; |
1431 | 1289 | ||
@@ -1447,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev, | |||
1447 | } | 1305 | } |
1448 | 1306 | ||
1449 | static int write_vector(struct gspca_dev *gspca_dev, | 1307 | static int write_vector(struct gspca_dev *gspca_dev, |
1450 | const u16 data[][2]) | 1308 | const u16 (*data)[2]) |
1451 | { | 1309 | { |
1452 | struct usb_device *dev = gspca_dev->dev; | 1310 | struct usb_device *dev = gspca_dev->dev; |
1453 | int ret, i = 0; | 1311 | int ret; |
1454 | 1312 | ||
1455 | while (data[i][1] != 0) { | 1313 | while ((*data)[1] != 0) { |
1456 | ret = reg_write(dev, data[i][1], data[i][0]); | 1314 | ret = reg_write(dev, (*data)[1], (*data)[0]); |
1457 | if (ret < 0) | 1315 | if (ret < 0) |
1458 | return ret; | 1316 | return ret; |
1459 | i++; | 1317 | data++; |
1460 | } | 1318 | } |
1461 | return 0; | 1319 | return 0; |
1462 | } | 1320 | } |
@@ -1468,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1468 | struct sd *sd = (struct sd *) gspca_dev; | 1326 | struct sd *sd = (struct sd *) gspca_dev; |
1469 | struct cam *cam; | 1327 | struct cam *cam; |
1470 | int data1, data2; | 1328 | int data1, data2; |
1329 | const u16 (*init_data)[2]; | ||
1330 | static const u16 (*(init_data_tb[]))[2] = { | ||
1331 | spca508_vista_init_data, /* CreativeVista 0 */ | ||
1332 | spca508_sightcam_init_data, /* HamaUSBSightcam 1 */ | ||
1333 | spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */ | ||
1334 | spca508cs110_init_data, /* IntelEasyPCCamera 3 */ | ||
1335 | spca508cs110_init_data, /* MicroInnovationIC200 4 */ | ||
1336 | spca508_init_data, /* ViewQuestVQ110 5 */ | ||
1337 | }; | ||
1471 | 1338 | ||
1472 | /* Read from global register the USB product and vendor IDs, just to | 1339 | /* Read from global register the USB product and vendor IDs, just to |
1473 | * prove that we can communicate with the device. This works, which | 1340 | * prove that we can communicate with the device. This works, which |
@@ -1491,37 +1358,13 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1491 | sd->subtype = id->driver_info; | 1358 | sd->subtype = id->driver_info; |
1492 | sd->brightness = BRIGHTNESS_DEF; | 1359 | sd->brightness = BRIGHTNESS_DEF; |
1493 | 1360 | ||
1494 | switch (sd->subtype) { | 1361 | init_data = init_data_tb[sd->subtype]; |
1495 | case ViewQuestVQ110: | 1362 | return write_vector(gspca_dev, init_data); |
1496 | if (write_vector(gspca_dev, spca508_init_data)) | ||
1497 | return -1; | ||
1498 | break; | ||
1499 | default: | ||
1500 | /* case MicroInnovationIC200: */ | ||
1501 | /* case IntelEasyPCCamera: */ | ||
1502 | if (write_vector(gspca_dev, spca508cs110_init_data)) | ||
1503 | return -1; | ||
1504 | break; | ||
1505 | case HamaUSBSightcam: | ||
1506 | if (write_vector(gspca_dev, spca508_sightcam_init_data)) | ||
1507 | return -1; | ||
1508 | break; | ||
1509 | case HamaUSBSightcam2: | ||
1510 | if (write_vector(gspca_dev, spca508_sightcam2_init_data)) | ||
1511 | return -1; | ||
1512 | break; | ||
1513 | case CreativeVista: | ||
1514 | if (write_vector(gspca_dev, spca508_vista_init_data)) | ||
1515 | return -1; | ||
1516 | break; | ||
1517 | } | ||
1518 | return 0; /* success */ | ||
1519 | } | 1363 | } |
1520 | 1364 | ||
1521 | /* this function is called at probe and resume time */ | 1365 | /* this function is called at probe and resume time */ |
1522 | static int sd_init(struct gspca_dev *gspca_dev) | 1366 | static int sd_init(struct gspca_dev *gspca_dev) |
1523 | { | 1367 | { |
1524 | /* write_vector(gspca_dev, spca508_open_data); */ | ||
1525 | return 0; | 1368 | return 0; |
1526 | } | 1369 | } |
1527 | 1370 | ||
@@ -1529,7 +1372,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1529 | { | 1372 | { |
1530 | int mode; | 1373 | int mode; |
1531 | 1374 | ||
1532 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 1375 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
1533 | reg_write(gspca_dev->dev, 0x8500, mode); | 1376 | reg_write(gspca_dev->dev, 0x8500, mode); |
1534 | switch (mode) { | 1377 | switch (mode) { |
1535 | case 0: | 1378 | case 0: |
@@ -1554,7 +1397,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1554 | 1397 | ||
1555 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1398 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1556 | struct gspca_frame *frame, /* target */ | 1399 | struct gspca_frame *frame, /* target */ |
1557 | __u8 *data, /* isoc packet */ | 1400 | u8 *data, /* isoc packet */ |
1558 | int len) /* iso packet length */ | 1401 | int len) /* iso packet length */ |
1559 | { | 1402 | { |
1560 | switch (data[0]) { | 1403 | switch (data[0]) { |
@@ -1567,7 +1410,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1567 | data, len); | 1410 | data, len); |
1568 | break; | 1411 | break; |
1569 | case 0xff: /* drop */ | 1412 | case 0xff: /* drop */ |
1570 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1571 | break; | 1413 | break; |
1572 | default: | 1414 | default: |
1573 | data += 1; | 1415 | data += 1; |
@@ -1581,7 +1423,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1581 | static void setbrightness(struct gspca_dev *gspca_dev) | 1423 | static void setbrightness(struct gspca_dev *gspca_dev) |
1582 | { | 1424 | { |
1583 | struct sd *sd = (struct sd *) gspca_dev; | 1425 | struct sd *sd = (struct sd *) gspca_dev; |
1584 | __u8 brightness = sd->brightness; | 1426 | u8 brightness = sd->brightness; |
1585 | 1427 | ||
1586 | /* MX seem contrast */ | 1428 | /* MX seem contrast */ |
1587 | reg_write(gspca_dev->dev, 0x8651, brightness); | 1429 | reg_write(gspca_dev->dev, 0x8651, brightness); |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index c99c5e34e211..27e82b35f3e7 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -34,8 +34,8 @@ struct sd { | |||
34 | 34 | ||
35 | __u16 exposure; /* rev12a only */ | 35 | __u16 exposure; /* rev12a only */ |
36 | #define EXPOSURE_MIN 1 | 36 | #define EXPOSURE_MIN 1 |
37 | #define EXPOSURE_DEF 200 | 37 | #define EXPOSURE_DEF 700 /* == 10 fps */ |
38 | #define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ | 38 | #define EXPOSURE_MAX (2047 + 325) /* see setexposure */ |
39 | 39 | ||
40 | __u8 contrast; /* rev72a only */ | 40 | __u8 contrast; /* rev72a only */ |
41 | #define CONTRAST_MIN 0x00 | 41 | #define CONTRAST_MIN 0x00 |
@@ -48,9 +48,9 @@ struct sd { | |||
48 | #define BRIGHTNESS_MAX 0x3f | 48 | #define BRIGHTNESS_MAX 0x3f |
49 | 49 | ||
50 | __u8 white; | 50 | __u8 white; |
51 | #define WHITE_MIN 1 | 51 | #define HUE_MIN 1 |
52 | #define WHITE_DEF 0x40 | 52 | #define HUE_DEF 0x40 |
53 | #define WHITE_MAX 0x7f | 53 | #define HUE_MAX 0x7f |
54 | 54 | ||
55 | __u8 autogain; | 55 | __u8 autogain; |
56 | #define AUTOGAIN_MIN 0 | 56 | #define AUTOGAIN_MIN 0 |
@@ -58,9 +58,9 @@ struct sd { | |||
58 | #define AUTOGAIN_MAX 1 | 58 | #define AUTOGAIN_MAX 1 |
59 | 59 | ||
60 | __u8 gain; /* rev12a only */ | 60 | __u8 gain; /* rev12a only */ |
61 | #define GAIN_MIN 0x0 | 61 | #define GAIN_MIN 0 |
62 | #define GAIN_DEF 0x24 | 62 | #define GAIN_DEF 63 |
63 | #define GAIN_MAX 0x24 | 63 | #define GAIN_MAX 255 |
64 | 64 | ||
65 | #define EXPO12A_DEF 3 | 65 | #define EXPO12A_DEF 3 |
66 | __u8 expo12a; /* expo/gain? for rev 12a */ | 66 | __u8 expo12a; /* expo/gain? for rev 12a */ |
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
461 | } | 461 | } |
462 | sd->brightness = BRIGHTNESS_DEF; | 462 | sd->brightness = BRIGHTNESS_DEF; |
463 | sd->contrast = CONTRAST_DEF; | 463 | sd->contrast = CONTRAST_DEF; |
464 | sd->white = WHITE_DEF; | 464 | sd->white = HUE_DEF; |
465 | sd->exposure = EXPOSURE_DEF; | 465 | sd->exposure = EXPOSURE_DEF; |
466 | sd->autogain = AUTOGAIN_DEF; | 466 | sd->autogain = AUTOGAIN_DEF; |
467 | sd->gain = GAIN_DEF; | 467 | sd->gain = GAIN_DEF; |
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
549 | static void setexposure(struct gspca_dev *gspca_dev) | 549 | static void setexposure(struct gspca_dev *gspca_dev) |
550 | { | 550 | { |
551 | struct sd *sd = (struct sd *) gspca_dev; | 551 | struct sd *sd = (struct sd *) gspca_dev; |
552 | int expo; | 552 | int i, expo = 0; |
553 | int clock_divider; | ||
554 | 553 | ||
555 | /* Register 0x8309 controls exposure for the spca561, | 554 | /* Register 0x8309 controls exposure for the spca561, |
556 | the basic exposure setting goes from 1-2047, where 1 is completely | 555 | the basic exposure setting goes from 1-2047, where 1 is completely |
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
564 | configure a divider for the base framerate which us used at the | 563 | configure a divider for the base framerate which us used at the |
565 | exposure setting of 1-300. These bits configure the base framerate | 564 | exposure setting of 1-300. These bits configure the base framerate |
566 | according to the following formula: fps = 60 / (value + 2) */ | 565 | according to the following formula: fps = 60 / (value + 2) */ |
567 | if (sd->exposure < 2048) { | 566 | |
568 | expo = sd->exposure; | 567 | /* We choose to use the high bits setting the fixed framerate divisor |
569 | clock_divider = 0; | 568 | asap, as setting high basic exposure setting without the fixed |
570 | } else { | 569 | divider in combination with high gains makes the cam stop */ |
571 | /* Add 900 to make the 0 setting of the second part of the | 570 | int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; |
572 | exposure equal to the 2047 setting of the first part. */ | 571 | |
573 | expo = (sd->exposure - 2048) + 900; | 572 | for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { |
574 | clock_divider = 3; | 573 | if (sd->exposure <= table[i + 1]) { |
574 | expo = sd->exposure - table[i]; | ||
575 | if (i) | ||
576 | expo += 300; | ||
577 | expo |= i << 11; | ||
578 | break; | ||
579 | } | ||
575 | } | 580 | } |
576 | expo |= clock_divider << 11; | 581 | |
577 | gspca_dev->usb_buf[0] = expo; | 582 | gspca_dev->usb_buf[0] = expo; |
578 | gspca_dev->usb_buf[1] = expo >> 8; | 583 | gspca_dev->usb_buf[1] = expo >> 8; |
579 | reg_w_buf(gspca_dev, 0x8309, 2); | 584 | reg_w_buf(gspca_dev, 0x8309, 2); |
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
584 | { | 589 | { |
585 | struct sd *sd = (struct sd *) gspca_dev; | 590 | struct sd *sd = (struct sd *) gspca_dev; |
586 | 591 | ||
587 | gspca_dev->usb_buf[0] = sd->gain; | 592 | /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the |
593 | sensitivity when set, so 31 + one of them set == 63, and 15 | ||
594 | with both of them set == 63 */ | ||
595 | if (sd->gain < 64) | ||
596 | gspca_dev->usb_buf[0] = sd->gain; | ||
597 | else if (sd->gain < 128) | ||
598 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; | ||
599 | else | ||
600 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0; | ||
601 | |||
588 | gspca_dev->usb_buf[1] = 0; | 602 | gspca_dev->usb_buf[1] = 0; |
589 | reg_w_buf(gspca_dev, 0x8335, 2); | 603 | reg_w_buf(gspca_dev, 0x8335, 2); |
590 | } | 604 | } |
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) | |||
629 | reg_w_buf(gspca_dev, 0x8391, 8); | 643 | reg_w_buf(gspca_dev, 0x8391, 8); |
630 | reg_w_buf(gspca_dev, 0x8390, 8); | 644 | reg_w_buf(gspca_dev, 0x8390, 8); |
631 | setwhite(gspca_dev); | 645 | setwhite(gspca_dev); |
632 | setautogain(gspca_dev); | 646 | setgain(gspca_dev); |
633 | /* setgain(gspca_dev); */ | ||
634 | setexposure(gspca_dev); | 647 | setexposure(gspca_dev); |
635 | return 0; | 648 | return 0; |
636 | } | 649 | } |
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
762 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); | 775 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); |
763 | } | 776 | } |
764 | break; | 777 | break; |
765 | case Rev012A: | ||
766 | reg_r(gspca_dev, 0x8330, 2); | ||
767 | if (gspca_dev->usb_buf[1] > 0x08) { | ||
768 | gspca_dev->usb_buf[0] = ++sd->expo12a; | ||
769 | gspca_dev->usb_buf[1] = 0; | ||
770 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
771 | } else if (gspca_dev->usb_buf[1] < 0x02) { | ||
772 | gspca_dev->usb_buf[0] = --sd->expo12a; | ||
773 | gspca_dev->usb_buf[1] = 0; | ||
774 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
775 | } | ||
776 | break; | ||
777 | } | 778 | } |
778 | } | 779 | } |
779 | 780 | ||
@@ -928,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | |||
928 | static struct ctrl sd_ctrls_12a[] = { | 929 | static struct ctrl sd_ctrls_12a[] = { |
929 | { | 930 | { |
930 | { | 931 | { |
931 | .id = V4L2_CID_DO_WHITE_BALANCE, | 932 | .id = V4L2_CID_HUE, |
932 | .type = V4L2_CTRL_TYPE_INTEGER, | 933 | .type = V4L2_CTRL_TYPE_INTEGER, |
933 | .name = "White Balance", | 934 | .name = "Hue", |
934 | .minimum = WHITE_MIN, | 935 | .minimum = HUE_MIN, |
935 | .maximum = WHITE_MAX, | 936 | .maximum = HUE_MAX, |
936 | .step = 1, | 937 | .step = 1, |
937 | .default_value = WHITE_DEF, | 938 | .default_value = HUE_DEF, |
938 | }, | 939 | }, |
939 | .set = sd_setwhite, | 940 | .set = sd_setwhite, |
940 | .get = sd_getwhite, | 941 | .get = sd_getwhite, |
@@ -954,19 +955,6 @@ static struct ctrl sd_ctrls_12a[] = { | |||
954 | }, | 955 | }, |
955 | { | 956 | { |
956 | { | 957 | { |
957 | .id = V4L2_CID_AUTOGAIN, | ||
958 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
959 | .name = "Auto Gain", | ||
960 | .minimum = AUTOGAIN_MIN, | ||
961 | .maximum = AUTOGAIN_MAX, | ||
962 | .step = 1, | ||
963 | .default_value = AUTOGAIN_DEF, | ||
964 | }, | ||
965 | .set = sd_setautogain, | ||
966 | .get = sd_getautogain, | ||
967 | }, | ||
968 | { | ||
969 | { | ||
970 | .id = V4L2_CID_GAIN, | 958 | .id = V4L2_CID_GAIN, |
971 | .type = V4L2_CTRL_TYPE_INTEGER, | 959 | .type = V4L2_CTRL_TYPE_INTEGER, |
972 | .name = "Gain", | 960 | .name = "Gain", |
@@ -983,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = { | |||
983 | static struct ctrl sd_ctrls_72a[] = { | 971 | static struct ctrl sd_ctrls_72a[] = { |
984 | { | 972 | { |
985 | { | 973 | { |
986 | .id = V4L2_CID_DO_WHITE_BALANCE, | 974 | .id = V4L2_CID_HUE, |
987 | .type = V4L2_CTRL_TYPE_INTEGER, | 975 | .type = V4L2_CTRL_TYPE_INTEGER, |
988 | .name = "White Balance", | 976 | .name = "Hue", |
989 | .minimum = WHITE_MIN, | 977 | .minimum = HUE_MIN, |
990 | .maximum = WHITE_MAX, | 978 | .maximum = HUE_MAX, |
991 | .step = 1, | 979 | .step = 1, |
992 | .default_value = WHITE_DEF, | 980 | .default_value = HUE_DEF, |
993 | }, | 981 | }, |
994 | .set = sd_setwhite, | 982 | .set = sd_setwhite, |
995 | .get = sd_getwhite, | 983 | .get = sd_getwhite, |
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = { | |||
1046 | .stopN = sd_stopN, | 1034 | .stopN = sd_stopN, |
1047 | .stop0 = sd_stop0, | 1035 | .stop0 = sd_stop0, |
1048 | .pkt_scan = sd_pkt_scan, | 1036 | .pkt_scan = sd_pkt_scan, |
1049 | /* .dq_callback = do_autogain, * fixme */ | ||
1050 | }; | 1037 | }; |
1051 | static const struct sd_desc sd_desc_72a = { | 1038 | static const struct sd_desc sd_desc_72a = { |
1052 | .name = MODULE_NAME, | 1039 | .name = MODULE_NAME, |
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 2e1cdf068fda..715a68f0156e 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
309 | struct sd *dev = (struct sd *) gspca_dev; | 309 | struct sd *dev = (struct sd *) gspca_dev; |
310 | 310 | ||
311 | /* We don't use the buffer gspca allocates so make it small. */ | 311 | /* We don't use the buffer gspca allocates so make it small. */ |
312 | cam->bulk = 1; | ||
312 | cam->bulk_size = 64; | 313 | cam->bulk_size = 64; |
313 | 314 | ||
314 | INIT_WORK(&dev->work_struct, sq905_dostream); | 315 | INIT_WORK(&dev->work_struct, sq905_dostream); |
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 0bcb74a1b143..916892505432 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
206 | cam->nmodes = 1; | 206 | cam->nmodes = 1; |
207 | /* We don't use the buffer gspca allocates so make it small. */ | 207 | /* We don't use the buffer gspca allocates so make it small. */ |
208 | cam->bulk_size = 32; | 208 | cam->bulk_size = 32; |
209 | cam->bulk = 1; | ||
209 | INIT_WORK(&dev->work_struct, sq905c_dostream); | 210 | INIT_WORK(&dev->work_struct, sq905c_dostream); |
210 | return 0; | 211 | return 0; |
211 | } | 212 | } |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 9dff2e65b116..e573c3406324 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c | |||
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev) | |||
293 | goto out; | 293 | goto out; |
294 | 294 | ||
295 | err = sd->sensor->stop(sd); | 295 | err = sd->sensor->stop(sd); |
296 | if (err < 0) | ||
297 | goto out; | ||
298 | 296 | ||
299 | out: | 297 | out: |
300 | if (err < 0) | 298 | if (err < 0) |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 69c77c932fc0..11a0c002f5dc 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | |||
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = { | |||
80 | .minimum = 0, | 80 | .minimum = 0, |
81 | .maximum = 15, | 81 | .maximum = 15, |
82 | .step = 1, | 82 | .step = 1, |
83 | .default_value = 0 | 83 | .default_value = 10 |
84 | }, | 84 | }, |
85 | .set = vv6410_set_analog_gain, | 85 | .set = vv6410_set_analog_gain, |
86 | .get = vv6410_get_analog_gain | 86 | .get = vv6410_get_analog_gain |
87 | }, | ||
88 | #define EXPOSURE_IDX 3 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_EXPOSURE, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "exposure", | ||
94 | .minimum = 0, | ||
95 | .maximum = 32768, | ||
96 | .step = 1, | ||
97 | .default_value = 20000 | ||
98 | }, | ||
99 | .set = vv6410_set_exposure, | ||
100 | .get = vv6410_get_exposure | ||
87 | } | 101 | } |
88 | }; | 102 | }; |
89 | 103 | ||
90 | static int vv6410_probe(struct sd *sd) | 104 | static int vv6410_probe(struct sd *sd) |
91 | { | 105 | { |
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd) | |||
121 | static int vv6410_init(struct sd *sd) | 135 | static int vv6410_init(struct sd *sd) |
122 | { | 136 | { |
123 | int err = 0, i; | 137 | int err = 0, i; |
138 | s32 *sensor_settings = sd->sensor_priv; | ||
124 | 139 | ||
125 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { | 140 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { |
126 | /* if NULL then len contains single value */ | 141 | /* if NULL then len contains single value */ |
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd) | |||
142 | 157 | ||
143 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, | 158 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, |
144 | ARRAY_SIZE(vv6410_sensor_init)); | 159 | ARRAY_SIZE(vv6410_sensor_init)); |
160 | if (err < 0) | ||
161 | return err; | ||
162 | |||
163 | err = vv6410_set_exposure(&sd->gspca_dev, | ||
164 | sensor_settings[EXPOSURE_IDX]); | ||
165 | if (err < 0) | ||
166 | return err; | ||
167 | |||
168 | err = vv6410_set_analog_gain(&sd->gspca_dev, | ||
169 | sensor_settings[GAIN_IDX]); | ||
145 | 170 | ||
146 | return (err < 0) ? err : 0; | 171 | return (err < 0) ? err : 0; |
147 | } | 172 | } |
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
318 | 343 | ||
319 | return (err < 0) ? err : 0; | 344 | return (err < 0) ? err : 0; |
320 | } | 345 | } |
346 | |||
347 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
348 | { | ||
349 | struct sd *sd = (struct sd *) gspca_dev; | ||
350 | s32 *sensor_settings = sd->sensor_priv; | ||
351 | |||
352 | *val = sensor_settings[EXPOSURE_IDX]; | ||
353 | |||
354 | PDEBUG(D_V4L2, "Read exposure %d", *val); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
360 | { | ||
361 | int err; | ||
362 | struct sd *sd = (struct sd *) gspca_dev; | ||
363 | s32 *sensor_settings = sd->sensor_priv; | ||
364 | unsigned int fine, coarse; | ||
365 | |||
366 | sensor_settings[EXPOSURE_IDX] = val; | ||
367 | |||
368 | val = (val * val >> 14) + val / 4; | ||
369 | |||
370 | fine = val % VV6410_CIF_LINELENGTH; | ||
371 | coarse = min(512, val / VV6410_CIF_LINELENGTH); | ||
372 | |||
373 | PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", | ||
374 | coarse, fine); | ||
375 | |||
376 | err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); | ||
377 | if (err < 0) | ||
378 | goto out; | ||
379 | |||
380 | err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff); | ||
381 | if (err < 0) | ||
382 | goto out; | ||
383 | |||
384 | err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8); | ||
385 | if (err < 0) | ||
386 | goto out; | ||
387 | |||
388 | err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff); | ||
389 | |||
390 | out: | ||
391 | return err; | ||
392 | } | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 95ac55891bd4..487d40555343 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -173,6 +173,8 @@ | |||
173 | #define VV6410_SUBSAMPLE 0x01 | 173 | #define VV6410_SUBSAMPLE 0x01 |
174 | #define VV6410_CROP_TO_QVGA 0x02 | 174 | #define VV6410_CROP_TO_QVGA 0x02 |
175 | 175 | ||
176 | #define VV6410_CIF_LINELENGTH 415 | ||
177 | |||
176 | static int vv6410_probe(struct sd *sd); | 178 | static int vv6410_probe(struct sd *sd); |
177 | static int vv6410_start(struct sd *sd); | 179 | static int vv6410_start(struct sd *sd); |
178 | static int vv6410_init(struct sd *sd); | 180 | static int vv6410_init(struct sd *sd); |
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | |||
187 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 189 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
188 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); | 190 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); |
189 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); | 191 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); |
192 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
193 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
190 | 194 | ||
191 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | 195 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { |
192 | .name = "ST VV6410", | 196 | .name = "ST VV6410", |
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = { | |||
242 | /* Pre-clock generator divide off */ | 246 | /* Pre-clock generator divide off */ |
243 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, | 247 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, |
244 | 248 | ||
245 | /* Exposure registers */ | ||
246 | {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8}, | ||
247 | {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff}, | ||
248 | {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8}, | ||
249 | {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff}, | ||
250 | {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN}, | ||
251 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, | 249 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, |
252 | 250 | ||
253 | /* System registers */ | 251 | /* System registers */ |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index c2b8c10c075a..9623f294bdac 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1103 | { | 1100 | { |
1104 | struct sd *sd = (struct sd *) gspca_dev; | 1101 | struct sd *sd = (struct sd *) gspca_dev; |
1105 | int i, sof = 0; | 1102 | int i, sof = 0; |
1106 | unsigned char *s, *d; | ||
1107 | static unsigned char ffd9[] = {0xff, 0xd9}; | 1103 | static unsigned char ffd9[] = {0xff, 0xd9}; |
1108 | 1104 | ||
1109 | /* frames are jpeg 4.1.1 without 0xff escape */ | 1105 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1177 | } | 1173 | } |
1178 | 1174 | ||
1179 | /* add 0x00 after 0xff */ | 1175 | /* add 0x00 after 0xff */ |
1180 | for (i = len; --i >= 0; ) | 1176 | i = 0; |
1181 | if (data[i] == 0xff) | 1177 | do { |
1182 | break; | 1178 | if (data[i] == 0xff) { |
1183 | if (i < 0) { /* no 0xff */ | 1179 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
1184 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 1180 | data, i + 1); |
1185 | return; | 1181 | len -= i; |
1186 | } | 1182 | data += i; |
1187 | s = data; | 1183 | *data = 0x00; |
1188 | d = sd->packet; | 1184 | i = 0; |
1189 | for (i = 0; i < len; i++) { | 1185 | } |
1190 | *d++ = *s++; | 1186 | i++; |
1191 | if (s[-1] == 0xff) | 1187 | } while (i < len); |
1192 | *d++ = 0x00; | 1188 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
1193 | } | ||
1194 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1195 | sd->packet, d - sd->packet); | ||
1196 | } | 1189 | } |
1197 | 1190 | ||
1198 | static void setbrightness(struct gspca_dev *gspca_dev) | 1191 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index f63e37e2e4fd..404214b8cd2b 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
697 | return -EINVAL; | 697 | return -EINVAL; |
698 | } | 698 | } |
699 | 699 | ||
700 | if (sd->sensor != SENSOR_OTHER) { | 700 | if (sd->sensor == SENSOR_OM6802) { |
701 | reg_w_buf(gspca_dev, n1, sizeof n1); | 701 | reg_w_buf(gspca_dev, n1, sizeof n1); |
702 | i = 5; | 702 | i = 5; |
703 | while (--i >= 0) { | 703 | while (--i >= 0) { |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index e4e933c400bc..26dd155efcc3 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -42,7 +42,7 @@ struct sd { | |||
42 | char bridge; | 42 | char bridge; |
43 | #define BRIDGE_VC0321 0 | 43 | #define BRIDGE_VC0321 0 |
44 | #define BRIDGE_VC0323 1 | 44 | #define BRIDGE_VC0323 1 |
45 | char sensor; | 45 | u8 sensor; |
46 | #define SENSOR_HV7131R 0 | 46 | #define SENSOR_HV7131R 0 |
47 | #define SENSOR_MI0360 1 | 47 | #define SENSOR_MI0360 1 |
48 | #define SENSOR_MI1310_SOC 2 | 48 | #define SENSOR_MI1310_SOC 2 |
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = { | |||
159 | .priv = 2}, | 159 | .priv = 2}, |
160 | }; | 160 | }; |
161 | static const struct v4l2_pix_format bi_mode[] = { | 161 | static const struct v4l2_pix_format bi_mode[] = { |
162 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 162 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
163 | .bytesperline = 320, | 163 | .bytesperline = 320, |
164 | .sizeimage = 320 * 240 * 2, | 164 | .sizeimage = 320 * 240 * 2, |
165 | .colorspace = V4L2_COLORSPACE_SRGB, | 165 | .colorspace = V4L2_COLORSPACE_SRGB, |
166 | .priv = 2}, | 166 | .priv = 2}, |
167 | {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 167 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
168 | .bytesperline = 640, | 168 | .bytesperline = 640, |
169 | .sizeimage = 640 * 480 * 2, | 169 | .sizeimage = 640 * 480 * 2, |
170 | .colorspace = V4L2_COLORSPACE_SRGB, | 170 | .colorspace = V4L2_COLORSPACE_SRGB, |
171 | .priv = 1}, | 171 | .priv = 1}, |
172 | {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 172 | {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
173 | .bytesperline = 1280, | 173 | .bytesperline = 1280, |
174 | .sizeimage = 1280 * 1024 * 2, | 174 | .sizeimage = 1280 * 1024 * 2, |
175 | .colorspace = V4L2_COLORSPACE_SRGB, | 175 | .colorspace = V4L2_COLORSPACE_SRGB, |
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2453 | struct usb_device *dev = gspca_dev->dev; | 2453 | struct usb_device *dev = gspca_dev->dev; |
2454 | struct cam *cam; | 2454 | struct cam *cam; |
2455 | int sensor; | 2455 | int sensor; |
2456 | static u8 npkt[] = { /* number of packets per ISOC message */ | ||
2457 | 64, /* HV7131R 0 */ | ||
2458 | 32, /* MI0360 1 */ | ||
2459 | 32, /* MI1310_SOC 2 */ | ||
2460 | 64, /* MI1320 3 */ | ||
2461 | 128, /* MI1320_SOC 4 */ | ||
2462 | 32, /* OV7660 5 */ | ||
2463 | 64, /* OV7670 6 */ | ||
2464 | 128, /* PO1200 7 */ | ||
2465 | 128, /* PO3130NC 8 */ | ||
2466 | }; | ||
2456 | 2467 | ||
2457 | cam = &gspca_dev->cam; | 2468 | cam = &gspca_dev->cam; |
2458 | sd->bridge = id->driver_info; | 2469 | sd->bridge = id->driver_info; |
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2508 | case SENSOR_MI1320_SOC: | 2519 | case SENSOR_MI1320_SOC: |
2509 | cam->cam_mode = bi_mode; | 2520 | cam->cam_mode = bi_mode; |
2510 | cam->nmodes = ARRAY_SIZE(bi_mode); | 2521 | cam->nmodes = ARRAY_SIZE(bi_mode); |
2522 | cam->input_flags = V4L2_IN_ST_VFLIP | | ||
2523 | V4L2_IN_ST_HFLIP; | ||
2511 | break; | 2524 | break; |
2512 | default: | 2525 | default: |
2513 | cam->cam_mode = vc0323_mode; | 2526 | cam->cam_mode = vc0323_mode; |
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2515 | break; | 2528 | break; |
2516 | } | 2529 | } |
2517 | } | 2530 | } |
2531 | cam->npkt = npkt[sd->sensor]; | ||
2518 | 2532 | ||
2519 | sd->hflip = HFLIP_DEF; | 2533 | sd->hflip = HFLIP_DEF; |
2520 | sd->vflip = VFLIP_DEF; | 2534 | sd->vflip = VFLIP_DEF; |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 4fe01d8b6c87..08422d315e68 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, | |||
6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | 6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ |
6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ | 6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ |
6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ | 6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ |
6310 | PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", | 6310 | PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", |
6311 | reg, retval, retbyte); | 6311 | reg, retval, retbyte); |
6312 | return retval; | 6312 | return retval; |
6313 | } | 6313 | } |
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { | |||
6868 | {0x8001, 0x13}, | 6868 | {0x8001, 0x13}, |
6869 | {0x8000, 0x14}, /* CS2102K */ | 6869 | {0x8000, 0x14}, /* CS2102K */ |
6870 | {0x8400, 0x15}, /* TAS5130K */ | 6870 | {0x8400, 0x15}, /* TAS5130K */ |
6871 | {0x4001, 0x16}, /* ADCM2700 */ | ||
6872 | }; | 6871 | }; |
6873 | 6872 | ||
6874 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) | 6873 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) |
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6904 | retword |= reg_r(gspca_dev, 0x000a); | 6903 | retword |= reg_r(gspca_dev, 0x000a); |
6905 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); | 6904 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); |
6906 | reg_r(gspca_dev, 0x0010); | 6905 | reg_r(gspca_dev, 0x0010); |
6907 | /* this is tested only once anyway */ | 6906 | /* value 0x4001 is meaningless */ |
6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { | 6907 | if (retword != 0x4001) { |
6909 | if (chipset_revision_sensor[i].revision == retword) { | 6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { |
6910 | sd->chip_revision = retword; | 6909 | if (chipset_revision_sensor[i].revision == retword) { |
6911 | send_unknown(dev, SENSOR_PB0330); | 6910 | sd->chip_revision = retword; |
6912 | return chipset_revision_sensor[i].internal_sensor_id; | 6911 | send_unknown(dev, SENSOR_PB0330); |
6912 | return chipset_revision_sensor[i] | ||
6913 | .internal_sensor_id; | ||
6914 | } | ||
6913 | } | 6915 | } |
6914 | } | 6916 | } |
6915 | 6917 | ||
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6980 | reg_w(dev, 0x01, 0x0001); | 6982 | reg_w(dev, 0x01, 0x0001); |
6981 | reg_w(dev, 0x03, 0x0012); | 6983 | reg_w(dev, 0x03, 0x0012); |
6982 | reg_w(dev, 0x01, 0x0012); | 6984 | reg_w(dev, 0x01, 0x0012); |
6983 | reg_w(dev, 0x05, 0x0001); | 6985 | reg_w(dev, 0x05, 0x0012); |
6984 | reg_w(dev, 0xd3, 0x008b); | 6986 | reg_w(dev, 0xd3, 0x008b); |
6985 | retword = i2c_read(gspca_dev, 0x01); | 6987 | retword = i2c_read(gspca_dev, 0x01); |
6986 | if (retword != 0) { | 6988 | if (retword != 0) { |
6987 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); | 6989 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); |
6988 | return retword; | 6990 | return 0x16; /* adcm2700 (6100/6200) */ |
6989 | } | 6991 | } |
6990 | return -1; | 6992 | return -1; |
6991 | } | 6993 | } |