diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 05:13:22 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 21:25:07 +0200 |
commit | 0c0d06cac63ee327ceaab4b5ffe2206574ab86bd (patch) | |
tree | e759f0dc3185d97f2a0c6b5cd5e32ea6faa74d40 /drivers/media/video/gspca | |
parent | [media] b2c2: fix driver's build due to the lack of pci DMA code (diff) | |
download | linux-0c0d06cac63ee327ceaab4b5ffe2206574ab86bd.tar.xz linux-0c0d06cac63ee327ceaab4b5ffe2206574ab86bd.zip |
[media] rename most media/video usb drivers to media/usb
Rename all USB drivers with their own directory under
drivers/media/video into drivers/media/usb and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
93 files changed, 0 insertions, 77859 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig deleted file mode 100644 index dfe268bfa4f8..000000000000 --- a/drivers/media/video/gspca/Kconfig +++ /dev/null @@ -1,425 +0,0 @@ -menuconfig USB_GSPCA - tristate "GSPCA based webcams" - depends on VIDEO_V4L2 - default m - ---help--- - Say Y here if you want to enable selecting webcams based - on the GSPCA framework. - - See <file:Documentation/video4linux/gspca.txt> for more info. - - This driver uses the Video For Linux API. You must say Y or M to - "Video For Linux" to use this driver. - - To compile this driver as modules, choose M here: the - module will be called gspca_main. - - -if USB_GSPCA && VIDEO_V4L2 - -source "drivers/media/video/gspca/m5602/Kconfig" -source "drivers/media/video/gspca/stv06xx/Kconfig" -source "drivers/media/video/gspca/gl860/Kconfig" - -config USB_GSPCA_BENQ - tristate "Benq USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for the Benq DC E300 camera. - - To compile this driver as a module, choose M here: the - module will be called gspca_benq. - -config USB_GSPCA_CONEX - tristate "Conexant Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Conexant chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_conex. - -config USB_GSPCA_CPIA1 - tristate "cpia CPiA (version 1) Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for USB cameras based on the cpia - CPiA chip. Note that you need atleast version 0.6.4 of libv4l for - applications to understand the videoformat generated by this driver. - - To compile this driver as a module, choose M here: the - module will be called gspca_cpia1. - -config USB_GSPCA_ETOMS - tristate "Etoms USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Etoms chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_etoms. - -config USB_GSPCA_FINEPIX - tristate "Fujifilm FinePix USB V4L2 driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the FinePix chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_finepix. - -config USB_GSPCA_JEILINJ - tristate "Jeilin JPEG USB V4L2 driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on this Jeilin chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_jeilinj. - -config USB_GSPCA_JL2005BCD - tristate "JL2005B/C/D USB V4L2 driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based the - JL2005B, JL2005C, or JL2005D chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_jl2005bcd. - -config USB_GSPCA_KINECT - tristate "Kinect sensor device USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for the Microsoft Kinect sensor device. - - To compile this driver as a module, choose M here: the - module will be called gspca_kinect. - -config USB_GSPCA_KONICA - tristate "Konica USB Camera V4L2 driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Konica chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_konica. - -config USB_GSPCA_MARS - tristate "Mars USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Mars chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_mars. - -config USB_GSPCA_MR97310A - tristate "Mars-Semi MR97310A USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the MR97310A chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_mr97310a. - -config USB_GSPCA_NW80X - tristate "Divio based (NW80x) USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the NW80x chips. - - To compile this driver as a module, choose M here: the - module will be called gspca_nw80x. - -config USB_GSPCA_OV519 - tristate "OV51x / OVFX2 / W996xCF USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on one of these: - OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF - - To compile this driver as a module, choose M here: the - module will be called gspca_ov519. - -config USB_GSPCA_OV534 - tristate "OV534 OV772x USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the OV534 chip - and sensor OV772x (e.g. Sony Playstation EYE) - - To compile this driver as a module, choose M here: the - module will be called gspca_ov534. - -config USB_GSPCA_OV534_9 - tristate "OV534 OV965x USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the OV534 chip - and sensor OV965x (e.g. Hercules Dualpix) - - To compile this driver as a module, choose M here: the - module will be called gspca_ov534_9. - -config USB_GSPCA_PAC207 - tristate "Pixart PAC207 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the PAC207 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_pac207. - -config USB_GSPCA_PAC7302 - tristate "Pixart PAC7302 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the PAC7302 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_pac7302. - -config USB_GSPCA_PAC7311 - tristate "Pixart PAC7311 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the PAC7311 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_pac7311. - -config USB_GSPCA_SE401 - tristate "SE401 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the - Endpoints (formerly known as AOX) se401 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_se401. - -config USB_GSPCA_SN9C2028 - tristate "SONIX Dual-Mode USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want streaming support for Sonix SN9C2028 cameras. - These are supported as stillcams in libgphoto2/camlibs/sonix. - - To compile this driver as a module, choose M here: the - module will be called gspca_sn9c2028. - -config USB_GSPCA_SN9C20X - tristate "SN9C20X USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the - sn9c20x chips (SN9C201 and SN9C202). - - To compile this driver as a module, choose M here: the - module will be called gspca_sn9c20x. - -config USB_GSPCA_SONIXB - tristate "SONIX Bayer USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Sonix - chips with Bayer format (SN9C101, SN9C102 and SN9C103). - - To compile this driver as a module, choose M here: the - module will be called gspca_sonixb. - -config USB_GSPCA_SONIXJ - tristate "SONIX JPEG USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Sonix - chips with JPEG format (SN9C102P, SN9C105 and >= SN9C110). - - To compile this driver as a module, choose M here: the - module will be called gspca_sonixj - -config USB_GSPCA_SPCA500 - tristate "SPCA500 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA500 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca500. - -config USB_GSPCA_SPCA501 - tristate "SPCA501 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA501 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca501. - -config USB_GSPCA_SPCA505 - tristate "SPCA505 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA505 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca505. - -config USB_GSPCA_SPCA506 - tristate "SPCA506 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA506 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca506. - -config USB_GSPCA_SPCA508 - tristate "SPCA508 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA508 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca508. - -config USB_GSPCA_SPCA561 - tristate "SPCA561 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA561 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca561. - -config USB_GSPCA_SPCA1528 - tristate "SPCA1528 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA1528 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca1528. - -config USB_GSPCA_SQ905 - tristate "SQ Technologies SQ905 based USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SQ905 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sq905. - -config USB_GSPCA_SQ905C - tristate "SQ Technologies SQ905C based USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SQ905C chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sq905c. - -config USB_GSPCA_SQ930X - tristate "SQ Technologies SQ930X based USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SQ930X chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sq930x. - -config USB_GSPCA_STK014 - tristate "Syntek DV4000 (STK014) USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the STK014 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_stk014. - -config USB_GSPCA_STV0680 - tristate "STV0680 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the STV0680 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_stv0680. - -config USB_GSPCA_SUNPLUS - tristate "SUNPLUS USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Sunplus - SPCA504(abc) SPCA533 SPCA536 chips. - - To compile this driver as a module, choose M here: the - module will be called gspca_sunplus. - -config USB_GSPCA_T613 - tristate "T613 (JPEG Compliance) USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the T613 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_t613. - -config USB_GSPCA_TOPRO - tristate "TOPRO USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the - TP6800 and TP6810 Topro chips. - - To compile this driver as a module, choose M here: the - module will be called gspca_topro. - -config USB_GSPCA_TV8532 - tristate "TV8532 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the TV8531 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_tv8532. - -config USB_GSPCA_VC032X - tristate "VC032X USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the VC032X chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_vc032x. - -config USB_GSPCA_VICAM - tristate "ViCam USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for the 3com homeconnect camera - (vicam). - - To compile this driver as a module, choose M here: the - module will be called gspca_vicam. - -config USB_GSPCA_XIRLINK_CIT - tristate "Xirlink C-It USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for Xirlink C-It bases cameras. - - To compile this driver as a module, choose M here: the - module will be called gspca_xirlink_cit. - -config USB_GSPCA_ZC3XX - tristate "ZC3XX USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the ZC3XX chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_zc3xx. - -endif diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile deleted file mode 100644 index c901da0bd657..000000000000 --- a/drivers/media/video/gspca/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -obj-$(CONFIG_USB_GSPCA) += gspca_main.o -obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o -obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o -obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o -obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o -obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o -obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o -obj-$(CONFIG_USB_GSPCA_JL2005BCD) += gspca_jl2005bcd.o -obj-$(CONFIG_USB_GSPCA_KINECT) += gspca_kinect.o -obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o -obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o -obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o -obj-$(CONFIG_USB_GSPCA_NW80X) += gspca_nw80x.o -obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o -obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o -obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o -obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o -obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o -obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o -obj-$(CONFIG_USB_GSPCA_SE401) += gspca_se401.o -obj-$(CONFIG_USB_GSPCA_SN9C2028) += gspca_sn9c2028.o -obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o -obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o -obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o -obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o -obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o -obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o -obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o -obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o -obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o -obj-$(CONFIG_USB_GSPCA_SPCA1528) += gspca_spca1528.o -obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o -obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o -obj-$(CONFIG_USB_GSPCA_SQ930X) += gspca_sq930x.o -obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o -obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o -obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o -obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o -obj-$(CONFIG_USB_GSPCA_TOPRO) += gspca_topro.o -obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o -obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o -obj-$(CONFIG_USB_GSPCA_VICAM) += gspca_vicam.o -obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o -obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o - -gspca_main-objs := gspca.o autogain_functions.o -gspca_benq-objs := benq.o -gspca_conex-objs := conex.o -gspca_cpia1-objs := cpia1.o -gspca_etoms-objs := etoms.o -gspca_finepix-objs := finepix.o -gspca_jeilinj-objs := jeilinj.o -gspca_jl2005bcd-objs := jl2005bcd.o -gspca_kinect-objs := kinect.o -gspca_konica-objs := konica.o -gspca_mars-objs := mars.o -gspca_mr97310a-objs := mr97310a.o -gspca_nw80x-objs := nw80x.o -gspca_ov519-objs := ov519.o -gspca_ov534-objs := ov534.o -gspca_ov534_9-objs := ov534_9.o -gspca_pac207-objs := pac207.o -gspca_pac7302-objs := pac7302.o -gspca_pac7311-objs := pac7311.o -gspca_se401-objs := se401.o -gspca_sn9c2028-objs := sn9c2028.o -gspca_sn9c20x-objs := sn9c20x.o -gspca_sonixb-objs := sonixb.o -gspca_sonixj-objs := sonixj.o -gspca_spca500-objs := spca500.o -gspca_spca501-objs := spca501.o -gspca_spca505-objs := spca505.o -gspca_spca506-objs := spca506.o -gspca_spca508-objs := spca508.o -gspca_spca561-objs := spca561.o -gspca_spca1528-objs := spca1528.o -gspca_sq905-objs := sq905.o -gspca_sq905c-objs := sq905c.o -gspca_sq930x-objs := sq930x.o -gspca_stk014-objs := stk014.o -gspca_stv0680-objs := stv0680.o -gspca_sunplus-objs := sunplus.o -gspca_t613-objs := t613.o -gspca_topro-objs := topro.o -gspca_tv8532-objs := tv8532.o -gspca_vc032x-objs := vc032x.o -gspca_vicam-objs := vicam.o -gspca_xirlink_cit-objs := xirlink_cit.o -gspca_zc3xx-objs := zc3xx.o - -obj-$(CONFIG_USB_M5602) += m5602/ -obj-$(CONFIG_USB_STV06XX) += stv06xx/ -obj-$(CONFIG_USB_GL860) += gl860/ diff --git a/drivers/media/video/gspca/autogain_functions.c b/drivers/media/video/gspca/autogain_functions.c deleted file mode 100644 index 67db674bb044..000000000000 --- a/drivers/media/video/gspca/autogain_functions.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Functions for auto gain. - * - * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "gspca.h" - -/* auto gain and exposure algorithm based on the knee algorithm described here: - http://ytse.tricolour.net/docs/LowLightOptimization.html - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -int gspca_expo_autogain( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone, - int gain_knee, - int exposure_knee) -{ - s32 gain, orig_gain, exposure, orig_exposure; - int i, steps, retval = 0; - - if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0) - return 0; - - orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain); - orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = abs(desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - for (i = 0; i < steps; i++) { - if (avg_lum > desired_avg_lum) { - if (gain > gain_knee) - gain--; - else if (exposure > exposure_knee) - exposure--; - else if (gain > gspca_dev->gain->default_value) - gain--; - else if (exposure > gspca_dev->exposure->minimum) - exposure--; - else if (gain > gspca_dev->gain->minimum) - gain--; - else - break; - } else { - if (gain < gspca_dev->gain->default_value) - gain++; - else if (exposure < exposure_knee) - exposure++; - else if (gain < gain_knee) - gain++; - else if (exposure < gspca_dev->exposure->maximum) - exposure++; - else if (gain < gspca_dev->gain->maximum) - gain++; - else - break; - } - } - - if (gain != orig_gain) { - v4l2_ctrl_s_ctrl(gspca_dev->gain, gain); - retval = 1; - } - if (exposure != orig_exposure) { - v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -EXPORT_SYMBOL(gspca_expo_autogain); - -/* Autogain + exposure algorithm for cameras with a coarse exposure control - (usually this means we can only control the clockdiv to change exposure) - As changing the clockdiv so that the fps drops from 30 to 15 fps for - example, will lead to a huge exposure change (it effectively doubles), - this algorithm normally tries to only adjust the gain (between 40 and - 80 %) and if that does not help, only then changes exposure. This leads - to a much more stable image then using the knee algorithm which at - certain points of the knee graph will only try to adjust exposure, - which leads to oscilating as one exposure step is huge. - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -int gspca_coarse_grained_expo_autogain( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone) -{ - s32 gain_low, gain_high, gain, orig_gain, exposure, orig_exposure; - int steps, retval = 0; - - if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0) - return 0; - - orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain); - orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - - gain_low = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) / - 5 * 2 + gspca_dev->gain->minimum; - gain_high = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) / - 5 * 4 + gspca_dev->gain->minimum; - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = (desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - if ((gain + steps) > gain_high && - exposure < gspca_dev->exposure->maximum) { - gain = gain_high; - gspca_dev->exp_too_low_cnt++; - gspca_dev->exp_too_high_cnt = 0; - } else if ((gain + steps) < gain_low && - exposure > gspca_dev->exposure->minimum) { - gain = gain_low; - gspca_dev->exp_too_high_cnt++; - gspca_dev->exp_too_low_cnt = 0; - } else { - gain += steps; - if (gain > gspca_dev->gain->maximum) - gain = gspca_dev->gain->maximum; - else if (gain < gspca_dev->gain->minimum) - gain = gspca_dev->gain->minimum; - gspca_dev->exp_too_high_cnt = 0; - gspca_dev->exp_too_low_cnt = 0; - } - - if (gspca_dev->exp_too_high_cnt > 3) { - exposure--; - gspca_dev->exp_too_high_cnt = 0; - } else if (gspca_dev->exp_too_low_cnt > 3) { - exposure++; - gspca_dev->exp_too_low_cnt = 0; - } - - if (gain != orig_gain) { - v4l2_ctrl_s_ctrl(gspca_dev->gain, gain); - retval = 1; - } - if (exposure != orig_exposure) { - v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -EXPORT_SYMBOL(gspca_coarse_grained_expo_autogain); diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/video/gspca/autogain_functions.h deleted file mode 100644 index d625eafe63eb..000000000000 --- a/drivers/media/video/gspca/autogain_functions.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Functions for auto gain. - * - * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef WANT_REGULAR_AUTOGAIN -/* auto gain and exposure algorithm based on the knee algorithm described here: - http://ytse.tricolour.net/docs/LowLightOptimization.html - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -static inline int auto_gain_n_exposure( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone, - int gain_knee, - int exposure_knee) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, steps, gain, orig_gain, exposure, orig_exposure; - int retval = 0; - - orig_gain = gain = sd->ctrls[GAIN].val; - orig_exposure = exposure = sd->ctrls[EXPOSURE].val; - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = abs(desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - for (i = 0; i < steps; i++) { - if (avg_lum > desired_avg_lum) { - if (gain > gain_knee) - gain--; - else if (exposure > exposure_knee) - exposure--; - else if (gain > sd->ctrls[GAIN].def) - gain--; - else if (exposure > sd->ctrls[EXPOSURE].min) - exposure--; - else if (gain > sd->ctrls[GAIN].min) - gain--; - else - break; - } else { - if (gain < sd->ctrls[GAIN].def) - gain++; - else if (exposure < exposure_knee) - exposure++; - else if (gain < gain_knee) - gain++; - else if (exposure < sd->ctrls[EXPOSURE].max) - exposure++; - else if (gain < sd->ctrls[GAIN].max) - gain++; - else - break; - } - } - - if (gain != orig_gain) { - sd->ctrls[GAIN].val = gain; - setgain(gspca_dev); - retval = 1; - } - if (exposure != orig_exposure) { - sd->ctrls[EXPOSURE].val = exposure; - setexposure(gspca_dev); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -#endif - -#ifdef WANT_COARSE_EXPO_AUTOGAIN -/* Autogain + exposure algorithm for cameras with a coarse exposure control - (usually this means we can only control the clockdiv to change exposure) - As changing the clockdiv so that the fps drops from 30 to 15 fps for - example, will lead to a huge exposure change (it effectively doubles), - this algorithm normally tries to only adjust the gain (between 40 and - 80 %) and if that does not help, only then changes exposure. This leads - to a much more stable image then using the knee algorithm which at - certain points of the knee graph will only try to adjust exposure, - which leads to oscilating as one exposure step is huge. - - Note this assumes that the sd struct for the cam in question has - exp_too_low_cnt and exp_too_high_cnt int members for use by this function. - - Returns 0 if no changes were made, 1 if the gain and or exposure settings - where changed. */ -static inline int coarse_grained_expo_autogain( - struct gspca_dev *gspca_dev, - int avg_lum, - int desired_avg_lum, - int deadzone) -{ - struct sd *sd = (struct sd *) gspca_dev; - int steps, gain, orig_gain, exposure, orig_exposure; - int gain_low, gain_high; - int retval = 0; - - orig_gain = gain = sd->ctrls[GAIN].val; - orig_exposure = exposure = sd->ctrls[EXPOSURE].val; - - gain_low = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 2; - gain_low += sd->ctrls[GAIN].min; - gain_high = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 4; - gain_high += sd->ctrls[GAIN].min; - - /* If we are of a multiple of deadzone, do multiple steps to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = (desired_avg_lum - avg_lum) / deadzone; - - PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d", - avg_lum, desired_avg_lum, steps); - - if ((gain + steps) > gain_high && - exposure < sd->ctrls[EXPOSURE].max) { - gain = gain_high; - sd->exp_too_low_cnt++; - sd->exp_too_high_cnt = 0; - } else if ((gain + steps) < gain_low && - exposure > sd->ctrls[EXPOSURE].min) { - gain = gain_low; - sd->exp_too_high_cnt++; - sd->exp_too_low_cnt = 0; - } else { - gain += steps; - if (gain > sd->ctrls[GAIN].max) - gain = sd->ctrls[GAIN].max; - else if (gain < sd->ctrls[GAIN].min) - gain = sd->ctrls[GAIN].min; - sd->exp_too_high_cnt = 0; - sd->exp_too_low_cnt = 0; - } - - if (sd->exp_too_high_cnt > 3) { - exposure--; - sd->exp_too_high_cnt = 0; - } else if (sd->exp_too_low_cnt > 3) { - exposure++; - sd->exp_too_low_cnt = 0; - } - - if (gain != orig_gain) { - sd->ctrls[GAIN].val = gain; - setgain(gspca_dev); - retval = 1; - } - if (exposure != orig_exposure) { - sd->ctrls[EXPOSURE].val = exposure; - setexposure(gspca_dev); - retval = 1; - } - - if (retval) - PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d", - gain, exposure); - return retval; -} -#endif diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c deleted file mode 100644 index 352f32190e68..000000000000 --- a/drivers/media/video/gspca/benq.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Benq DC E300 subdriver - * - * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "benq" - -#include "gspca.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -}; - -static void sd_isoc_irq(struct urb *urb); - -/* -- write a register -- */ -static void reg_w(struct gspca_dev *gspca_dev, - u16 value, u16 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x02, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - NULL, - 0, - 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - gspca_dev->cam.no_urb_create = 1; - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct urb *urb; - int i, n; - - /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */ -#if MAX_NURBS < 4 -#error "Not enough URBs in the gspca table" -#endif -#define SD_PKT_SZ 64 -#define SD_NPKT 32 - for (n = 0; n < 4; n++) { - urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); - if (!urb) { - pr_err("usb_alloc_urb failed\n"); - return -ENOMEM; - } - gspca_dev->urb[n] = urb; - urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, - SD_PKT_SZ * SD_NPKT, - GFP_KERNEL, - &urb->transfer_dma); - - if (urb->transfer_buffer == NULL) { - pr_err("usb_alloc_coherent failed\n"); - return -ENOMEM; - } - urb->dev = gspca_dev->dev; - urb->context = gspca_dev; - urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT; - urb->pipe = usb_rcvisocpipe(gspca_dev->dev, - n & 1 ? 0x82 : 0x83); - urb->transfer_flags = URB_ISO_ASAP - | URB_NO_TRANSFER_DMA_MAP; - urb->interval = 1; - urb->complete = sd_isoc_irq; - urb->number_of_packets = SD_NPKT; - for (i = 0; i < SD_NPKT; i++) { - urb->iso_frame_desc[i].length = SD_PKT_SZ; - urb->iso_frame_desc[i].offset = SD_PKT_SZ * i; - } - } - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct usb_interface *intf; - - reg_w(gspca_dev, 0x003c, 0x0003); - reg_w(gspca_dev, 0x003c, 0x0004); - reg_w(gspca_dev, 0x003c, 0x0005); - reg_w(gspca_dev, 0x003c, 0x0006); - reg_w(gspca_dev, 0x003c, 0x0007); - - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - usb_set_interface(gspca_dev->dev, gspca_dev->iface, - intf->num_altsetting - 1); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - /* unused */ -} - -/* reception of an URB */ -static void sd_isoc_irq(struct urb *urb) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - struct urb *urb0; - u8 *data; - int i, st; - - PDEBUG(D_PACK, "sd isoc irq"); - if (!gspca_dev->streaming) - return; - if (urb->status != 0) { - if (urb->status == -ESHUTDOWN) - return; /* disconnection */ -#ifdef CONFIG_PM - if (gspca_dev->frozen) - return; -#endif - pr_err("urb status: %d\n", urb->status); - return; - } - - /* if this is a control URN (ep 0x83), wait */ - if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2]) - return; - - /* scan both received URBs */ - if (urb == gspca_dev->urb[1]) - urb0 = gspca_dev->urb[0]; - else - urb0 = gspca_dev->urb[2]; - for (i = 0; i < urb->number_of_packets; i++) { - - /* check the packet status and length */ - if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ - || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) { - PDEBUG(D_ERR, "ISOC bad lengths %d / %d", - urb0->iso_frame_desc[i].actual_length, - urb->iso_frame_desc[i].actual_length); - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - st = urb0->iso_frame_desc[i].status; - if (st == 0) - st = urb->iso_frame_desc[i].status; - if (st) { - pr_err("ISOC data error: [%d] status=%d\n", - i, st); - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - - /* - * The images are received in URBs of different endpoints - * (0x83 and 0x82). - * Image pieces in URBs of ep 0x83 are continuated in URBs of - * ep 0x82 of the same index. - * The packets in the URBs of endpoint 0x83 start with: - * - 80 ba/bb 00 00 = start of image followed by 'ff d8' - * - 04 ba/bb oo oo = image piece - * where 'oo oo' is the image offset - (not cheked) - * - (other -> bad frame) - * The images are JPEG encoded with full header and - * normal ff escape. - * The end of image ('ff d9') may occur in any URB. - * (not cheked) - */ - data = (u8 *) urb0->transfer_buffer - + urb0->iso_frame_desc[i].offset; - if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) { - - /* new image */ - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, - data + 4, SD_PKT_SZ - 4); - } else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) { - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 4, SD_PKT_SZ - 4); - } else { - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - data = (u8 *) urb->transfer_buffer - + urb->iso_frame_desc[i].offset; - gspca_frame_add(gspca_dev, INTER_PACKET, - data, SD_PKT_SZ); - } - - /* resubmit the URBs */ - st = usb_submit_urb(urb0, GFP_ATOMIC); - if (st < 0) - pr_err("usb_submit_urb(0) ret %d\n", st); - st = usb_submit_urb(urb, GFP_ATOMIC); - if (st < 0) - pr_err("usb_submit_urb() ret %d\n", st); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x04a5, 0x3035)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c deleted file mode 100644 index c9052f20435e..000000000000 --- a/drivers/media/video/gspca/conex.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Connexant Cx11646 library - * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "conex" - -#include "gspca.h" -#define CONEX_CAM 1 /* special JPEG header */ -#include "jpeg.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); -MODULE_LICENSE("GPL"); - -#define QUALITY 50 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *contrast; - struct v4l2_ctrl *sat; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* the read bytes are found in gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 index, - __u16 len) -{ - struct usb_device *dev = gspca_dev->dev; - -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); - return; - } -#endif - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), - 0, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, - index, gspca_dev->usb_buf, len, - 500); - PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", - index, gspca_dev->usb_buf[0]); -} - -/* the bytes to write are in gspca_dev->usb_buf */ -static void reg_w_val(struct gspca_dev *gspca_dev, - __u16 index, - __u8 val) -{ - struct usb_device *dev = gspca_dev->dev; - - gspca_dev->usb_buf[0] = val; - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, - index, gspca_dev->usb_buf, 1, 500); -} - -static void reg_w(struct gspca_dev *gspca_dev, - __u16 index, - const __u8 *buffer, - __u16 len) -{ - struct usb_device *dev = gspca_dev->dev; - -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_w: buffer overflow\n"); - return; - } - PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); -#endif - memcpy(gspca_dev->usb_buf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, - index, gspca_dev->usb_buf, len, 500); -} - -static const __u8 cx_sensor_init[][4] = { - {0x88, 0x11, 0x01, 0x01}, - {0x88, 0x12, 0x70, 0x01}, - {0x88, 0x0f, 0x00, 0x01}, - {0x88, 0x05, 0x01, 0x01}, - {} -}; - -static const __u8 cx11646_fw1[][3] = { - {0x00, 0x02, 0x00}, - {0x01, 0x43, 0x00}, - {0x02, 0xA7, 0x00}, - {0x03, 0x8B, 0x01}, - {0x04, 0xE9, 0x02}, - {0x05, 0x08, 0x04}, - {0x06, 0x08, 0x05}, - {0x07, 0x07, 0x06}, - {0x08, 0xE7, 0x06}, - {0x09, 0xC6, 0x07}, - {0x0A, 0x86, 0x08}, - {0x0B, 0x46, 0x09}, - {0x0C, 0x05, 0x0A}, - {0x0D, 0xA5, 0x0A}, - {0x0E, 0x45, 0x0B}, - {0x0F, 0xE5, 0x0B}, - {0x10, 0x85, 0x0C}, - {0x11, 0x25, 0x0D}, - {0x12, 0xC4, 0x0D}, - {0x13, 0x45, 0x0E}, - {0x14, 0xE4, 0x0E}, - {0x15, 0x64, 0x0F}, - {0x16, 0xE4, 0x0F}, - {0x17, 0x64, 0x10}, - {0x18, 0xE4, 0x10}, - {0x19, 0x64, 0x11}, - {0x1A, 0xE4, 0x11}, - {0x1B, 0x64, 0x12}, - {0x1C, 0xE3, 0x12}, - {0x1D, 0x44, 0x13}, - {0x1E, 0xC3, 0x13}, - {0x1F, 0x24, 0x14}, - {0x20, 0xA3, 0x14}, - {0x21, 0x04, 0x15}, - {0x22, 0x83, 0x15}, - {0x23, 0xE3, 0x15}, - {0x24, 0x43, 0x16}, - {0x25, 0xA4, 0x16}, - {0x26, 0x23, 0x17}, - {0x27, 0x83, 0x17}, - {0x28, 0xE3, 0x17}, - {0x29, 0x43, 0x18}, - {0x2A, 0xA3, 0x18}, - {0x2B, 0x03, 0x19}, - {0x2C, 0x63, 0x19}, - {0x2D, 0xC3, 0x19}, - {0x2E, 0x22, 0x1A}, - {0x2F, 0x63, 0x1A}, - {0x30, 0xC3, 0x1A}, - {0x31, 0x23, 0x1B}, - {0x32, 0x83, 0x1B}, - {0x33, 0xE2, 0x1B}, - {0x34, 0x23, 0x1C}, - {0x35, 0x83, 0x1C}, - {0x36, 0xE2, 0x1C}, - {0x37, 0x23, 0x1D}, - {0x38, 0x83, 0x1D}, - {0x39, 0xE2, 0x1D}, - {0x3A, 0x23, 0x1E}, - {0x3B, 0x82, 0x1E}, - {0x3C, 0xC3, 0x1E}, - {0x3D, 0x22, 0x1F}, - {0x3E, 0x63, 0x1F}, - {0x3F, 0xC1, 0x1F}, - {} -}; -static void cx11646_fw(struct gspca_dev*gspca_dev) -{ - int i = 0; - - reg_w_val(gspca_dev, 0x006a, 0x02); - while (cx11646_fw1[i][1]) { - reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3); - i++; - } - reg_w_val(gspca_dev, 0x006a, 0x00); -} - -static const __u8 cxsensor[] = { - 0x88, 0x12, 0x70, 0x01, - 0x88, 0x0d, 0x02, 0x01, - 0x88, 0x0f, 0x00, 0x01, - 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */ - 0x88, 0x02, 0x10, 0x01, - 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */ - 0x88, 0x0B, 0x00, 0x01, - 0x88, 0x0A, 0x0A, 0x01, - 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */ - 0x88, 0x05, 0x01, 0x01, - 0xA1, 0x18, 0x00, 0x01, - 0x00 -}; - -static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; -static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; -static const __u8 reg10[] = { 0xb1, 0xb1 }; -static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ -static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; - /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */ -static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; - /* 320{0x04,0x0c,0x05,0x0f}; //320 */ -static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ -static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; - -static void cx_sensor(struct gspca_dev*gspca_dev) -{ - int i = 0; - int length; - const __u8 *ptsensor = cxsensor; - - reg_w(gspca_dev, 0x0020, reg20, 8); - reg_w(gspca_dev, 0x0028, reg28, 8); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0092, 0x03); - - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 0: - reg_w(gspca_dev, 0x0071, reg71a, 4); - break; - case 1: - reg_w(gspca_dev, 0x0071, reg71b, 4); - break; - default: -/* case 2: */ - reg_w(gspca_dev, 0x0071, reg71c, 4); - break; - case 3: - reg_w(gspca_dev, 0x0071, reg71d, 4); - break; - } - reg_w(gspca_dev, 0x007b, reg7b, 6); - reg_w_val(gspca_dev, 0x00f8, 0x00); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0098, 0x41); - for (i = 0; i < 11; i++) { - if (i == 3 || i == 5 || i == 8) - length = 8; - else - length = 4; - reg_w(gspca_dev, 0x00e5, ptsensor, length); - if (length == 4) - reg_r(gspca_dev, 0x00e8, 1); - else - reg_r(gspca_dev, 0x00e8, length); - ptsensor += length; - } - reg_r(gspca_dev, 0x00e7, 8); -} - -static const __u8 cx_inits_176[] = { - 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */ - 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03, - 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30, - 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF, - 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02, - 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const __u8 cx_inits_320[] = { - 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01, - 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01, - 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81, - 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, - 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02, - 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const __u8 cx_inits_352[] = { - 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03, - 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b, - 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25, - 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00, - 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, - 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02, - 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const __u8 cx_inits_640[] = { - 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01, - 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01, - 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81, - 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, - 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02, - 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static void cx11646_initsize(struct gspca_dev *gspca_dev) -{ - const __u8 *cxinit; - static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; - static const __u8 reg17[] = - { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; - - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 0: - cxinit = cx_inits_640; - break; - case 1: - cxinit = cx_inits_352; - break; - default: -/* case 2: */ - cxinit = cx_inits_320; - break; - case 3: - cxinit = cx_inits_176; - break; - } - reg_w_val(gspca_dev, 0x009a, 0x01); - reg_w_val(gspca_dev, 0x0010, 0x10); - reg_w(gspca_dev, 0x0012, reg12, 5); - reg_w(gspca_dev, 0x0017, reg17, 8); - reg_w_val(gspca_dev, 0x00c0, 0x00); - reg_w_val(gspca_dev, 0x00c1, 0x04); - reg_w_val(gspca_dev, 0x00c2, 0x04); - - reg_w(gspca_dev, 0x0061, cxinit, 8); - cxinit += 8; - reg_w(gspca_dev, 0x00ca, cxinit, 8); - cxinit += 8; - reg_w(gspca_dev, 0x00d2, cxinit, 8); - cxinit += 8; - reg_w(gspca_dev, 0x00da, cxinit, 6); - cxinit += 8; - reg_w(gspca_dev, 0x0041, cxinit, 8); - cxinit += 8; - reg_w(gspca_dev, 0x0049, cxinit, 8); - cxinit += 8; - reg_w(gspca_dev, 0x0051, cxinit, 2); - - reg_r(gspca_dev, 0x0010, 1); -} - -static const __u8 cx_jpeg_init[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */ - {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11}, - {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22}, - {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26}, - {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a}, - {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73}, - {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D}, - {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0}, - {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01}, - {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12}, - {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35}, - {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31}, - {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43}, - {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A}, - {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73}, - {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95}, - {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83}, - {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05}, - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}, - {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, - {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01}, - {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, - {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00}, - {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05}, - {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01}, - {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21}, - {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22}, - {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23}, - {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24}, - {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17}, - {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29}, - {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A}, - {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A}, - {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A}, - {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A}, - {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A}, - {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A}, - {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99}, - {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8}, - {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, - {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6}, - {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5}, - {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3}, - {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1}, - {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9}, - {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04}, - {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01}, - {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04}, - {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07}, - {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14}, - {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33}, - {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16}, - {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19}, - {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36}, - {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46}, - {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56}, - {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66}, - {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76}, - {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85}, - {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94}, - {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3}, - {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2}, - {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA}, - {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9}, - {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8}, - {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7}, - {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6}, - {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F}, - {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22}, - {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11}, - {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00}, - {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08}, - {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00}, - {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA}, - {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02}, - {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */ -}; - - -static const __u8 cxjpeg_640[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */ - {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d}, - {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a}, - {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d}, - {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38}, - {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57}, - {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F}, - {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79}, - {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01}, - {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E}, - {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28}, - {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25}, - {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33}, - {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44}, - {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57}, - {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71}, - {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63}, - {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00}, - {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, - {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, - {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, - {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF}, - {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80}, - {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, - {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, - {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, - {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ -}; -static const __u8 cxjpeg_352[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, - {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a}, - {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14}, - {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17}, - {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, - {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, - {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, - {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, - {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, - {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, - {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, - {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, - {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, - {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, - {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, - {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, - {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, - {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00}, - {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, - {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, - {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, - {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF}, - {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60}, - {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, - {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, - {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, - {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; -static const __u8 cxjpeg_320[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05}, - {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04}, - {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08}, - {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09}, - {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11}, - {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A}, - {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D}, - {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24}, - {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01}, - {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04}, - {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C}, - {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B}, - {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F}, - {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14}, - {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A}, - {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22}, - {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E}, - {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00}, - {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, - {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, - {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, - {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF}, - {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40}, - {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, - {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, - {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, - {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ -}; -static const __u8 cxjpeg_176[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, - {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A}, - {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14}, - {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17}, - {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, - {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, - {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, - {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, - {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, - {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, - {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, - {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, - {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, - {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, - {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, - {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, - {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, - {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00}, - {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, - {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, - {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, - {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF}, - {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0}, - {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, - {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, - {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, - {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; -/* 640 take with the zcx30x part */ -static const __u8 cxjpeg_qtable[][8] = { - {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08}, - {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07}, - {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a}, - {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f}, - {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c}, - {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c}, - {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30}, - {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d}, - {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01}, - {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a}, - {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, - {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */ -}; - - -static void cx11646_jpegInit(struct gspca_dev*gspca_dev) -{ - int i; - int length; - - reg_w_val(gspca_dev, 0x00c0, 0x01); - reg_w_val(gspca_dev, 0x00c3, 0x00); - reg_w_val(gspca_dev, 0x00c0, 0x00); - reg_r(gspca_dev, 0x0001, 1); - length = 8; - for (i = 0; i < 79; i++) { - if (i == 78) - length = 6; - reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length); - } - reg_r(gspca_dev, 0x0002, 1); - reg_w_val(gspca_dev, 0x0055, 0x14); -} - -static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; -static const __u8 regE5_8[] = - { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; -static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; -static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; -static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; -static const __u8 reg51[] = { 0x77, 0x03 }; -#define reg70 0x03 - -static void cx11646_jpeg(struct gspca_dev*gspca_dev) -{ - int i; - int length; - __u8 Reg55; - int retry; - - reg_w_val(gspca_dev, 0x00c0, 0x01); - reg_w_val(gspca_dev, 0x00c3, 0x00); - reg_w_val(gspca_dev, 0x00c0, 0x00); - reg_r(gspca_dev, 0x0001, 1); - length = 8; - switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) { - case 0: - for (i = 0; i < 27; i++) { - if (i == 26) - length = 2; - reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length); - } - Reg55 = 0x28; - break; - case 1: - for (i = 0; i < 27; i++) { - if (i == 26) - length = 2; - reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length); - } - Reg55 = 0x16; - break; - default: -/* case 2: */ - for (i = 0; i < 27; i++) { - if (i == 26) - length = 2; - reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length); - } - Reg55 = 0x14; - break; - case 3: - for (i = 0; i < 27; i++) { - if (i == 26) - length = 2; - reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length); - } - Reg55 = 0x0B; - break; - } - - reg_r(gspca_dev, 0x0002, 1); - reg_w_val(gspca_dev, 0x0055, Reg55); - reg_r(gspca_dev, 0x0002, 1); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0054, 0x02); - reg_w_val(gspca_dev, 0x0054, 0x01); - reg_w_val(gspca_dev, 0x0000, 0x94); - reg_w_val(gspca_dev, 0x0053, 0xc0); - reg_w_val(gspca_dev, 0x00fc, 0xe1); - reg_w_val(gspca_dev, 0x0000, 0x00); - /* wait for completion */ - retry = 50; - do { - reg_r(gspca_dev, 0x0002, 1); - /* 0x07 until 0x00 */ - if (gspca_dev->usb_buf[0] == 0x00) - break; - reg_w_val(gspca_dev, 0x0053, 0x00); - } while (--retry); - if (retry == 0) - PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); - /* send the qtable now */ - reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */ - length = 8; - for (i = 0; i < 18; i++) { - if (i == 17) - length = 2; - reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length); - - } - reg_r(gspca_dev, 0x0002, 1); /* 0x00 */ - reg_r(gspca_dev, 0x0053, 1); /* 0x00 */ - reg_w_val(gspca_dev, 0x0054, 0x02); - reg_w_val(gspca_dev, 0x0054, 0x01); - reg_w_val(gspca_dev, 0x0000, 0x94); - reg_w_val(gspca_dev, 0x0053, 0xc0); - - reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ - reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ - reg_r(gspca_dev, 0x001f, 1); /* 0x38 */ - reg_w(gspca_dev, 0x0012, reg12, 5); - reg_w(gspca_dev, 0x00e5, regE5_8, 8); - reg_r(gspca_dev, 0x00e8, 8); - reg_w(gspca_dev, 0x00e5, regE5a, 4); - reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ - reg_w_val(gspca_dev, 0x009a, 0x01); - reg_w(gspca_dev, 0x00e5, regE5b, 4); - reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ - reg_w(gspca_dev, 0x00e5, regE5c, 4); - reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ - - reg_w(gspca_dev, 0x0051, reg51, 2); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0070, reg70); -} - -static void cx11646_init1(struct gspca_dev *gspca_dev) -{ - int i = 0; - - reg_w_val(gspca_dev, 0x0010, 0x00); - reg_w_val(gspca_dev, 0x0053, 0x00); - reg_w_val(gspca_dev, 0x0052, 0x00); - reg_w_val(gspca_dev, 0x009b, 0x2f); - reg_w_val(gspca_dev, 0x009c, 0x10); - reg_r(gspca_dev, 0x0098, 1); - reg_w_val(gspca_dev, 0x0098, 0x40); - reg_r(gspca_dev, 0x0099, 1); - reg_w_val(gspca_dev, 0x0099, 0x07); - reg_w_val(gspca_dev, 0x0039, 0x40); - reg_w_val(gspca_dev, 0x003c, 0xff); - reg_w_val(gspca_dev, 0x003f, 0x1f); - reg_w_val(gspca_dev, 0x003d, 0x40); -/* reg_w_val(gspca_dev, 0x003d, 0x60); */ - reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */ - - while (cx_sensor_init[i][0]) { - reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]); - reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */ - if (i == 1) { - reg_w_val(gspca_dev, 0x00ed, 0x01); - reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */ - } - i++; - } - reg_w_val(gspca_dev, 0x00c3, 0x00); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - cx11646_init1(gspca_dev); - cx11646_initsize(gspca_dev); - cx11646_fw(gspca_dev); - cx_sensor(gspca_dev); - cx11646_jpegInit(gspca_dev); - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, QUALITY); - - cx11646_initsize(gspca_dev); - cx11646_fw(gspca_dev); - cx_sensor(gspca_dev); - cx11646_jpeg(gspca_dev); - return 0; -} - -/* called on streamoff with alt 0 and on disconnect */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - int retry = 50; - - if (!gspca_dev->present) - return; - reg_w_val(gspca_dev, 0x0000, 0x00); - reg_r(gspca_dev, 0x0002, 1); - reg_w_val(gspca_dev, 0x0053, 0x00); - - while (retry--) { -/* reg_r(gspca_dev, 0x0002, 1);*/ - reg_r(gspca_dev, 0x0053, 1); - if (gspca_dev->usb_buf[0] == 0) - break; - } - reg_w_val(gspca_dev, 0x0000, 0x00); - reg_r(gspca_dev, 0x0002, 1); - - reg_w_val(gspca_dev, 0x0010, 0x00); - reg_r(gspca_dev, 0x0033, 1); - reg_w_val(gspca_dev, 0x00fc, 0xe0); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (data[0] == 0xff && data[1] == 0xd8) { - - /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - data += 2; - len -= 2; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat) -{ - __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; - __u8 reg51c[2]; - - regE5cbx[2] = val; - reg_w(gspca_dev, 0x00e5, regE5cbx, 8); - reg_r(gspca_dev, 0x00e8, 8); - reg_w(gspca_dev, 0x00e5, regE5c, 4); - reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ - - reg51c[0] = 0x77; - reg51c[1] = sat; - reg_w(gspca_dev, 0x0051, reg51c, 2); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0070, reg70); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat) -{ - __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ -/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ - __u8 reg51c[2]; - - regE5acx[2] = val; - reg_w(gspca_dev, 0x00e5, regE5acx, 4); - reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ - reg51c[0] = 0x77; - reg51c[1] = sat; - reg_w(gspca_dev, 0x0051, reg51c, 2); - reg_w(gspca_dev, 0x0010, reg10, 2); - reg_w_val(gspca_dev, 0x0070, reg70); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val); - break; - case V4L2_CID_SATURATION: - setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val); - setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 3); - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4); - sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c); - sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 7, 1, 3); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0572, 0x0041)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c deleted file mode 100644 index 2499a881d9a3..000000000000 --- a/drivers/media/video/gspca/cpia1.c +++ /dev/null @@ -1,1905 +0,0 @@ -/* - * cpia CPiA (1) gspca driver - * - * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> - * - * This module is adapted from the in kernel v4l1 cpia driver which is : - * - * (C) Copyright 1999-2000 Peter Pregler - * (C) Copyright 1999-2000 Scott J. Bertin - * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com> - * (C) Copyright 2000 STMicroelectronics - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "cpia1" - -#include <linux/input.h> -#include "gspca.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Vision CPiA"); -MODULE_LICENSE("GPL"); - -/* constant value's */ -#define MAGIC_0 0x19 -#define MAGIC_1 0x68 -#define DATA_IN 0xc0 -#define DATA_OUT 0x40 -#define VIDEOSIZE_QCIF 0 /* 176x144 */ -#define VIDEOSIZE_CIF 1 /* 352x288 */ -#define SUBSAMPLE_420 0 -#define SUBSAMPLE_422 1 -#define YUVORDER_YUYV 0 -#define YUVORDER_UYVY 1 -#define NOT_COMPRESSED 0 -#define COMPRESSED 1 -#define NO_DECIMATION 0 -#define DECIMATION_ENAB 1 -#define EOI 0xff /* End Of Image */ -#define EOL 0xfd /* End Of Line */ -#define FRAME_HEADER_SIZE 64 - -/* Image grab modes */ -#define CPIA_GRAB_SINGLE 0 -#define CPIA_GRAB_CONTINEOUS 1 - -/* Compression parameters */ -#define CPIA_COMPRESSION_NONE 0 -#define CPIA_COMPRESSION_AUTO 1 -#define CPIA_COMPRESSION_MANUAL 2 -#define CPIA_COMPRESSION_TARGET_QUALITY 0 -#define CPIA_COMPRESSION_TARGET_FRAMERATE 1 - -/* Return offsets for GetCameraState */ -#define SYSTEMSTATE 0 -#define GRABSTATE 1 -#define STREAMSTATE 2 -#define FATALERROR 3 -#define CMDERROR 4 -#define DEBUGFLAGS 5 -#define VPSTATUS 6 -#define ERRORCODE 7 - -/* SystemState */ -#define UNINITIALISED_STATE 0 -#define PASS_THROUGH_STATE 1 -#define LO_POWER_STATE 2 -#define HI_POWER_STATE 3 -#define WARM_BOOT_STATE 4 - -/* GrabState */ -#define GRAB_IDLE 0 -#define GRAB_ACTIVE 1 -#define GRAB_DONE 2 - -/* StreamState */ -#define STREAM_NOT_READY 0 -#define STREAM_READY 1 -#define STREAM_OPEN 2 -#define STREAM_PAUSED 3 -#define STREAM_FINISHED 4 - -/* Fatal Error, CmdError, and DebugFlags */ -#define CPIA_FLAG 1 -#define SYSTEM_FLAG 2 -#define INT_CTRL_FLAG 4 -#define PROCESS_FLAG 8 -#define COM_FLAG 16 -#define VP_CTRL_FLAG 32 -#define CAPTURE_FLAG 64 -#define DEBUG_FLAG 128 - -/* VPStatus */ -#define VP_STATE_OK 0x00 - -#define VP_STATE_FAILED_VIDEOINIT 0x01 -#define VP_STATE_FAILED_AECACBINIT 0x02 -#define VP_STATE_AEC_MAX 0x04 -#define VP_STATE_ACB_BMAX 0x08 - -#define VP_STATE_ACB_RMIN 0x10 -#define VP_STATE_ACB_GMIN 0x20 -#define VP_STATE_ACB_RMAX 0x40 -#define VP_STATE_ACB_GMAX 0x80 - -/* default (minimum) compensation values */ -#define COMP_RED 220 -#define COMP_GREEN1 214 -#define COMP_GREEN2 COMP_GREEN1 -#define COMP_BLUE 230 - -/* exposure status */ -#define EXPOSURE_VERY_LIGHT 0 -#define EXPOSURE_LIGHT 1 -#define EXPOSURE_NORMAL 2 -#define EXPOSURE_DARK 3 -#define EXPOSURE_VERY_DARK 4 - -#define CPIA_MODULE_CPIA (0 << 5) -#define CPIA_MODULE_SYSTEM (1 << 5) -#define CPIA_MODULE_VP_CTRL (5 << 5) -#define CPIA_MODULE_CAPTURE (6 << 5) -#define CPIA_MODULE_DEBUG (7 << 5) - -#define INPUT (DATA_IN << 8) -#define OUTPUT (DATA_OUT << 8) - -#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1) -#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2) -#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3) -#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4) -#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5) -#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7) -#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8) -#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10) - -#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1) -#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2) -#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3) -#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4) -#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5) -#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6) -#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7) -#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8) -#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9) -#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10) -#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11) -#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12) -#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13) - -#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1) -#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2) -#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3) -#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4) -#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6) -#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7) -#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8) -#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9) -#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10) -#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11) -#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16) -#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17) -#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18) -#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19) -#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25) -#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30) -#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31) - -#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1) -#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2) -#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3) -#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4) -#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5) -#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6) -#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7) -#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8) -#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9) -#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10) -#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11) -#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12) -#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13) -#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14) -#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15) - -#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1) -#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4) -#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5) -#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6) -#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8) -#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9) -#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10) -#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11) - -#define ROUND_UP_EXP_FOR_FLICKER 15 - -/* Constants for automatic frame rate adjustment */ -#define MAX_EXP 302 -#define MAX_EXP_102 255 -#define LOW_EXP 140 -#define VERY_LOW_EXP 70 -#define TC 94 -#define EXP_ACC_DARK 50 -#define EXP_ACC_LIGHT 90 -#define HIGH_COMP_102 160 -#define MAX_COMP 239 -#define DARK_TIME 3 -#define LIGHT_TIME 3 - -#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \ - sd->params.version.firmwareRevision == (y)) - -#define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000) -#define BRIGHTNESS_DEF 50 -#define CONTRAST_DEF 48 -#define SATURATION_DEF 50 -#define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ -#define ILLUMINATORS_1_DEF 0 -#define ILLUMINATORS_2_DEF 0 -#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY - -/* Developer's Guide Table 5 p 3-34 - * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ -static u8 flicker_jumps[2][2][4] = -{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } }, - { { 64, 32, 16, 8 }, { 76, 38, 19, 9} } -}; - -struct cam_params { - struct { - u8 firmwareVersion; - u8 firmwareRevision; - u8 vcVersion; - u8 vcRevision; - } version; - struct { - u16 vendor; - u16 product; - u16 deviceRevision; - } pnpID; - struct { - u8 vpVersion; - u8 vpRevision; - u16 cameraHeadID; - } vpVersion; - struct { - u8 systemState; - u8 grabState; - u8 streamState; - u8 fatalError; - u8 cmdError; - u8 debugFlags; - u8 vpStatus; - u8 errorCode; - } status; - struct { - u8 brightness; - u8 contrast; - u8 saturation; - } colourParams; - struct { - u8 gainMode; - u8 expMode; - u8 compMode; - u8 centreWeight; - u8 gain; - u8 fineExp; - u8 coarseExpLo; - u8 coarseExpHi; - u8 redComp; - u8 green1Comp; - u8 green2Comp; - u8 blueComp; - } exposure; - struct { - u8 balanceMode; - u8 redGain; - u8 greenGain; - u8 blueGain; - } colourBalance; - struct { - u8 divisor; - u8 baserate; - } sensorFps; - struct { - u8 gain1; - u8 gain2; - u8 gain4; - u8 gain8; - } apcor; - struct { - u8 disabled; - u8 flickerMode; - u8 coarseJump; - u8 allowableOverExposure; - } flickerControl; - struct { - u8 gain1; - u8 gain2; - u8 gain4; - u8 gain8; - } vlOffset; - struct { - u8 mode; - u8 decimation; - } compression; - struct { - u8 frTargeting; - u8 targetFR; - u8 targetQ; - } compressionTarget; - struct { - u8 yThreshold; - u8 uvThreshold; - } yuvThreshold; - struct { - u8 hysteresis; - u8 threshMax; - u8 smallStep; - u8 largeStep; - u8 decimationHysteresis; - u8 frDiffStepThresh; - u8 qDiffStepThresh; - u8 decimationThreshMod; - } compressionParams; - struct { - u8 videoSize; /* CIF/QCIF */ - u8 subSample; - u8 yuvOrder; - } format; - struct { /* Intel QX3 specific data */ - u8 qx3_detected; /* a QX3 is present */ - u8 toplight; /* top light lit , R/W */ - u8 bottomlight; /* bottom light lit, R/W */ - u8 button; /* snapshot button pressed (R/O) */ - u8 cradled; /* microscope is in cradle (R/O) */ - } qx3; - struct { - u8 colStart; /* skip first 8*colStart pixels */ - u8 colEnd; /* finish at 8*colEnd pixels */ - u8 rowStart; /* skip first 4*rowStart lines */ - u8 rowEnd; /* finish at 4*rowEnd lines */ - } roi; - u8 ecpTiming; - u8 streamStartLine; -}; - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct cam_params params; /* camera settings */ - - atomic_t cam_exposure; - atomic_t fps; - int exposure_count; - u8 exposure_status; - struct v4l2_ctrl *freq; - u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */ - u8 first_frame; -}; - -static const struct v4l2_pix_format mode[] = { - {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE, - /* The sizeimage is trial and error, as with low framerates - the camera will pad out usb frames, making the image - data larger then strictly necessary */ - .bytesperline = 160, - .sizeimage = 65536, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE, - .bytesperline = 172, - .sizeimage = 65536, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 262144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 262144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/********************************************************************** - * - * General functions - * - **********************************************************************/ - -static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command) -{ - u8 requesttype; - unsigned int pipe; - int ret, databytes = command[6] | (command[7] << 8); - /* Sometimes we see spurious EPIPE errors */ - int retries = 3; - - if (command[0] == DATA_IN) { - pipe = usb_rcvctrlpipe(gspca_dev->dev, 0); - requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - } else if (command[0] == DATA_OUT) { - pipe = usb_sndctrlpipe(gspca_dev->dev, 0); - requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE; - } else { - PDEBUG(D_ERR, "Unexpected first byte of command: %x", - command[0]); - return -EINVAL; - } - -retry: - ret = usb_control_msg(gspca_dev->dev, pipe, - command[1], - requesttype, - command[2] | (command[3] << 8), - command[4] | (command[5] << 8), - gspca_dev->usb_buf, databytes, 1000); - - if (ret < 0) - pr_err("usb_control_msg %02x, error %d\n", command[1], ret); - - if (ret == -EPIPE && retries > 0) { - retries--; - goto retry; - } - - return (ret < 0) ? ret : 0; -} - -/* send an arbitrary command to the camera */ -static int do_command(struct gspca_dev *gspca_dev, u16 command, - u8 a, u8 b, u8 c, u8 d) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret, datasize; - u8 cmd[8]; - - switch (command) { - case CPIA_COMMAND_GetCPIAVersion: - case CPIA_COMMAND_GetPnPID: - case CPIA_COMMAND_GetCameraStatus: - case CPIA_COMMAND_GetVPVersion: - case CPIA_COMMAND_GetColourParams: - case CPIA_COMMAND_GetColourBalance: - case CPIA_COMMAND_GetExposure: - datasize = 8; - break; - case CPIA_COMMAND_ReadMCPorts: - case CPIA_COMMAND_ReadVCRegs: - datasize = 4; - break; - default: - datasize = 0; - break; - } - - cmd[0] = command >> 8; - cmd[1] = command & 0xff; - cmd[2] = a; - cmd[3] = b; - cmd[4] = c; - cmd[5] = d; - cmd[6] = datasize; - cmd[7] = 0; - - ret = cpia_usb_transferCmd(gspca_dev, cmd); - if (ret) - return ret; - - switch (command) { - case CPIA_COMMAND_GetCPIAVersion: - sd->params.version.firmwareVersion = gspca_dev->usb_buf[0]; - sd->params.version.firmwareRevision = gspca_dev->usb_buf[1]; - sd->params.version.vcVersion = gspca_dev->usb_buf[2]; - sd->params.version.vcRevision = gspca_dev->usb_buf[3]; - break; - case CPIA_COMMAND_GetPnPID: - sd->params.pnpID.vendor = - gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8); - sd->params.pnpID.product = - gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8); - sd->params.pnpID.deviceRevision = - gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8); - break; - case CPIA_COMMAND_GetCameraStatus: - sd->params.status.systemState = gspca_dev->usb_buf[0]; - sd->params.status.grabState = gspca_dev->usb_buf[1]; - sd->params.status.streamState = gspca_dev->usb_buf[2]; - sd->params.status.fatalError = gspca_dev->usb_buf[3]; - sd->params.status.cmdError = gspca_dev->usb_buf[4]; - sd->params.status.debugFlags = gspca_dev->usb_buf[5]; - sd->params.status.vpStatus = gspca_dev->usb_buf[6]; - sd->params.status.errorCode = gspca_dev->usb_buf[7]; - break; - case CPIA_COMMAND_GetVPVersion: - sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0]; - sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1]; - sd->params.vpVersion.cameraHeadID = - gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8); - break; - case CPIA_COMMAND_GetColourParams: - sd->params.colourParams.brightness = gspca_dev->usb_buf[0]; - sd->params.colourParams.contrast = gspca_dev->usb_buf[1]; - sd->params.colourParams.saturation = gspca_dev->usb_buf[2]; - break; - case CPIA_COMMAND_GetColourBalance: - sd->params.colourBalance.redGain = gspca_dev->usb_buf[0]; - sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1]; - sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2]; - break; - case CPIA_COMMAND_GetExposure: - sd->params.exposure.gain = gspca_dev->usb_buf[0]; - sd->params.exposure.fineExp = gspca_dev->usb_buf[1]; - sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2]; - sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3]; - sd->params.exposure.redComp = gspca_dev->usb_buf[4]; - sd->params.exposure.green1Comp = gspca_dev->usb_buf[5]; - sd->params.exposure.green2Comp = gspca_dev->usb_buf[6]; - sd->params.exposure.blueComp = gspca_dev->usb_buf[7]; - break; - - case CPIA_COMMAND_ReadMCPorts: - /* test button press */ - a = ((gspca_dev->usb_buf[1] & 0x02) == 0); - if (a != sd->params.qx3.button) { -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - input_report_key(gspca_dev->input_dev, KEY_CAMERA, a); - input_sync(gspca_dev->input_dev); -#endif - sd->params.qx3.button = a; - } - if (sd->params.qx3.button) { - /* button pressed - unlock the latch */ - do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, - 3, 0xdf, 0xdf, 0); - do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, - 3, 0xff, 0xff, 0); - } - - /* test whether microscope is cradled */ - sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0); - break; - } - - return 0; -} - -/* send a command to the camera with an additional data transaction */ -static int do_command_extended(struct gspca_dev *gspca_dev, u16 command, - u8 a, u8 b, u8 c, u8 d, - u8 e, u8 f, u8 g, u8 h, - u8 i, u8 j, u8 k, u8 l) -{ - u8 cmd[8]; - - cmd[0] = command >> 8; - cmd[1] = command & 0xff; - cmd[2] = a; - cmd[3] = b; - cmd[4] = c; - cmd[5] = d; - cmd[6] = 8; - cmd[7] = 0; - gspca_dev->usb_buf[0] = e; - gspca_dev->usb_buf[1] = f; - gspca_dev->usb_buf[2] = g; - gspca_dev->usb_buf[3] = h; - gspca_dev->usb_buf[4] = i; - gspca_dev->usb_buf[5] = j; - gspca_dev->usb_buf[6] = k; - gspca_dev->usb_buf[7] = l; - - return cpia_usb_transferCmd(gspca_dev, cmd); -} - -/* find_over_exposure - * Finds a suitable value of OverExposure for use with SetFlickerCtrl - * Some calculation is required because this value changes with the brightness - * set with SetColourParameters - * - * Parameters: Brightness - last brightness value set with SetColourParameters - * - * Returns: OverExposure value to use with SetFlickerCtrl - */ -#define FLICKER_MAX_EXPOSURE 250 -#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146 -#define FLICKER_BRIGHTNESS_CONSTANT 59 -static int find_over_exposure(int brightness) -{ - int MaxAllowableOverExposure, OverExposure; - - MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness - - FLICKER_BRIGHTNESS_CONSTANT; - - if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) - OverExposure = MaxAllowableOverExposure; - else - OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE; - - return OverExposure; -} -#undef FLICKER_MAX_EXPOSURE -#undef FLICKER_ALLOWABLE_OVER_EXPOSURE -#undef FLICKER_BRIGHTNESS_CONSTANT - -/* initialise cam_data structure */ -static void reset_camera_params(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam_params *params = &sd->params; - - /* The following parameter values are the defaults from - * "Software Developer's Guide for CPiA Cameras". Any changes - * to the defaults are noted in comments. */ - params->colourParams.brightness = BRIGHTNESS_DEF; - params->colourParams.contrast = CONTRAST_DEF; - params->colourParams.saturation = SATURATION_DEF; - params->exposure.gainMode = 4; - params->exposure.expMode = 2; /* AEC */ - params->exposure.compMode = 1; - params->exposure.centreWeight = 1; - params->exposure.gain = 0; - params->exposure.fineExp = 0; - params->exposure.coarseExpLo = 185; - params->exposure.coarseExpHi = 0; - params->exposure.redComp = COMP_RED; - params->exposure.green1Comp = COMP_GREEN1; - params->exposure.green2Comp = COMP_GREEN2; - params->exposure.blueComp = COMP_BLUE; - params->colourBalance.balanceMode = 2; /* ACB */ - params->colourBalance.redGain = 32; - params->colourBalance.greenGain = 6; - params->colourBalance.blueGain = 92; - params->apcor.gain1 = 0x18; - params->apcor.gain2 = 0x16; - params->apcor.gain4 = 0x24; - params->apcor.gain8 = 0x34; - params->vlOffset.gain1 = 20; - params->vlOffset.gain2 = 24; - params->vlOffset.gain4 = 26; - params->vlOffset.gain8 = 26; - params->compressionParams.hysteresis = 3; - params->compressionParams.threshMax = 11; - params->compressionParams.smallStep = 1; - params->compressionParams.largeStep = 3; - params->compressionParams.decimationHysteresis = 2; - params->compressionParams.frDiffStepThresh = 5; - params->compressionParams.qDiffStepThresh = 3; - params->compressionParams.decimationThreshMod = 2; - /* End of default values from Software Developer's Guide */ - - /* Set Sensor FPS to 15fps. This seems better than 30fps - * for indoor lighting. */ - params->sensorFps.divisor = 1; - params->sensorFps.baserate = 1; - - params->flickerControl.flickerMode = 0; - params->flickerControl.disabled = 1; - params->flickerControl.coarseJump = - flicker_jumps[sd->mainsFreq] - [params->sensorFps.baserate] - [params->sensorFps.divisor]; - params->flickerControl.allowableOverExposure = - find_over_exposure(params->colourParams.brightness); - - params->yuvThreshold.yThreshold = 6; /* From windows driver */ - params->yuvThreshold.uvThreshold = 6; /* From windows driver */ - - params->format.subSample = SUBSAMPLE_420; - params->format.yuvOrder = YUVORDER_YUYV; - - params->compression.mode = CPIA_COMPRESSION_AUTO; - params->compression.decimation = NO_DECIMATION; - - params->compressionTarget.frTargeting = COMP_TARGET_DEF; - params->compressionTarget.targetFR = 15; /* From windows driver */ - params->compressionTarget.targetQ = 5; /* From windows driver */ - - params->qx3.qx3_detected = 0; - params->qx3.toplight = 0; - params->qx3.bottomlight = 0; - params->qx3.button = 0; - params->qx3.cradled = 0; -} - -static void printstatus(struct cam_params *params) -{ - PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x", - params->status.systemState, params->status.grabState, - params->status.streamState, params->status.fatalError, - params->status.cmdError, params->status.debugFlags, - params->status.vpStatus, params->status.errorCode); -} - -static int goto_low_power(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0); - if (ret) - return ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); - if (ret) - return ret; - - if (sd->params.status.systemState != LO_POWER_STATE) { - if (sd->params.status.systemState != WARM_BOOT_STATE) { - PDEBUG(D_ERR, - "unexpected state after lo power cmd: %02x", - sd->params.status.systemState); - printstatus(&sd->params); - } - return -EIO; - } - - PDEBUG(D_CONF, "camera now in LOW power state"); - return 0; -} - -static int goto_high_power(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0); - if (ret) - return ret; - - msleep_interruptible(40); /* windows driver does it too */ - - if (signal_pending(current)) - return -EINTR; - - do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); - if (ret) - return ret; - - if (sd->params.status.systemState != HI_POWER_STATE) { - PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x", - sd->params.status.systemState); - printstatus(&sd->params); - return -EIO; - } - - PDEBUG(D_CONF, "camera now in HIGH power state"); - return 0; -} - -static int get_version_information(struct gspca_dev *gspca_dev) -{ - int ret; - - /* GetCPIAVersion */ - ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0); - if (ret) - return ret; - - /* GetPnPID */ - return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0); -} - -static int save_camera_state(struct gspca_dev *gspca_dev) -{ - int ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0); - if (ret) - return ret; - - return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); -} - -static int command_setformat(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat, - sd->params.format.videoSize, - sd->params.format.subSample, - sd->params.format.yuvOrder, 0); - if (ret) - return ret; - - return do_command(gspca_dev, CPIA_COMMAND_SetROI, - sd->params.roi.colStart, sd->params.roi.colEnd, - sd->params.roi.rowStart, sd->params.roi.rowEnd); -} - -static int command_setcolourparams(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - return do_command(gspca_dev, CPIA_COMMAND_SetColourParams, - sd->params.colourParams.brightness, - sd->params.colourParams.contrast, - sd->params.colourParams.saturation, 0); -} - -static int command_setapcor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - return do_command(gspca_dev, CPIA_COMMAND_SetApcor, - sd->params.apcor.gain1, - sd->params.apcor.gain2, - sd->params.apcor.gain4, - sd->params.apcor.gain8); -} - -static int command_setvloffset(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset, - sd->params.vlOffset.gain1, - sd->params.vlOffset.gain2, - sd->params.vlOffset.gain4, - sd->params.vlOffset.gain8); -} - -static int command_setexposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure, - sd->params.exposure.gainMode, - 1, - sd->params.exposure.compMode, - sd->params.exposure.centreWeight, - sd->params.exposure.gain, - sd->params.exposure.fineExp, - sd->params.exposure.coarseExpLo, - sd->params.exposure.coarseExpHi, - sd->params.exposure.redComp, - sd->params.exposure.green1Comp, - sd->params.exposure.green2Comp, - sd->params.exposure.blueComp); - if (ret) - return ret; - - if (sd->params.exposure.expMode != 1) { - ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure, - 0, - sd->params.exposure.expMode, - 0, 0, - sd->params.exposure.gain, - sd->params.exposure.fineExp, - sd->params.exposure.coarseExpLo, - sd->params.exposure.coarseExpHi, - 0, 0, 0, 0); - } - - return ret; -} - -static int command_setcolourbalance(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->params.colourBalance.balanceMode == 1) { - int ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance, - 1, - sd->params.colourBalance.redGain, - sd->params.colourBalance.greenGain, - sd->params.colourBalance.blueGain); - if (ret) - return ret; - - return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance, - 3, 0, 0, 0); - } - if (sd->params.colourBalance.balanceMode == 2) { - return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance, - 2, 0, 0, 0); - } - if (sd->params.colourBalance.balanceMode == 3) { - return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance, - 3, 0, 0, 0); - } - - return -EINVAL; -} - -static int command_setcompressiontarget(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget, - sd->params.compressionTarget.frTargeting, - sd->params.compressionTarget.targetFR, - sd->params.compressionTarget.targetQ, 0); -} - -static int command_setyuvtresh(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh, - sd->params.yuvThreshold.yThreshold, - sd->params.yuvThreshold.uvThreshold, 0, 0); -} - -static int command_setcompressionparams(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command_extended(gspca_dev, - CPIA_COMMAND_SetCompressionParams, - 0, 0, 0, 0, - sd->params.compressionParams.hysteresis, - sd->params.compressionParams.threshMax, - sd->params.compressionParams.smallStep, - sd->params.compressionParams.largeStep, - sd->params.compressionParams.decimationHysteresis, - sd->params.compressionParams.frDiffStepThresh, - sd->params.compressionParams.qDiffStepThresh, - sd->params.compressionParams.decimationThreshMod); -} - -static int command_setcompression(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetCompression, - sd->params.compression.mode, - sd->params.compression.decimation, 0, 0); -} - -static int command_setsensorfps(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS, - sd->params.sensorFps.divisor, - sd->params.sensorFps.baserate, 0, 0); -} - -static int command_setflickerctrl(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl, - sd->params.flickerControl.flickerMode, - sd->params.flickerControl.coarseJump, - sd->params.flickerControl.allowableOverExposure, - 0); -} - -static int command_setecptiming(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming, - sd->params.ecpTiming, 0, 0, 0); -} - -static int command_pause(struct gspca_dev *gspca_dev) -{ - return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0); -} - -static int command_resume(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap, - 0, sd->params.streamStartLine, 0, 0); -} - -static int command_setlights(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret, p1, p2; - - p1 = (sd->params.qx3.bottomlight == 0) << 1; - p2 = (sd->params.qx3.toplight == 0) << 3; - - ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg, - 0x90, 0x8f, 0x50, 0); - if (ret) - return ret; - - return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, - p1 | p2 | 0xe0, 0); -} - -static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) -{ - /* Everything in here is from the Windows driver */ -/* define for compgain calculation */ -#if 0 -#define COMPGAIN(base, curexp, newexp) \ - (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5) -#define EXP_FROM_COMP(basecomp, curcomp, curexp) \ - (u16)((float)curexp * (float)(u8)(curcomp + 128) / \ - (float)(u8)(basecomp - 128)) -#else - /* equivalent functions without floating point math */ -#define COMPGAIN(base, curexp, newexp) \ - (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp))) -#define EXP_FROM_COMP(basecomp, curcomp, curexp) \ - (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128))) -#endif - - struct sd *sd = (struct sd *) gspca_dev; - int currentexp = sd->params.exposure.coarseExpLo + - sd->params.exposure.coarseExpHi * 256; - int ret, startexp; - - if (on) { - int cj = sd->params.flickerControl.coarseJump; - sd->params.flickerControl.flickerMode = 1; - sd->params.flickerControl.disabled = 0; - if (sd->params.exposure.expMode != 2) { - sd->params.exposure.expMode = 2; - sd->exposure_status = EXPOSURE_NORMAL; - } - currentexp = currentexp << sd->params.exposure.gain; - sd->params.exposure.gain = 0; - /* round down current exposure to nearest value */ - startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj; - if (startexp < 1) - startexp = 1; - startexp = (startexp * cj) - 1; - if (FIRMWARE_VERSION(1, 2)) - while (startexp > MAX_EXP_102) - startexp -= cj; - else - while (startexp > MAX_EXP) - startexp -= cj; - sd->params.exposure.coarseExpLo = startexp & 0xff; - sd->params.exposure.coarseExpHi = startexp >> 8; - if (currentexp > startexp) { - if (currentexp > (2 * startexp)) - currentexp = 2 * startexp; - sd->params.exposure.redComp = - COMPGAIN(COMP_RED, currentexp, startexp); - sd->params.exposure.green1Comp = - COMPGAIN(COMP_GREEN1, currentexp, startexp); - sd->params.exposure.green2Comp = - COMPGAIN(COMP_GREEN2, currentexp, startexp); - sd->params.exposure.blueComp = - COMPGAIN(COMP_BLUE, currentexp, startexp); - } else { - sd->params.exposure.redComp = COMP_RED; - sd->params.exposure.green1Comp = COMP_GREEN1; - sd->params.exposure.green2Comp = COMP_GREEN2; - sd->params.exposure.blueComp = COMP_BLUE; - } - if (FIRMWARE_VERSION(1, 2)) - sd->params.exposure.compMode = 0; - else - sd->params.exposure.compMode = 1; - - sd->params.apcor.gain1 = 0x18; - sd->params.apcor.gain2 = 0x18; - sd->params.apcor.gain4 = 0x16; - sd->params.apcor.gain8 = 0x14; - } else { - sd->params.flickerControl.flickerMode = 0; - sd->params.flickerControl.disabled = 1; - /* Average equivalent coarse for each comp channel */ - startexp = EXP_FROM_COMP(COMP_RED, - sd->params.exposure.redComp, currentexp); - startexp += EXP_FROM_COMP(COMP_GREEN1, - sd->params.exposure.green1Comp, currentexp); - startexp += EXP_FROM_COMP(COMP_GREEN2, - sd->params.exposure.green2Comp, currentexp); - startexp += EXP_FROM_COMP(COMP_BLUE, - sd->params.exposure.blueComp, currentexp); - startexp = startexp >> 2; - while (startexp > MAX_EXP && sd->params.exposure.gain < - sd->params.exposure.gainMode - 1) { - startexp = startexp >> 1; - ++sd->params.exposure.gain; - } - if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102) - startexp = MAX_EXP_102; - if (startexp > MAX_EXP) - startexp = MAX_EXP; - sd->params.exposure.coarseExpLo = startexp & 0xff; - sd->params.exposure.coarseExpHi = startexp >> 8; - sd->params.exposure.redComp = COMP_RED; - sd->params.exposure.green1Comp = COMP_GREEN1; - sd->params.exposure.green2Comp = COMP_GREEN2; - sd->params.exposure.blueComp = COMP_BLUE; - sd->params.exposure.compMode = 1; - sd->params.apcor.gain1 = 0x18; - sd->params.apcor.gain2 = 0x16; - sd->params.apcor.gain4 = 0x24; - sd->params.apcor.gain8 = 0x34; - } - sd->params.vlOffset.gain1 = 20; - sd->params.vlOffset.gain2 = 24; - sd->params.vlOffset.gain4 = 26; - sd->params.vlOffset.gain8 = 26; - - if (apply) { - ret = command_setexposure(gspca_dev); - if (ret) - return ret; - - ret = command_setapcor(gspca_dev); - if (ret) - return ret; - - ret = command_setvloffset(gspca_dev); - if (ret) - return ret; - - ret = command_setflickerctrl(gspca_dev); - if (ret) - return ret; - } - - return 0; -#undef EXP_FROM_COMP -#undef COMPGAIN -} - -/* monitor the exposure and adjust the sensor frame rate if needed */ -static void monitor_exposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 exp_acc, bcomp, cmd[8]; - int ret, light_exp, dark_exp, very_dark_exp; - int old_exposure, new_exposure, framerate; - int setfps = 0, setexp = 0, setflicker = 0; - - /* get necessary stats and register settings from camera */ - /* do_command can't handle this, so do it ourselves */ - cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8; - cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff; - cmd[2] = 30; - cmd[3] = 4; - cmd[4] = 9; - cmd[5] = 8; - cmd[6] = 8; - cmd[7] = 0; - ret = cpia_usb_transferCmd(gspca_dev, cmd); - if (ret) { - pr_err("ReadVPRegs(30,4,9,8) - failed: %d\n", ret); - return; - } - exp_acc = gspca_dev->usb_buf[0]; - bcomp = gspca_dev->usb_buf[1]; - - light_exp = sd->params.colourParams.brightness + - TC - 50 + EXP_ACC_LIGHT; - if (light_exp > 255) - light_exp = 255; - dark_exp = sd->params.colourParams.brightness + - TC - 50 - EXP_ACC_DARK; - if (dark_exp < 0) - dark_exp = 0; - very_dark_exp = dark_exp / 2; - - old_exposure = sd->params.exposure.coarseExpHi * 256 + - sd->params.exposure.coarseExpLo; - - if (!sd->params.flickerControl.disabled) { - /* Flicker control on */ - int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP : - HIGH_COMP_102; - bcomp += 128; /* decode */ - if (bcomp >= max_comp && exp_acc < dark_exp) { - /* dark */ - if (exp_acc < very_dark_exp) { - /* very dark */ - if (sd->exposure_status == EXPOSURE_VERY_DARK) - ++sd->exposure_count; - else { - sd->exposure_status = - EXPOSURE_VERY_DARK; - sd->exposure_count = 1; - } - } else { - /* just dark */ - if (sd->exposure_status == EXPOSURE_DARK) - ++sd->exposure_count; - else { - sd->exposure_status = EXPOSURE_DARK; - sd->exposure_count = 1; - } - } - } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) { - /* light */ - if (old_exposure <= VERY_LOW_EXP) { - /* very light */ - if (sd->exposure_status == EXPOSURE_VERY_LIGHT) - ++sd->exposure_count; - else { - sd->exposure_status = - EXPOSURE_VERY_LIGHT; - sd->exposure_count = 1; - } - } else { - /* just light */ - if (sd->exposure_status == EXPOSURE_LIGHT) - ++sd->exposure_count; - else { - sd->exposure_status = EXPOSURE_LIGHT; - sd->exposure_count = 1; - } - } - } else { - /* not dark or light */ - sd->exposure_status = EXPOSURE_NORMAL; - } - } else { - /* Flicker control off */ - if (old_exposure >= MAX_EXP && exp_acc < dark_exp) { - /* dark */ - if (exp_acc < very_dark_exp) { - /* very dark */ - if (sd->exposure_status == EXPOSURE_VERY_DARK) - ++sd->exposure_count; - else { - sd->exposure_status = - EXPOSURE_VERY_DARK; - sd->exposure_count = 1; - } - } else { - /* just dark */ - if (sd->exposure_status == EXPOSURE_DARK) - ++sd->exposure_count; - else { - sd->exposure_status = EXPOSURE_DARK; - sd->exposure_count = 1; - } - } - } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) { - /* light */ - if (old_exposure <= VERY_LOW_EXP) { - /* very light */ - if (sd->exposure_status == EXPOSURE_VERY_LIGHT) - ++sd->exposure_count; - else { - sd->exposure_status = - EXPOSURE_VERY_LIGHT; - sd->exposure_count = 1; - } - } else { - /* just light */ - if (sd->exposure_status == EXPOSURE_LIGHT) - ++sd->exposure_count; - else { - sd->exposure_status = EXPOSURE_LIGHT; - sd->exposure_count = 1; - } - } - } else { - /* not dark or light */ - sd->exposure_status = EXPOSURE_NORMAL; - } - } - - framerate = atomic_read(&sd->fps); - if (framerate > 30 || framerate < 1) - framerate = 1; - - if (!sd->params.flickerControl.disabled) { - /* Flicker control on */ - if ((sd->exposure_status == EXPOSURE_VERY_DARK || - sd->exposure_status == EXPOSURE_DARK) && - sd->exposure_count >= DARK_TIME * framerate && - sd->params.sensorFps.divisor < 2) { - - /* dark for too long */ - ++sd->params.sensorFps.divisor; - setfps = 1; - - sd->params.flickerControl.coarseJump = - flicker_jumps[sd->mainsFreq] - [sd->params.sensorFps.baserate] - [sd->params.sensorFps.divisor]; - setflicker = 1; - - new_exposure = sd->params.flickerControl.coarseJump-1; - while (new_exposure < old_exposure / 2) - new_exposure += - sd->params.flickerControl.coarseJump; - sd->params.exposure.coarseExpLo = new_exposure & 0xff; - sd->params.exposure.coarseExpHi = new_exposure >> 8; - setexp = 1; - sd->exposure_status = EXPOSURE_NORMAL; - PDEBUG(D_CONF, "Automatically decreasing sensor_fps"); - - } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT || - sd->exposure_status == EXPOSURE_LIGHT) && - sd->exposure_count >= LIGHT_TIME * framerate && - sd->params.sensorFps.divisor > 0) { - - /* light for too long */ - int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 : - MAX_EXP; - --sd->params.sensorFps.divisor; - setfps = 1; - - sd->params.flickerControl.coarseJump = - flicker_jumps[sd->mainsFreq] - [sd->params.sensorFps.baserate] - [sd->params.sensorFps.divisor]; - setflicker = 1; - - new_exposure = sd->params.flickerControl.coarseJump-1; - while (new_exposure < 2 * old_exposure && - new_exposure + - sd->params.flickerControl.coarseJump < max_exp) - new_exposure += - sd->params.flickerControl.coarseJump; - sd->params.exposure.coarseExpLo = new_exposure & 0xff; - sd->params.exposure.coarseExpHi = new_exposure >> 8; - setexp = 1; - sd->exposure_status = EXPOSURE_NORMAL; - PDEBUG(D_CONF, "Automatically increasing sensor_fps"); - } - } else { - /* Flicker control off */ - if ((sd->exposure_status == EXPOSURE_VERY_DARK || - sd->exposure_status == EXPOSURE_DARK) && - sd->exposure_count >= DARK_TIME * framerate && - sd->params.sensorFps.divisor < 2) { - - /* dark for too long */ - ++sd->params.sensorFps.divisor; - setfps = 1; - - if (sd->params.exposure.gain > 0) { - --sd->params.exposure.gain; - setexp = 1; - } - sd->exposure_status = EXPOSURE_NORMAL; - PDEBUG(D_CONF, "Automatically decreasing sensor_fps"); - - } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT || - sd->exposure_status == EXPOSURE_LIGHT) && - sd->exposure_count >= LIGHT_TIME * framerate && - sd->params.sensorFps.divisor > 0) { - - /* light for too long */ - --sd->params.sensorFps.divisor; - setfps = 1; - - if (sd->params.exposure.gain < - sd->params.exposure.gainMode - 1) { - ++sd->params.exposure.gain; - setexp = 1; - } - sd->exposure_status = EXPOSURE_NORMAL; - PDEBUG(D_CONF, "Automatically increasing sensor_fps"); - } - } - - if (setexp) - command_setexposure(gspca_dev); - - if (setfps) - command_setsensorfps(gspca_dev); - - if (setflicker) - command_setflickerctrl(gspca_dev); -} - -/*-----------------------------------------------------------------*/ -/* if flicker is switched off, this function switches it back on.It checks, - however, that conditions are suitable before restarting it. - This should only be called for firmware version 1.2. - - It also adjust the colour balance when an exposure step is detected - as - long as flicker is running -*/ -static void restart_flicker(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int cam_exposure, old_exp; - - if (!FIRMWARE_VERSION(1, 2)) - return; - - cam_exposure = atomic_read(&sd->cam_exposure); - - if (sd->params.flickerControl.flickerMode == 0 || - cam_exposure == 0) - return; - - old_exp = sd->params.exposure.coarseExpLo + - sd->params.exposure.coarseExpHi*256; - /* - see how far away camera exposure is from a valid - flicker exposure value - */ - cam_exposure %= sd->params.flickerControl.coarseJump; - if (!sd->params.flickerControl.disabled && - cam_exposure <= sd->params.flickerControl.coarseJump - 3) { - /* Flicker control auto-disabled */ - sd->params.flickerControl.disabled = 1; - } - - if (sd->params.flickerControl.disabled && - old_exp > sd->params.flickerControl.coarseJump + - ROUND_UP_EXP_FOR_FLICKER) { - /* exposure is now high enough to switch - flicker control back on */ - set_flicker(gspca_dev, 1, 1); - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; - reset_camera_params(gspca_dev); - - PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)", - id->idVendor, id->idProduct); - - cam = &gspca_dev->cam; - cam->cam_mode = mode; - cam->nmodes = ARRAY_SIZE(mode); - - goto_low_power(gspca_dev); - /* Check the firmware version. */ - sd->params.version.firmwareVersion = 0; - get_version_information(gspca_dev); - if (sd->params.version.firmwareVersion != 1) { - PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", - sd->params.version.firmwareVersion); - return -ENODEV; - } - - /* A bug in firmware 1-02 limits gainMode to 2 */ - if (sd->params.version.firmwareRevision <= 2 && - sd->params.exposure.gainMode > 2) { - sd->params.exposure.gainMode = 2; - } - - /* set QX3 detected flag */ - sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && - sd->params.pnpID.product == 0x0001); - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int priv, ret; - - /* Start the camera in low power mode */ - if (goto_low_power(gspca_dev)) { - if (sd->params.status.systemState != WARM_BOOT_STATE) { - PDEBUG(D_ERR, "unexpected systemstate: %02x", - sd->params.status.systemState); - printstatus(&sd->params); - return -ENODEV; - } - - /* FIXME: this is just dirty trial and error */ - ret = goto_high_power(gspca_dev); - if (ret) - return ret; - - ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame, - 0, 0, 0, 0); - if (ret) - return ret; - - ret = goto_low_power(gspca_dev); - if (ret) - return ret; - } - - /* procedure described in developer's guide p3-28 */ - - /* Check the firmware version. */ - sd->params.version.firmwareVersion = 0; - get_version_information(gspca_dev); - - /* The fatal error checking should be done after - * the camera powers up (developer's guide p 3-38) */ - - /* Set streamState before transition to high power to avoid bug - * in firmware 1-02 */ - ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus, - STREAMSTATE, 0, STREAM_NOT_READY, 0); - if (ret) - return ret; - - /* GotoHiPower */ - ret = goto_high_power(gspca_dev); - if (ret) - return ret; - - /* Check the camera status */ - ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); - if (ret) - return ret; - - if (sd->params.status.fatalError) { - PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x", - sd->params.status.fatalError, - sd->params.status.vpStatus); - return -EIO; - } - - /* VPVersion can't be retrieved before the camera is in HiPower, - * so get it here instead of in get_version_information. */ - ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0); - if (ret) - return ret; - - /* Determine video mode settings */ - sd->params.streamStartLine = 120; - - priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - if (priv & 0x01) { /* crop */ - sd->params.roi.colStart = 2; - sd->params.roi.rowStart = 6; - } else { - sd->params.roi.colStart = 0; - sd->params.roi.rowStart = 0; - } - - if (priv & 0x02) { /* quarter */ - sd->params.format.videoSize = VIDEOSIZE_QCIF; - sd->params.roi.colStart /= 2; - sd->params.roi.rowStart /= 2; - sd->params.streamStartLine /= 2; - } else - sd->params.format.videoSize = VIDEOSIZE_CIF; - - sd->params.roi.colEnd = sd->params.roi.colStart + - (gspca_dev->width >> 3); - sd->params.roi.rowEnd = sd->params.roi.rowStart + - (gspca_dev->height >> 2); - - /* And now set the camera to a known state */ - ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode, - CPIA_GRAB_CONTINEOUS, 0, 0, 0); - if (ret) - return ret; - /* We start with compression disabled, as we need one uncompressed - frame to handle later compressed frames */ - ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression, - CPIA_COMPRESSION_NONE, - NO_DECIMATION, 0, 0); - if (ret) - return ret; - ret = command_setcompressiontarget(gspca_dev); - if (ret) - return ret; - ret = command_setcolourparams(gspca_dev); - if (ret) - return ret; - ret = command_setformat(gspca_dev); - if (ret) - return ret; - ret = command_setyuvtresh(gspca_dev); - if (ret) - return ret; - ret = command_setecptiming(gspca_dev); - if (ret) - return ret; - ret = command_setcompressionparams(gspca_dev); - if (ret) - return ret; - ret = command_setexposure(gspca_dev); - if (ret) - return ret; - ret = command_setcolourbalance(gspca_dev); - if (ret) - return ret; - ret = command_setsensorfps(gspca_dev); - if (ret) - return ret; - ret = command_setapcor(gspca_dev); - if (ret) - return ret; - ret = command_setflickerctrl(gspca_dev); - if (ret) - return ret; - ret = command_setvloffset(gspca_dev); - if (ret) - return ret; - - /* Start stream */ - ret = command_resume(gspca_dev); - if (ret) - return ret; - - /* Wait 6 frames before turning compression on for the sensor to get - all settings and AEC/ACB to settle */ - sd->first_frame = 6; - sd->exposure_status = EXPOSURE_NORMAL; - sd->exposure_count = 0; - atomic_set(&sd->cam_exposure, 0); - atomic_set(&sd->fps, 0); - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - command_pause(gspca_dev); - - /* save camera state for later open (developers guide ch 3.5.3) */ - save_camera_state(gspca_dev); - - /* GotoLoPower */ - goto_low_power(gspca_dev); - - /* Update the camera status */ - do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - /* If the last button state is pressed, release it now! */ - if (sd->params.qx3.button) { - /* The camera latch will hold the pressed state until we reset - the latch, so we do not reset sd->params.qx3.button now, to - avoid a false keypress being reported the next sd_start */ - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - } -#endif -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - /* Start / Stop the camera to make sure we are talking to - a supported camera, and to get some information from it - to print. */ - ret = sd_start(gspca_dev); - if (ret) - return ret; - - /* Ensure the QX3 illuminators' states are restored upon resume, - or disable the illuminator controls, if this isn't a QX3 */ - if (sd->params.qx3.qx3_detected) - command_setlights(gspca_dev); - - sd_stopN(gspca_dev); - - PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)", - sd->params.version.firmwareVersion, - sd->params.version.firmwareRevision, - sd->params.version.vcVersion, - sd->params.version.vcRevision); - PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x", - sd->params.pnpID.vendor, sd->params.pnpID.product, - sd->params.pnpID.deviceRevision); - PDEBUG(D_PROBE, "VP-Version: %d.%d %04x", - sd->params.vpVersion.vpVersion, - sd->params.vpVersion.vpRevision, - sd->params.vpVersion.cameraHeadID); - - return 0; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Check for SOF */ - if (len >= 64 && - data[0] == MAGIC_0 && data[1] == MAGIC_1 && - data[16] == sd->params.format.videoSize && - data[17] == sd->params.format.subSample && - data[18] == sd->params.format.yuvOrder && - data[24] == sd->params.roi.colStart && - data[25] == sd->params.roi.colEnd && - data[26] == sd->params.roi.rowStart && - data[27] == sd->params.roi.rowEnd) { - u8 *image; - - atomic_set(&sd->cam_exposure, data[39] * 2); - atomic_set(&sd->fps, data[41]); - - /* Check for proper EOF for last frame */ - image = gspca_dev->image; - if (image != NULL && - gspca_dev->image_len > 4 && - image[gspca_dev->image_len - 4] == 0xff && - image[gspca_dev->image_len - 3] == 0xff && - image[gspca_dev->image_len - 2] == 0xff && - image[gspca_dev->image_len - 1] == 0xff) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - return; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void sd_dq_callback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Set the normal compression settings once we have captured a - few uncompressed frames (and AEC has hopefully settled) */ - if (sd->first_frame) { - sd->first_frame--; - if (sd->first_frame == 0) - command_setcompression(gspca_dev); - } - - /* Switch flicker control back on if it got turned off */ - restart_flicker(gspca_dev); - - /* If AEC is enabled, monitor the exposure and - adjust the sensor frame rate if needed */ - if (sd->params.exposure.expMode == 2) - monitor_exposure(gspca_dev); - - /* Update our knowledge of the camera state */ - do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); - do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - sd->params.colourParams.brightness = ctrl->val; - sd->params.flickerControl.allowableOverExposure = - find_over_exposure(sd->params.colourParams.brightness); - gspca_dev->usb_err = command_setcolourparams(gspca_dev); - if (!gspca_dev->usb_err) - gspca_dev->usb_err = command_setflickerctrl(gspca_dev); - break; - case V4L2_CID_CONTRAST: - sd->params.colourParams.contrast = ctrl->val; - gspca_dev->usb_err = command_setcolourparams(gspca_dev); - break; - case V4L2_CID_SATURATION: - sd->params.colourParams.saturation = ctrl->val; - gspca_dev->usb_err = command_setcolourparams(gspca_dev); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; - sd->params.flickerControl.coarseJump = - flicker_jumps[sd->mainsFreq] - [sd->params.sensorFps.baserate] - [sd->params.sensorFps.divisor]; - - gspca_dev->usb_err = set_flicker(gspca_dev, - ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, - gspca_dev->streaming); - break; - case V4L2_CID_ILLUMINATORS_1: - sd->params.qx3.bottomlight = ctrl->val; - gspca_dev->usb_err = command_setlights(gspca_dev); - break; - case V4L2_CID_ILLUMINATORS_2: - sd->params.qx3.toplight = ctrl->val; - gspca_dev->usb_err = command_setlights(gspca_dev); - break; - case CPIA1_CID_COMP_TARGET: - sd->params.compressionTarget.frTargeting = ctrl->val; - gspca_dev->usb_err = command_setcompressiontarget(gspca_dev); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - static const char * const comp_target_menu[] = { - "Quality", - "Framerate", - NULL - }; - static const struct v4l2_ctrl_config comp_target = { - .ops = &sd_ctrl_ops, - .id = CPIA1_CID_COMP_TARGET, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Compression Target", - .qmenu = comp_target_menu, - .max = 1, - .def = COMP_TARGET_DEF, - }; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 7); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF); - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, - FREQ_DEF); - if (sd->params.qx3.qx3_detected) { - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_ILLUMINATORS_1, 0, 1, 1, - ILLUMINATORS_1_DEF); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_ILLUMINATORS_2, 0, 1, 1, - ILLUMINATORS_2_DEF); - } - v4l2_ctrl_new_custom(hdl, &comp_target, NULL); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .dq_callback = sd_dq_callback, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0553, 0x0002)}, - {USB_DEVICE(0x0813, 0x0001)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c deleted file mode 100644 index 38f68e11c3a2..000000000000 --- a/drivers/media/video/gspca/etoms.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004) - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "etoms" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("Etoms USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - unsigned char autogain; - - char sensor; -#define SENSOR_PAS106 0 -#define SENSOR_TAS5130CXX 1 - signed char ag_cnt; -#define AG_CNT_START 13 -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, -/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, */ -}; - -static const struct v4l2_pix_format sif_mode[] = { - {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -#define ETOMS_ALT_SIZE_1000 12 - -#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */ -#define ET_GPIO_OUT 0x05 /* Only IO data */ -#define ET_GPIO_IN 0x06 /* Read Only IO data */ -#define ET_RESET_ALL 0x03 -#define ET_ClCK 0x01 -#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */ - -#define ET_COMP 0x12 /* Compression register */ -#define ET_MAXQt 0x13 -#define ET_MINQt 0x14 -#define ET_COMP_VAL0 0x02 -#define ET_COMP_VAL1 0x03 - -#define ET_REG1d 0x1d -#define ET_REG1e 0x1e -#define ET_REG1f 0x1f -#define ET_REG20 0x20 -#define ET_REG21 0x21 -#define ET_REG22 0x22 -#define ET_REG23 0x23 -#define ET_REG24 0x24 -#define ET_REG25 0x25 -/* base registers for luma calculation */ -#define ET_LUMA_CENTER 0x39 - -#define ET_G_RED 0x4d -#define ET_G_GREEN1 0x4e -#define ET_G_BLUE 0x4f -#define ET_G_GREEN2 0x50 -#define ET_G_GR_H 0x51 -#define ET_G_GB_H 0x52 - -#define ET_O_RED 0x34 -#define ET_O_GREEN1 0x35 -#define ET_O_BLUE 0x36 -#define ET_O_GREEN2 0x37 - -#define ET_SYNCHRO 0x68 -#define ET_STARTX 0x69 -#define ET_STARTY 0x6a -#define ET_WIDTH_LOW 0x6b -#define ET_HEIGTH_LOW 0x6c -#define ET_W_H_HEIGTH 0x6d - -#define ET_REG6e 0x6e /* OBW */ -#define ET_REG6f 0x6f /* OBW */ -#define ET_REG70 0x70 /* OBW_AWB */ -#define ET_REG71 0x71 /* OBW_AWB */ -#define ET_REG72 0x72 /* OBW_AWB */ -#define ET_REG73 0x73 /* Clkdelay ns */ -#define ET_REG74 0x74 /* test pattern */ -#define ET_REG75 0x75 /* test pattern */ - -#define ET_I2C_CLK 0x8c -#define ET_PXL_CLK 0x60 - -#define ET_I2C_BASE 0x89 -#define ET_I2C_COUNT 0x8a -#define ET_I2C_PREFETCH 0x8b -#define ET_I2C_REG 0x88 -#define ET_I2C_DATA7 0x87 -#define ET_I2C_DATA6 0x86 -#define ET_I2C_DATA5 0x85 -#define ET_I2C_DATA4 0x84 -#define ET_I2C_DATA3 0x83 -#define ET_I2C_DATA2 0x82 -#define ET_I2C_DATA1 0x81 -#define ET_I2C_DATA0 0x80 - -#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */ -#define PAS106_REG3 0x03 /* line/frame H [11..4] */ -#define PAS106_REG4 0x04 /* line/frame L [3..0] */ -#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */ -#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */ -#define PAS106_REG7 0x07 /* signbit Dac (default 0) */ -#define PAS106_REG9 0x09 -#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ -#define PAS106_REG13 0x13 /* end i2c write */ - -static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; - -static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; - -static const __u8 I2c3[] = { 0x12, 0x05 }; - -static const __u8 I2c4[] = { 0x41, 0x08 }; - -/* read 'len' bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 index, - __u16 len) -{ - struct usb_device *dev = gspca_dev->dev; - -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); - return; - } -#endif - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), - 0, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, - index, gspca_dev->usb_buf, len, 500); - PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", - index, gspca_dev->usb_buf[0]); -} - -static void reg_w_val(struct gspca_dev *gspca_dev, - __u16 index, - __u8 val) -{ - struct usb_device *dev = gspca_dev->dev; - - gspca_dev->usb_buf[0] = val; - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, - index, gspca_dev->usb_buf, 1, 500); -} - -static void reg_w(struct gspca_dev *gspca_dev, - __u16 index, - const __u8 *buffer, - __u16 len) -{ - struct usb_device *dev = gspca_dev->dev; - -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_w: buffer overflow\n"); - return; - } - PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); -#endif - memcpy(gspca_dev->usb_buf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, gspca_dev->usb_buf, len, 500); -} - -static int i2c_w(struct gspca_dev *gspca_dev, - __u8 reg, - const __u8 *buffer, - int len, __u8 mode) -{ - /* buffer should be [D0..D7] */ - __u8 ptchcount; - - /* set the base address */ - reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); - /* sensor base for the pas106 */ - /* set count and prefetch */ - ptchcount = ((len & 0x07) << 4) | (mode & 0x03); - reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount); - /* set the register base */ - reg_w_val(gspca_dev, ET_I2C_REG, reg); - while (--len >= 0) - reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]); - return 0; -} - -static int i2c_r(struct gspca_dev *gspca_dev, - __u8 reg) -{ - /* set the base address */ - reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); - /* sensor base for the pas106 */ - /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */ - reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11); - reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */ - reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ - reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00); - reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */ - return 0; -} - -static int Et_WaitStatus(struct gspca_dev *gspca_dev) -{ - int retry = 10; - - while (retry--) { - reg_r(gspca_dev, ET_ClCK, 1); - if (gspca_dev->usb_buf[0] != 0) - return 1; - } - return 0; -} - -static int et_video(struct gspca_dev *gspca_dev, - int on) -{ - int ret; - - reg_w_val(gspca_dev, ET_GPIO_OUT, - on ? 0x10 /* startvideo - set Bit5 */ - : 0); /* stopvideo */ - ret = Et_WaitStatus(gspca_dev); - if (ret != 0) - PDEBUG(D_ERR, "timeout video on/off"); - return ret; -} - -static void Et_init2(struct gspca_dev *gspca_dev) -{ - __u8 value; - static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; - - PDEBUG(D_STREAM, "Open Init2 ET"); - reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f); - reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10); - reg_r(gspca_dev, ET_GPIO_IN, 1); - reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ - reg_w_val(gspca_dev, ET_CTRL, 0x1b); - - /* compression et subsampling */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) - value = ET_COMP_VAL1; /* 320 */ - else - value = ET_COMP_VAL0; /* 640 */ - reg_w_val(gspca_dev, ET_COMP, value); - reg_w_val(gspca_dev, ET_MAXQt, 0x1f); - reg_w_val(gspca_dev, ET_MINQt, 0x04); - /* undocumented registers */ - reg_w_val(gspca_dev, ET_REG1d, 0xff); - reg_w_val(gspca_dev, ET_REG1e, 0xff); - reg_w_val(gspca_dev, ET_REG1f, 0xff); - reg_w_val(gspca_dev, ET_REG20, 0x35); - reg_w_val(gspca_dev, ET_REG21, 0x01); - reg_w_val(gspca_dev, ET_REG22, 0x00); - reg_w_val(gspca_dev, ET_REG23, 0xff); - reg_w_val(gspca_dev, ET_REG24, 0xff); - reg_w_val(gspca_dev, ET_REG25, 0x0f); - /* colors setting */ - reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */ - reg_w_val(gspca_dev, 0x31, 0x40); - reg_w_val(gspca_dev, 0x32, 0x00); - reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */ - reg_w_val(gspca_dev, ET_O_GREEN1, 0x00); - reg_w_val(gspca_dev, ET_O_BLUE, 0x00); - reg_w_val(gspca_dev, ET_O_GREEN2, 0x00); - /*************/ - reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */ - reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); - reg_w_val(gspca_dev, ET_G_BLUE, 0x80); - reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); - reg_w_val(gspca_dev, ET_G_GR_H, 0x00); - reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */ - /* Window control registers */ - reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */ - reg_w_val(gspca_dev, 0x62, 0x02); - reg_w_val(gspca_dev, 0x63, 0x03); - reg_w_val(gspca_dev, 0x64, 0x14); - reg_w_val(gspca_dev, 0x65, 0x0e); - reg_w_val(gspca_dev, 0x66, 0x02); - reg_w_val(gspca_dev, 0x67, 0x02); - - /**************************************/ - reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */ - reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ - reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ - reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80); - reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0); - reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */ - reg_w_val(gspca_dev, ET_REG6e, 0x86); - reg_w_val(gspca_dev, ET_REG6f, 0x01); - reg_w_val(gspca_dev, ET_REG70, 0x26); - reg_w_val(gspca_dev, ET_REG71, 0x7a); - reg_w_val(gspca_dev, ET_REG72, 0x01); - /* Clock Pattern registers ***************** */ - reg_w_val(gspca_dev, ET_REG73, 0x00); - reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */ - reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */ - /**********************************************/ - reg_w_val(gspca_dev, 0x8a, 0x20); - reg_w_val(gspca_dev, 0x8d, 0x0f); - reg_w_val(gspca_dev, 0x8e, 0x08); - /**************************************/ - reg_w_val(gspca_dev, 0x03, 0x08); - reg_w_val(gspca_dev, ET_PXL_CLK, 0x03); - reg_w_val(gspca_dev, 0x81, 0xff); - reg_w_val(gspca_dev, 0x80, 0x00); - reg_w_val(gspca_dev, 0x81, 0xff); - reg_w_val(gspca_dev, 0x80, 0x20); - reg_w_val(gspca_dev, 0x03, 0x01); - reg_w_val(gspca_dev, 0x03, 0x00); - reg_w_val(gspca_dev, 0x03, 0x08); - /********************************************/ - -/* reg_r(gspca_dev, ET_I2C_BASE, 1); - always 0x40 as the pas106 ??? */ - /* set the sensor */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) - value = 0x04; /* 320 */ - else /* 640 */ - value = 0x1e; /* 0x17 * setting PixelClock - * 0x03 mean 24/(3+1) = 6 Mhz - * 0x05 -> 24/(5+1) = 4 Mhz - * 0x0b -> 24/(11+1) = 2 Mhz - * 0x17 -> 24/(23+1) = 1 Mhz - */ - reg_w_val(gspca_dev, ET_PXL_CLK, value); - /* now set by fifo the FormatLine setting */ - reg_w(gspca_dev, 0x62, FormLine, 6); - - /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ - reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */ - reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */ - /* Pedro change */ - /* Brightness change Brith+ decrease value */ - /* Brigth- increase value */ - /* original value = 0x70; */ - reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */ - reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - int i; - - for (i = 0; i < 4; i++) - reg_w_val(gspca_dev, ET_O_RED + i, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; - - memset(RGBG, val, sizeof(RGBG) - 2); - reg_w(gspca_dev, ET_G_RED, RGBG, 6); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; - __u8 i2cflags = 0x01; - /* __u8 green = 0; */ - - I2cc[3] = val; /* red */ - I2cc[0] = 15 - val; /* blue */ - /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ - /* I2cc[1] = I2cc[2] = green; */ - if (sd->sensor == SENSOR_PAS106) { - i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); - i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1); - } -/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", - I2cc[3], I2cc[0], green); */ -} - -static s32 getcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAS106) { -/* i2c_r(gspca_dev, PAS106_REG9); * blue */ - i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ - return gspca_dev->usb_buf[0] & 0x0f; - } - return 0; -} - -static void setautogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->autogain) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; -} - -static void Et_init1(struct gspca_dev *gspca_dev) -{ - __u8 value; -/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ - __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; - /* try 1/120 0x6d 0xcd 0x40 */ -/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00}; - * 1/60000 hmm ?? */ - - PDEBUG(D_STREAM, "Open Init1 ET"); - reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7); - reg_r(gspca_dev, ET_GPIO_IN, 1); - reg_w_val(gspca_dev, ET_RESET_ALL, 1); - reg_w_val(gspca_dev, ET_RESET_ALL, 0); - reg_w_val(gspca_dev, ET_ClCK, 0x10); - reg_w_val(gspca_dev, ET_CTRL, 0x19); - /* compression et subsampling */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) - value = ET_COMP_VAL1; - else - value = ET_COMP_VAL0; - PDEBUG(D_STREAM, "Open mode %d Compression %d", - gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, - value); - reg_w_val(gspca_dev, ET_COMP, value); - reg_w_val(gspca_dev, ET_MAXQt, 0x1d); - reg_w_val(gspca_dev, ET_MINQt, 0x02); - /* undocumented registers */ - reg_w_val(gspca_dev, ET_REG1d, 0xff); - reg_w_val(gspca_dev, ET_REG1e, 0xff); - reg_w_val(gspca_dev, ET_REG1f, 0xff); - reg_w_val(gspca_dev, ET_REG20, 0x35); - reg_w_val(gspca_dev, ET_REG21, 0x01); - reg_w_val(gspca_dev, ET_REG22, 0x00); - reg_w_val(gspca_dev, ET_REG23, 0xf7); - reg_w_val(gspca_dev, ET_REG24, 0xff); - reg_w_val(gspca_dev, ET_REG25, 0x07); - /* colors setting */ - reg_w_val(gspca_dev, ET_G_RED, 0x80); - reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); - reg_w_val(gspca_dev, ET_G_BLUE, 0x80); - reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); - reg_w_val(gspca_dev, ET_G_GR_H, 0x00); - reg_w_val(gspca_dev, ET_G_GB_H, 0x00); - /* Window control registers */ - reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0); - reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */ - reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */ - reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60); - reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20); - reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50); - reg_w_val(gspca_dev, ET_REG6e, 0x86); - reg_w_val(gspca_dev, ET_REG6f, 0x01); - reg_w_val(gspca_dev, ET_REG70, 0x86); - reg_w_val(gspca_dev, ET_REG71, 0x14); - reg_w_val(gspca_dev, ET_REG72, 0x00); - /* Clock Pattern registers */ - reg_w_val(gspca_dev, ET_REG73, 0x00); - reg_w_val(gspca_dev, ET_REG74, 0x00); - reg_w_val(gspca_dev, ET_REG75, 0x0a); - reg_w_val(gspca_dev, ET_I2C_CLK, 0x04); - reg_w_val(gspca_dev, ET_PXL_CLK, 0x01); - /* set the sensor */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - I2c0[0] = 0x06; - i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); - i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); - value = 0x06; - i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); - i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); - /* value = 0x1f; */ - value = 0x04; - i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); - } else { - I2c0[0] = 0x0a; - - i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); - i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); - value = 0x0a; - i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); - i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); - value = 0x04; - /* value = 0x10; */ - i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); - /* bit 2 enable bit 1:2 select 0 1 2 3 - value = 0x07; * curve 0 * - i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1); - */ - } - -/* value = 0x01; */ -/* value = 0x22; */ -/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */ - /* magnetude and sign bit for DAC */ - i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); - /* now set by fifo the whole colors setting */ - reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); - setcolors(gspca_dev, getcolors(gspca_dev)); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - sd->sensor = id->driver_info; - if (sd->sensor == SENSOR_PAS106) { - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - } else { - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - } - sd->ag_cnt = -1; - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAS106) - Et_init1(gspca_dev); - else - Et_init2(gspca_dev); - reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); - et_video(gspca_dev, 0); /* video off */ - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAS106) - Et_init1(gspca_dev); - else - Et_init2(gspca_dev); - - setautogain(gspca_dev); - - reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); - et_video(gspca_dev, 1); /* video on */ - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - et_video(gspca_dev, 0); /* video off */ -} - -static __u8 Et_getgainG(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAS106) { - i2c_r(gspca_dev, PAS106_REG0e); - PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]); - return gspca_dev->usb_buf[0]; - } - return 0x1f; -} - -static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PAS106) { - __u8 i2cflags = 0x01; - - i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); - i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1); - } -} - -#define BLIMIT(bright) \ - (u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright)) -#define LIMIT(color) \ - (u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color)) - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 luma; - __u8 luma_mean = 128; - __u8 luma_delta = 20; - __u8 spring = 4; - int Gbright; - __u8 r, g, b; - - if (sd->ag_cnt < 0) - return; - if (--sd->ag_cnt >= 0) - return; - sd->ag_cnt = AG_CNT_START; - - Gbright = Et_getgainG(gspca_dev); - reg_r(gspca_dev, ET_LUMA_CENTER, 4); - g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; - r = gspca_dev->usb_buf[1]; - b = gspca_dev->usb_buf[2]; - r = ((r << 8) - (r << 4) - (r << 3)) >> 10; - b = ((b << 7) >> 10); - g = ((g << 9) + (g << 7) + (g << 5)) >> 10; - luma = LIMIT(r + g + b); - PDEBUG(D_FRAM, "Etoms luma G %d", luma); - if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { - Gbright += (luma_mean - luma) >> spring; - Gbright = BLIMIT(Gbright); - PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright); - Et_setgainG(gspca_dev, (__u8) Gbright); - } -} - -#undef BLIMIT -#undef LIMIT - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - int seqframe; - - seqframe = data[0] & 0x3f; - len = (int) (((data[0] & 0xc0) << 2) | data[1]); - if (seqframe == 0x3f) { - PDEBUG(D_FRAM, - "header packet found datalength %d !!", len); - PDEBUG(D_FRAM, "G %d R %d G %d B %d", - data[2], data[3], data[4], data[5]); - data += 30; - /* don't change datalength as the chips provided it */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - return; - } - if (len) { - data += 8; - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - } else { /* Drop Packet */ - gspca_dev->last_packet_type = DISCARD_PACKET; - } -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - sd->autogain = ctrl->val; - setautogain(gspca_dev); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 1, 127, 1, 63); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 127); - if (sd->sensor == SENSOR_PAS106) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 15, 1, 7); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, -#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE - {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, -#endif - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c deleted file mode 100644 index c8f2201cc35a..000000000000 --- a/drivers/media/video/gspca/finepix.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Fujifilm Finepix subdriver - * - * Copyright (C) 2008 Frank Zago - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "finepix" - -#include "gspca.h" - -MODULE_AUTHOR("Frank Zago <frank@zago.net>"); -MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver"); -MODULE_LICENSE("GPL"); - -/* Default timeout, in ms */ -#define FPIX_TIMEOUT 250 - -/* Maximum transfer size to use. The windows driver reads by chunks of - * 0x2000 bytes, so do the same. Note: reading more seems to work - * too. */ -#define FPIX_MAX_TRANSFER 0x2000 - -/* Structure to hold all of our device specific stuff */ -struct usb_fpix { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -/* Delay after which claim the next frame. If the delay is too small, - * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms - * will fail every 4 or 5 frames, but 30ms is perfect. On the A210, - * 30ms is bad while 35ms is perfect. */ -#define NEXT_FRAME_DELAY 35 - -/* These cameras only support 320x200. */ -static const struct v4l2_pix_format fpix_mode[1] = { - { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* send a command to the webcam */ -static int command(struct gspca_dev *gspca_dev, - int order) /* 0: reset, 1: frame request */ -{ - static u8 order_values[2][12] = { - {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */ - {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */ - }; - - memcpy(gspca_dev->usb_buf, order_values[order], 12); - return usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_OUT | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, - 12, FPIX_TIMEOUT); -} - -/* workqueue */ -static void dostream(struct work_struct *work) -{ - struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct urb *urb = gspca_dev->urb[0]; - u8 *data = urb->transfer_buffer; - int ret = 0; - int len; - - /* synchronize with the main driver */ - mutex_lock(&gspca_dev->usb_lock); - mutex_unlock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, "dostream started"); - - /* loop reading a frame */ -again: - while (gspca_dev->dev && gspca_dev->streaming) { -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - - /* request a frame */ - mutex_lock(&gspca_dev->usb_lock); - ret = command(gspca_dev, 1); - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) - break; -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - if (!gspca_dev->dev || !gspca_dev->streaming) - break; - - /* the frame comes in parts */ - for (;;) { - ret = usb_bulk_msg(gspca_dev->dev, - urb->pipe, - data, - FPIX_MAX_TRANSFER, - &len, FPIX_TIMEOUT); - if (ret < 0) { - /* Most of the time we get a timeout - * error. Just restart. */ - goto again; - } -#ifdef CONFIG_PM - if (gspca_dev->frozen) - goto out; -#endif - if (!gspca_dev->dev || !gspca_dev->streaming) - goto out; - if (len < FPIX_MAX_TRANSFER || - (data[len - 2] == 0xff && - data[len - 1] == 0xd9)) { - - /* If the result is less than what was asked - * for, then it's the end of the - * frame. Sometimes the jpeg is not complete, - * but there's nothing we can do. We also end - * here if the the jpeg ends right at the end - * of the frame. */ - gspca_frame_add(gspca_dev, LAST_PACKET, - data, len); - break; - } - - /* got a partial image */ - gspca_frame_add(gspca_dev, - gspca_dev->last_packet_type - == LAST_PACKET - ? FIRST_PACKET : INTER_PACKET, - data, len); - } - - /* We must wait before trying reading the next - * frame. If we don't, or if the delay is too short, - * the camera will disconnect. */ - msleep(NEXT_FRAME_DELAY); - } - -out: - PDEBUG(D_STREAM, "dostream stopped"); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - cam->cam_mode = fpix_mode; - cam->nmodes = 1; - cam->bulk = 1; - cam->bulk_size = FPIX_MAX_TRANSFER; - - INIT_WORK(&dev->work_struct, dostream); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -/* start the camera */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - int ret, len; - - /* Init the device */ - ret = command(gspca_dev, 0); - if (ret < 0) { - pr_err("init failed %d\n", ret); - return ret; - } - - /* Read the result of the command. Ignore the result, for it - * varies with the device. */ - ret = usb_bulk_msg(gspca_dev->dev, - gspca_dev->urb[0]->pipe, - gspca_dev->urb[0]->transfer_buffer, - FPIX_MAX_TRANSFER, &len, - FPIX_TIMEOUT); - if (ret < 0) { - pr_err("usb_bulk_msg failed %d\n", ret); - return ret; - } - - /* Request a frame, but don't read it */ - ret = command(gspca_dev, 1); - if (ret < 0) { - pr_err("frame request failed %d\n", ret); - return ret; - } - - /* Again, reset bulk in endpoint */ - usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); - - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); - - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - destroy_workqueue(dev->work_thread); - mutex_lock(&gspca_dev->usb_lock); - dev->work_thread = NULL; -} - -/* Table of supported USB devices */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x04cb, 0x0104)}, - {USB_DEVICE(0x04cb, 0x0109)}, - {USB_DEVICE(0x04cb, 0x010b)}, - {USB_DEVICE(0x04cb, 0x010f)}, - {USB_DEVICE(0x04cb, 0x0111)}, - {USB_DEVICE(0x04cb, 0x0113)}, - {USB_DEVICE(0x04cb, 0x0115)}, - {USB_DEVICE(0x04cb, 0x0117)}, - {USB_DEVICE(0x04cb, 0x0119)}, - {USB_DEVICE(0x04cb, 0x011b)}, - {USB_DEVICE(0x04cb, 0x011d)}, - {USB_DEVICE(0x04cb, 0x0121)}, - {USB_DEVICE(0x04cb, 0x0123)}, - {USB_DEVICE(0x04cb, 0x0125)}, - {USB_DEVICE(0x04cb, 0x0127)}, - {USB_DEVICE(0x04cb, 0x0129)}, - {USB_DEVICE(0x04cb, 0x012b)}, - {USB_DEVICE(0x04cb, 0x012d)}, - {USB_DEVICE(0x04cb, 0x012f)}, - {USB_DEVICE(0x04cb, 0x0131)}, - {USB_DEVICE(0x04cb, 0x013b)}, - {USB_DEVICE(0x04cb, 0x013d)}, - {USB_DEVICE(0x04cb, 0x013f)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct usb_fpix), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/video/gspca/gl860/Kconfig deleted file mode 100644 index 22772f53ec7b..000000000000 --- a/drivers/media/video/gspca/gl860/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -config USB_GL860 - tristate "GL860 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the GL860 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_gl860. diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile deleted file mode 100644 index 773ea3426561..000000000000 --- a/drivers/media/video/gspca/gl860/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -obj-$(CONFIG_USB_GL860) += gspca_gl860.o - -gspca_gl860-objs := gl860.o \ - gl860-mi1320.o \ - gl860-ov2640.o \ - gl860-ov9655.o \ - gl860-mi2020.o - -ccflags-y += -I$(srctree)/drivers/media/video/gspca - diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c deleted file mode 100644 index b57160e04866..000000000000 --- a/drivers/media/video/gspca/gl860/gl860-mi1320.c +++ /dev/null @@ -1,536 +0,0 @@ -/* Subdriver for the GL860 chip with the MI1320 sensor - * Author Olivier LORIN from own logs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Sensor : MI1320 */ - -#include "gl860.h" - -static struct validx tbl_common[] = { - {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1}, - {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, - {0xffff, 0xffff}, - {0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1}, - {0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1}, - {0xba70, 0x0006}, {0xba0e, 0x00f1}, - {0xffff, 0xffff}, - {0xba74, 0x0006}, {0xba0e, 0x00f1}, - {0xffff, 0xffff}, - {0x0061, 0x0000}, {0x0068, 0x000d}, -}; - -static struct validx tbl_init_at_startup[] = { - {0x0000, 0x0000}, {0x0010, 0x0010}, - {35, 0xffff}, - {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006}, - {0x006a, 0x000d}, -}; - -static struct validx tbl_sensor_settings_common[] = { - {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000}, - {0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006}, -}; -static struct validx tbl_sensor_settings_1280[] = { - {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1}, - {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1}, -}; -static struct validx tbl_sensor_settings_800[] = { - {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1}, - {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1}, -}; -static struct validx tbl_sensor_settings_640[] = { - {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, - {0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1}, - {0xba20, 0x0065}, {0xba00, 0x00f1}, -}; -static struct validx tbl_post_unset_alt[] = { - {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, - {0x0061, 0x0000}, {0x0068, 0x000d}, -}; - -static u8 *tbl_1280[] = { - "\x0d\x80\xf1\x08\x03\x04\xf1\x00" "\x04\x05\xf1\x02\x05\x00\xf1\xf1" - "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08" - "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00" - "\xa9\x04\xf1\x00\xa1\x05\xf1\x00" "\xa4\x04\xf1\x00\xae\x0a\xf1\x08" - , - "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47" - "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c" - "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01" - , - "\xd3\x02\xd4\x28\xd5\x01\xd0\x02" "\xd1\x18\xd2\xc1" -}; - -static u8 *tbl_800[] = { - "\x0d\x80\xf1\x08\x03\x03\xf1\xc0" "\x04\x05\xf1\x02\x05\x00\xf1\xf1" - "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08" - "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00" - "\xa9\x03\xf1\xc0\xa1\x03\xf1\x20" "\xa4\x02\xf1\x5a\xae\x0a\xf1\x08" - , - "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47" - "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c" - "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01" - , - "\xd3\x02\xd4\x18\xd5\x21\xd0\x02" "\xd1\x10\xd2\x59" -}; - -static u8 *tbl_640[] = { - "\x0d\x80\xf1\x08\x03\x04\xf1\x04" "\x04\x05\xf1\x02\x07\x01\xf1\x7c" - "\x08\x00\xf1\x0e\x21\x80\xf1\x00" "\x0d\x00\xf1\x08\xf0\x00\xf1\x01" - "\x34\x10\xf1\x10\x3a\x43\xf1\x00" "\xa6\x05\xf1\x02\xa9\x04\xf1\x04" - "\xa7\x02\xf1\x81\xaa\x01\xf1\xe2" "\xae\x0c\xf1\x09" - , - "\xf0\x00\xf1\x02\x39\x03\xf1\xfc" "\x3b\x04\xf1\x04\x57\x01\xf1\xb6" - "\x58\x02\xf1\x0d\x5c\x1f\xf1\x19" "\x5d\x24\xf1\x1e\x64\x5e\xf1\x1c" - "\xd2\x00\xf1\x00\xcb\x00\xf1\x01" - , - "\xd3\x02\xd4\x10\xd5\x81\xd0\x02" "\xd1\x08\xd2\xe1" -}; - -static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d}; -static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70}; -static s32 tbl_backlight[] = {0x0e, 0x06, 0x02}; - -static s32 tbl_cntr1[] = { - 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0}; -static s32 tbl_cntr2[] = { - 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10}; - -static u8 dat_wbalNL[] = - "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10" - "\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20" - "\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00"; - -static u8 dat_wbalLL[] = - "\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40" - "\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00" - "\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00"; - -static u8 dat_wbalBL[] = - "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae" - "\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20" - "\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00"; - -static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00}; - -static u8 dat_common00[] = - "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42" - "\xd8\x04\x58\x00\x04\x02"; -static u8 dat_common01[] = - "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d" - "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0"; -static u8 dat_common02[] = - "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e" - "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00" - "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff"; -static u8 dat_common03[] = - "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda" - "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c" - "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c"; -static u8 dat_common04[] = - "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43"; -static u8 dat_common05[] = - "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68" - "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82" - "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b"; -static u8 dat_common06[] = - "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06" - "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4" - "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f"; -static u8 dat_common07[] = - "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72" - "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03" - "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea" - "\xe1\xff\xf1\x00"; -static u8 dat_common08[] = - "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7" - "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06" - "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a"; -static u8 dat_common09[] = - "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03" - "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa" - "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14"; -static u8 dat_common10[] = - "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00" - "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f" - "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01" - "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10"; -static u8 dat_common11[] = - "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10" - "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00" - "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81"; - -static int mi1320_init_at_startup(struct gspca_dev *gspca_dev); -static int mi1320_configure_alt(struct gspca_dev *gspca_dev); -static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev); -static int mi1320_init_post_alt(struct gspca_dev *gspca_dev); -static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev); -static int mi1320_sensor_settings(struct gspca_dev *gspca_dev); -static int mi1320_camera_settings(struct gspca_dev *gspca_dev); -/*==========================================================================*/ - -void mi1320_init_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vcur.backlight = 0; - sd->vcur.brightness = 0; - sd->vcur.sharpness = 6; - sd->vcur.contrast = 10; - sd->vcur.gamma = 20; - sd->vcur.hue = 0; - sd->vcur.saturation = 6; - sd->vcur.whitebal = 0; - sd->vcur.mirror = 0; - sd->vcur.flip = 0; - sd->vcur.AC50Hz = 1; - - sd->vmax.backlight = 2; - sd->vmax.brightness = 8; - sd->vmax.sharpness = 7; - sd->vmax.contrast = 0; /* 10 but not working with this driver */ - sd->vmax.gamma = 40; - sd->vmax.hue = 5 + 1; - sd->vmax.saturation = 8; - sd->vmax.whitebal = 2; - sd->vmax.mirror = 1; - sd->vmax.flip = 1; - sd->vmax.AC50Hz = 1; - - sd->dev_camera_settings = mi1320_camera_settings; - sd->dev_init_at_startup = mi1320_init_at_startup; - sd->dev_configure_alt = mi1320_configure_alt; - sd->dev_init_pre_alt = mi1320_init_pre_alt; - sd->dev_post_unset_alt = mi1320_post_unset_alt; -} - -/*==========================================================================*/ - -static void common(struct gspca_dev *gspca_dev) -{ - s32 n; /* reserved for FETCH functions */ - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00); - ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01); - n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06); - keep_on_fetching_validx(gspca_dev, tbl_common, - ARRAY_SIZE(tbl_common), n); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10); - keep_on_fetching_validx(gspca_dev, tbl_common, - ARRAY_SIZE(tbl_common), n); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11); - keep_on_fetching_validx(gspca_dev, tbl_common, - ARRAY_SIZE(tbl_common), n); -} - -static int mi1320_init_at_startup(struct gspca_dev *gspca_dev) -{ - fetch_validx(gspca_dev, tbl_init_at_startup, - ARRAY_SIZE(tbl_init_at_startup)); - - common(gspca_dev); - -/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ - - return 0; -} - -static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->mirrorMask = 0; - - sd->vold.backlight = -1; - sd->vold.brightness = -1; - sd->vold.sharpness = -1; - sd->vold.contrast = -1; - sd->vold.saturation = -1; - sd->vold.gamma = -1; - sd->vold.hue = -1; - sd->vold.whitebal = -1; - sd->vold.mirror = -1; - sd->vold.flip = -1; - sd->vold.AC50Hz = -1; - - common(gspca_dev); - - mi1320_sensor_settings(gspca_dev); - - mi1320_init_post_alt(gspca_dev); - - return 0; -} - -static int mi1320_init_post_alt(struct gspca_dev *gspca_dev) -{ - mi1320_camera_settings(gspca_dev); - - return 0; -} - -static int mi1320_sensor_settings(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); - - fetch_validx(gspca_dev, tbl_sensor_settings_common, - ARRAY_SIZE(tbl_sensor_settings_common)); - - switch (reso) { - case IMAGE_1280: - fetch_validx(gspca_dev, tbl_sensor_settings_1280, - ARRAY_SIZE(tbl_sensor_settings_1280)); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]); - break; - - case IMAGE_800: - fetch_validx(gspca_dev, tbl_sensor_settings_800, - ARRAY_SIZE(tbl_sensor_settings_800)); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]); - break; - - default: - fetch_validx(gspca_dev, tbl_sensor_settings_640, - ARRAY_SIZE(tbl_sensor_settings_640)); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]); - break; - } - return 0; -} - -static int mi1320_configure_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - switch (reso) { - case IMAGE_640: - gspca_dev->alt = 3 + 1; - break; - - case IMAGE_800: - case IMAGE_1280: - gspca_dev->alt = 1 + 1; - break; - } - return 0; -} - -static int mi1320_camera_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - s32 backlight = sd->vcur.backlight; - s32 bright = sd->vcur.brightness; - s32 sharp = sd->vcur.sharpness; - s32 cntr = sd->vcur.contrast; - s32 gam = sd->vcur.gamma; - s32 hue = sd->vcur.hue; - s32 sat = sd->vcur.saturation; - s32 wbal = sd->vcur.whitebal; - s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); - s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); - s32 freq = (sd->vcur.AC50Hz > 0); - s32 i; - - if (freq != sd->vold.AC50Hz) { - sd->vold.AC50Hz = freq; - - freq = 2 * (freq == 0); - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x005b, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL); - } - - if (wbal != sd->vold.whitebal) { - sd->vold.whitebal = wbal; - if (wbal < 0 || wbal > sd->vmax.whitebal) - wbal = 0; - - for (i = 0; i < 2; i++) { - if (wbal == 0) { /* Normal light */ - ctrl_out(gspca_dev, 0x40, 1, - 0x0010, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0003, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0042, 0x00c2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, - 0xba00, 0x0200, 48, dat_wbalNL); - } - - if (wbal == 1) { /* Low light */ - ctrl_out(gspca_dev, 0x40, 1, - 0x0010, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0004, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0043, 0x00c2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, - 0xba00, 0x0200, 48, dat_wbalLL); - } - - if (wbal == 2) { /* Back light */ - ctrl_out(gspca_dev, 0x40, 1, - 0x0010, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0003, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, - 0x0042, 0x00c2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, - 0xba00, 0x0200, 44, dat_wbalBL); - } - } - } - - if (bright != sd->vold.brightness) { - sd->vold.brightness = bright; - if (bright < 0 || bright > sd->vmax.brightness) - bright = 0; - - bright = tbl_bright[bright]; - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL); - } - - if (sat != sd->vold.saturation) { - sd->vold.saturation = sat; - if (sat < 0 || sat > sd->vmax.saturation) - sat = 0; - - sat = tbl_sat[sat]; - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0025, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL); - } - - if (sharp != sd->vold.sharpness) { - sd->vold.sharpness = sharp; - if (sharp < 0 || sharp > sd->vmax.sharpness) - sharp = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0005, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL); - } - - if (hue != sd->vold.hue) { - /* 0=normal 1=NB 2="sepia" 3=negative 4=other 5=other2 */ - if (hue < 0 || hue > sd->vmax.hue) - hue = 0; - if (hue == sd->vmax.hue) - sd->swapRB = 1; - else - sd->swapRB = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1, - 0, NULL); - } - - if (backlight != sd->vold.backlight) { - sd->vold.backlight = backlight; - if (backlight < 0 || backlight > sd->vmax.backlight) - backlight = 0; - - backlight = tbl_backlight[backlight]; - for (i = 0; i < 2; i++) { - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1, - 0, NULL); - } - } - - if (hue != sd->vold.hue) { - sd->vold.hue = hue; - - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1, - 0, NULL); - } - - if (mirror != sd->vold.mirror || flip != sd->vold.flip) { - u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00}; - sd->vold.mirror = mirror; - sd->vold.flip = flip; - - dat_hvflip2[3] = flip + 2 * mirror; - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1); - ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2); - } - - if (gam != sd->vold.gamma) { - sd->vold.gamma = gam; - if (gam < 0 || gam > sd->vmax.gamma) - gam = 0; - - gam = 2 * gam; - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba04 , 0x003b, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL); - } - - if (cntr != sd->vold.contrast) { - sd->vold.contrast = cntr; - if (cntr < 0 || cntr > sd->vmax.contrast) - cntr = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035, - 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1, - 0, NULL); - } - - return 0; -} - -static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev) -{ - ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); - - fetch_validx(gspca_dev, tbl_post_unset_alt, - ARRAY_SIZE(tbl_post_unset_alt)); -} diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c deleted file mode 100644 index 2edda6b7d653..000000000000 --- a/drivers/media/video/gspca/gl860/gl860-mi2020.c +++ /dev/null @@ -1,733 +0,0 @@ -/* Subdriver for the GL860 chip with the MI2020 sensor - * Author Olivier LORIN, from logs by Iceman/Soro2005 + Fret_saw/Hulkie/Tricid - * with the help of Kytrix/BUGabundo/Blazercist. - * Driver achieved thanks to a webcam gift by Kytrix. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Sensor : MI2020 */ - -#include "gl860.h" - -static u8 dat_wbal1[] = {0x8c, 0xa2, 0x0c}; - -static u8 dat_bright1[] = {0x8c, 0xa2, 0x06}; -static u8 dat_bright3[] = {0x8c, 0xa1, 0x02}; -static u8 dat_bright4[] = {0x90, 0x00, 0x0f}; -static u8 dat_bright5[] = {0x8c, 0xa1, 0x03}; -static u8 dat_bright6[] = {0x90, 0x00, 0x05}; - -static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19}; -static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b}; -static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03}; -static u8 dat_hvflip6[] = {0x90, 0x00, 0x06}; - -static struct idxdata tbl_middle_hvflip_low[] = { - {0x33, "\x90\x00\x06"}, - {6, "\xff\xff\xff"}, - {0x33, "\x90\x00\x06"}, - {6, "\xff\xff\xff"}, - {0x33, "\x90\x00\x06"}, - {6, "\xff\xff\xff"}, - {0x33, "\x90\x00\x06"}, - {6, "\xff\xff\xff"}, -}; - -static struct idxdata tbl_middle_hvflip_big[] = { - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa1\x20"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, - {102, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x20"}, - {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, -}; - -static struct idxdata tbl_end_hvflip[] = { - {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, - {6, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, - {6, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, - {6, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, -}; - -static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 }; - -static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; -static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; - -static struct validx tbl_init_at_startup[] = { - {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, - {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, - {53, 0xffff}, - {0x0040, 0x0000}, {0x0063, 0x0006}, -}; - -static struct validx tbl_common_0B[] = { - {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, - {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, - {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, -}; - -static struct idxdata tbl_common_3B[] = { - {0x33, "\x86\x25\x01"}, {0x33, "\x86\x25\x00"}, - {2, "\xff\xff\xff"}, - {0x30, "\x1a\x0a\xcc"}, {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"}, - {6, "\xff\xff\xff"}, /* 12 */ - {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, - {2, "\xff\xff\xff"}, /* - */ - {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"}, - {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"}, - {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"}, - {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"}, - {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"}, - {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"}, - {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"}, - {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, - {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, - {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, - {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"}, - {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"}, - {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"}, - {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"}, - {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"}, - {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"}, - {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"}, - {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"}, - {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"}, - {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"}, - {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"}, - {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"}, - {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"}, - {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"}, - {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"}, - {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"}, - {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"}, - {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"}, - {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"}, - {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"}, - {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"}, - {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"}, - {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, - {0x33, "\x78\x00\x00"}, - {2, "\xff\xff\xff"}, - {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"}, - {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"}, - {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"}, - {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"}, - {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, {0x33, "\x8c\xa4\x04"}, - {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, {0x33, "\x90\x00\x00"}, - {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0c"}, - {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, {0x33, "\x90\x00\x04"}, - {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"}, - {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x25"}, - {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, - {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x47"}, - {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x02\x84"}, - {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"}, {0x33, "\x8c\x27\x07"}, - {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"}, {0x33, "\x90\x04\xb0"}, - {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x0f"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"}, {0x33, "\x90\x04\xbd"}, - {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"}, {0x33, "\x8c\x27\x15"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"}, - {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"}, {0x33, "\x8c\x27\x1b"}, - {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"}, {0x33, "\x90\x01\x02"}, - {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"}, {0x33, "\x8c\x27\x21"}, - {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"}, {0x33, "\x90\x02\x85"}, - {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x27"}, - {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"}, {0x33, "\x90\x20\x20"}, - {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"}, {0x33, "\x8c\x27\x2d"}, - {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"}, {0x33, "\x90\x00\x04"}, - {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x33"}, - {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"}, {0x33, "\x90\x06\x4b"}, - {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x39"}, - {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, - {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x41"}, - {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"}, {0x33, "\x90\x04\xed"}, - {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x51"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"}, {0x33, "\x90\x03\x20"}, - {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x57"}, - {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"}, {0x33, "\x90\x00\x00"}, - {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x63"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"}, {0x33, "\x90\x04\xb0"}, - {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\xa4\x08"}, - {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"}, - {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"}, - {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa1"}, - {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"}, {0x33, "\x8c\x24\x15"}, - {0x33, "\x90\x00\x6a"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\x80"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, - {3, "\xff\xff\xff"}, -}; - -static struct idxdata tbl_init_post_alt_low1[] = { - {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"}, - {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"}, - {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"}, - {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"}, - {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"}, - {0x33, "\x90\x00\x9b"}, -}; - -static struct idxdata tbl_init_post_alt_low2[] = { - {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"}, - {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, - {2, "\xff\xff\xff"}, -}; - -static struct idxdata tbl_init_post_alt_low3[] = { - {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, - {2, "\xff\xff\xff"}, - {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, - {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, - {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, -}; - -static struct idxdata tbl_init_post_alt_big[] = { - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, - {2, "\xff\xff\xff"}, - {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, - {2, "\xff\xff\xff"}, - {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, - {2, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"}, - {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"}, - {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"}, - {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"}, - {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"}, - {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, - {0x33, "\x8c\x27\x97"}, {0x33, "\x90\x01\x00"}, - {51, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, - {51, "\xff\xff\xff"}, - {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"}, - {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, - {51, "\xff\xff\xff"}, -}; - -static struct idxdata tbl_init_post_alt_3B[] = { - {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, - {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, - {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, - {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"}, - {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"}, - {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"}, - {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"}, - {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"}, - {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"}, - {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"}, - {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"}, - {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"}, - {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"}, - {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"}, - {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"}, - {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"}, - {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"}, - {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"}, - {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"}, - {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"}, - {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"}, - {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"}, - {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"}, - {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"}, - {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"}, - {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, -}; - -static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81"; -static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21"; -static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01"; -static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41"; - -static int mi2020_init_at_startup(struct gspca_dev *gspca_dev); -static int mi2020_configure_alt(struct gspca_dev *gspca_dev); -static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev); -static int mi2020_init_post_alt(struct gspca_dev *gspca_dev); -static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev); -static int mi2020_camera_settings(struct gspca_dev *gspca_dev); -/*==========================================================================*/ - -void mi2020_init_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vcur.backlight = 0; - sd->vcur.brightness = 70; - sd->vcur.sharpness = 20; - sd->vcur.contrast = 0; - sd->vcur.gamma = 0; - sd->vcur.hue = 0; - sd->vcur.saturation = 60; - sd->vcur.whitebal = 0; /* 50, not done by hardware */ - sd->vcur.mirror = 0; - sd->vcur.flip = 0; - sd->vcur.AC50Hz = 1; - - sd->vmax.backlight = 64; - sd->vmax.brightness = 128; - sd->vmax.sharpness = 40; - sd->vmax.contrast = 3; - sd->vmax.gamma = 2; - sd->vmax.hue = 0 + 1; /* 200, not done by hardware */ - sd->vmax.saturation = 0; /* 100, not done by hardware */ - sd->vmax.whitebal = 2; /* 100, not done by hardware */ - sd->vmax.mirror = 1; - sd->vmax.flip = 1; - sd->vmax.AC50Hz = 1; - - sd->dev_camera_settings = mi2020_camera_settings; - sd->dev_init_at_startup = mi2020_init_at_startup; - sd->dev_configure_alt = mi2020_configure_alt; - sd->dev_init_pre_alt = mi2020_init_pre_alt; - sd->dev_post_unset_alt = mi2020_post_unset_alt; -} - -/*==========================================================================*/ - -static void common(struct gspca_dev *gspca_dev) -{ - fetch_validx(gspca_dev, tbl_common_0B, ARRAY_SIZE(tbl_common_0B)); - fetch_idxdata(gspca_dev, tbl_common_3B, ARRAY_SIZE(tbl_common_3B)); - ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); -} - -static int mi2020_init_at_startup(struct gspca_dev *gspca_dev) -{ - u8 c; - - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c); - - fetch_validx(gspca_dev, tbl_init_at_startup, - ARRAY_SIZE(tbl_init_at_startup)); - - ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); - ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &c); - - common(gspca_dev); - - msleep(61); -/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ -/* msleep(36); */ - ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL); - - return 0; -} - -static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->mirrorMask = 0; - sd->vold.hue = -1; - - /* These controls need to be reset */ - sd->vold.brightness = -1; - sd->vold.sharpness = -1; - - /* If not different from default, they do not need to be set */ - sd->vold.contrast = 0; - sd->vold.gamma = 0; - sd->vold.backlight = 0; - - mi2020_init_post_alt(gspca_dev); - - return 0; -} - -static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); - s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); - s32 freq = (sd->vcur.AC50Hz > 0); - s32 wbal = sd->vcur.whitebal; - - u8 dat_freq2[] = {0x90, 0x00, 0x80}; - u8 dat_multi1[] = {0x8c, 0xa7, 0x00}; - u8 dat_multi2[] = {0x90, 0x00, 0x00}; - u8 dat_multi3[] = {0x8c, 0xa7, 0x00}; - u8 dat_multi4[] = {0x90, 0x00, 0x00}; - u8 dat_hvflip2[] = {0x90, 0x04, 0x6c}; - u8 dat_hvflip4[] = {0x90, 0x00, 0x24}; - u8 dat_wbal2[] = {0x90, 0x00, 0x00}; - u8 c; - - sd->nbIm = -1; - - dat_freq2[2] = freq ? 0xc0 : 0x80; - dat_multi1[2] = 0x9d; - dat_multi3[2] = dat_multi1[2] + 1; - if (wbal == 0) { - dat_multi4[2] = dat_multi2[2] = 0; - dat_wbal2[2] = 0x17; - } else if (wbal == 1) { - dat_multi4[2] = dat_multi2[2] = 0; - dat_wbal2[2] = 0x35; - } else if (wbal == 2) { - dat_multi4[2] = dat_multi2[2] = 0x20; - dat_wbal2[2] = 0x17; - } - dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror); - dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror); - - msleep(200); - ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); - msleep(2); - - common(gspca_dev); - - msleep(142); - ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); - - switch (reso) { - case IMAGE_640: - case IMAGE_800: - if (reso != IMAGE_800) - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_640); - else - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_800); - - fetch_idxdata(gspca_dev, tbl_init_post_alt_low1, - ARRAY_SIZE(tbl_init_post_alt_low1)); - - if (reso == IMAGE_800) - fetch_idxdata(gspca_dev, tbl_init_post_alt_low2, - ARRAY_SIZE(tbl_init_post_alt_low2)); - - fetch_idxdata(gspca_dev, tbl_init_post_alt_low3, - ARRAY_SIZE(tbl_init_post_alt_low3)); - - ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL); - msleep(120); - break; - - case IMAGE_1280: - case IMAGE_1600: - if (reso == IMAGE_1280) { - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_1280); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x8c\x27\x07"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x90\x05\x04"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x8c\x27\x09"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x90\x04\x02"); - } else { - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_1600); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x8c\x27\x07"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x90\x06\x40"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x8c\x27\x09"); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, - 3, "\x90\x04\xb0"); - } - - fetch_idxdata(gspca_dev, tbl_init_post_alt_big, - ARRAY_SIZE(tbl_init_post_alt_big)); - - ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL); - msleep(1850); - } - - ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); - msleep(40); - - /* AC power frequency */ - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2); - msleep(33); - /* light source */ - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); - msleep(7); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c); - - fetch_idxdata(gspca_dev, tbl_init_post_alt_3B, - ARRAY_SIZE(tbl_init_post_alt_3B)); - - /* hvflip */ - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6); - msleep(250); - - if (reso == IMAGE_640 || reso == IMAGE_800) - fetch_idxdata(gspca_dev, tbl_middle_hvflip_low, - ARRAY_SIZE(tbl_middle_hvflip_low)); - else - fetch_idxdata(gspca_dev, tbl_middle_hvflip_big, - ARRAY_SIZE(tbl_middle_hvflip_big)); - - fetch_idxdata(gspca_dev, tbl_end_hvflip, - ARRAY_SIZE(tbl_end_hvflip)); - - sd->nbIm = 0; - - sd->vold.mirror = mirror; - sd->vold.flip = flip; - sd->vold.AC50Hz = freq; - sd->vold.whitebal = wbal; - - mi2020_camera_settings(gspca_dev); - - return 0; -} - -static int mi2020_configure_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - switch (reso) { - case IMAGE_640: - gspca_dev->alt = 3 + 1; - break; - - case IMAGE_800: - case IMAGE_1280: - case IMAGE_1600: - gspca_dev->alt = 1 + 1; - break; - } - return 0; -} - -static int mi2020_camera_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - s32 backlight = sd->vcur.backlight; - s32 bright = sd->vcur.brightness; - s32 sharp = sd->vcur.sharpness; - s32 cntr = sd->vcur.contrast; - s32 gam = sd->vcur.gamma; - s32 hue = (sd->vcur.hue > 0); - s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); - s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); - s32 freq = (sd->vcur.AC50Hz > 0); - s32 wbal = sd->vcur.whitebal; - - u8 dat_sharp[] = {0x6c, 0x00, 0x08}; - u8 dat_bright2[] = {0x90, 0x00, 0x00}; - u8 dat_freq2[] = {0x90, 0x00, 0x80}; - u8 dat_multi1[] = {0x8c, 0xa7, 0x00}; - u8 dat_multi2[] = {0x90, 0x00, 0x00}; - u8 dat_multi3[] = {0x8c, 0xa7, 0x00}; - u8 dat_multi4[] = {0x90, 0x00, 0x00}; - u8 dat_hvflip2[] = {0x90, 0x04, 0x6c}; - u8 dat_hvflip4[] = {0x90, 0x00, 0x24}; - u8 dat_wbal2[] = {0x90, 0x00, 0x00}; - - /* Less than 4 images received -> too early to set the settings */ - if (sd->nbIm < 4) { - sd->waitSet = 1; - return 0; - } - sd->waitSet = 0; - - if (freq != sd->vold.AC50Hz) { - sd->vold.AC50Hz = freq; - - dat_freq2[2] = freq ? 0xc0 : 0x80; - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2); - msleep(20); - } - - if (wbal != sd->vold.whitebal) { - sd->vold.whitebal = wbal; - if (wbal < 0 || wbal > sd->vmax.whitebal) - wbal = 0; - - dat_multi1[2] = 0x9d; - dat_multi3[2] = dat_multi1[2] + 1; - if (wbal == 0) { - dat_multi4[2] = dat_multi2[2] = 0; - dat_wbal2[2] = 0x17; - } else if (wbal == 1) { - dat_multi4[2] = dat_multi2[2] = 0; - dat_wbal2[2] = 0x35; - } else if (wbal == 2) { - dat_multi4[2] = dat_multi2[2] = 0x20; - dat_wbal2[2] = 0x17; - } - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); - } - - if (mirror != sd->vold.mirror || flip != sd->vold.flip) { - sd->vold.mirror = mirror; - sd->vold.flip = flip; - - dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror); - dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror); - - fetch_idxdata(gspca_dev, tbl_init_post_alt_3B, - ARRAY_SIZE(tbl_init_post_alt_3B)); - - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6); - msleep(40); - - if (reso == IMAGE_640 || reso == IMAGE_800) - fetch_idxdata(gspca_dev, tbl_middle_hvflip_low, - ARRAY_SIZE(tbl_middle_hvflip_low)); - else - fetch_idxdata(gspca_dev, tbl_middle_hvflip_big, - ARRAY_SIZE(tbl_middle_hvflip_big)); - - fetch_idxdata(gspca_dev, tbl_end_hvflip, - ARRAY_SIZE(tbl_end_hvflip)); - } - - if (bright != sd->vold.brightness) { - sd->vold.brightness = bright; - if (bright < 0 || bright > sd->vmax.brightness) - bright = 0; - - dat_bright2[2] = bright; - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6); - } - - if (cntr != sd->vold.contrast || gam != sd->vold.gamma) { - sd->vold.contrast = cntr; - if (cntr < 0 || cntr > sd->vmax.contrast) - cntr = 0; - sd->vold.gamma = gam; - if (gam < 0 || gam > sd->vmax.gamma) - gam = 0; - - dat_multi1[2] = 0x6d; - dat_multi3[2] = dat_multi1[2] + 1; - if (cntr == 0) - cntr = 4; - dat_multi4[2] = dat_multi2[2] = cntr * 0x10 + 2 - gam; - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); - } - - if (backlight != sd->vold.backlight) { - sd->vold.backlight = backlight; - if (backlight < 0 || backlight > sd->vmax.backlight) - backlight = 0; - - dat_multi1[2] = 0x9d; - dat_multi3[2] = dat_multi1[2] + 1; - dat_multi4[2] = dat_multi2[2] = backlight; - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); - } - - if (sharp != sd->vold.sharpness) { - sd->vold.sharpness = sharp; - if (sharp < 0 || sharp > sd->vmax.sharpness) - sharp = 0; - - dat_sharp[1] = sharp; - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp); - } - - if (hue != sd->vold.hue) { - sd->swapRB = hue; - sd->vold.hue = hue; - } - - return 0; -} - -static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev) -{ - ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); - msleep(40); - ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL); -} diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c deleted file mode 100644 index 768cac5cd72b..000000000000 --- a/drivers/media/video/gspca/gl860/gl860-ov2640.c +++ /dev/null @@ -1,489 +0,0 @@ -/* Subdriver for the GL860 chip with the OV2640 sensor - * Author Olivier LORIN, from Malmostoso's logs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Sensor : OV2640 */ - -#include "gl860.h" - -static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; - -static u8 c61[] = {0x61}; /* expected */ -static u8 c51[] = {0x51}; /* expected */ -static u8 c50[] = {0x50}; /* expected */ -static u8 c28[] = {0x28}; /* expected */ -static u8 ca8[] = {0xa8}; /* expected */ - -static u8 dat_post[] = - "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; - -static u8 dat_640[] = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81"; -static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21"; -static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; -static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; - -static struct validx tbl_init_at_startup[] = { - {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, - {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, - {0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006}, - {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, - {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, - {0x0041, 0x0000}, {0x0061, 0x0000}, -}; - -static struct validx tbl_common[] = { - {0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff}, - {0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010}, - {0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013}, - {0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b}, - {0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039}, - {0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023}, - {0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007}, - {0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a}, - {0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025}, - {0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010}, - {0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061}, - {0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c}, - {0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073}, - {0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050}, - {0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b}, - {0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076}, - {0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c}, - {0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9}, - {0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044}, - {0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8}, - {0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d}, - {0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091}, - {0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091}, - {0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091}, - {0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091}, - {0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093}, - {0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093}, - {0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, - {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, - {0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097}, - {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097}, - {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097}, - {0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4}, - {0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7}, - {0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9}, - {0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0}, - {0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8}, - {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050}, - {0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054}, - {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b}, - {0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da}, - {0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd}, - {0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045}, - {0x6000, 0x0010}, -}; - -static struct validx tbl_sensor_settings_common1[] = { - {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, - {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, - {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000}, - {50, 0xffff}, - {0x0061, 0x0000}, - {0xffff, 0xffff}, - {0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d}, - {30, 0xffff}, - {0x0040, 0x0000}, -}; - -static struct validx tbl_sensor_settings_common2[] = { - {0x6001, 0x00ff}, {0x6038, 0x000c}, - {10, 0xffff}, - {0x6000, 0x0011}, -}; - -static struct validx tbl_640[] = { - {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1}, - {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, - {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017}, - {0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, - {0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d}, - {0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff}, - {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086}, - {0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053}, - {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a}, - {0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0}, - {0x60ff, 0x00dd}, {0x60a1, 0x005a}, -}; - -static struct validx tbl_800[] = { - {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1}, - {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, - {0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017}, - {0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032}, - {0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d}, - {0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020}, - {0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1}, - {0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0}, - {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018}, -}; - -static struct validx tbl_big1[] = { - {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, - {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, - {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018}, - {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f}, - {0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f}, - {0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff}, - {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, -}; - -static struct validx tbl_big2[] = { - {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, - {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, - {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3}, - {0x6000, 0x008e}, -}; - -static struct validx tbl_big3[] = { - {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd}, - {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, - {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7}, - {0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093}, - {0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087}, - {0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, - {0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff}, - {0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e}, - {0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014}, - {0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd}, -}; - -static struct validx tbl_post_unset_alt[] = { - {0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000}, - {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d}, - {50, 0xffff}, - {0x0021, 0x0000}, -}; - -static int ov2640_init_at_startup(struct gspca_dev *gspca_dev); -static int ov2640_configure_alt(struct gspca_dev *gspca_dev); -static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev); -static int ov2640_init_post_alt(struct gspca_dev *gspca_dev); -static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev); -static int ov2640_camera_settings(struct gspca_dev *gspca_dev); -/*==========================================================================*/ - -void ov2640_init_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vcur.backlight = 32; - sd->vcur.brightness = 0; - sd->vcur.sharpness = 6; - sd->vcur.contrast = 0; - sd->vcur.gamma = 32; - sd->vcur.hue = 0; - sd->vcur.saturation = 128; - sd->vcur.whitebal = 64; - sd->vcur.mirror = 0; - sd->vcur.flip = 0; - - sd->vmax.backlight = 64; - sd->vmax.brightness = 255; - sd->vmax.sharpness = 31; - sd->vmax.contrast = 255; - sd->vmax.gamma = 64; - sd->vmax.hue = 254 + 2; - sd->vmax.saturation = 255; - sd->vmax.whitebal = 128; - sd->vmax.mirror = 1; - sd->vmax.flip = 1; - sd->vmax.AC50Hz = 0; - - sd->dev_camera_settings = ov2640_camera_settings; - sd->dev_init_at_startup = ov2640_init_at_startup; - sd->dev_configure_alt = ov2640_configure_alt; - sd->dev_init_pre_alt = ov2640_init_pre_alt; - sd->dev_post_unset_alt = ov2640_post_unset_alt; -} - -/*==========================================================================*/ - -static void common(struct gspca_dev *gspca_dev) -{ - fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); -} - -static int ov2640_init_at_startup(struct gspca_dev *gspca_dev) -{ - fetch_validx(gspca_dev, tbl_init_at_startup, - ARRAY_SIZE(tbl_init_at_startup)); - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1); - - common(gspca_dev); - - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61); - - ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); - - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51); - - ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); -/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ - - return 0; -} - -static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->mirrorMask = 0; - - sd->vold.backlight = -1; - sd->vold.brightness = -1; - sd->vold.sharpness = -1; - sd->vold.contrast = -1; - sd->vold.saturation = -1; - sd->vold.gamma = -1; - sd->vold.hue = -1; - sd->vold.whitebal = -1; - sd->vold.mirror = -1; - sd->vold.flip = -1; - - ov2640_init_post_alt(gspca_dev); - - return 0; -} - -static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - s32 n; /* reserved for FETCH functions */ - - ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); - - n = fetch_validx(gspca_dev, tbl_sensor_settings_common1, - ARRAY_SIZE(tbl_sensor_settings_common1)); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post); - common(gspca_dev); - keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1, - ARRAY_SIZE(tbl_sensor_settings_common1), n); - - switch (reso) { - case IMAGE_640: - n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640)); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640); - break; - - case IMAGE_800: - n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800)); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800); - break; - - case IMAGE_1600: - case IMAGE_1280: - n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1)); - - if (reso == IMAGE_1280) { - n = fetch_validx(gspca_dev, tbl_big2, - ARRAY_SIZE(tbl_big2)); - } else { - ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL); - } - - n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3)); - - if (reso == IMAGE_1280) { - ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_1280); - } else { - ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - 12, dat_1600); - } - break; - } - - n = fetch_validx(gspca_dev, tbl_sensor_settings_common2, - ARRAY_SIZE(tbl_sensor_settings_common2)); - - ov2640_camera_settings(gspca_dev); - - return 0; -} - -static int ov2640_configure_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - switch (reso) { - case IMAGE_640: - gspca_dev->alt = 3 + 1; - break; - - case IMAGE_800: - case IMAGE_1280: - case IMAGE_1600: - gspca_dev->alt = 1 + 1; - break; - } - return 0; -} - -static int ov2640_camera_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - s32 backlight = sd->vcur.backlight; - s32 bright = sd->vcur.brightness; - s32 sharp = sd->vcur.sharpness; - s32 gam = sd->vcur.gamma; - s32 cntr = sd->vcur.contrast; - s32 sat = sd->vcur.saturation; - s32 hue = sd->vcur.hue; - s32 wbal = sd->vcur.whitebal; - s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0); - s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0); - - if (backlight != sd->vold.backlight) { - /* No sd->vold.backlight=backlight; (to be done again later) */ - if (backlight < 0 || backlight > sd->vmax.backlight) - backlight = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, - 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024, - 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025, - 0, NULL); - } - - if (bright != sd->vold.brightness) { - sd->vold.brightness = bright; - if (bright < 0 || bright > sd->vmax.brightness) - bright = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6009 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL); - } - - if (wbal != sd->vold.whitebal) { - sd->vold.whitebal = wbal; - if (wbal < 0 || wbal > sd->vmax.whitebal) - wbal = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6003 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL); - } - - if (cntr != sd->vold.contrast) { - sd->vold.contrast = cntr; - if (cntr < 0 || cntr > sd->vmax.contrast) - cntr = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6007 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL); - } - - if (sat != sd->vold.saturation) { - sd->vold.saturation = sat; - if (sat < 0 || sat > sd->vmax.saturation) - sat = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL); - } - - if (sharp != sd->vold.sharpness) { - sd->vold.sharpness = sharp; - if (sharp < 0 || sharp > sd->vmax.sharpness) - sharp = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x0092, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL); - } - - if (hue != sd->vold.hue) { - sd->vold.hue = hue; - if (hue < 0 || hue > sd->vmax.hue) - hue = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, - 0, NULL); - if (hue >= 255) - sd->swapRB = 1; - else - sd->swapRB = 0; - } - - if (gam != sd->vold.gamma) { - sd->vold.gamma = gam; - if (gam < 0 || gam > sd->vmax.gamma) - gam = 0; - - ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6008 , 0x007c, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); - } - - if (mirror != sd->vold.mirror || flip != sd->vold.flip) { - sd->vold.mirror = mirror; - sd->vold.flip = flip; - - mirror = 0x80 * mirror; - ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28); - ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL); - - flip = 0x50 * flip + mirror; - ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8); - ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL); - - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); - } - - if (backlight != sd->vold.backlight) { - sd->vold.backlight = backlight; - - ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, - 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024, - 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025, - 0, NULL); - } - - return 0; -} - -static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev) -{ - ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); - msleep(20); - fetch_validx(gspca_dev, tbl_post_unset_alt, - ARRAY_SIZE(tbl_post_unset_alt)); -} diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c deleted file mode 100644 index 5ae9619d72a5..000000000000 --- a/drivers/media/video/gspca/gl860/gl860-ov9655.c +++ /dev/null @@ -1,336 +0,0 @@ -/* Subdriver for the GL860 chip with the OV9655 sensor - * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt - * on dsd's weblog - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Sensor : OV9655 */ - -#include "gl860.h" - -static struct validx tbl_init_at_startup[] = { - {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, - {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, - - {0x0040, 0x0000}, -}; - -static struct validx tbl_commmon[] = { - {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, - {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, - {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000}, - {0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000}, -}; - -static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12}; - -static u8 *tbl_640[] = { - "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01" - , - "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x03\x0b\x57\x0e\x61" - "\x0f\x42\x11\x01\x12\x60\x13\x00" "\x14\x3a\x16\x24\x17\x14\x18\x00" - "\x19\x01\x1a\x3d\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08" - "\x29\x15\x2a\x00\x2b\x00\x2c\x08" - , - "\x32\xff\x33\x00\x34\x3d\x35\x00" "\x36\xfa\x38\x72\x39\x57\x3a\x00" - "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc1" "\x40\xc0\x41\x00\x42\xc0\x43\x0a" - "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xee\x4b\xe7\x4c\xe7" - "\x4d\xe7\x4e\xe7" - , - "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85" - "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0" - "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x0a\x6b\x5a\x6c\x04" - "\x6d\x55\x6e\x00\x6f\x9d" - , - "\x70\x15\x71\x78\x72\x00\x73\x00" "\x74\x3a\x75\x35\x76\x01\x77\x02" - "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52" - "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5" - "\x8a\x23\x8c\x8d\x90\x7c\x91\x7b" - , - "\x9d\x02\x9e\x02\x9f\x74\xa0\x73" "\xa1\x40\xa4\x50\xa5\x68\xa6\x70" - "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80" - "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf" - , - "\xbb\xae\xbc\x4f\xbd\x4e\xbe\x6a" "\xbf\x68\xc0\xaa\xc1\xc0\xc2\x01" - "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93" - , - "\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80" -}; - -static u8 *tbl_1280[] = { - "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01" - , - "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61" - "\x0f\x42\x11\x00\x12\x00\x13\x00" "\x14\x3a\x16\x24\x17\x1b\x18\xbb" - "\x19\x01\x1a\x81\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08" - "\x29\x15\x2a\x00\x2b\x00\x2c\x08" - , - "\x32\xa4\x33\x00\x34\x3d\x35\x00" "\x36\xf8\x38\x72\x39\x57\x3a\x00" - "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc2" "\x40\xc0\x41\x00\x42\xc0\x43\x0a" - "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xec\x4b\xe8\x4c\xe8" - "\x4d\xe8\x4e\xe8" - , - "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85" - "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0" - "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x02\x6b\x5a\x6c\x04" - "\x6d\x55\x6e\x00\x6f\x9d" - , - "\x70\x08\x71\x78\x72\x00\x73\x01" "\x74\x3a\x75\x35\x76\x01\x77\x02" - "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52" - "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5" - "\x8a\x23\x8c\x0d\x90\x90\x91\x90" - , - "\x9d\x02\x9e\x02\x9f\x94\xa0\x94" "\xa1\x01\xa4\x50\xa5\x68\xa6\x70" - "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80" - "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf" - , - "\xbb\xae\xbc\x38\xbd\x39\xbe\x01" "\xbf\x01\xc0\xe2\xc1\xc0\xc2\x01" - "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93" - , - "\xd0\x21\xd1\x18\xd2\xe0\xd3\x01" "\xd4\x28\xd5\x00" -}; - -static u8 c04[] = {0x04}; -static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02"; -static u8 dat_post2[] = "\x10\x10\xc1\x02"; -static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04"; -static u8 dat_post4[] = "\x10\x02\xc1\x06"; -static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08"; -static u8 dat_post6[] = "\x10\x10\xc1\x05"; -static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08"; -static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09"; - -static struct validx tbl_init_post_alt[] = { - {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff}, - {0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff}, - {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6012, 0x0003}, - {0xffff, 0xffff}, - {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6012, 0x0003}, - {0xffff, 0xffff}, - {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6000, 0x801e}, - {0xffff, 0xffff}, - {0x6004, 0x001e}, {0x6012, 0x0003}, -}; - -static int ov9655_init_at_startup(struct gspca_dev *gspca_dev); -static int ov9655_configure_alt(struct gspca_dev *gspca_dev); -static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev); -static int ov9655_init_post_alt(struct gspca_dev *gspca_dev); -static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev); -static int ov9655_camera_settings(struct gspca_dev *gspca_dev); -/*==========================================================================*/ - -void ov9655_init_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vcur.backlight = 0; - sd->vcur.brightness = 128; - sd->vcur.sharpness = 0; - sd->vcur.contrast = 0; - sd->vcur.gamma = 0; - sd->vcur.hue = 0; - sd->vcur.saturation = 0; - sd->vcur.whitebal = 0; - - sd->vmax.backlight = 0; - sd->vmax.brightness = 255; - sd->vmax.sharpness = 0; - sd->vmax.contrast = 0; - sd->vmax.gamma = 0; - sd->vmax.hue = 0 + 1; - sd->vmax.saturation = 0; - sd->vmax.whitebal = 0; - sd->vmax.mirror = 0; - sd->vmax.flip = 0; - sd->vmax.AC50Hz = 0; - - sd->dev_camera_settings = ov9655_camera_settings; - sd->dev_init_at_startup = ov9655_init_at_startup; - sd->dev_configure_alt = ov9655_configure_alt; - sd->dev_init_pre_alt = ov9655_init_pre_alt; - sd->dev_post_unset_alt = ov9655_post_unset_alt; -} - -/*==========================================================================*/ - -static int ov9655_init_at_startup(struct gspca_dev *gspca_dev) -{ - fetch_validx(gspca_dev, tbl_init_at_startup, - ARRAY_SIZE(tbl_init_at_startup)); - fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon)); -/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/ - - return 0; -} - -static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vold.brightness = -1; - sd->vold.hue = -1; - - fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon)); - - ov9655_init_post_alt(gspca_dev); - - return 0; -} - -static int ov9655_init_post_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - s32 n; /* reserved for FETCH functions */ - s32 i; - u8 **tbl; - - ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); - - tbl = (reso == IMAGE_640) ? tbl_640 : tbl_1280; - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - tbl_length[0], tbl[0]); - for (i = 1; i < 7; i++) - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, - tbl_length[i], tbl[i]); - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, - tbl_length[7], tbl[7]); - - n = fetch_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt)); - - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04); - keep_on_fetching_validx(gspca_dev, tbl_init_post_alt, - ARRAY_SIZE(tbl_init_post_alt), n); - - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1); - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3); - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5); - - ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6); - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7); - - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8); - - ov9655_camera_settings(gspca_dev); - - return 0; -} - -static int ov9655_configure_alt(struct gspca_dev *gspca_dev) -{ - s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; - - switch (reso) { - case IMAGE_640: - gspca_dev->alt = 1 + 1; - break; - - default: - gspca_dev->alt = 1 + 1; - break; - } - return 0; -} - -static int ov9655_camera_settings(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70"; - - s32 bright = sd->vcur.brightness; - s32 hue = sd->vcur.hue; - - if (bright != sd->vold.brightness) { - sd->vold.brightness = bright; - if (bright < 0 || bright > sd->vmax.brightness) - bright = 0; - - dat_bright[3] = bright; - ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright); - } - - if (hue != sd->vold.hue) { - sd->vold.hue = hue; - sd->swapRB = (hue != 0); - } - - return 0; -} - -static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev) -{ - ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); - ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL); -} diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c deleted file mode 100644 index ced3b71f14e5..000000000000 --- a/drivers/media/video/gspca/gl860/gl860.c +++ /dev/null @@ -1,725 +0,0 @@ -/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip - * Subdriver core - * - * 2009/09/24 Olivier Lorin <o.lorin@laposte.net> - * GSPCA by Jean-Francois Moine <http://moinejf.free.fr> - * Thanks BUGabundo and Malmostoso for your amazing help! - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "gspca.h" -#include "gl860.h" - -MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>"); -MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver"); -MODULE_LICENSE("GPL"); - -/*======================== static function declarations ====================*/ - -static void (*dev_init_settings)(struct gspca_dev *gspca_dev); - -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id); -static int sd_init(struct gspca_dev *gspca_dev); -static int sd_isoc_init(struct gspca_dev *gspca_dev); -static int sd_start(struct gspca_dev *gspca_dev); -static void sd_stop0(struct gspca_dev *gspca_dev); -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len); -static void sd_callback(struct gspca_dev *gspca_dev); - -static int gl860_guess_sensor(struct gspca_dev *gspca_dev, - u16 vendor_id, u16 product_id); - -/*============================ driver options ==============================*/ - -static s32 AC50Hz = 0xff; -module_param(AC50Hz, int, 0644); -MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)"); - -static char sensor[7]; -module_param_string(sensor, sensor, sizeof(sensor), 0644); -MODULE_PARM_DESC(sensor, - " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')"); - -/*============================ webcam controls =============================*/ - -/* Functions to get and set a control value */ -#define SD_SETGET(thename) \ -static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\ -{\ - struct sd *sd = (struct sd *) gspca_dev;\ -\ - sd->vcur.thename = val;\ - if (gspca_dev->streaming)\ - sd->waitSet = 1;\ - return 0;\ -} \ -static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\ -{\ - struct sd *sd = (struct sd *) gspca_dev;\ -\ - *val = sd->vcur.thename;\ - return 0;\ -} - -SD_SETGET(mirror) -SD_SETGET(flip) -SD_SETGET(AC50Hz) -SD_SETGET(backlight) -SD_SETGET(brightness) -SD_SETGET(gamma) -SD_SETGET(hue) -SD_SETGET(saturation) -SD_SETGET(sharpness) -SD_SETGET(whitebal) -SD_SETGET(contrast) - -#define GL860_NCTRLS 11 - -/* control table */ -static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS]; -static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS]; -static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS]; -static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS]; - -#define SET_MY_CTRL(theid, \ - thetype, thelabel, thename) \ - if (sd->vmax.thename != 0) {\ - sd_ctrls[nCtrls].qctrl.id = theid;\ - sd_ctrls[nCtrls].qctrl.type = thetype;\ - strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\ - sd_ctrls[nCtrls].qctrl.minimum = 0;\ - sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\ - sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\ - sd_ctrls[nCtrls].qctrl.step = \ - (sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\ - sd_ctrls[nCtrls].set = sd_set_##thename;\ - sd_ctrls[nCtrls].get = sd_get_##thename;\ - nCtrls++;\ - } - -static int gl860_build_control_table(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct ctrl *sd_ctrls; - int nCtrls = 0; - - if (_MI1320_) - sd_ctrls = sd_ctrls_mi1320; - else if (_MI2020_) - sd_ctrls = sd_ctrls_mi2020; - else if (_OV2640_) - sd_ctrls = sd_ctrls_ov2640; - else if (_OV9655_) - sd_ctrls = sd_ctrls_ov9655; - else - return 0; - - memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl)); - - SET_MY_CTRL(V4L2_CID_BRIGHTNESS, - V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness) - SET_MY_CTRL(V4L2_CID_SHARPNESS, - V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness) - SET_MY_CTRL(V4L2_CID_CONTRAST, - V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast) - SET_MY_CTRL(V4L2_CID_GAMMA, - V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma) - SET_MY_CTRL(V4L2_CID_HUE, - V4L2_CTRL_TYPE_INTEGER, "Palette", hue) - SET_MY_CTRL(V4L2_CID_SATURATION, - V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation) - SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE, - V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal) - SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION, - V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight) - - SET_MY_CTRL(V4L2_CID_HFLIP, - V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror) - SET_MY_CTRL(V4L2_CID_VFLIP, - V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip) - SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz) - - return nCtrls; -} - -/*==================== sud-driver structure initialisation =================*/ - -static const struct sd_desc sd_desc_mi1320 = { - .name = MODULE_NAME, - .ctrls = sd_ctrls_mi1320, - .nctrls = GL860_NCTRLS, - .config = sd_config, - .init = sd_init, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_callback, -}; - -static const struct sd_desc sd_desc_mi2020 = { - .name = MODULE_NAME, - .ctrls = sd_ctrls_mi2020, - .nctrls = GL860_NCTRLS, - .config = sd_config, - .init = sd_init, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_callback, -}; - -static const struct sd_desc sd_desc_ov2640 = { - .name = MODULE_NAME, - .ctrls = sd_ctrls_ov2640, - .nctrls = GL860_NCTRLS, - .config = sd_config, - .init = sd_init, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_callback, -}; - -static const struct sd_desc sd_desc_ov9655 = { - .name = MODULE_NAME, - .ctrls = sd_ctrls_ov9655, - .nctrls = GL860_NCTRLS, - .config = sd_config, - .init = sd_init, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_callback, -}; - -/*=========================== sub-driver image sizes =======================*/ - -static struct v4l2_pix_format mi2020_mode[] = { - { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - { 800, 598, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 598, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - {1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2 - }, - {1600, 1198, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1600, - .sizeimage = 1600 * 1198, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3 - }, -}; - -static struct v4l2_pix_format ov2640_mode[] = { - { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2 - }, - {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1600, - .sizeimage = 1600 * 1200, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3 - }, -}; - -static struct v4l2_pix_format mi1320_mode[] = { - { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2 - }, -}; - -static struct v4l2_pix_format ov9655_mode[] = { - { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, -}; - -/*========================= sud-driver functions ===========================*/ - -/* This function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - u16 vendor_id, product_id; - - /* Get USB VendorID and ProductID */ - vendor_id = id->idVendor; - product_id = id->idProduct; - - sd->nbRightUp = 1; - sd->nbIm = -1; - - sd->sensor = 0xff; - if (strcmp(sensor, "MI1320") == 0) - sd->sensor = ID_MI1320; - else if (strcmp(sensor, "OV2640") == 0) - sd->sensor = ID_OV2640; - else if (strcmp(sensor, "OV9655") == 0) - sd->sensor = ID_OV9655; - else if (strcmp(sensor, "MI2020") == 0) - sd->sensor = ID_MI2020; - - /* Get sensor and set the suitable init/start/../stop functions */ - if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1) - return -1; - - cam = &gspca_dev->cam; - - switch (sd->sensor) { - case ID_MI1320: - gspca_dev->sd_desc = &sd_desc_mi1320; - cam->cam_mode = mi1320_mode; - cam->nmodes = ARRAY_SIZE(mi1320_mode); - dev_init_settings = mi1320_init_settings; - break; - - case ID_MI2020: - gspca_dev->sd_desc = &sd_desc_mi2020; - cam->cam_mode = mi2020_mode; - cam->nmodes = ARRAY_SIZE(mi2020_mode); - dev_init_settings = mi2020_init_settings; - break; - - case ID_OV2640: - gspca_dev->sd_desc = &sd_desc_ov2640; - cam->cam_mode = ov2640_mode; - cam->nmodes = ARRAY_SIZE(ov2640_mode); - dev_init_settings = ov2640_init_settings; - break; - - case ID_OV9655: - gspca_dev->sd_desc = &sd_desc_ov9655; - cam->cam_mode = ov9655_mode; - cam->nmodes = ARRAY_SIZE(ov9655_mode); - dev_init_settings = ov9655_init_settings; - break; - } - - dev_init_settings(gspca_dev); - if (AC50Hz != 0xff) - ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz; - gl860_build_control_table(gspca_dev); - - return 0; -} - -/* This function is called at probe time after sd_config */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return sd->dev_init_at_startup(gspca_dev); -} - -/* This function is called before to choose the alt setting */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return sd->dev_configure_alt(gspca_dev); -} - -/* This function is called to start the webcam */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - return sd->dev_init_pre_alt(gspca_dev); -} - -/* This function is called to stop the webcam */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!sd->gspca_dev.present) - return; - - return sd->dev_post_unset_alt(gspca_dev); -} - -/* This function is called when an image is being received */ -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - static s32 nSkipped; - - s32 mode = (s32) gspca_dev->curr_mode; - s32 nToSkip = - sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1); - - /* Test only against 0202h, so endianess does not matter */ - switch (*(s16 *) data) { - case 0x0202: /* End of frame, start a new one */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - nSkipped = 0; - if (sd->nbIm >= 0 && sd->nbIm < 10) - sd->nbIm++; - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - break; - - default: - data += 2; - len -= 2; - if (nSkipped + len <= nToSkip) - nSkipped += len; - else { - if (nSkipped < nToSkip && nSkipped + len > nToSkip) { - data += nToSkip - nSkipped; - len -= nToSkip - nSkipped; - nSkipped = nToSkip + 1; - } - gspca_frame_add(gspca_dev, - INTER_PACKET, data, len); - } - break; - } -} - -/* This function is called when an image has been read */ -/* This function is used to monitor webcam orientation */ -static void sd_callback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!_OV9655_) { - u8 state; - u8 upsideDown; - - /* Probe sensor orientation */ - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state); - - /* C8/40 means upside-down (looking backwards) */ - /* D8/50 means right-up (looking onwards) */ - upsideDown = (state == 0xc8 || state == 0x40); - - if (upsideDown && sd->nbRightUp > -4) { - if (sd->nbRightUp > 0) - sd->nbRightUp = 0; - if (sd->nbRightUp == -3) { - sd->mirrorMask = 1; - sd->waitSet = 1; - } - sd->nbRightUp--; - } - if (!upsideDown && sd->nbRightUp < 4) { - if (sd->nbRightUp < 0) - sd->nbRightUp = 0; - if (sd->nbRightUp == 3) { - sd->mirrorMask = 0; - sd->waitSet = 1; - } - sd->nbRightUp++; - } - } - - if (sd->waitSet) - sd->dev_camera_settings(gspca_dev); -} - -/*=================== USB driver structure initialisation ==================*/ - -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x05e3, 0x0503)}, - {USB_DEVICE(0x05e3, 0xf191)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE); -} - -static void sd_disconnect(struct usb_interface *intf) -{ - gspca_disconnect(intf); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = sd_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -/*====================== Init and Exit module functions ====================*/ - -module_usb_driver(sd_driver); - -/*==========================================================================*/ - -int gl860_RTx(struct gspca_dev *gspca_dev, - unsigned char pref, u32 req, u16 val, u16 index, - s32 len, void *pdata) -{ - struct usb_device *udev = gspca_dev->dev; - s32 r = 0; - - if (pref == 0x40) { /* Send */ - if (len > 0) { - memcpy(gspca_dev->usb_buf, pdata, len); - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - req, pref, val, index, - gspca_dev->usb_buf, - len, 400 + 200 * (len > 1)); - } else { - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - req, pref, val, index, NULL, len, 400); - } - } else { /* Receive */ - if (len > 0) { - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - req, pref, val, index, - gspca_dev->usb_buf, - len, 400 + 200 * (len > 1)); - memcpy(pdata, gspca_dev->usb_buf, len); - } else { - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - req, pref, val, index, NULL, len, 400); - } - } - - if (r < 0) - pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n", - r, pref, req, val, index, len); - else if (len > 1 && r < len) - PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len); - - msleep(1); - - return r; -} - -int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len) -{ - int n; - - for (n = 0; n < len; n++) { - if (tbl[n].idx != 0xffff) - ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, - tbl[n].idx, 0, NULL); - else if (tbl[n].val == 0xffff) - break; - else - msleep(tbl[n].val); - } - return n; -} - -int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl, - int len, int n) -{ - while (++n < len) { - if (tbl[n].idx != 0xffff) - ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx, - 0, NULL); - else if (tbl[n].val == 0xffff) - break; - else - msleep(tbl[n].val); - } - return n; -} - -void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len) -{ - int n; - - for (n = 0; n < len; n++) { - if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0) - ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx, - 3, tbl[n].data); - else - msleep(tbl[n].idx); - } -} - -static int gl860_guess_sensor(struct gspca_dev *gspca_dev, - u16 vendor_id, u16 product_id) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 probe, nb26, nb96, nOV, ntry; - - if (product_id == 0xf191) - sd->sensor = ID_MI1320; - - if (sd->sensor == 0xff) { - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe); - ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe); - - ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); - msleep(56); - - PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX"); - nOV = 0; - for (ntry = 0; ntry < 4; ntry++) { - ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); - msleep(10); - ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe); - PDEBUG(D_PROBE, "probe=0x%02x", probe); - if (probe == 0xff) - nOV++; - } - - if (nOV) { - PDEBUG(D_PROBE, "0xff -> OVXXXX"); - PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655"); - - nb26 = nb96 = 0; - for (ntry = 0; ntry < 4; ntry++) { - ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, - 0, NULL); - msleep(3); - ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a, - 0, NULL); - msleep(10); - - /* Wait for 26(OV2640) or 96(OV9655) */ - ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a, - 1, &probe); - - if (probe == 0x26 || probe == 0x40) { - PDEBUG(D_PROBE, - "probe=0x%02x -> OV2640", - probe); - sd->sensor = ID_OV2640; - nb26 += 4; - break; - } - if (probe == 0x96 || probe == 0x55) { - PDEBUG(D_PROBE, - "probe=0x%02x -> OV9655", - probe); - sd->sensor = ID_OV9655; - nb96 += 4; - break; - } - PDEBUG(D_PROBE, "probe=0x%02x", probe); - if (probe == 0x00) - nb26++; - if (probe == 0xff) - nb96++; - msleep(3); - } - if (nb26 < 4 && nb96 < 4) - return -1; - } else { - PDEBUG(D_PROBE, "Not any 0xff -> MI2020"); - sd->sensor = ID_MI2020; - } - } - - if (_MI1320_) { - PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)"); - } else if (_MI2020_) { - PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)"); - } else if (_OV9655_) { - PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)"); - } else if (_OV2640_) { - PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)"); - } else { - PDEBUG(D_PROBE, "***** Unknown sensor *****"); - return -1; - } - - return 0; -} diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h deleted file mode 100644 index 0330a0293b9c..000000000000 --- a/drivers/media/video/gspca/gl860/gl860.h +++ /dev/null @@ -1,105 +0,0 @@ -/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip - * Subdriver declarations - * - * 2009/10/14 Olivier LORIN <o.lorin@laposte.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef GL860_DEV_H -#define GL860_DEV_H - -#include "gspca.h" - -#define MODULE_NAME "gspca_gl860" -#define DRIVER_VERSION "0.9d10" - -#define ctrl_in gl860_RTx -#define ctrl_out gl860_RTx - -#define ID_MI1320 1 -#define ID_OV2640 2 -#define ID_OV9655 4 -#define ID_MI2020 8 - -#define _MI1320_ (((struct sd *) gspca_dev)->sensor == ID_MI1320) -#define _MI2020_ (((struct sd *) gspca_dev)->sensor == ID_MI2020) -#define _OV2640_ (((struct sd *) gspca_dev)->sensor == ID_OV2640) -#define _OV9655_ (((struct sd *) gspca_dev)->sensor == ID_OV9655) - -#define IMAGE_640 0 -#define IMAGE_800 1 -#define IMAGE_1280 2 -#define IMAGE_1600 3 - -struct sd_gl860 { - u16 backlight; - u16 brightness; - u16 sharpness; - u16 contrast; - u16 gamma; - u16 hue; - u16 saturation; - u16 whitebal; - u8 mirror; - u8 flip; - u8 AC50Hz; -}; - -/* Specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct sd_gl860 vcur; - struct sd_gl860 vold; - struct sd_gl860 vmax; - - int (*dev_configure_alt) (struct gspca_dev *); - int (*dev_init_at_startup)(struct gspca_dev *); - int (*dev_init_pre_alt) (struct gspca_dev *); - void (*dev_post_unset_alt) (struct gspca_dev *); - int (*dev_camera_settings)(struct gspca_dev *); - - u8 swapRB; - u8 mirrorMask; - u8 sensor; - s32 nbIm; - s32 nbRightUp; - u8 waitSet; -}; - -struct validx { - u16 val; - u16 idx; -}; - -struct idxdata { - u8 idx; - u8 data[3]; -}; - -int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len); -int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl, - int len, int n); -void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len); - -int gl860_RTx(struct gspca_dev *gspca_dev, - unsigned char pref, u32 req, u16 val, u16 index, - s32 len, void *pdata); - -void mi1320_init_settings(struct gspca_dev *); -void ov2640_init_settings(struct gspca_dev *); -void ov9655_init_settings(struct gspca_dev *); -void mi2020_init_settings(struct gspca_dev *); - -#endif diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c deleted file mode 100644 index d4e8343f5b10..000000000000 --- a/drivers/media/video/gspca/gspca.c +++ /dev/null @@ -1,2456 +0,0 @@ -/* - * Main USB camera driver - * - * Copyright (C) 2008-2011 Jean-François Moine <http://moinejf.free.fr> - * - * Camera button input handling by Márton Németh - * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define GSPCA_VERSION "2.14.0" - -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/vmalloc.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pagemap.h> -#include <linux/io.h> -#include <asm/page.h> -#include <linux/uaccess.h> -#include <linux/ktime.h> -#include <media/v4l2-ioctl.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-fh.h> -#include <media/v4l2-event.h> - -#include "gspca.h" - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -#include <linux/input.h> -#include <linux/usb/input.h> -#endif - -/* global values */ -#define DEF_NURBS 3 /* default number of URBs */ -#if DEF_NURBS > MAX_NURBS -#error "DEF_NURBS too big" -#endif - -MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("GSPCA USB Camera Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(GSPCA_VERSION); - -#ifdef GSPCA_DEBUG -int gspca_debug = D_ERR | D_PROBE; -EXPORT_SYMBOL(gspca_debug); - -static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) -{ - if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') { - PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d", - txt, - pixfmt & 0xff, - (pixfmt >> 8) & 0xff, - (pixfmt >> 16) & 0xff, - pixfmt >> 24, - w, h); - } else { - PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d", - txt, - pixfmt, - w, h); - } -} -#else -#define PDEBUG_MODE(txt, pixfmt, w, h) -#endif - -/* specific memory types - !! should be different from V4L2_MEMORY_xxx */ -#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ -#define GSPCA_MEMORY_READ 7 - -#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) - -/* - * VMA operations. - */ -static void gspca_vm_open(struct vm_area_struct *vma) -{ - struct gspca_frame *frame = vma->vm_private_data; - - frame->vma_use_count++; - frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED; -} - -static void gspca_vm_close(struct vm_area_struct *vma) -{ - struct gspca_frame *frame = vma->vm_private_data; - - if (--frame->vma_use_count <= 0) - frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED; -} - -static const struct vm_operations_struct gspca_vm_ops = { - .open = gspca_vm_open, - .close = gspca_vm_close, -}; - -/* - * Input and interrupt endpoint handling functions - */ -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static void int_irq(struct urb *urb) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - int ret; - - ret = urb->status; - switch (ret) { - case 0: - if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev, - urb->transfer_buffer, urb->actual_length) < 0) { - PDEBUG(D_ERR, "Unknown packet received"); - } - break; - - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - /* Stop is requested either by software or hardware is gone, - * keep the ret value non-zero and don't resubmit later. - */ - break; - - default: - PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status); - urb->status = 0; - ret = 0; - } - - if (ret == 0) { - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) - pr_err("Resubmit URB failed with error %i\n", ret); - } -} - -static int gspca_input_connect(struct gspca_dev *dev) -{ - struct input_dev *input_dev; - int err = 0; - - dev->input_dev = NULL; - if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input) { - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - usb_make_path(dev->dev, dev->phys, sizeof(dev->phys)); - strlcat(dev->phys, "/input0", sizeof(dev->phys)); - - input_dev->name = dev->sd_desc->name; - input_dev->phys = dev->phys; - - usb_to_input_id(dev->dev, &input_dev->id); - - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); - input_dev->dev.parent = &dev->dev->dev; - - err = input_register_device(input_dev); - if (err) { - pr_err("Input device registration failed with error %i\n", - err); - input_dev->dev.parent = NULL; - input_free_device(input_dev); - } else { - dev->input_dev = input_dev; - } - } - - return err; -} - -static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, - struct usb_endpoint_descriptor *ep) -{ - unsigned int buffer_len; - int interval; - struct urb *urb; - struct usb_device *dev; - void *buffer = NULL; - int ret = -EINVAL; - - buffer_len = le16_to_cpu(ep->wMaxPacketSize); - interval = ep->bInterval; - PDEBUG(D_CONF, "found int in endpoint: 0x%x, " - "buffer_len=%u, interval=%u", - ep->bEndpointAddress, buffer_len, interval); - - dev = gspca_dev->dev; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - ret = -ENOMEM; - goto error; - } - - buffer = usb_alloc_coherent(dev, buffer_len, - GFP_KERNEL, &urb->transfer_dma); - if (!buffer) { - ret = -ENOMEM; - goto error_buffer; - } - usb_fill_int_urb(urb, dev, - usb_rcvintpipe(dev, ep->bEndpointAddress), - buffer, buffer_len, - int_irq, (void *)gspca_dev, interval); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret < 0) { - PDEBUG(D_ERR, "submit int URB failed with error %i", ret); - goto error_submit; - } - gspca_dev->int_urb = urb; - return ret; - -error_submit: - usb_free_coherent(dev, - urb->transfer_buffer_length, - urb->transfer_buffer, - urb->transfer_dma); -error_buffer: - usb_free_urb(urb); -error: - return ret; -} - -static void gspca_input_create_urb(struct gspca_dev *gspca_dev) -{ - struct usb_interface *intf; - struct usb_host_interface *intf_desc; - struct usb_endpoint_descriptor *ep; - int i; - - if (gspca_dev->sd_desc->int_pkt_scan) { - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - intf_desc = intf->cur_altsetting; - for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) { - ep = &intf_desc->endpoint[i].desc; - if (usb_endpoint_dir_in(ep) && - usb_endpoint_xfer_int(ep)) { - - alloc_and_submit_int_urb(gspca_dev, ep); - break; - } - } - } -} - -static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev) -{ - struct urb *urb; - - urb = gspca_dev->int_urb; - if (urb) { - gspca_dev->int_urb = NULL; - usb_kill_urb(urb); - usb_free_coherent(gspca_dev->dev, - urb->transfer_buffer_length, - urb->transfer_buffer, - urb->transfer_dma); - usb_free_urb(urb); - } -} -#else -static inline void gspca_input_destroy_urb(struct gspca_dev *gspca_dev) -{ -} - -static inline void gspca_input_create_urb(struct gspca_dev *gspca_dev) -{ -} - -static inline int gspca_input_connect(struct gspca_dev *dev) -{ - return 0; -} -#endif - -/* - * fill a video frame from an URB and resubmit - */ -static void fill_frame(struct gspca_dev *gspca_dev, - struct urb *urb) -{ - u8 *data; /* address of data in the iso message */ - int i, len, st; - cam_pkt_op pkt_scan; - - if (urb->status != 0) { - if (urb->status == -ESHUTDOWN) - return; /* disconnection */ -#ifdef CONFIG_PM - if (gspca_dev->frozen) - return; -#endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - urb->status = 0; - goto resubmit; - } - pkt_scan = gspca_dev->sd_desc->pkt_scan; - for (i = 0; i < urb->number_of_packets; i++) { - len = urb->iso_frame_desc[i].actual_length; - - /* check the packet status and length */ - st = urb->iso_frame_desc[i].status; - if (st) { - pr_err("ISOC data error: [%d] len=%d, status=%d\n", - i, len, st); - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - if (len == 0) { - if (gspca_dev->empty_packet == 0) - gspca_dev->empty_packet = 1; - continue; - } - - /* let the packet be analyzed by the subdriver */ - PDEBUG(D_PACK, "packet [%d] o:%d l:%d", - i, urb->iso_frame_desc[i].offset, len); - data = (u8 *) urb->transfer_buffer - + urb->iso_frame_desc[i].offset; - pkt_scan(gspca_dev, data, len); - } - -resubmit: - /* resubmit the URB */ - st = usb_submit_urb(urb, GFP_ATOMIC); - if (st < 0) - pr_err("usb_submit_urb() ret %d\n", st); -} - -/* - * ISOC message interrupt from the USB device - * - * Analyse each packet and call the subdriver for copy to the frame buffer. - */ -static void isoc_irq(struct urb *urb) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - - PDEBUG(D_PACK, "isoc irq"); - if (!gspca_dev->streaming) - return; - fill_frame(gspca_dev, urb); -} - -/* - * bulk message interrupt from the USB device - */ -static void bulk_irq(struct urb *urb) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - int st; - - PDEBUG(D_PACK, "bulk irq"); - if (!gspca_dev->streaming) - return; - switch (urb->status) { - case 0: - break; - case -ESHUTDOWN: - return; /* disconnection */ - default: -#ifdef CONFIG_PM - if (gspca_dev->frozen) - return; -#endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - urb->status = 0; - goto resubmit; - } - - PDEBUG(D_PACK, "packet l:%d", urb->actual_length); - gspca_dev->sd_desc->pkt_scan(gspca_dev, - urb->transfer_buffer, - urb->actual_length); - -resubmit: - /* resubmit the URB */ - if (gspca_dev->cam.bulk_nurbs != 0) { - st = usb_submit_urb(urb, GFP_ATOMIC); - if (st < 0) - pr_err("usb_submit_urb() ret %d\n", st); - } -} - -/* - * add data to the current frame - * - * This function is called by the subdrivers at interrupt level. - * - * To build a frame, these ones must add - * - one FIRST_PACKET - * - 0 or many INTER_PACKETs - * - one LAST_PACKET - * DISCARD_PACKET invalidates the whole frame. - */ -void gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, - const u8 *data, - int len) -{ - struct gspca_frame *frame; - int i, j; - - PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); - - if (packet_type == FIRST_PACKET) { - i = atomic_read(&gspca_dev->fr_i); - - /* if there are no queued buffer, discard the whole frame */ - if (i == atomic_read(&gspca_dev->fr_q)) { - gspca_dev->last_packet_type = DISCARD_PACKET; - gspca_dev->sequence++; - return; - } - j = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[j]; - frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); - frame->v4l2_buf.sequence = gspca_dev->sequence++; - gspca_dev->image = frame->data; - gspca_dev->image_len = 0; - } else { - switch (gspca_dev->last_packet_type) { - case DISCARD_PACKET: - if (packet_type == LAST_PACKET) { - gspca_dev->last_packet_type = packet_type; - gspca_dev->image = NULL; - gspca_dev->image_len = 0; - } - return; - case LAST_PACKET: - return; - } - } - - /* append the packet to the frame buffer */ - if (len > 0) { - if (gspca_dev->image_len + len > gspca_dev->frsz) { - PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", - gspca_dev->image_len + len, - gspca_dev->frsz); - packet_type = DISCARD_PACKET; - } else { -/* !! image is NULL only when last pkt is LAST or DISCARD - if (gspca_dev->image == NULL) { - pr_err("gspca_frame_add() image == NULL\n"); - return; - } - */ - memcpy(gspca_dev->image + gspca_dev->image_len, - data, len); - gspca_dev->image_len += len; - } - } - gspca_dev->last_packet_type = packet_type; - - /* if last packet, invalidate packet concatenation until - * next first packet, wake up the application and advance - * in the queue */ - if (packet_type == LAST_PACKET) { - i = atomic_read(&gspca_dev->fr_i); - j = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[j]; - frame->v4l2_buf.bytesused = gspca_dev->image_len; - frame->v4l2_buf.flags = (frame->v4l2_buf.flags - | V4L2_BUF_FLAG_DONE) - & ~V4L2_BUF_FLAG_QUEUED; - i = (i + 1) % GSPCA_MAX_FRAMES; - atomic_set(&gspca_dev->fr_i, i); - wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ - PDEBUG(D_FRAM, "frame complete len:%d", - frame->v4l2_buf.bytesused); - gspca_dev->image = NULL; - gspca_dev->image_len = 0; - } -} -EXPORT_SYMBOL(gspca_frame_add); - -static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file, - enum v4l2_memory memory, unsigned int count) -{ - struct gspca_frame *frame; - unsigned int frsz; - int i; - - i = gspca_dev->curr_mode; - frsz = gspca_dev->cam.cam_mode[i].sizeimage; - PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); - frsz = PAGE_ALIGN(frsz); - if (count >= GSPCA_MAX_FRAMES) - count = GSPCA_MAX_FRAMES - 1; - gspca_dev->frbuf = vmalloc_32(frsz * count); - if (!gspca_dev->frbuf) { - pr_err("frame alloc failed\n"); - return -ENOMEM; - } - gspca_dev->capt_file = file; - gspca_dev->memory = memory; - gspca_dev->frsz = frsz; - gspca_dev->nframes = count; - for (i = 0; i < count; i++) { - frame = &gspca_dev->frame[i]; - frame->v4l2_buf.index = i; - frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - frame->v4l2_buf.flags = 0; - frame->v4l2_buf.field = V4L2_FIELD_NONE; - frame->v4l2_buf.length = frsz; - frame->v4l2_buf.memory = memory; - frame->v4l2_buf.sequence = 0; - frame->data = gspca_dev->frbuf + i * frsz; - frame->v4l2_buf.m.offset = i * frsz; - } - atomic_set(&gspca_dev->fr_q, 0); - atomic_set(&gspca_dev->fr_i, 0); - gspca_dev->fr_o = 0; - return 0; -} - -static void frame_free(struct gspca_dev *gspca_dev) -{ - int i; - - PDEBUG(D_STREAM, "frame free"); - if (gspca_dev->frbuf != NULL) { - vfree(gspca_dev->frbuf); - gspca_dev->frbuf = NULL; - for (i = 0; i < gspca_dev->nframes; i++) - gspca_dev->frame[i].data = NULL; - } - gspca_dev->nframes = 0; - gspca_dev->frsz = 0; - gspca_dev->capt_file = NULL; - gspca_dev->memory = GSPCA_MEMORY_NO; -} - -static void destroy_urbs(struct gspca_dev *gspca_dev) -{ - struct urb *urb; - unsigned int i; - - PDEBUG(D_STREAM, "kill transfer"); - for (i = 0; i < MAX_NURBS; i++) { - urb = gspca_dev->urb[i]; - if (urb == NULL) - break; - - gspca_dev->urb[i] = NULL; - usb_kill_urb(urb); - if (urb->transfer_buffer != NULL) - usb_free_coherent(gspca_dev->dev, - urb->transfer_buffer_length, - urb->transfer_buffer, - urb->transfer_dma); - usb_free_urb(urb); - } -} - -static int gspca_set_alt0(struct gspca_dev *gspca_dev) -{ - int ret; - - if (gspca_dev->alt == 0) - return 0; - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); - if (ret < 0) - pr_err("set alt 0 err %d\n", ret); - return ret; -} - -/* Note: both the queue and the usb locks should be held when calling this */ -static void gspca_stream_off(struct gspca_dev *gspca_dev) -{ - gspca_dev->streaming = 0; - gspca_dev->usb_err = 0; - if (gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - gspca_input_destroy_urb(gspca_dev); - gspca_set_alt0(gspca_dev); - gspca_input_create_urb(gspca_dev); - if (gspca_dev->sd_desc->stop0) - gspca_dev->sd_desc->stop0(gspca_dev); - PDEBUG(D_STREAM, "stream off OK"); -} - -/* - * look for an input transfer endpoint in an alternate setting - */ -static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, - int xfer) -{ - struct usb_host_endpoint *ep; - int i, attr; - - for (i = 0; i < alt->desc.bNumEndpoints; i++) { - ep = &alt->endpoint[i]; - attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (attr == xfer - && ep->desc.wMaxPacketSize != 0 - && usb_endpoint_dir_in(&ep->desc)) - return ep; - } - return NULL; -} - -/* compute the minimum bandwidth for the current transfer */ -static u32 which_bandwidth(struct gspca_dev *gspca_dev) -{ - u32 bandwidth; - int i; - - /* get the (max) image size */ - i = gspca_dev->curr_mode; - bandwidth = gspca_dev->cam.cam_mode[i].sizeimage; - - /* if the image is compressed, estimate its mean size */ - if (!gspca_dev->cam.needs_full_bandwidth && - bandwidth < gspca_dev->cam.cam_mode[i].width * - gspca_dev->cam.cam_mode[i].height) - bandwidth = bandwidth * 3 / 8; /* 0.375 */ - - /* estimate the frame rate */ - if (gspca_dev->sd_desc->get_streamparm) { - struct v4l2_streamparm parm; - - gspca_dev->sd_desc->get_streamparm(gspca_dev, &parm); - bandwidth *= parm.parm.capture.timeperframe.denominator; - bandwidth /= parm.parm.capture.timeperframe.numerator; - } else { - - /* don't hope more than 15 fps with USB 1.1 and - * image resolution >= 640x480 */ - if (gspca_dev->width >= 640 - && gspca_dev->dev->speed == USB_SPEED_FULL) - bandwidth *= 15; /* 15 fps */ - else - bandwidth *= 30; /* 30 fps */ - } - - PDEBUG(D_STREAM, "min bandwidth: %d", bandwidth); - return bandwidth; -} - -/* endpoint table */ -#define MAX_ALT 16 -struct ep_tb_s { - u32 alt; - u32 bandwidth; -}; - -/* - * build the table of the endpoints - * and compute the minimum bandwidth for the image transfer - */ -static int build_isoc_ep_tb(struct gspca_dev *gspca_dev, - struct usb_interface *intf, - struct ep_tb_s *ep_tb) -{ - struct usb_host_endpoint *ep; - int i, j, nbalt, psize, found; - u32 bandwidth, last_bw; - - nbalt = intf->num_altsetting; - if (nbalt > MAX_ALT) - nbalt = MAX_ALT; /* fixme: should warn */ - - /* build the endpoint table */ - i = 0; - last_bw = 0; - for (;;) { - ep_tb->bandwidth = 2000 * 2000 * 120; - found = 0; - for (j = 0; j < nbalt; j++) { - ep = alt_xfer(&intf->altsetting[j], - USB_ENDPOINT_XFER_ISOC); - if (ep == NULL) - continue; - if (ep->desc.bInterval == 0) { - pr_err("alt %d iso endp with 0 interval\n", j); - continue; - } - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - bandwidth = psize * 1000; - if (gspca_dev->dev->speed == USB_SPEED_HIGH - || gspca_dev->dev->speed == USB_SPEED_SUPER) - bandwidth *= 8; - bandwidth /= 1 << (ep->desc.bInterval - 1); - if (bandwidth <= last_bw) - continue; - if (bandwidth < ep_tb->bandwidth) { - ep_tb->bandwidth = bandwidth; - ep_tb->alt = j; - found = 1; - } - } - if (!found) - break; - PDEBUG(D_STREAM, "alt %d bandwidth %d", - ep_tb->alt, ep_tb->bandwidth); - last_bw = ep_tb->bandwidth; - i++; - ep_tb++; - } - - /* - * If the camera: - * has a usb audio class interface (a built in usb mic); and - * is a usb 1 full speed device; and - * uses the max full speed iso bandwidth; and - * and has more than 1 alt setting - * then skip the highest alt setting to spare bandwidth for the mic - */ - if (gspca_dev->audio && - gspca_dev->dev->speed == USB_SPEED_FULL && - last_bw >= 1000000 && - i > 1) { - PDEBUG(D_STREAM, "dev has usb audio, skipping highest alt"); - i--; - ep_tb--; - } - - /* get the requested bandwidth and start at the highest atlsetting */ - bandwidth = which_bandwidth(gspca_dev); - ep_tb--; - while (i > 1) { - ep_tb--; - if (ep_tb->bandwidth < bandwidth) - break; - i--; - } - return i; -} - -/* - * create the URBs for image transfer - */ -static int create_urbs(struct gspca_dev *gspca_dev, - struct usb_host_endpoint *ep) -{ - struct urb *urb; - int n, nurbs, i, psize, npkt, bsize; - - /* calculate the packet size and the number of packets */ - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - - if (!gspca_dev->cam.bulk) { /* isoc */ - - /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ - if (gspca_dev->pkt_size == 0) - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - else - psize = gspca_dev->pkt_size; - npkt = gspca_dev->cam.npkt; - if (npkt == 0) - npkt = 32; /* default value */ - bsize = psize * npkt; - PDEBUG(D_STREAM, - "isoc %d pkts size %d = bsize:%d", - npkt, psize, bsize); - nurbs = DEF_NURBS; - } else { /* bulk */ - npkt = 0; - bsize = gspca_dev->cam.bulk_size; - if (bsize == 0) - bsize = psize; - PDEBUG(D_STREAM, "bulk bsize:%d", bsize); - if (gspca_dev->cam.bulk_nurbs != 0) - nurbs = gspca_dev->cam.bulk_nurbs; - else - nurbs = 1; - } - - for (n = 0; n < nurbs; n++) { - urb = usb_alloc_urb(npkt, GFP_KERNEL); - if (!urb) { - pr_err("usb_alloc_urb failed\n"); - return -ENOMEM; - } - gspca_dev->urb[n] = urb; - urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, - bsize, - GFP_KERNEL, - &urb->transfer_dma); - - if (urb->transfer_buffer == NULL) { - pr_err("usb_alloc_coherent failed\n"); - return -ENOMEM; - } - urb->dev = gspca_dev->dev; - urb->context = gspca_dev; - urb->transfer_buffer_length = bsize; - if (npkt != 0) { /* ISOC */ - urb->pipe = usb_rcvisocpipe(gspca_dev->dev, - ep->desc.bEndpointAddress); - urb->transfer_flags = URB_ISO_ASAP - | URB_NO_TRANSFER_DMA_MAP; - urb->interval = 1 << (ep->desc.bInterval - 1); - urb->complete = isoc_irq; - urb->number_of_packets = npkt; - for (i = 0; i < npkt; i++) { - urb->iso_frame_desc[i].length = psize; - urb->iso_frame_desc[i].offset = psize * i; - } - } else { /* bulk */ - urb->pipe = usb_rcvbulkpipe(gspca_dev->dev, - ep->desc.bEndpointAddress); - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; - urb->complete = bulk_irq; - } - } - return 0; -} - -/* - * start the USB transfer - */ -static int gspca_init_transfer(struct gspca_dev *gspca_dev) -{ - struct usb_interface *intf; - struct usb_host_endpoint *ep; - struct urb *urb; - struct ep_tb_s ep_tb[MAX_ALT]; - int n, ret, xfer, alt, alt_idx; - - /* reset the streaming variables */ - gspca_dev->image = NULL; - gspca_dev->image_len = 0; - gspca_dev->last_packet_type = DISCARD_PACKET; - gspca_dev->sequence = 0; - - gspca_dev->usb_err = 0; - - /* do the specific subdriver stuff before endpoint selection */ - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - gspca_dev->alt = gspca_dev->cam.bulk ? intf->num_altsetting : 0; - if (gspca_dev->sd_desc->isoc_init) { - ret = gspca_dev->sd_desc->isoc_init(gspca_dev); - if (ret < 0) - return ret; - } - xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK - : USB_ENDPOINT_XFER_ISOC; - - /* if bulk or the subdriver forced an altsetting, get the endpoint */ - if (gspca_dev->alt != 0) { - gspca_dev->alt--; /* (previous version compatibility) */ - ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer); - if (ep == NULL) { - pr_err("bad altsetting %d\n", gspca_dev->alt); - return -EIO; - } - ep_tb[0].alt = gspca_dev->alt; - alt_idx = 1; - } else { - - /* else, compute the minimum bandwidth - * and build the endpoint table */ - alt_idx = build_isoc_ep_tb(gspca_dev, intf, ep_tb); - if (alt_idx <= 0) { - pr_err("no transfer endpoint found\n"); - return -EIO; - } - } - - /* set the highest alternate setting and - * loop until urb submit succeeds */ - gspca_input_destroy_urb(gspca_dev); - - gspca_dev->alt = ep_tb[--alt_idx].alt; - alt = -1; - for (;;) { - if (alt != gspca_dev->alt) { - alt = gspca_dev->alt; - if (intf->num_altsetting > 1) { - ret = usb_set_interface(gspca_dev->dev, - gspca_dev->iface, - alt); - if (ret < 0) { - if (ret == -ENOSPC) - goto retry; /*fixme: ugly*/ - pr_err("set alt %d err %d\n", alt, ret); - goto out; - } - } - } - if (!gspca_dev->cam.no_urb_create) { - PDEBUG(D_STREAM, "init transfer alt %d", alt); - ret = create_urbs(gspca_dev, - alt_xfer(&intf->altsetting[alt], xfer)); - if (ret < 0) { - destroy_urbs(gspca_dev); - goto out; - } - } - - /* clear the bulk endpoint */ - if (gspca_dev->cam.bulk) - usb_clear_halt(gspca_dev->dev, - gspca_dev->urb[0]->pipe); - - /* start the cam */ - ret = gspca_dev->sd_desc->start(gspca_dev); - if (ret < 0) { - destroy_urbs(gspca_dev); - goto out; - } - gspca_dev->streaming = 1; - v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); - - /* some bulk transfers are started by the subdriver */ - if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) - break; - - /* submit the URBs */ - for (n = 0; n < MAX_NURBS; n++) { - urb = gspca_dev->urb[n]; - if (urb == NULL) - break; - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret < 0) - break; - } - if (ret >= 0) - break; /* transfer is started */ - - /* something when wrong - * stop the webcam and free the transfer resources */ - gspca_stream_off(gspca_dev); - if (ret != -ENOSPC) { - pr_err("usb_submit_urb alt %d err %d\n", - gspca_dev->alt, ret); - goto out; - } - - /* the bandwidth is not wide enough - * negotiate or try a lower alternate setting */ -retry: - PDEBUG(D_ERR|D_STREAM, - "alt %d - bandwidth not wide enough - trying again", - alt); - msleep(20); /* wait for kill complete */ - if (gspca_dev->sd_desc->isoc_nego) { - ret = gspca_dev->sd_desc->isoc_nego(gspca_dev); - if (ret < 0) - goto out; - } else { - if (alt_idx <= 0) { - pr_err("no transfer endpoint found\n"); - ret = -EIO; - goto out; - } - gspca_dev->alt = ep_tb[--alt_idx].alt; - } - } -out: - gspca_input_create_urb(gspca_dev); - return ret; -} - -static void gspca_set_default_mode(struct gspca_dev *gspca_dev) -{ - struct gspca_ctrl *ctrl; - int i; - - i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ - gspca_dev->curr_mode = i; - gspca_dev->width = gspca_dev->cam.cam_mode[i].width; - gspca_dev->height = gspca_dev->cam.cam_mode[i].height; - gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; - - /* set the current control values to their default values - * which may have changed in sd_init() */ - /* does nothing if ctrl_handler == NULL */ - v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); - ctrl = gspca_dev->cam.ctrls; - if (ctrl != NULL) { - for (i = 0; - i < gspca_dev->sd_desc->nctrls; - i++, ctrl++) - ctrl->val = ctrl->def; - } -} - -static int wxh_to_mode(struct gspca_dev *gspca_dev, - int width, int height) -{ - int i; - - for (i = gspca_dev->cam.nmodes; --i > 0; ) { - if (width >= gspca_dev->cam.cam_mode[i].width - && height >= gspca_dev->cam.cam_mode[i].height) - break; - } - return i; -} - -/* - * search a mode with the right pixel format - */ -static int gspca_get_mode(struct gspca_dev *gspca_dev, - int mode, - int pixfmt) -{ - int modeU, modeD; - - modeU = modeD = mode; - while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) { - if (--modeD >= 0) { - if (gspca_dev->cam.cam_mode[modeD].pixelformat - == pixfmt) - return modeD; - } - if (++modeU < gspca_dev->cam.nmodes) { - if (gspca_dev->cam.cam_mode[modeU].pixelformat - == pixfmt) - return modeU; - } - } - return -EINVAL; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - gspca_dev->usb_err = 0; - return gspca_dev->sd_desc->get_register(gspca_dev, reg); -} - -static int vidioc_s_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - gspca_dev->usb_err = 0; - return gspca_dev->sd_desc->set_register(gspca_dev, reg); -} -#endif - -static int vidioc_g_chip_ident(struct file *file, void *priv, - struct v4l2_dbg_chip_ident *chip) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - gspca_dev->usb_err = 0; - return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *fmtdesc) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int i, j, index; - __u32 fmt_tb[8]; - - /* give an index to each format */ - index = 0; - j = 0; - for (i = gspca_dev->cam.nmodes; --i >= 0; ) { - fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat; - j = 0; - for (;;) { - if (fmt_tb[j] == fmt_tb[index]) - break; - j++; - } - if (j == index) { - if (fmtdesc->index == index) - break; /* new format */ - index++; - if (index >= ARRAY_SIZE(fmt_tb)) - return -EINVAL; - } - } - if (i < 0) - return -EINVAL; /* no more format */ - - fmtdesc->pixelformat = fmt_tb[index]; - if (gspca_dev->cam.cam_mode[i].sizeimage < - gspca_dev->cam.cam_mode[i].width * - gspca_dev->cam.cam_mode[i].height) - fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; - fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; - fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; - fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; - fmtdesc->description[3] = fmtdesc->pixelformat >> 24; - fmtdesc->description[4] = '\0'; - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *fmt) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int mode; - - mode = gspca_dev->curr_mode; - fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; - /* some drivers use priv internally, zero it before giving it to - userspace */ - fmt->fmt.pix.priv = 0; - return 0; -} - -static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, - struct v4l2_format *fmt) -{ - int w, h, mode, mode2; - - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; - -#ifdef GSPCA_DEBUG - if (gspca_debug & D_CONF) - PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); -#endif - /* search the closest mode for width and height */ - mode = wxh_to_mode(gspca_dev, w, h); - - /* OK if right palette */ - if (gspca_dev->cam.cam_mode[mode].pixelformat - != fmt->fmt.pix.pixelformat) { - - /* else, search the closest mode with the same pixel format */ - mode2 = gspca_get_mode(gspca_dev, mode, - fmt->fmt.pix.pixelformat); - if (mode2 >= 0) - mode = mode2; -/* else - ; * no chance, return this mode */ - } - fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; - /* some drivers use priv internally, zero it before giving it to - userspace */ - fmt->fmt.pix.priv = 0; - return mode; /* used when s_fmt */ -} - -static int vidioc_try_fmt_vid_cap(struct file *file, - void *priv, - struct v4l2_format *fmt) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; - - ret = try_fmt_vid_cap(gspca_dev, fmt); - if (ret < 0) - return ret; - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *fmt) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - ret = try_fmt_vid_cap(gspca_dev, fmt); - if (ret < 0) - goto out; - - if (gspca_dev->nframes != 0 - && fmt->fmt.pix.sizeimage > gspca_dev->frsz) { - ret = -EINVAL; - goto out; - } - - if (ret == gspca_dev->curr_mode) { - ret = 0; - goto out; /* same mode */ - } - - if (gspca_dev->streaming) { - ret = -EBUSY; - goto out; - } - gspca_dev->width = fmt->fmt.pix.width; - gspca_dev->height = fmt->fmt.pix.height; - gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; - gspca_dev->curr_mode = ret; - - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -static int vidioc_enum_framesizes(struct file *file, void *priv, - struct v4l2_frmsizeenum *fsize) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int i; - __u32 index = 0; - - for (i = 0; i < gspca_dev->cam.nmodes; i++) { - if (fsize->pixel_format != - gspca_dev->cam.cam_mode[i].pixelformat) - continue; - - if (fsize->index == index) { - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = - gspca_dev->cam.cam_mode[i].width; - fsize->discrete.height = - gspca_dev->cam.cam_mode[i].height; - return 0; - } - index++; - } - - return -EINVAL; -} - -static int vidioc_enum_frameintervals(struct file *filp, void *priv, - struct v4l2_frmivalenum *fival) -{ - struct gspca_dev *gspca_dev = video_drvdata(filp); - int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); - __u32 i; - - if (gspca_dev->cam.mode_framerates == NULL || - gspca_dev->cam.mode_framerates[mode].nrates == 0) - return -EINVAL; - - if (fival->pixel_format != - gspca_dev->cam.cam_mode[mode].pixelformat) - return -EINVAL; - - for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) { - if (fival->index == i) { - fival->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fival->discrete.numerator = 1; - fival->discrete.denominator = - gspca_dev->cam.mode_framerates[mode].rates[i]; - return 0; - } - } - - return -EINVAL; -} - -static void gspca_release(struct v4l2_device *v4l2_device) -{ - struct gspca_dev *gspca_dev = - container_of(v4l2_device, struct gspca_dev, v4l2_dev); - - v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); - v4l2_device_unregister(&gspca_dev->v4l2_dev); - kfree(gspca_dev->usb_buf); - kfree(gspca_dev); -} - -static int dev_open(struct file *file) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - PDEBUG(D_STREAM, "[%s] open", current->comm); - - /* protect the subdriver against rmmod */ - if (!try_module_get(gspca_dev->module)) - return -ENODEV; - -#ifdef GSPCA_DEBUG - /* activate the v4l2 debug */ - if (gspca_debug & D_V4L2) - gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG; - else - gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG); -#endif - return v4l2_fh_open(file); -} - -static int dev_close(struct file *file) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - PDEBUG(D_STREAM, "[%s] close", current->comm); - - /* Needed for gspca_stream_off, always lock before queue_lock! */ - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) - return -ERESTARTSYS; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) { - mutex_unlock(&gspca_dev->usb_lock); - return -ERESTARTSYS; - } - - /* if the file did the capture, free the streaming resources */ - if (gspca_dev->capt_file == file) { - if (gspca_dev->streaming) - gspca_stream_off(gspca_dev); - frame_free(gspca_dev); - } - module_put(gspca_dev->module); - mutex_unlock(&gspca_dev->queue_lock); - mutex_unlock(&gspca_dev->usb_lock); - - PDEBUG(D_STREAM, "close done"); - - return v4l2_fh_release(file); -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - strlcpy((char *) cap->driver, gspca_dev->sd_desc->name, - sizeof cap->driver); - if (gspca_dev->dev->product != NULL) { - strlcpy((char *) cap->card, gspca_dev->dev->product, - sizeof cap->card); - } else { - snprintf((char *) cap->card, sizeof cap->card, - "USB Camera (%04x:%04x)", - le16_to_cpu(gspca_dev->dev->descriptor.idVendor), - le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); - } - usb_make_path(gspca_dev->dev, (char *) cap->bus_info, - sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE - | V4L2_CAP_STREAMING - | V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; -} - -static int get_ctrl(struct gspca_dev *gspca_dev, - int id) -{ - const struct ctrl *ctrls; - int i; - - for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; - i < gspca_dev->sd_desc->nctrls; - i++, ctrls++) { - if (gspca_dev->ctrl_dis & (1 << i)) - continue; - if (id == ctrls->qctrl.id) - return i; - } - return -1; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *q_ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - struct gspca_ctrl *gspca_ctrl; - int i, idx; - u32 id; - - id = q_ctrl->id; - if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { - id &= V4L2_CTRL_ID_MASK; - id++; - idx = -1; - for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { - if (gspca_dev->ctrl_dis & (1 << i)) - continue; - if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) - continue; - if (idx >= 0 - && gspca_dev->sd_desc->ctrls[i].qctrl.id - > gspca_dev->sd_desc->ctrls[idx].qctrl.id) - continue; - idx = i; - } - } else { - idx = get_ctrl(gspca_dev, id); - } - if (idx < 0) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl); - if (gspca_dev->cam.ctrls != NULL) { - gspca_ctrl = &gspca_dev->cam.ctrls[idx]; - q_ctrl->default_value = gspca_ctrl->def; - q_ctrl->minimum = gspca_ctrl->min; - q_ctrl->maximum = gspca_ctrl->max; - } - if (gspca_dev->ctrl_inac & (1 << idx)) - q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - struct gspca_ctrl *gspca_ctrl; - int idx; - - idx = get_ctrl(gspca_dev, ctrl->id); - if (idx < 0) - return -EINVAL; - if (gspca_dev->ctrl_inac & (1 << idx)) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - if (gspca_dev->cam.ctrls != NULL) { - gspca_ctrl = &gspca_dev->cam.ctrls[idx]; - if (ctrl->value < gspca_ctrl->min - || ctrl->value > gspca_ctrl->max) - return -ERANGE; - } else { - gspca_ctrl = NULL; - if (ctrl->value < ctrls->qctrl.minimum - || ctrl->value > ctrls->qctrl.maximum) - return -ERANGE; - } - PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); - gspca_dev->usb_err = 0; - if (ctrls->set != NULL) - return ctrls->set(gspca_dev, ctrl->value); - if (gspca_ctrl != NULL) { - gspca_ctrl->val = ctrl->value; - if (ctrls->set_control != NULL - && gspca_dev->streaming) - ctrls->set_control(gspca_dev); - } - return gspca_dev->usb_err; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - const struct ctrl *ctrls; - int idx; - - idx = get_ctrl(gspca_dev, ctrl->id); - if (idx < 0) - return -EINVAL; - ctrls = &gspca_dev->sd_desc->ctrls[idx]; - - gspca_dev->usb_err = 0; - if (ctrls->get != NULL) - return ctrls->get(gspca_dev, &ctrl->value); - if (gspca_dev->cam.ctrls != NULL) - ctrl->value = gspca_dev->cam.ctrls[idx].val; - return 0; -} - -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *qmenu) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - if (!gspca_dev->sd_desc->querymenu) - return -ENOTTY; - return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu); -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *input) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - if (input->index != 0) - return -EINVAL; - input->type = V4L2_INPUT_TYPE_CAMERA; - input->status = gspca_dev->cam.input_flags; - strlcpy(input->name, gspca_dev->sd_desc->name, - sizeof input->name); - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - if (i > 0) - return -EINVAL; - return (0); -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *rb) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int i, ret = 0, streaming; - - i = rb->memory; /* (avoid compilation warning) */ - switch (i) { - case GSPCA_MEMORY_READ: /* (internal call) */ - case V4L2_MEMORY_MMAP: - case V4L2_MEMORY_USERPTR: - break; - default: - return -EINVAL; - } - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - if (gspca_dev->memory != GSPCA_MEMORY_NO - && gspca_dev->memory != GSPCA_MEMORY_READ - && gspca_dev->memory != rb->memory) { - ret = -EBUSY; - goto out; - } - - /* only one file may do the capture */ - if (gspca_dev->capt_file != NULL - && gspca_dev->capt_file != file) { - ret = -EBUSY; - goto out; - } - - /* if allocated, the buffers must not be mapped */ - for (i = 0; i < gspca_dev->nframes; i++) { - if (gspca_dev->frame[i].vma_use_count) { - ret = -EBUSY; - goto out; - } - } - - /* stop streaming */ - streaming = gspca_dev->streaming; - if (streaming) { - gspca_stream_off(gspca_dev); - - /* Don't restart the stream when switching from read - * to mmap mode */ - if (gspca_dev->memory == GSPCA_MEMORY_READ) - streaming = 0; - } - - /* free the previous allocated buffers, if any */ - if (gspca_dev->nframes != 0) - frame_free(gspca_dev); - if (rb->count == 0) /* unrequest */ - goto out; - ret = frame_alloc(gspca_dev, file, rb->memory, rb->count); - if (ret == 0) { - rb->count = gspca_dev->nframes; - if (streaming) - ret = gspca_init_transfer(gspca_dev); - } -out: - mutex_unlock(&gspca_dev->queue_lock); - PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count); - return ret; -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *v4l2_buf) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - struct gspca_frame *frame; - - if (v4l2_buf->index < 0 - || v4l2_buf->index >= gspca_dev->nframes) - return -EINVAL; - - frame = &gspca_dev->frame[v4l2_buf->index]; - memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); - return 0; -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type buf_type) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; - - if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - /* check the capture file */ - if (gspca_dev->capt_file != file) { - ret = -EBUSY; - goto out; - } - - if (gspca_dev->nframes == 0 - || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { - ret = -EINVAL; - goto out; - } - if (!gspca_dev->streaming) { - ret = gspca_init_transfer(gspca_dev); - if (ret < 0) - goto out; - } -#ifdef GSPCA_DEBUG - if (gspca_debug & D_STREAM) { - PDEBUG_MODE("stream on OK", - gspca_dev->pixfmt, - gspca_dev->width, - gspca_dev->height); - } -#endif - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type buf_type) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - int i, ret; - - if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - if (!gspca_dev->streaming) { - ret = 0; - goto out; - } - - /* check the capture file */ - if (gspca_dev->capt_file != file) { - ret = -EBUSY; - goto out; - } - - /* stop streaming */ - gspca_stream_off(gspca_dev); - /* In case another thread is waiting in dqbuf */ - wake_up_interruptible(&gspca_dev->wq); - - /* empty the transfer queues */ - for (i = 0; i < gspca_dev->nframes; i++) - gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; - atomic_set(&gspca_dev->fr_q, 0); - atomic_set(&gspca_dev->fr_i, 0); - gspca_dev->fr_o = 0; - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -static int vidioc_g_jpegcomp(struct file *file, void *priv, - struct v4l2_jpegcompression *jpegcomp) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - gspca_dev->usb_err = 0; - return gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); -} - -static int vidioc_s_jpegcomp(struct file *file, void *priv, - struct v4l2_jpegcompression *jpegcomp) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - - gspca_dev->usb_err = 0; - return gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); -} - -static int vidioc_g_parm(struct file *filp, void *priv, - struct v4l2_streamparm *parm) -{ - struct gspca_dev *gspca_dev = video_drvdata(filp); - - parm->parm.capture.readbuffers = gspca_dev->nbufread; - - if (gspca_dev->sd_desc->get_streamparm) { - gspca_dev->usb_err = 0; - gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); - return gspca_dev->usb_err; - } - return 0; -} - -static int vidioc_s_parm(struct file *filp, void *priv, - struct v4l2_streamparm *parm) -{ - struct gspca_dev *gspca_dev = video_drvdata(filp); - int n; - - n = parm->parm.capture.readbuffers; - if (n == 0 || n >= GSPCA_MAX_FRAMES) - parm->parm.capture.readbuffers = gspca_dev->nbufread; - else - gspca_dev->nbufread = n; - - if (gspca_dev->sd_desc->set_streamparm) { - gspca_dev->usb_err = 0; - gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); - return gspca_dev->usb_err; - } - - return 0; -} - -static int dev_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - struct gspca_frame *frame; - struct page *page; - unsigned long addr, start, size; - int i, ret; - - start = vma->vm_start; - size = vma->vm_end - vma->vm_start; - PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size); - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - if (gspca_dev->capt_file != file) { - ret = -EINVAL; - goto out; - } - - frame = NULL; - for (i = 0; i < gspca_dev->nframes; ++i) { - if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) { - PDEBUG(D_STREAM, "mmap bad memory type"); - break; - } - if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT) - == vma->vm_pgoff) { - frame = &gspca_dev->frame[i]; - break; - } - } - if (frame == NULL) { - PDEBUG(D_STREAM, "mmap no frame buffer found"); - ret = -EINVAL; - goto out; - } - if (size != frame->v4l2_buf.length) { - PDEBUG(D_STREAM, "mmap bad size"); - ret = -EINVAL; - goto out; - } - - /* - * - VM_IO marks the area as being a mmaped region for I/O to a - * device. It also prevents the region from being core dumped. - */ - vma->vm_flags |= VM_IO; - - addr = (unsigned long) frame->data; - while (size > 0) { - page = vmalloc_to_page((void *) addr); - ret = vm_insert_page(vma, start, page); - if (ret < 0) - goto out; - start += PAGE_SIZE; - addr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vma->vm_ops = &gspca_vm_ops; - vma->vm_private_data = frame; - gspca_vm_open(vma); - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file, - enum v4l2_memory memory) -{ - if (!gspca_dev->present) - return -ENODEV; - if (gspca_dev->capt_file != file || gspca_dev->memory != memory || - !gspca_dev->streaming) - return -EINVAL; - - /* check if a frame is ready */ - return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i); -} - -static int frame_ready(struct gspca_dev *gspca_dev, struct file *file, - enum v4l2_memory memory) -{ - int ret; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - ret = frame_ready_nolock(gspca_dev, file, memory); - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -/* - * dequeue a video buffer - * - * If nonblock_ing is false, block until a buffer is available. - */ -static int vidioc_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *v4l2_buf) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - struct gspca_frame *frame; - int i, j, ret; - - PDEBUG(D_FRAM, "dqbuf"); - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - for (;;) { - ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory); - if (ret < 0) - goto out; - if (ret > 0) - break; - - mutex_unlock(&gspca_dev->queue_lock); - - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - /* wait till a frame is ready */ - ret = wait_event_interruptible_timeout(gspca_dev->wq, - frame_ready(gspca_dev, file, v4l2_buf->memory), - msecs_to_jiffies(3000)); - if (ret < 0) - return ret; - if (ret == 0) - return -EIO; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - } - - i = gspca_dev->fr_o; - j = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[j]; - - gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; - - frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; - memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); - PDEBUG(D_FRAM, "dqbuf %d", j); - ret = 0; - - if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { - if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, - frame->data, - frame->v4l2_buf.bytesused)) { - PDEBUG(D_ERR|D_STREAM, - "dqbuf cp to user failed"); - ret = -EFAULT; - } - } -out: - mutex_unlock(&gspca_dev->queue_lock); - - if (ret == 0 && gspca_dev->sd_desc->dq_callback) { - mutex_lock(&gspca_dev->usb_lock); - gspca_dev->usb_err = 0; - if (gspca_dev->present) - gspca_dev->sd_desc->dq_callback(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - } - - return ret; -} - -/* - * queue a video buffer - * - * Attempting to queue a buffer that has already been - * queued will return -EINVAL. - */ -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *v4l2_buf) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - struct gspca_frame *frame; - int i, index, ret; - - PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index); - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - - index = v4l2_buf->index; - if ((unsigned) index >= gspca_dev->nframes) { - PDEBUG(D_FRAM, - "qbuf idx %d >= %d", index, gspca_dev->nframes); - ret = -EINVAL; - goto out; - } - if (v4l2_buf->memory != gspca_dev->memory) { - PDEBUG(D_FRAM, "qbuf bad memory type"); - ret = -EINVAL; - goto out; - } - - frame = &gspca_dev->frame[index]; - if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { - PDEBUG(D_FRAM, "qbuf bad state"); - ret = -EINVAL; - goto out; - } - - frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; - - if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { - frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; - frame->v4l2_buf.length = v4l2_buf->length; - } - - /* put the buffer in the 'queued' queue */ - i = atomic_read(&gspca_dev->fr_q); - gspca_dev->fr_queue[i] = index; - atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES); - - v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; - v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE; - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - -/* - * allocate the resources for read() - */ -static int read_alloc(struct gspca_dev *gspca_dev, - struct file *file) -{ - struct v4l2_buffer v4l2_buf; - int i, ret; - - PDEBUG(D_STREAM, "read alloc"); - - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) - return -ERESTARTSYS; - - if (gspca_dev->nframes == 0) { - struct v4l2_requestbuffers rb; - - memset(&rb, 0, sizeof rb); - rb.count = gspca_dev->nbufread; - rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - rb.memory = GSPCA_MEMORY_READ; - ret = vidioc_reqbufs(file, gspca_dev, &rb); - if (ret != 0) { - PDEBUG(D_STREAM, "read reqbuf err %d", ret); - goto out; - } - memset(&v4l2_buf, 0, sizeof v4l2_buf); - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buf.memory = GSPCA_MEMORY_READ; - for (i = 0; i < gspca_dev->nbufread; i++) { - v4l2_buf.index = i; - ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); - if (ret != 0) { - PDEBUG(D_STREAM, "read qbuf err: %d", ret); - goto out; - } - } - } - - /* start streaming */ - ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (ret != 0) - PDEBUG(D_STREAM, "read streamon err %d", ret); -out: - mutex_unlock(&gspca_dev->usb_lock); - return ret; -} - -static unsigned int dev_poll(struct file *file, poll_table *wait) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - unsigned long req_events = poll_requested_events(wait); - int ret = 0; - - PDEBUG(D_FRAM, "poll"); - - if (req_events & POLLPRI) - ret |= v4l2_ctrl_poll(file, wait); - - if (req_events & (POLLIN | POLLRDNORM)) { - /* if reqbufs is not done, the user would use read() */ - if (gspca_dev->memory == GSPCA_MEMORY_NO) { - if (read_alloc(gspca_dev, file) != 0) { - ret |= POLLERR; - goto out; - } - } - - poll_wait(file, &gspca_dev->wq, wait); - - /* check if an image has been received */ - if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) { - ret |= POLLERR; - goto out; - } - if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i)) - ret |= POLLIN | POLLRDNORM; - mutex_unlock(&gspca_dev->queue_lock); - } - -out: - if (!gspca_dev->present) - ret |= POLLHUP; - - return ret; -} - -static ssize_t dev_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct gspca_dev *gspca_dev = video_drvdata(file); - struct gspca_frame *frame; - struct v4l2_buffer v4l2_buf; - struct timeval timestamp; - int n, ret, ret2; - - PDEBUG(D_FRAM, "read (%zd)", count); - if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */ - ret = read_alloc(gspca_dev, file); - if (ret != 0) - return ret; - } - - /* get a frame */ - timestamp = ktime_to_timeval(ktime_get()); - timestamp.tv_sec--; - n = 2; - for (;;) { - memset(&v4l2_buf, 0, sizeof v4l2_buf); - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buf.memory = GSPCA_MEMORY_READ; - ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf); - if (ret != 0) { - PDEBUG(D_STREAM, "read dqbuf err %d", ret); - return ret; - } - - /* if the process slept for more than 1 second, - * get a newer frame */ - frame = &gspca_dev->frame[v4l2_buf.index]; - if (--n < 0) - break; /* avoid infinite loop */ - if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec) - break; - ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); - if (ret != 0) { - PDEBUG(D_STREAM, "read qbuf err %d", ret); - return ret; - } - } - - /* copy the frame */ - if (count > frame->v4l2_buf.bytesused) - count = frame->v4l2_buf.bytesused; - ret = copy_to_user(data, frame->data, count); - if (ret != 0) { - PDEBUG(D_ERR|D_STREAM, - "read cp to user lack %d / %zd", ret, count); - ret = -EFAULT; - goto out; - } - ret = count; -out: - /* in each case, requeue the buffer */ - ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf); - if (ret2 != 0) - return ret2; - return ret; -} - -static struct v4l2_file_operations dev_fops = { - .owner = THIS_MODULE, - .open = dev_open, - .release = dev_close, - .read = dev_read, - .mmap = dev_mmap, - .unlocked_ioctl = video_ioctl2, - .poll = dev_poll, -}; - -static const struct v4l2_ioctl_ops dev_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_streamon = vidioc_streamon, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_querymenu = vidioc_querymenu, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_jpegcomp = vidioc_g_jpegcomp, - .vidioc_s_jpegcomp = vidioc_s_jpegcomp, - .vidioc_g_parm = vidioc_g_parm, - .vidioc_s_parm = vidioc_s_parm, - .vidioc_enum_framesizes = vidioc_enum_framesizes, - .vidioc_enum_frameintervals = vidioc_enum_frameintervals, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, -#endif - .vidioc_g_chip_ident = vidioc_g_chip_ident, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -}; - -static const struct video_device gspca_template = { - .name = "gspca main driver", - .fops = &dev_fops, - .ioctl_ops = &dev_ioctl_ops, - .release = video_device_release_empty, /* We use v4l2_dev.release */ -}; - -/* initialize the controls */ -static void ctrls_init(struct gspca_dev *gspca_dev) -{ - struct gspca_ctrl *ctrl; - int i; - - for (i = 0, ctrl = gspca_dev->cam.ctrls; - i < gspca_dev->sd_desc->nctrls; - i++, ctrl++) { - ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value; - ctrl->val = ctrl->def; - ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum; - ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum; - } -} - -/* - * probe and create a new gspca device - * - * This function must be called by the sub-driver when it is - * called for probing a new device. - */ -int gspca_dev_probe2(struct usb_interface *intf, - const struct usb_device_id *id, - const struct sd_desc *sd_desc, - int dev_size, - struct module *module) -{ - struct gspca_dev *gspca_dev; - struct usb_device *dev = interface_to_usbdev(intf); - int ret; - - pr_info("%s-" GSPCA_VERSION " probing %04x:%04x\n", - sd_desc->name, id->idVendor, id->idProduct); - - /* create the device */ - if (dev_size < sizeof *gspca_dev) - dev_size = sizeof *gspca_dev; - gspca_dev = kzalloc(dev_size, GFP_KERNEL); - if (!gspca_dev) { - pr_err("couldn't kzalloc gspca struct\n"); - return -ENOMEM; - } - gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); - if (!gspca_dev->usb_buf) { - pr_err("out of memory\n"); - ret = -ENOMEM; - goto out; - } - gspca_dev->dev = dev; - gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; - - /* check if any audio device */ - if (dev->actconfig->desc.bNumInterfaces != 1) { - int i; - struct usb_interface *intf2; - - for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { - intf2 = dev->actconfig->interface[i]; - if (intf2 != NULL - && intf2->altsetting != NULL - && intf2->altsetting->desc.bInterfaceClass == - USB_CLASS_AUDIO) { - gspca_dev->audio = 1; - break; - } - } - } - - gspca_dev->v4l2_dev.release = gspca_release; - ret = v4l2_device_register(&intf->dev, &gspca_dev->v4l2_dev); - if (ret) - goto out; - gspca_dev->sd_desc = sd_desc; - gspca_dev->nbufread = 2; - gspca_dev->empty_packet = -1; /* don't check the empty packets */ - gspca_dev->vdev = gspca_template; - gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev; - video_set_drvdata(&gspca_dev->vdev, gspca_dev); - set_bit(V4L2_FL_USE_FH_PRIO, &gspca_dev->vdev.flags); - gspca_dev->module = module; - gspca_dev->present = 1; - - mutex_init(&gspca_dev->usb_lock); - gspca_dev->vdev.lock = &gspca_dev->usb_lock; - mutex_init(&gspca_dev->queue_lock); - init_waitqueue_head(&gspca_dev->wq); - - /* configure the subdriver and initialize the USB device */ - ret = sd_desc->config(gspca_dev, id); - if (ret < 0) - goto out; - if (gspca_dev->cam.ctrls != NULL) - ctrls_init(gspca_dev); - ret = sd_desc->init(gspca_dev); - if (ret < 0) - goto out; - if (sd_desc->init_controls) - ret = sd_desc->init_controls(gspca_dev); - if (ret < 0) - goto out; - gspca_set_default_mode(gspca_dev); - - ret = gspca_input_connect(gspca_dev); - if (ret) - goto out; - - /* - * Don't take usb_lock for these ioctls. This improves latency if - * usb_lock is taken for a long time, e.g. when changing a control - * value, and a new frame is ready to be dequeued. - */ - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF); - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF); - v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF); - if (!gspca_dev->sd_desc->get_chip_ident) - v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT); -#ifdef CONFIG_VIDEO_ADV_DEBUG - if (!gspca_dev->sd_desc->get_chip_ident || - !gspca_dev->sd_desc->get_register) - v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER); - if (!gspca_dev->sd_desc->get_chip_ident || - !gspca_dev->sd_desc->set_register) - v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER); -#endif - if (!gspca_dev->sd_desc->get_jcomp) - v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_G_JPEGCOMP); - if (!gspca_dev->sd_desc->set_jcomp) - v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_S_JPEGCOMP); - - /* init video stuff */ - ret = video_register_device(&gspca_dev->vdev, - VFL_TYPE_GRABBER, - -1); - if (ret < 0) { - pr_err("video_register_device err %d\n", ret); - goto out; - } - - usb_set_intfdata(intf, gspca_dev); - PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); - - gspca_input_create_urb(gspca_dev); - - return 0; -out: -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - if (gspca_dev->input_dev) - input_unregister_device(gspca_dev->input_dev); -#endif - v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); - kfree(gspca_dev->usb_buf); - kfree(gspca_dev); - return ret; -} -EXPORT_SYMBOL(gspca_dev_probe2); - -/* same function as the previous one, but check the interface */ -int gspca_dev_probe(struct usb_interface *intf, - const struct usb_device_id *id, - const struct sd_desc *sd_desc, - int dev_size, - struct module *module) -{ - struct usb_device *dev = interface_to_usbdev(intf); - - /* we don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) { - pr_err("%04x:%04x too many config\n", - id->idVendor, id->idProduct); - return -ENODEV; - } - - /* the USB video interface must be the first one */ - if (dev->actconfig->desc.bNumInterfaces != 1 - && intf->cur_altsetting->desc.bInterfaceNumber != 0) - return -ENODEV; - - return gspca_dev_probe2(intf, id, sd_desc, dev_size, module); -} -EXPORT_SYMBOL(gspca_dev_probe); - -/* - * USB disconnection - * - * This function must be called by the sub-driver - * when the device disconnects, after the specific resources are freed. - */ -void gspca_disconnect(struct usb_interface *intf) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - struct input_dev *input_dev; -#endif - - PDEBUG(D_PROBE, "%s disconnect", - video_device_node_name(&gspca_dev->vdev)); - - mutex_lock(&gspca_dev->usb_lock); - - usb_set_intfdata(intf, NULL); - gspca_dev->dev = NULL; - gspca_dev->present = 0; - destroy_urbs(gspca_dev); - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - gspca_input_destroy_urb(gspca_dev); - input_dev = gspca_dev->input_dev; - if (input_dev) { - gspca_dev->input_dev = NULL; - input_unregister_device(input_dev); - } -#endif - /* Free subdriver's streaming resources / stop sd workqueue(s) */ - if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming) - gspca_dev->sd_desc->stop0(gspca_dev); - gspca_dev->streaming = 0; - wake_up_interruptible(&gspca_dev->wq); - - v4l2_device_disconnect(&gspca_dev->v4l2_dev); - video_unregister_device(&gspca_dev->vdev); - - mutex_unlock(&gspca_dev->usb_lock); - - /* (this will call gspca_release() immediately or on last close) */ - v4l2_device_put(&gspca_dev->v4l2_dev); -} -EXPORT_SYMBOL(gspca_disconnect); - -#ifdef CONFIG_PM -int gspca_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - - if (!gspca_dev->streaming) - return 0; - mutex_lock(&gspca_dev->usb_lock); - gspca_dev->frozen = 1; /* avoid urb error messages */ - gspca_dev->usb_err = 0; - if (gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - gspca_input_destroy_urb(gspca_dev); - gspca_set_alt0(gspca_dev); - if (gspca_dev->sd_desc->stop0) - gspca_dev->sd_desc->stop0(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - return 0; -} -EXPORT_SYMBOL(gspca_suspend); - -int gspca_resume(struct usb_interface *intf) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - int streaming, ret = 0; - - mutex_lock(&gspca_dev->usb_lock); - gspca_dev->frozen = 0; - gspca_dev->usb_err = 0; - gspca_dev->sd_desc->init(gspca_dev); - gspca_input_create_urb(gspca_dev); - /* - * Most subdrivers send all ctrl values on sd_start and thus - * only write to the device registers on s_ctrl when streaming -> - * Clear streaming to avoid setting all ctrls twice. - */ - streaming = gspca_dev->streaming; - gspca_dev->streaming = 0; - if (streaming) - ret = gspca_init_transfer(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - return ret; -} -EXPORT_SYMBOL(gspca_resume); -#endif - -/* -- module insert / remove -- */ -static int __init gspca_init(void) -{ - pr_info("v" GSPCA_VERSION " registered\n"); - return 0; -} -static void __exit gspca_exit(void) -{ -} - -module_init(gspca_init); -module_exit(gspca_exit); - -#ifdef GSPCA_DEBUG -module_param_named(debug, gspca_debug, int, 0644); -MODULE_PARM_DESC(debug, - "Debug (bit) 0x01:error 0x02:probe 0x04:config" - " 0x08:stream 0x10:frame 0x20:packet" - " 0x0100: v4l2"); -#endif diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h deleted file mode 100644 index dc688c7f5e48..000000000000 --- a/drivers/media/video/gspca/gspca.h +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef GSPCAV2_H -#define GSPCAV2_H - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/usb.h> -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include <linux/mutex.h> - -/* compilation option */ -/*#define GSPCA_DEBUG 1*/ - -#ifdef GSPCA_DEBUG -/* GSPCA our debug messages */ -extern int gspca_debug; -#define PDEBUG(level, fmt, ...) \ -do { \ - if (gspca_debug & (level)) \ - pr_info(fmt, ##__VA_ARGS__); \ -} while (0) - -#define D_ERR 0x01 -#define D_PROBE 0x02 -#define D_CONF 0x04 -#define D_STREAM 0x08 -#define D_FRAM 0x10 -#define D_PACK 0x20 -#define D_USBI 0x00 -#define D_USBO 0x00 -#define D_V4L2 0x0100 -#else -#define PDEBUG(level, fmt, ...) -#endif - -#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ -/* image transfers */ -#define MAX_NURBS 4 /* max number of URBs */ - - -/* used to list framerates supported by a camera mode (resolution) */ -struct framerates { - const u8 *rates; - int nrates; -}; - -/* control definition */ -struct gspca_ctrl { - s16 val; /* current value */ - s16 def; /* default value */ - s16 min, max; /* minimum and maximum values */ -}; - -/* device information - set at probe time */ -struct cam { - const struct v4l2_pix_format *cam_mode; /* size nmodes */ - const struct framerates *mode_framerates; /* must have size nmodes, - * just like cam_mode */ - struct gspca_ctrl *ctrls; /* control table - size nctrls */ - /* may be NULL */ - u32 bulk_size; /* buffer size when image transfer by bulk */ - u32 input_flags; /* value for ENUM_INPUT status flags */ - u8 nmodes; /* size of cam_mode */ - u8 no_urb_create; /* don't create transfer URBs */ - u8 bulk_nurbs; /* number of URBs in bulk mode - * - cannot be > MAX_NURBS - * - when 0 and bulk_size != 0 means - * 1 URB and submit done by subdriver */ - u8 bulk; /* image transfer by 0:isoc / 1:bulk */ - u8 npkt; /* number of packets in an ISOC message - * 0 is the default value: 32 packets */ - u8 needs_full_bandwidth;/* Set this flag to notify the bandwidth calc. - * code that the cam fills all image buffers to - * the max, even when using compression. */ -}; - -struct gspca_dev; -struct gspca_frame; - -/* subdriver operations */ -typedef int (*cam_op) (struct gspca_dev *); -typedef void (*cam_v_op) (struct gspca_dev *); -typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); -typedef int (*cam_jpg_op) (struct gspca_dev *, - struct v4l2_jpegcompression *); -typedef int (*cam_reg_op) (struct gspca_dev *, - struct v4l2_dbg_register *); -typedef int (*cam_ident_op) (struct gspca_dev *, - struct v4l2_dbg_chip_ident *); -typedef void (*cam_streamparm_op) (struct gspca_dev *, - struct v4l2_streamparm *); -typedef int (*cam_qmnu_op) (struct gspca_dev *, - struct v4l2_querymenu *); -typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, - u8 *data, - int len); -typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev, - u8 *data, - int len); - -struct ctrl { - struct v4l2_queryctrl qctrl; - int (*set)(struct gspca_dev *, __s32); - int (*get)(struct gspca_dev *, __s32 *); - cam_v_op set_control; -}; - -/* subdriver description */ -struct sd_desc { -/* information */ - const char *name; /* sub-driver name */ -/* controls */ - const struct ctrl *ctrls; /* static control definition */ - int nctrls; -/* mandatory operations */ - cam_cf_op config; /* called on probe */ - cam_op init; /* called on probe and resume */ - cam_op init_controls; /* called on probe */ - cam_op start; /* called on stream on after URBs creation */ - cam_pkt_op pkt_scan; -/* optional operations */ - cam_op isoc_init; /* called on stream on before getting the EP */ - cam_op isoc_nego; /* called when URB submit failed with NOSPC */ - cam_v_op stopN; /* called on stream off - main alt */ - cam_v_op stop0; /* called on stream off & disconnect - alt 0 */ - cam_v_op dq_callback; /* called when a frame has been dequeued */ - cam_jpg_op get_jcomp; - cam_jpg_op set_jcomp; - cam_qmnu_op querymenu; - cam_streamparm_op get_streamparm; - cam_streamparm_op set_streamparm; -#ifdef CONFIG_VIDEO_ADV_DEBUG - cam_reg_op set_register; - cam_reg_op get_register; -#endif - cam_ident_op get_chip_ident; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - cam_int_pkt_op int_pkt_scan; - /* other_input makes the gspca core create gspca_dev->input even when - int_pkt_scan is NULL, for cams with non interrupt driven buttons */ - u8 other_input; -#endif -}; - -/* packet types when moving from iso buf to frame buf */ -enum gspca_packet_type { - DISCARD_PACKET, - FIRST_PACKET, - INTER_PACKET, - LAST_PACKET -}; - -struct gspca_frame { - __u8 *data; /* frame buffer */ - int vma_use_count; - struct v4l2_buffer v4l2_buf; -}; - -struct gspca_dev { - struct video_device vdev; /* !! must be the first item */ - struct module *module; /* subdriver handling the device */ - struct v4l2_device v4l2_dev; - struct usb_device *dev; - struct file *capt_file; /* file doing video capture */ - /* protected by queue_lock */ -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - struct input_dev *input_dev; - char phys[64]; /* physical device path */ -#endif - - struct cam cam; /* device information */ - const struct sd_desc *sd_desc; /* subdriver description */ - unsigned ctrl_dis; /* disabled controls (bit map) */ - unsigned ctrl_inac; /* inactive controls (bit map) */ - struct v4l2_ctrl_handler ctrl_handler; - - /* autogain and exposure or gain control cluster, these are global as - the autogain/exposure functions in autogain_functions.c use them */ - struct { - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; - int exp_too_low_cnt, exp_too_high_cnt; - }; - -#define USB_BUF_SZ 64 - __u8 *usb_buf; /* buffer for USB exchanges */ - struct urb *urb[MAX_NURBS]; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - struct urb *int_urb; -#endif - - __u8 *frbuf; /* buffer for nframes */ - struct gspca_frame frame[GSPCA_MAX_FRAMES]; - u8 *image; /* image beeing filled */ - __u32 frsz; /* frame size */ - u32 image_len; /* current length of image */ - atomic_t fr_q; /* next frame to queue */ - atomic_t fr_i; /* frame being filled */ - signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ - char nframes; /* number of frames */ - u8 fr_o; /* next frame to dequeue */ - __u8 last_packet_type; - __s8 empty_packet; /* if (-1) don't check empty packets */ - __u8 streaming; /* protected by both mutexes (*) */ - - __u8 curr_mode; /* current camera mode */ - __u32 pixfmt; /* current mode parameters */ - __u16 width; - __u16 height; - __u32 sequence; /* frame sequence number */ - - wait_queue_head_t wq; /* wait queue */ - struct mutex usb_lock; /* usb exchange protection */ - struct mutex queue_lock; /* ISOC queue protection */ - int usb_err; /* USB error - protected by usb_lock */ - u16 pkt_size; /* ISOC packet size */ -#ifdef CONFIG_PM - char frozen; /* suspend - resume */ -#endif - char present; /* device connected */ - char nbufread; /* number of buffers for read() */ - char memory; /* memory type (V4L2_MEMORY_xxx) */ - __u8 iface; /* USB interface number */ - __u8 alt; /* USB alternate setting */ - u8 audio; /* presence of audio device */ - - /* (*) These variables are proteced by both usb_lock and queue_lock, - that is any code setting them is holding *both*, which means that - any code getting them needs to hold at least one of them */ -}; - -int gspca_dev_probe(struct usb_interface *intf, - const struct usb_device_id *id, - const struct sd_desc *sd_desc, - int dev_size, - struct module *module); -int gspca_dev_probe2(struct usb_interface *intf, - const struct usb_device_id *id, - const struct sd_desc *sd_desc, - int dev_size, - struct module *module); -void gspca_disconnect(struct usb_interface *intf); -void gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, - const u8 *data, - int len); -#ifdef CONFIG_PM -int gspca_suspend(struct usb_interface *intf, pm_message_t message); -int gspca_resume(struct usb_interface *intf); -#endif -int gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum, - int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); -int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev, - int avg_lum, int desired_avg_lum, int deadzone); - -#endif /* GSPCAV2_H */ diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c deleted file mode 100644 index 26b99310d628..000000000000 --- a/drivers/media/video/gspca/jeilinj.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Jeilinj subdriver - * - * Supports some Jeilin dual-mode cameras which use bulk transport and - * download raw JPEG data. - * - * Copyright (C) 2009 Theodore Kilgore - * - * Sportscam DV15 support and control settings are - * Copyright (C) 2011 Patrice Chotard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "jeilinj" - -#include <linux/slab.h> -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define JEILINJ_CMD_TIMEOUT 500 -#define JEILINJ_CMD_DELAY 160 -#define JEILINJ_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define JEILINJ_MAX_TRANSFER 0x200 -#define FRAME_HEADER_LEN 0x10 -#define FRAME_START 0xFFFFFFFF - -enum { - SAKAR_57379, - SPORTSCAM_DV15, -}; - -#define CAMQUALITY_MIN 0 /* highest cam quality */ -#define CAMQUALITY_MAX 97 /* lowest cam quality */ - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - int blocks_left; - const struct v4l2_pix_format *cap_mode; - struct v4l2_ctrl *freq; - struct v4l2_ctrl *jpegqual; - /* Driver stuff */ - u8 type; - u8 quality; /* image quality */ -#define QUALITY_MIN 35 -#define QUALITY_MAX 85 -#define QUALITY_DEF 85 - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -struct jlj_command { - unsigned char instruction[2]; - unsigned char ack_wanted; - unsigned char delay; -}; - -/* AFAICT these cameras will only do 320x240. */ -static struct v4l2_pix_format jlj_mode[] = { - { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, - { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0} -}; - -/* - * cam uses endpoint 0x03 to send commands, 0x84 for read commands, - * and 0x82 for bulk transfer. - */ - -/* All commands are two bytes only */ -static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command) -{ - int retval; - - if (gspca_dev->usb_err < 0) - return; - memcpy(gspca_dev->usb_buf, command, 2); - retval = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 3), - gspca_dev->usb_buf, 2, NULL, 500); - if (retval < 0) { - pr_err("command write [%02x] error %d\n", - gspca_dev->usb_buf[0], retval); - gspca_dev->usb_err = retval; - } -} - -/* Responses are one byte only */ -static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) -{ - int retval; - - if (gspca_dev->usb_err < 0) - return; - retval = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x84), - gspca_dev->usb_buf, 1, NULL, 500); - response = gspca_dev->usb_buf[0]; - if (retval < 0) { - pr_err("read command [%02x] error %d\n", - gspca_dev->usb_buf[0], retval); - gspca_dev->usb_err = retval; - } -} - -static void setfreq(struct gspca_dev *gspca_dev, s32 val) -{ - u8 freq_commands[][2] = { - {0x71, 0x80}, - {0x70, 0x07} - }; - - freq_commands[0][1] |= val >> 1; - - jlj_write2(gspca_dev, freq_commands[0]); - jlj_write2(gspca_dev, freq_commands[1]); -} - -static void setcamquality(struct gspca_dev *gspca_dev, s32 val) -{ - u8 quality_commands[][2] = { - {0x71, 0x1E}, - {0x70, 0x06} - }; - u8 camquality; - - /* adapt camera quality from jpeg quality */ - camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX) - / (QUALITY_MAX - QUALITY_MIN); - quality_commands[0][1] += camquality; - - jlj_write2(gspca_dev, quality_commands[0]); - jlj_write2(gspca_dev, quality_commands[1]); -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - u8 autogain_commands[][2] = { - {0x94, 0x02}, - {0xcf, 0x00} - }; - - autogain_commands[1][1] = val << 4; - - jlj_write2(gspca_dev, autogain_commands[0]); - jlj_write2(gspca_dev, autogain_commands[1]); -} - -static void setred(struct gspca_dev *gspca_dev, s32 val) -{ - u8 setred_commands[][2] = { - {0x94, 0x02}, - {0xe6, 0x00} - }; - - setred_commands[1][1] = val; - - jlj_write2(gspca_dev, setred_commands[0]); - jlj_write2(gspca_dev, setred_commands[1]); -} - -static void setgreen(struct gspca_dev *gspca_dev, s32 val) -{ - u8 setgreen_commands[][2] = { - {0x94, 0x02}, - {0xe7, 0x00} - }; - - setgreen_commands[1][1] = val; - - jlj_write2(gspca_dev, setgreen_commands[0]); - jlj_write2(gspca_dev, setgreen_commands[1]); -} - -static void setblue(struct gspca_dev *gspca_dev, s32 val) -{ - u8 setblue_commands[][2] = { - {0x94, 0x02}, - {0xe9, 0x00} - }; - - setblue_commands[1][1] = val; - - jlj_write2(gspca_dev, setblue_commands[0]); - jlj_write2(gspca_dev, setblue_commands[1]); -} - -static int jlj_start(struct gspca_dev *gspca_dev) -{ - int i; - int start_commands_size; - u8 response = 0xff; - struct sd *sd = (struct sd *) gspca_dev; - struct jlj_command start_commands[] = { - {{0x71, 0x81}, 0, 0}, - {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY}, - {{0x95, 0x70}, 1, 0}, - {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0}, - {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY}, - {{0x95, 0x70}, 1, 0}, - {{0x71, 0x00}, 0, 0}, /* start streaming ??*/ - {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY}, - {{0x95, 0x70}, 1, 0}, -#define SPORTSCAM_DV15_CMD_SIZE 9 - {{0x94, 0x02}, 0, 0}, - {{0xde, 0x24}, 0, 0}, - {{0x94, 0x02}, 0, 0}, - {{0xdd, 0xf0}, 0, 0}, - {{0x94, 0x02}, 0, 0}, - {{0xe3, 0x2c}, 0, 0}, - {{0x94, 0x02}, 0, 0}, - {{0xe4, 0x00}, 0, 0}, - {{0x94, 0x02}, 0, 0}, - {{0xe5, 0x00}, 0, 0}, - {{0x94, 0x02}, 0, 0}, - {{0xe6, 0x2c}, 0, 0}, - {{0x94, 0x03}, 0, 0}, - {{0xaa, 0x00}, 0, 0} - }; - - sd->blocks_left = 0; - /* Under Windows, USB spy shows that only the 9 first start - * commands are used for SPORTSCAM_DV15 webcam - */ - if (sd->type == SPORTSCAM_DV15) - start_commands_size = SPORTSCAM_DV15_CMD_SIZE; - else - start_commands_size = ARRAY_SIZE(start_commands); - - for (i = 0; i < start_commands_size; i++) { - jlj_write2(gspca_dev, start_commands[i].instruction); - if (start_commands[i].delay) - msleep(start_commands[i].delay); - if (start_commands[i].ack_wanted) - jlj_read1(gspca_dev, response); - } - setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); - msleep(2); - setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq)); - if (gspca_dev->usb_err < 0) - PDEBUG(D_ERR, "Start streaming command failed"); - return gspca_dev->usb_err; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - int packet_type; - u32 header_marker; - - PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0", - len, JEILINJ_MAX_TRANSFER); - if (len != JEILINJ_MAX_TRANSFER) { - PDEBUG(D_PACK, "bad length"); - goto discard; - } - /* check if it's start of frame */ - header_marker = ((u32 *)data)[0]; - if (header_marker == FRAME_START) { - sd->blocks_left = data[0x0a] - 1; - PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left); - /* Start a new frame, and add the JPEG header, first thing */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - /* Toss line 0 of data block 0, keep the rest. */ - gspca_frame_add(gspca_dev, INTER_PACKET, - data + FRAME_HEADER_LEN, - JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); - } else if (sd->blocks_left > 0) { - PDEBUG(D_STREAM, "%d blocks remaining for frame", - sd->blocks_left); - sd->blocks_left -= 1; - if (sd->blocks_left == 0) - packet_type = LAST_PACKET; - else - packet_type = INTER_PACKET; - gspca_frame_add(gspca_dev, packet_type, - data, JEILINJ_MAX_TRANSFER); - } else - goto discard; - return; -discard: - /* Discard data until a new frame starts. */ - gspca_dev->last_packet_type = DISCARD_PACKET; -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *dev = (struct sd *) gspca_dev; - - dev->type = id->driver_info; - dev->quality = QUALITY_DEF; - - cam->cam_mode = jlj_mode; - cam->nmodes = ARRAY_SIZE(jlj_mode); - cam->bulk = 1; - cam->bulk_nurbs = 1; - cam->bulk_size = JEILINJ_MAX_TRANSFER; - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - int i; - u8 *buf; - static u8 stop_commands[][2] = { - {0x71, 0x00}, - {0x70, 0x09}, - {0x71, 0x80}, - {0x70, 0x05} - }; - - for (;;) { - /* get the image remaining blocks */ - usb_bulk_msg(gspca_dev->dev, - gspca_dev->urb[0]->pipe, - gspca_dev->urb[0]->transfer_buffer, - JEILINJ_MAX_TRANSFER, NULL, - JEILINJ_DATA_TIMEOUT); - - /* search for 0xff 0xd9 (EOF for JPEG) */ - i = 0; - buf = gspca_dev->urb[0]->transfer_buffer; - while ((i < (JEILINJ_MAX_TRANSFER - 1)) && - ((buf[i] != 0xff) || (buf[i+1] != 0xd9))) - i++; - - if (i != (JEILINJ_MAX_TRANSFER - 1)) - /* last remaining block found */ - break; - } - - for (i = 0; i < ARRAY_SIZE(stop_commands); i++) - jlj_write2(gspca_dev, stop_commands[i]); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return gspca_dev->usb_err; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* create the JPEG header */ - jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - jpeg_set_qual(dev->jpeg_hdr, dev->quality); - PDEBUG(D_STREAM, "Start streaming at %dx%d", - gspca_dev->height, gspca_dev->width); - jlj_start(gspca_dev); - return gspca_dev->usb_err; -} - -/* Table of supported USB devices */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379}, - {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - setfreq(gspca_dev, ctrl->val); - break; - case V4L2_CID_RED_BALANCE: - setred(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - setgreen(gspca_dev, ctrl->val); - break; - case V4L2_CID_BLUE_BALANCE: - setblue(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - setautogain(gspca_dev, ctrl->val); - break; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - jpeg_set_qual(sd->jpeg_hdr, ctrl->val); - setcamquality(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - static const struct v4l2_ctrl_config custom_autogain = { - .ops = &sd_ctrl_ops, - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Automatic Gain (and Exposure)", - .max = 3, - .step = 1, - .def = 0, - }; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 6); - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ); - v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 3, 1, 2); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 3, 1, 2); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2); - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, - QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - - -/* sub-driver description */ -static const struct sd_desc sd_desc_sakar_57379 = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* sub-driver description */ -static const struct sd_desc sd_desc_sportscam_dv15 = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, -}; - -static const struct sd_desc *sd_desc[2] = { - &sd_desc_sakar_57379, - &sd_desc_sportscam_dv15 -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - sd_desc[id->driver_info], - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c deleted file mode 100644 index cf9d9fca5b84..000000000000 --- a/drivers/media/video/gspca/jl2005bcd.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * Jeilin JL2005B/C/D library - * - * Copyright (C) 2011 Theodore Kilgore <kilgota@auburn.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MODULE_NAME "jl2005bcd" - -#include <linux/workqueue.h> -#include <linux/slab.h> -#include "gspca.h" - - -MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("JL2005B/C/D USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define JL2005C_CMD_TIMEOUT 500 -#define JL2005C_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define JL2005C_MAX_TRANSFER 0x200 -#define FRAME_HEADER_LEN 16 - - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char firmware_id[6]; - const struct v4l2_pix_format *cap_mode; - /* Driver stuff */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; - u8 frame_brightness; - int block_size; /* block size of camera */ - int vga; /* 1 if vga cam, 0 if cif cam */ -}; - - -/* Camera has two resolution settings. What they are depends on model. */ -static const struct v4l2_pix_format cif_mode[] = { - {176, 144, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - {352, 288, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - {640, 480, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* - * cam uses endpoint 0x03 to send commands, 0x84 for read commands, - * and 0x82 for bulk data transfer. - */ - -/* All commands are two bytes only */ -static int jl2005c_write2(struct gspca_dev *gspca_dev, unsigned char *command) -{ - int retval; - - memcpy(gspca_dev->usb_buf, command, 2); - retval = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 3), - gspca_dev->usb_buf, 2, NULL, 500); - if (retval < 0) - pr_err("command write [%02x] error %d\n", - gspca_dev->usb_buf[0], retval); - return retval; -} - -/* Response to a command is one byte in usb_buf[0], only if requested. */ -static int jl2005c_read1(struct gspca_dev *gspca_dev) -{ - int retval; - - retval = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x84), - gspca_dev->usb_buf, 1, NULL, 500); - if (retval < 0) - pr_err("read command [0x%02x] error %d\n", - gspca_dev->usb_buf[0], retval); - return retval; -} - -/* Response appears in gspca_dev->usb_buf[0] */ -static int jl2005c_read_reg(struct gspca_dev *gspca_dev, unsigned char reg) -{ - int retval; - - static u8 instruction[2] = {0x95, 0x00}; - /* put register to read in byte 1 */ - instruction[1] = reg; - /* Send the read request */ - retval = jl2005c_write2(gspca_dev, instruction); - if (retval < 0) - return retval; - retval = jl2005c_read1(gspca_dev); - - return retval; -} - -static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev) -{ - int i; - int retval; - int frame_brightness = 0; - - static u8 instruction[2] = {0x7f, 0x01}; - - retval = jl2005c_write2(gspca_dev, instruction); - if (retval < 0) - return retval; - - i = 0; - while (i < 20 && !frame_brightness) { - /* If we tried 20 times, give up. */ - retval = jl2005c_read_reg(gspca_dev, 0x7e); - if (retval < 0) - return retval; - frame_brightness = gspca_dev->usb_buf[0]; - retval = jl2005c_read_reg(gspca_dev, 0x7d); - if (retval < 0) - return retval; - i++; - } - PDEBUG(D_FRAM, "frame_brightness is 0x%02x", gspca_dev->usb_buf[0]); - return retval; -} - -static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg, - unsigned char value) -{ - int retval; - u8 instruction[2]; - - instruction[0] = reg; - instruction[1] = value; - - retval = jl2005c_write2(gspca_dev, instruction); - if (retval < 0) - return retval; - - return retval; -} - -static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - int i = 0; - int retval = -1; - unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f}; - - PDEBUG(D_PROBE, "Running jl2005c_get_firmware_id"); - /* Read the first ID byte once for warmup */ - retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]); - PDEBUG(D_PROBE, "response is %02x", gspca_dev->usb_buf[0]); - if (retval < 0) - return retval; - /* Now actually get the ID string */ - for (i = 0; i < 6; i++) { - retval = jl2005c_read_reg(gspca_dev, regs_to_read[i]); - if (retval < 0) - return retval; - sd->firmware_id[i] = gspca_dev->usb_buf[0]; - } - PDEBUG(D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x", - sd->firmware_id[0], - sd->firmware_id[1], - sd->firmware_id[2], - sd->firmware_id[3], - sd->firmware_id[4], - sd->firmware_id[5]); - return 0; -} - -static int jl2005c_stream_start_vga_lg - (struct gspca_dev *gspca_dev) -{ - int i; - int retval = -1; - static u8 instruction[][2] = { - {0x05, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x18}, - {0x02, 0x00}, - {0x01, 0x00}, - {0x04, 0x52}, - }; - - for (i = 0; i < ARRAY_SIZE(instruction); i++) { - msleep(60); - retval = jl2005c_write2(gspca_dev, instruction[i]); - if (retval < 0) - return retval; - } - msleep(60); - return retval; -} - -static int jl2005c_stream_start_vga_small(struct gspca_dev *gspca_dev) -{ - int i; - int retval = -1; - static u8 instruction[][2] = { - {0x06, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x1a}, - {0x02, 0x00}, - {0x01, 0x00}, - {0x04, 0x52}, - }; - - for (i = 0; i < ARRAY_SIZE(instruction); i++) { - msleep(60); - retval = jl2005c_write2(gspca_dev, instruction[i]); - if (retval < 0) - return retval; - } - msleep(60); - return retval; -} - -static int jl2005c_stream_start_cif_lg(struct gspca_dev *gspca_dev) -{ - int i; - int retval = -1; - static u8 instruction[][2] = { - {0x05, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x30}, - {0x02, 0x00}, - {0x01, 0x00}, - {0x04, 0x42}, - }; - - for (i = 0; i < ARRAY_SIZE(instruction); i++) { - msleep(60); - retval = jl2005c_write2(gspca_dev, instruction[i]); - if (retval < 0) - return retval; - } - msleep(60); - return retval; -} - -static int jl2005c_stream_start_cif_small(struct gspca_dev *gspca_dev) -{ - int i; - int retval = -1; - static u8 instruction[][2] = { - {0x06, 0x00}, - {0x7c, 0x00}, - {0x7d, 0x32}, - {0x02, 0x00}, - {0x01, 0x00}, - {0x04, 0x42}, - }; - - for (i = 0; i < ARRAY_SIZE(instruction); i++) { - msleep(60); - retval = jl2005c_write2(gspca_dev, instruction[i]); - if (retval < 0) - return retval; - } - msleep(60); - return retval; -} - - -static int jl2005c_stop(struct gspca_dev *gspca_dev) -{ - int retval; - - retval = jl2005c_write_reg(gspca_dev, 0x07, 0x00); - return retval; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface the gspca usb_lock is - * used when performing the one USB control operation inside the workqueue, - * which tells the camera to close the stream. In practice the only thing - * which needs to be protected against is the usb_set_interface call that - * gspca makes during stream_off. Otherwise the camera doesn't provide any - * controls that the user could try to change. - */ -static void jl2005c_dostream(struct work_struct *work) -{ - struct sd *dev = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - int bytes_left = 0; /* bytes remaining in current frame. */ - int data_len; /* size to use for the next read. */ - int header_read = 0; - unsigned char header_sig[2] = {0x4a, 0x4c}; - int act_len; - int packet_type; - int ret; - u8 *buffer; - - buffer = kmalloc(JL2005C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - if (!buffer) { - pr_err("Couldn't allocate USB buffer\n"); - goto quit_stream; - } - - while (gspca_dev->dev && gspca_dev->streaming) { -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - /* Check if this is a new frame. If so, start the frame first */ - if (!header_read) { - mutex_lock(&gspca_dev->usb_lock); - ret = jl2005c_start_new_frame(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) - goto quit_stream; - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x82), - buffer, JL2005C_MAX_TRANSFER, &act_len, - JL2005C_DATA_TIMEOUT); - PDEBUG(D_PACK, - "Got %d bytes out of %d for header", - act_len, JL2005C_MAX_TRANSFER); - if (ret < 0 || act_len < JL2005C_MAX_TRANSFER) - goto quit_stream; - /* Check whether we actually got the first blodk */ - if (memcmp(header_sig, buffer, 2) != 0) { - pr_err("First block is not the first block\n"); - goto quit_stream; - } - /* total size to fetch is byte 7, times blocksize - * of which we already got act_len */ - bytes_left = buffer[0x07] * dev->block_size - act_len; - PDEBUG(D_PACK, "bytes_left = 0x%x", bytes_left); - /* We keep the header. It has other information, too.*/ - packet_type = FIRST_PACKET; - gspca_frame_add(gspca_dev, packet_type, - buffer, act_len); - header_read = 1; - } - while (bytes_left > 0 && gspca_dev->dev) { - data_len = bytes_left > JL2005C_MAX_TRANSFER ? - JL2005C_MAX_TRANSFER : bytes_left; - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x82), - buffer, data_len, &act_len, - JL2005C_DATA_TIMEOUT); - if (ret < 0 || act_len < data_len) - goto quit_stream; - PDEBUG(D_PACK, - "Got %d bytes out of %d for frame", - data_len, bytes_left); - bytes_left -= data_len; - if (bytes_left == 0) { - packet_type = LAST_PACKET; - header_read = 0; - } else - packet_type = INTER_PACKET; - gspca_frame_add(gspca_dev, packet_type, - buffer, data_len); - } - } -quit_stream: - if (gspca_dev->dev) { - mutex_lock(&gspca_dev->usb_lock); - jl2005c_stop(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - } - kfree(buffer); -} - - - - -/* This function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - struct sd *sd = (struct sd *) gspca_dev; - - cam = &gspca_dev->cam; - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk_size = 64; - cam->bulk = 1; - /* For the rest, the camera needs to be detected */ - jl2005c_get_firmware_id(gspca_dev); - /* Here are some known firmware IDs - * First some JL2005B cameras - * {0x41, 0x07, 0x04, 0x2c, 0xe8, 0xf2} Sakar KidzCam - * {0x45, 0x02, 0x08, 0xb9, 0x00, 0xd2} No-name JL2005B - * JL2005C cameras - * {0x01, 0x0c, 0x16, 0x10, 0xf8, 0xc8} Argus DC-1512 - * {0x12, 0x04, 0x03, 0xc0, 0x00, 0xd8} ICarly - * {0x86, 0x08, 0x05, 0x02, 0x00, 0xd4} Jazz - * - * Based upon this scanty evidence, we can detect a CIF camera by - * testing byte 0 for 0x4x. - */ - if ((sd->firmware_id[0] & 0xf0) == 0x40) { - cam->cam_mode = cif_mode; - cam->nmodes = ARRAY_SIZE(cif_mode); - sd->block_size = 0x80; - } else { - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - sd->block_size = 0x200; - } - - INIT_WORK(&sd->work_struct, jl2005c_dostream); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - - struct sd *sd = (struct sd *) gspca_dev; - sd->cap_mode = gspca_dev->cam.cam_mode; - - switch (gspca_dev->width) { - case 640: - PDEBUG(D_STREAM, "Start streaming at vga resolution"); - jl2005c_stream_start_vga_lg(gspca_dev); - break; - case 320: - PDEBUG(D_STREAM, "Start streaming at qvga resolution"); - jl2005c_stream_start_vga_small(gspca_dev); - break; - case 352: - PDEBUG(D_STREAM, "Start streaming at cif resolution"); - jl2005c_stream_start_cif_lg(gspca_dev); - break; - case 176: - PDEBUG(D_STREAM, "Start streaming at qcif resolution"); - jl2005c_stream_start_cif_small(gspca_dev); - break; - default: - pr_err("Unknown resolution specified\n"); - return -1; - } - - /* Start the workqueue function to do the streaming */ - sd->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(sd->work_thread, &sd->work_struct); - - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for sq905c_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); -} - - - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0979, 0x0227)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -/* -- module insert / remove -- */ -static int __init sd_mod_init(void) -{ - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; - return 0; -} -static void __exit sd_mod_exit(void) -{ - usb_deregister(&sd_driver); -} - -module_init(sd_mod_init); -module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h deleted file mode 100644 index ab54910418b4..000000000000 --- a/drivers/media/video/gspca/jpeg.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef JPEG_H -#define JPEG_H 1 -/* - * Insert a JPEG header at start of frame - * - * This module is used by the gspca subdrivers. - * A special case is done for Conexant webcams. - * - * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - * generation options - * CONEX_CAM Conexant if present - */ - -/* JPEG header */ -static const u8 jpeg_head[] = { - 0xff, 0xd8, /* jpeg */ - -/* quantization table quality 50% */ - 0xff, 0xdb, 0x00, 0x84, /* DQT */ -0, -#define JPEG_QT0_OFFSET 7 - 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, -1, -#define JPEG_QT1_OFFSET 72 - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - -/* huffman table */ - 0xff, 0xc4, 0x01, 0xa2, - 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, - 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, - 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, - 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, - 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, - 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, - 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, - 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, - 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, - 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, - 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, - 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02, - 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, - 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, - 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, - 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, - 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, - 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, - 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, - 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, - 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, - 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, - 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, -#ifdef CONEX_CAM -/* the Conexant frames start with SOF0 */ -#define JPEG_HDR_SZ 556 -#else - 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */ - 0x08, /* data precision */ -#define JPEG_HEIGHT_OFFSET 561 - 0x01, 0xe0, /* height */ - 0x02, 0x80, /* width */ - 0x03, /* component number */ - 0x01, - 0x21, /* samples Y */ - 0x00, /* quant Y */ - 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ - 0x03, 0x11, 0x01, - - 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */ - 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 -#define JPEG_HDR_SZ 589 -#endif -}; - -/* define the JPEG header */ -static void jpeg_define(u8 *jpeg_hdr, - int height, - int width, - int samplesY) -{ - memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head); -#ifndef CONEX_CAM - jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY; -#endif -} - -/* set the JPEG quality */ -static void jpeg_set_qual(u8 *jpeg_hdr, - int quality) -{ - int i, sc; - - if (quality < 50) - sc = 5000 / quality; - else - sc = 200 - quality * 2; - for (i = 0; i < 64; i++) { - jpeg_hdr[JPEG_QT0_OFFSET + i] = - (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; - jpeg_hdr[JPEG_QT1_OFFSET + i] = - (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; - } -} -#endif diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/video/gspca/kinect.c deleted file mode 100644 index 40ad6687ee5d..000000000000 --- a/drivers/media/video/gspca/kinect.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * kinect sensor device camera, gspca driver - * - * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it> - * - * Based on the OpenKinect project and libfreenect - * http://openkinect.org/wiki/Init_Analysis - * - * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect - * sensor device which I tested the driver on. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "kinect" - -#include "gspca.h" - -#define CTRL_TIMEOUT 500 - -MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); -MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver"); -MODULE_LICENSE("GPL"); - -struct pkt_hdr { - uint8_t magic[2]; - uint8_t pad; - uint8_t flag; - uint8_t unk1; - uint8_t seq; - uint8_t unk2; - uint8_t unk3; - uint32_t timestamp; -}; - -struct cam_hdr { - uint8_t magic[2]; - uint16_t len; - uint16_t cmd; - uint16_t tag; -}; - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - uint16_t cam_tag; /* a sequence number for packets */ - uint8_t stream_flag; /* to identify different stream types */ - uint8_t obuf[0x400]; /* output buffer for control commands */ - uint8_t ibuf[0x200]; /* input buffer for control commands */ -}; - -#define MODE_640x480 0x0001 -#define MODE_640x488 0x0002 -#define MODE_1280x1024 0x0004 - -#define FORMAT_BAYER 0x0010 -#define FORMAT_UYVY 0x0020 -#define FORMAT_Y10B 0x0040 - -#define FPS_HIGH 0x0100 - -static const struct v4l2_pix_format video_camera_mode[] = { - {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH}, - {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = MODE_640x480 | FORMAT_UYVY}, - {1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = MODE_1280x1024 | FORMAT_BAYER}, - {640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE, - .bytesperline = 640 * 10 / 8, - .sizeimage = 640 * 488 * 10 / 8, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH}, - {1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE, - .bytesperline = 1280 * 10 / 8, - .sizeimage = 1280 * 1024 * 10 / 8, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = MODE_1280x1024 | FORMAT_Y10B}, -}; - -static int kinect_write(struct usb_device *udev, uint8_t *data, - uint16_t wLength) -{ - return usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - 0x00, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0, data, wLength, CTRL_TIMEOUT); -} - -static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength) -{ - return usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - 0x00, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0, data, wLength, CTRL_TIMEOUT); -} - -static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf, - unsigned int cmd_len, void *replybuf, unsigned int reply_len) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *udev = gspca_dev->dev; - int res, actual_len; - uint8_t *obuf = sd->obuf; - uint8_t *ibuf = sd->ibuf; - struct cam_hdr *chdr = (void *)obuf; - struct cam_hdr *rhdr = (void *)ibuf; - - if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) { - pr_err("send_cmd: Invalid command length (0x%x)\n", cmd_len); - return -1; - } - - chdr->magic[0] = 0x47; - chdr->magic[1] = 0x4d; - chdr->cmd = cpu_to_le16(cmd); - chdr->tag = cpu_to_le16(sd->cam_tag); - chdr->len = cpu_to_le16(cmd_len / 2); - - memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len); - - res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr)); - PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd, - sd->cam_tag, cmd_len, res); - if (res < 0) { - pr_err("send_cmd: Output control transfer failed (%d)\n", res); - return res; - } - - do { - actual_len = kinect_read(udev, ibuf, 0x200); - } while (actual_len == 0); - PDEBUG(D_USBO, "Control reply: %d", res); - if (actual_len < sizeof(*rhdr)) { - pr_err("send_cmd: Input control transfer failed (%d)\n", res); - return res; - } - actual_len -= sizeof(*rhdr); - - if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) { - pr_err("send_cmd: Bad magic %02x %02x\n", - rhdr->magic[0], rhdr->magic[1]); - return -1; - } - if (rhdr->cmd != chdr->cmd) { - pr_err("send_cmd: Bad cmd %02x != %02x\n", - rhdr->cmd, chdr->cmd); - return -1; - } - if (rhdr->tag != chdr->tag) { - pr_err("send_cmd: Bad tag %04x != %04x\n", - rhdr->tag, chdr->tag); - return -1; - } - if (cpu_to_le16(rhdr->len) != (actual_len/2)) { - pr_err("send_cmd: Bad len %04x != %04x\n", - cpu_to_le16(rhdr->len), (int)(actual_len/2)); - return -1; - } - - if (actual_len > reply_len) { - pr_warn("send_cmd: Data buffer is %d bytes long, but got %d bytes\n", - reply_len, actual_len); - memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len); - } else { - memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len); - } - - sd->cam_tag++; - - return actual_len; -} - -static int write_register(struct gspca_dev *gspca_dev, uint16_t reg, - uint16_t data) -{ - uint16_t reply[2]; - uint16_t cmd[2]; - int res; - - cmd[0] = cpu_to_le16(reg); - cmd[1] = cpu_to_le16(data); - - PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data); - res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4); - if (res < 0) - return res; - if (res != 2) { - pr_warn("send_cmd returned %d [%04x %04x], 0000 expected\n", - res, reply[0], reply[1]); - } - return 0; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - sd->cam_tag = 0; - - /* Only video stream is supported for now, - * which has stream flag = 0x80 */ - sd->stream_flag = 0x80; - - cam = &gspca_dev->cam; - - cam->cam_mode = video_camera_mode; - cam->nmodes = ARRAY_SIZE(video_camera_mode); - -#if 0 - /* Setting those values is not needed for video stream */ - cam->npkt = 15; - gspca_dev->pkt_size = 960 * 2; -#endif - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - PDEBUG(D_PROBE, "Kinect Camera device."); - - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - int mode; - uint8_t fmt_reg, fmt_val; - uint8_t res_reg, res_val; - uint8_t fps_reg, fps_val; - uint8_t mode_val; - - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - - if (mode & FORMAT_Y10B) { - fmt_reg = 0x19; - res_reg = 0x1a; - fps_reg = 0x1b; - mode_val = 0x03; - } else { - fmt_reg = 0x0c; - res_reg = 0x0d; - fps_reg = 0x0e; - mode_val = 0x01; - } - - /* format */ - if (mode & FORMAT_UYVY) - fmt_val = 0x05; - else - fmt_val = 0x00; - - if (mode & MODE_1280x1024) - res_val = 0x02; - else - res_val = 0x01; - - if (mode & FPS_HIGH) - fps_val = 0x1e; - else - fps_val = 0x0f; - - - /* turn off IR-reset function */ - write_register(gspca_dev, 0x105, 0x00); - - /* Reset video stream */ - write_register(gspca_dev, 0x05, 0x00); - - /* Due to some ridiculous condition in the firmware, we have to start - * and stop the depth stream before the camera will hand us 1280x1024 - * IR. This is a stupid workaround, but we've yet to find a better - * solution. - * - * Thanks to Drew Fisher for figuring this out. - */ - if (mode & (FORMAT_Y10B | MODE_1280x1024)) { - write_register(gspca_dev, 0x13, 0x01); - write_register(gspca_dev, 0x14, 0x1e); - write_register(gspca_dev, 0x06, 0x02); - write_register(gspca_dev, 0x06, 0x00); - } - - write_register(gspca_dev, fmt_reg, fmt_val); - write_register(gspca_dev, res_reg, res_val); - write_register(gspca_dev, fps_reg, fps_val); - - /* Start video stream */ - write_register(gspca_dev, 0x05, mode_val); - - /* disable Hflip */ - write_register(gspca_dev, 0x47, 0x00); - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* reset video stream */ - write_register(gspca_dev, 0x05, 0x00); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - struct pkt_hdr *hdr = (void *)__data; - uint8_t *data = __data + sizeof(*hdr); - int datalen = len - sizeof(*hdr); - - uint8_t sof = sd->stream_flag | 1; - uint8_t mof = sd->stream_flag | 2; - uint8_t eof = sd->stream_flag | 5; - - if (len < 12) - return; - - if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') { - pr_warn("[Stream %02x] Invalid magic %02x%02x\n", - sd->stream_flag, hdr->magic[0], hdr->magic[1]); - return; - } - - if (hdr->flag == sof) - gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen); - - else if (hdr->flag == mof) - gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen); - - else if (hdr->flag == eof) - gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen); - - else - pr_warn("Packet type not recognized...\n"); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - /* - .get_streamparm = sd_get_streamparm, - .set_streamparm = sd_set_streamparm, - */ -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x045e, 0x02ae)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c deleted file mode 100644 index bbf91e07e38b..000000000000 --- a/drivers/media/video/gspca/konica.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Driver for USB webcams based on Konica chipset. This - * chipset is used in Intel YC76 camera. - * - * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> - * - * Based on the usbvideo v4l1 konicawc driver which is: - * - * Copyright (C) 2002 Simon Evans <spse@secret.org.uk> - * - * The code for making gspca work with a webcam with 2 isoc endpoints was - * taken from the benq gspca subdriver which is: - * - * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "konica" - -#include <linux/input.h> -#include "gspca.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Konica chipset USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define WHITEBAL_REG 0x01 -#define BRIGHTNESS_REG 0x02 -#define SHARPNESS_REG 0x03 -#define CONTRAST_REG 0x04 -#define SATURATION_REG 0x05 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct urb *last_data_urb; - u8 snapshot_pressed; -}; - - -/* .priv is what goes to register 8 for this mode, known working values: - 0x00 -> 176x144, cropped - 0x01 -> 176x144, cropped - 0x02 -> 176x144, cropped - 0x03 -> 176x144, cropped - 0x04 -> 176x144, binned - 0x05 -> 320x240 - 0x06 -> 320x240 - 0x07 -> 160x120, cropped - 0x08 -> 160x120, cropped - 0x09 -> 160x120, binned (note has 136 lines) - 0x0a -> 160x120, binned (note has 136 lines) - 0x0b -> 160x120, cropped -*/ -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 136 * 3 / 2 + 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0x0a}, - {176, 144, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2 + 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0x04}, - {320, 240, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2 + 960, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0x05}, -}; - -static void sd_isoc_irq(struct urb *urb); - -static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x02, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - NULL, - 0, - 1000); - if (ret < 0) { - pr_err("reg_w err writing %02x to %02x: %d\n", - value, index, ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x03, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - gspca_dev->usb_buf, - 2, - 1000); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void konica_stream_on(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 1, 0x0b); -} - -static void konica_stream_off(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 0, 0x0b); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - gspca_dev->cam.no_urb_create = 1; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - int i; - - /* - * The konica needs a freaking large time to "boot" (approx 6.5 sec.), - * and does not want to be bothered while doing so :| - * Register 0x10 counts from 1 - 3, with 3 being "ready" - */ - msleep(6000); - for (i = 0; i < 20; i++) { - reg_r(gspca_dev, 0, 0x10); - if (gspca_dev->usb_buf[0] == 3) - break; - msleep(100); - } - reg_w(gspca_dev, 0, 0x0d); - - return gspca_dev->usb_err; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct urb *urb; - int i, n, packet_size; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - pr_err("Couldn't get altsetting\n"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - - n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - reg_w(gspca_dev, n, 0x08); - - konica_stream_on(gspca_dev); - - if (gspca_dev->usb_err) - return gspca_dev->usb_err; - - /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */ -#if MAX_NURBS < 4 -#error "Not enough URBs in the gspca table" -#endif -#define SD_NPKT 32 - for (n = 0; n < 4; n++) { - i = n & 1 ? 0 : 1; - packet_size = - le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize); - urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); - if (!urb) { - pr_err("usb_alloc_urb failed\n"); - return -ENOMEM; - } - gspca_dev->urb[n] = urb; - urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, - packet_size * SD_NPKT, - GFP_KERNEL, - &urb->transfer_dma); - if (urb->transfer_buffer == NULL) { - pr_err("usb_buffer_alloc failed\n"); - return -ENOMEM; - } - - urb->dev = gspca_dev->dev; - urb->context = gspca_dev; - urb->transfer_buffer_length = packet_size * SD_NPKT; - urb->pipe = usb_rcvisocpipe(gspca_dev->dev, - n & 1 ? 0x81 : 0x82); - urb->transfer_flags = URB_ISO_ASAP - | URB_NO_TRANSFER_DMA_MAP; - urb->interval = 1; - urb->complete = sd_isoc_irq; - urb->number_of_packets = SD_NPKT; - for (i = 0; i < SD_NPKT; i++) { - urb->iso_frame_desc[i].length = packet_size; - urb->iso_frame_desc[i].offset = packet_size * i; - } - } - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - konica_stream_off(gspca_dev); -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - /* Don't keep the button in the pressed state "forever" if it was - pressed when streaming is stopped */ - if (sd->snapshot_pressed) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - sd->snapshot_pressed = 0; - } -#endif -} - -/* reception of an URB */ -static void sd_isoc_irq(struct urb *urb) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - struct sd *sd = (struct sd *) gspca_dev; - struct urb *data_urb, *status_urb; - u8 *data; - int i, st; - - PDEBUG(D_PACK, "sd isoc irq"); - if (!gspca_dev->streaming) - return; - - if (urb->status != 0) { - if (urb->status == -ESHUTDOWN) - return; /* disconnection */ -#ifdef CONFIG_PM - if (gspca_dev->frozen) - return; -#endif - PDEBUG(D_ERR, "urb status: %d", urb->status); - st = usb_submit_urb(urb, GFP_ATOMIC); - if (st < 0) - pr_err("resubmit urb error %d\n", st); - return; - } - - /* if this is a data URB (ep 0x82), wait */ - if (urb->transfer_buffer_length > 32) { - sd->last_data_urb = urb; - return; - } - - status_urb = urb; - data_urb = sd->last_data_urb; - sd->last_data_urb = NULL; - - if (!data_urb || data_urb->start_frame != status_urb->start_frame) { - PDEBUG(D_ERR|D_PACK, "lost sync on frames"); - goto resubmit; - } - - if (data_urb->number_of_packets != status_urb->number_of_packets) { - PDEBUG(D_ERR|D_PACK, - "no packets does not match, data: %d, status: %d", - data_urb->number_of_packets, - status_urb->number_of_packets); - goto resubmit; - } - - for (i = 0; i < status_urb->number_of_packets; i++) { - if (data_urb->iso_frame_desc[i].status || - status_urb->iso_frame_desc[i].status) { - PDEBUG(D_ERR|D_PACK, - "pkt %d data-status %d, status-status %d", i, - data_urb->iso_frame_desc[i].status, - status_urb->iso_frame_desc[i].status); - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - - if (status_urb->iso_frame_desc[i].actual_length != 1) { - PDEBUG(D_ERR|D_PACK, - "bad status packet length %d", - status_urb->iso_frame_desc[i].actual_length); - gspca_dev->last_packet_type = DISCARD_PACKET; - continue; - } - - st = *((u8 *)status_urb->transfer_buffer - + status_urb->iso_frame_desc[i].offset); - - data = (u8 *)data_urb->transfer_buffer - + data_urb->iso_frame_desc[i].offset; - - /* st: 0x80-0xff: frame start with frame number (ie 0-7f) - * otherwise: - * bit 0 0: keep packet - * 1: drop packet (padding data) - * - * bit 4 0 button not clicked - * 1 button clicked - * button is used to `take a picture' (in software) - */ - if (st & 0x80) { - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - } else { -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - u8 button_state = st & 0x40 ? 1 : 0; - if (sd->snapshot_pressed != button_state) { - input_report_key(gspca_dev->input_dev, - KEY_CAMERA, - button_state); - input_sync(gspca_dev->input_dev); - sd->snapshot_pressed = button_state; - } -#endif - if (st & 0x01) - continue; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, - data_urb->iso_frame_desc[i].actual_length); - } - -resubmit: - if (data_urb) { - st = usb_submit_urb(data_urb, GFP_ATOMIC); - if (st < 0) - PDEBUG(D_ERR|D_PACK, - "usb_submit_urb(data_urb) ret %d", st); - } - st = usb_submit_urb(status_urb, GFP_ATOMIC); - if (st < 0) - pr_err("usb_submit_urb(status_urb) ret %d\n", st); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - konica_stream_off(gspca_dev); - reg_w(gspca_dev, ctrl->val, BRIGHTNESS_REG); - konica_stream_on(gspca_dev); - break; - case V4L2_CID_CONTRAST: - konica_stream_off(gspca_dev); - reg_w(gspca_dev, ctrl->val, CONTRAST_REG); - konica_stream_on(gspca_dev); - break; - case V4L2_CID_SATURATION: - konica_stream_off(gspca_dev); - reg_w(gspca_dev, ctrl->val, SATURATION_REG); - konica_stream_on(gspca_dev); - break; - case V4L2_CID_WHITE_BALANCE_TEMPERATURE: - konica_stream_off(gspca_dev); - reg_w(gspca_dev, ctrl->val, WHITEBAL_REG); - konica_stream_on(gspca_dev); - break; - case V4L2_CID_SHARPNESS: - konica_stream_off(gspca_dev); - reg_w(gspca_dev, ctrl->val, SHARPNESS_REG); - konica_stream_on(gspca_dev); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 9, 1, 4); - /* Needs to be verified */ - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 9, 1, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 9, 1, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_WHITE_BALANCE_TEMPERATURE, - 0, 33, 1, 25); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 9, 1, 4); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/m5602/Kconfig b/drivers/media/video/gspca/m5602/Kconfig deleted file mode 100644 index 5a69016ed75f..000000000000 --- a/drivers/media/video/gspca/m5602/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_M5602 - tristate "ALi USB m5602 Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the - ALi m5602 connected to various image sensors. - - See <file:Documentation/video4linux/m5602.txt> for more info. - - To compile this driver as a module, choose M here: the - module will be called gspca_m5602. diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile deleted file mode 100644 index 575b75bacb62..000000000000 --- a/drivers/media/video/gspca/m5602/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -obj-$(CONFIG_USB_M5602) += gspca_m5602.o - -gspca_m5602-objs := m5602_core.o \ - m5602_ov9650.o \ - m5602_ov7660.o \ - m5602_mt9m111.o \ - m5602_po1030.o \ - m5602_s5k83a.o \ - m5602_s5k4aa.o - -ccflags-y += -I$(srctree)/drivers/media/video/gspca diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h deleted file mode 100644 index 51af3ee3ab85..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_BRIDGE_H_ -#define M5602_BRIDGE_H_ - -#include <linux/slab.h> -#include "gspca.h" - -#define MODULE_NAME "ALi m5602" - -/*****************************************************************************/ - -#define M5602_XB_SENSOR_TYPE 0x00 -#define M5602_XB_SENSOR_CTRL 0x01 -#define M5602_XB_LINE_OF_FRAME_H 0x02 -#define M5602_XB_LINE_OF_FRAME_L 0x03 -#define M5602_XB_PIX_OF_LINE_H 0x04 -#define M5602_XB_PIX_OF_LINE_L 0x05 -#define M5602_XB_VSYNC_PARA 0x06 -#define M5602_XB_HSYNC_PARA 0x07 -#define M5602_XB_TEST_MODE_1 0x08 -#define M5602_XB_TEST_MODE_2 0x09 -#define M5602_XB_SIG_INI 0x0a -#define M5602_XB_DS_PARA 0x0e -#define M5602_XB_TRIG_PARA 0x0f -#define M5602_XB_CLK_PD 0x10 -#define M5602_XB_MCU_CLK_CTRL 0x12 -#define M5602_XB_MCU_CLK_DIV 0x13 -#define M5602_XB_SEN_CLK_CTRL 0x14 -#define M5602_XB_SEN_CLK_DIV 0x15 -#define M5602_XB_AUD_CLK_CTRL 0x16 -#define M5602_XB_AUD_CLK_DIV 0x17 -#define M5602_OB_AC_LINK_STATE 0x22 -#define M5602_OB_PCM_SLOT_INDEX 0x24 -#define M5602_OB_GPIO_SLOT_INDEX 0x25 -#define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28 -#define M5602_OB_ACRX_STATUS_DATA_L 0x29 -#define M5602_OB_ACRX_STATUS_DATA_H 0x2a -#define M5602_OB_ACTX_COMMAND_ADDRESS 0x31 -#define M5602_OB_ACRX_COMMAND_DATA_L 0x32 -#define M5602_OB_ACTX_COMMAND_DATA_H 0X33 -#define M5602_XB_DEVCTR1 0x41 -#define M5602_XB_EPSETR0 0x42 -#define M5602_XB_EPAFCTR 0x47 -#define M5602_XB_EPBFCTR 0x49 -#define M5602_XB_EPEFCTR 0x4f -#define M5602_XB_TEST_REG 0x53 -#define M5602_XB_ALT2SIZE 0x54 -#define M5602_XB_ALT3SIZE 0x55 -#define M5602_XB_OBSFRAME 0x56 -#define M5602_XB_PWR_CTL 0x59 -#define M5602_XB_ADC_CTRL 0x60 -#define M5602_XB_ADC_DATA 0x61 -#define M5602_XB_MISC_CTRL 0x62 -#define M5602_XB_SNAPSHOT 0x63 -#define M5602_XB_SCRATCH_1 0x64 -#define M5602_XB_SCRATCH_2 0x65 -#define M5602_XB_SCRATCH_3 0x66 -#define M5602_XB_SCRATCH_4 0x67 -#define M5602_XB_I2C_CTRL 0x68 -#define M5602_XB_I2C_CLK_DIV 0x69 -#define M5602_XB_I2C_DEV_ADDR 0x6a -#define M5602_XB_I2C_REG_ADDR 0x6b -#define M5602_XB_I2C_DATA 0x6c -#define M5602_XB_I2C_STATUS 0x6d -#define M5602_XB_GPIO_DAT_H 0x70 -#define M5602_XB_GPIO_DAT_L 0x71 -#define M5602_XB_GPIO_DIR_H 0x72 -#define M5602_XB_GPIO_DIR_L 0x73 -#define M5602_XB_GPIO_EN_H 0x74 -#define M5602_XB_GPIO_EN_L 0x75 -#define M5602_XB_GPIO_DAT 0x76 -#define M5602_XB_GPIO_DIR 0x77 -#define M5602_XB_SEN_CLK_CONTROL 0x80 -#define M5602_XB_SEN_CLK_DIVISION 0x81 -#define M5602_XB_CPR_CLK_CONTROL 0x82 -#define M5602_XB_CPR_CLK_DIVISION 0x83 -#define M5602_XB_MCU_CLK_CONTROL 0x84 -#define M5602_XB_MCU_CLK_DIVISION 0x85 -#define M5602_XB_DCT_CLK_CONTROL 0x86 -#define M5602_XB_DCT_CLK_DIVISION 0x87 -#define M5602_XB_EC_CLK_CONTROL 0x88 -#define M5602_XB_EC_CLK_DIVISION 0x89 -#define M5602_XB_LBUF_CLK_CONTROL 0x8a -#define M5602_XB_LBUF_CLK_DIVISION 0x8b - -#define I2C_BUSY 0x80 - -/*****************************************************************************/ - -/* Driver info */ -#define DRIVER_AUTHOR "ALi m5602 Linux Driver Project" -#define DRIVER_DESC "ALi m5602 webcam driver" - -#define M5602_ISOC_ENDPOINT_ADDR 0x81 -#define M5602_INTR_ENDPOINT_ADDR 0x82 - -#define M5602_URB_MSG_TIMEOUT 5000 - -/*****************************************************************************/ - -/* A skeleton used for sending messages to the m5602 bridge */ -static const unsigned char bridge_urb_skeleton[] = { - 0x13, 0x00, 0x81, 0x00 -}; - -/* A skeleton used for sending messages to the sensor */ -static const unsigned char sensor_urb_skeleton[] = { - 0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06, - 0x23, M5602_XB_MISC_CTRL, 0x81, 0x80, - 0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00, - 0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00, - 0x13, M5602_XB_I2C_DATA, 0x81, 0x00, - 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11 -}; - -struct sd { - struct gspca_dev gspca_dev; - - /* A pointer to the currently connected sensor */ - const struct m5602_sensor *sensor; - - struct sd_desc *desc; - - /* Sensor private data */ - void *sensor_priv; - - /* The current frame's id, used to detect frame boundaries */ - u8 frame_id; - - /* The current frame count */ - u32 frame_count; -}; - -int m5602_read_bridge( - struct sd *sd, const u8 address, u8 *i2c_data); - -int m5602_write_bridge( - struct sd *sd, const u8 address, const u8 i2c_data); - -int m5602_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -int m5602_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c deleted file mode 100644 index ed22638978ce..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ /dev/null @@ -1,424 +0,0 @@ - /* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_ov9650.h" -#include "m5602_ov7660.h" -#include "m5602_mt9m111.h" -#include "m5602_po1030.h" -#include "m5602_s5k83a.h" -#include "m5602_s5k4aa.h" - -/* Kernel module parameters */ -int force_sensor; -static bool dump_bridge; -bool dump_sensor; - -static const struct usb_device_id m5602_table[] = { - {USB_DEVICE(0x0402, 0x5602)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, m5602_table); - -/* Reads a byte from the m5602 */ -int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, 0x14, - 0x8100 + address, buf, - 1, M5602_URB_MSG_TIMEOUT); - *i2c_data = buf[0]; - - PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x", - address, *i2c_data); - - /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero instead*/ - return (err < 0) ? err : 0; -} - -/* Writes a byte to the m5602 */ -int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x", - address, i2c_data); - - memcpy(buf, bridge_urb_skeleton, - sizeof(bridge_urb_skeleton)); - buf[1] = address; - buf[3] = i2c_data; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 4, M5602_URB_MSG_TIMEOUT); - - /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero instead */ - return (err < 0) ? err : 0; -} - -static int m5602_wait_for_i2c(struct sd *sd) -{ - int err; - u8 data; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data); - } while ((data & I2C_BUSY) && !err); - return err; -} - -int m5602_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - - if (!len || len > sd->sensor->i2c_regW) - return -EINVAL; - - err = m5602_wait_for_i2c(sd); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - sd->sensor->i2c_slave_id); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - if (err < 0) - return err; - - /* Sensors with registers that are of only - one byte width are differently read */ - - /* FIXME: This works with the ov9650, but has issues with the po1030 */ - if (sd->sensor->i2c_regW == 1) { - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); - } else { - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); - } - - for (i = 0; (i < len) && !err; i++) { - err = m5602_wait_for_i2c(sd); - if (err < 0) - return err; - - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(D_CONF, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); - } - return err; -} - -int m5602_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* No sensor with a data width larger than 16 bits has yet been seen */ - if (len > sd->sensor->i2c_regW || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, - sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - /* Special case larger sensor writes */ - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the tailer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -/* Dump all the registers of the m5602 bridge, - unfortunately this breaks the camera until it's power cycled */ -static void m5602_dump_bridge(struct sd *sd) -{ - int i; - for (i = 0; i < 0x80; i++) { - unsigned char val = 0; - m5602_read_bridge(sd, i, &val); - pr_info("ALi m5602 address 0x%x contains 0x%x\n", i, val); - } - pr_info("Warning: The ALi m5602 webcam probably won't work until it's power cycled\n"); -} - -static int m5602_probe_sensor(struct sd *sd) -{ - /* Try the po1030 */ - sd->sensor = &po1030; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the mt9m111 sensor */ - sd->sensor = &mt9m111; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the s5k4aa */ - sd->sensor = &s5k4aa; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the ov9650 */ - sd->sensor = &ov9650; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the ov7660 */ - sd->sensor = &ov7660; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the s5k83a */ - sd->sensor = &s5k83a; - if (!sd->sensor->probe(sd)) - return 0; - - /* More sensor probe function goes here */ - pr_info("Failed to find a sensor\n"); - sd->sensor = NULL; - return -ENODEV; -} - -static int m5602_configure(struct gspca_dev *gspca_dev, - const struct usb_device_id *id); - -static int m5602_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - PDEBUG(D_CONF, "Initializing ALi m5602 webcam"); - /* Run the init sequence */ - err = sd->sensor->init(sd); - - return err; -} - -static int m5602_start_transfer(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *buf = sd->gspca_dev.usb_buf; - int err; - - /* Send start command to the camera */ - const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; - - if (sd->sensor->start) - sd->sensor->start(sd); - - memcpy(buf, buffer, sizeof(buffer)); - err = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x04, 0x40, 0x19, 0x0000, buf, - sizeof(buffer), M5602_URB_MSG_TIMEOUT); - - PDEBUG(D_STREAM, "Transfer started"); - return (err < 0) ? err : 0; -} - -static void m5602_urb_complete(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (len < 6) { - PDEBUG(D_PACK, "Packet is less than 6 bytes"); - return; - } - - /* Frame delimiter: ff xx xx xx ff ff */ - if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff && - data[2] != sd->frame_id) { - PDEBUG(D_FRAM, "Frame delimiter detected"); - sd->frame_id = data[2]; - - /* Remove the extra fluff appended on each header */ - data += 6; - len -= 6; - - /* Complete the last frame (if any) */ - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - sd->frame_count++; - - /* Create a new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - - PDEBUG(D_FRAM, "Starting new frame %d", - sd->frame_count); - - } else { - int cur_frame_len; - - cur_frame_len = gspca_dev->image_len; - /* Remove urb header */ - data += 4; - len -= 4; - - if (cur_frame_len + len <= gspca_dev->frsz) { - PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", - sd->frame_count, len); - - gspca_frame_add(gspca_dev, INTER_PACKET, - data, len); - } else { - /* Add the remaining data up to frame size */ - gspca_frame_add(gspca_dev, INTER_PACKET, data, - gspca_dev->frsz - cur_frame_len); - } - } -} - -static void m5602_stop_transfer(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Run the sensor specific end transfer sequence */ - if (sd->sensor->stop) - sd->sensor->stop(sd); -} - -/* sub-driver description, the ctrl and nctrl is filled at probe time */ -static struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = m5602_configure, - .init = m5602_init, - .start = m5602_start_transfer, - .stopN = m5602_stop_transfer, - .pkt_scan = m5602_urb_complete -}; - -/* this function is called at probe time */ -static int m5602_configure(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int err; - - cam = &gspca_dev->cam; - sd->desc = &sd_desc; - - if (dump_bridge) - m5602_dump_bridge(sd); - - /* Probe sensor */ - err = m5602_probe_sensor(sd); - if (err) - goto fail; - - return 0; - -fail: - PDEBUG(D_ERR, "ALi m5602 webcam failed"); - cam->cam_mode = NULL; - cam->nmodes = 0; - - return err; -} - -static int m5602_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static void m5602_disconnect(struct usb_interface *intf) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor->disconnect) - sd->sensor->disconnect(sd); - - gspca_disconnect(intf); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = m5602_table, - .probe = m5602_probe, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif - .disconnect = m5602_disconnect -}; - -module_usb_driver(sd_driver); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -module_param(force_sensor, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(force_sensor, - "forces detection of a sensor, " - "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, " - "4 = MT9M111, 5 = PO1030, 6 = OV7660"); - -module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); - -module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers " - "at startup providing a sensor is found"); diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c deleted file mode 100644 index 6268aa24ec5d..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Driver for the mt9m111 sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_mt9m111.h" - -static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); - -static struct v4l2_pix_format mt9m111_modes[] = { - { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static const struct ctrl mt9m111_ctrls[] = { -#define VFLIP_IDX 0 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_vflip, - .get = mt9m111_get_vflip - }, -#define HFLIP_IDX 1 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_hflip, - .get = mt9m111_get_hflip - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0, - .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, - .step = 1, - .default_value = MT9M111_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_gain, - .get = mt9m111_get_gain - }, -#define AUTO_WHITE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = mt9m111_set_auto_white_balance, - .get = mt9m111_get_auto_white_balance - }, -#define GREEN_BALANCE_IDX 4 - { - { - .id = M5602_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_GREEN_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_green_balance, - .get = mt9m111_get_green_balance - }, -#define BLUE_BALANCE_IDX 5 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_blue_balance, - .get = mt9m111_get_blue_balance - }, -#define RED_BALANCE_IDX 5 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0x7ff, - .step = 0x1, - .default_value = MT9M111_RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_red_balance, - .get = mt9m111_get_red_balance - }, -}; - -static void mt9m111_dump_registers(struct sd *sd); - -int mt9m111_probe(struct sd *sd) -{ - u8 data[2] = {0x00, 0x00}; - int i; - s32 *sensor_settings; - - if (force_sensor) { - if (force_sensor == MT9M111_SENSOR) { - pr_info("Forcing a %s sensor\n", mt9m111.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - PDEBUG(D_PROBE, "Probing for a mt9m111 sensor"); - - /* Do the preinit */ - for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { - if (preinit_mt9m111[i][0] == BRIDGE) { - m5602_write_bridge(sd, - preinit_mt9m111[i][1], - preinit_mt9m111[i][2]); - } else { - data[0] = preinit_mt9m111[i][2]; - data[1] = preinit_mt9m111[i][3]; - m5602_write_sensor(sd, - preinit_mt9m111[i][1], data, 2); - } - } - - if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) - return -ENODEV; - - if ((data[0] == 0x14) && (data[1] == 0x3a)) { - pr_info("Detected a mt9m111 sensor\n"); - goto sensor_found; - } - - return -ENODEV; - -sensor_found: - sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), - GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = mt9m111_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); - sd->desc->ctrls = mt9m111_ctrls; - sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); - - for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) - sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; - - return 0; -} - -int mt9m111_init(struct sd *sd) -{ - int i, err = 0; - s32 *sensor_settings = sd->sensor_priv; - - /* Init the sensor */ - for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { - u8 data[2]; - - if (init_mt9m111[i][0] == BRIDGE) { - err = m5602_write_bridge(sd, - init_mt9m111[i][1], - init_mt9m111[i][2]); - } else { - data[0] = init_mt9m111[i][2]; - data[1] = init_mt9m111[i][3]; - err = m5602_write_sensor(sd, - init_mt9m111[i][1], data, 2); - } - } - - if (dump_sensor) - mt9m111_dump_registers(sd); - - err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_green_balance(&sd->gspca_dev, - sensor_settings[GREEN_BALANCE_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; - - err = mt9m111_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; - - return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); -} - -int mt9m111_start(struct sd *sd) -{ - int i, err = 0; - u8 data[2]; - struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; - - int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; - int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; - - for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) { - if (start_mt9m111[i][0] == BRIDGE) { - err = m5602_write_bridge(sd, - start_mt9m111[i][1], - start_mt9m111[i][2]); - } else { - data[0] = start_mt9m111[i][2]; - data[1] = start_mt9m111[i][3]; - err = m5602_write_sensor(sd, - start_mt9m111[i][1], data, 2); - } - } - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); - if (err < 0) - return err; - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); - if (err < 0) - return err; - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, - (width >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - if (err < 0) - return err; - - switch (width) { - case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); - data[0] = MT9M111_RMB_OVER_SIZED; - data[1] = MT9M111_RMB_ROW_SKIP_2X | - MT9M111_RMB_COLUMN_SKIP_2X | - (sensor_settings[VFLIP_IDX] << 0) | - (sensor_settings[HFLIP_IDX] << 1); - - err = m5602_write_sensor(sd, - MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - break; - - case 320: - PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); - data[0] = MT9M111_RMB_OVER_SIZED; - data[1] = MT9M111_RMB_ROW_SKIP_4X | - MT9M111_RMB_COLUMN_SKIP_4X | - (sensor_settings[VFLIP_IDX] << 0) | - (sensor_settings[HFLIP_IDX] << 1); - err = m5602_write_sensor(sd, - MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - break; - } - return err; -} - -void mt9m111_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - - sensor_settings[VFLIP_IDX] = val; - - /* The mt9m111 is flipped by default */ - val = !val; - - /* Set the correct page map */ - err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - return err; - - data[1] = (data[1] & 0xfe) | val; - err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - return err; -} - -static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - - return 0; -} - -static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - - sensor_settings[HFLIP_IDX] = val; - - /* The mt9m111 is flipped by default */ - val = !val; - - /* Set the correct page map */ - err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - return err; - - data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02); - err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - return err; -} - -static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - - return 0; -} - -static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - int err; - u8 data[2]; - - err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); - if (err < 0) - return err; - - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; - data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); - - err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); - - PDEBUG(D_V4L2, "Set auto white balance %d", val); - return err; -} - -static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) { - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read auto white balance %d", *val); - return 0; -} - -static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err, tmp; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[GAIN_IDX] = val; - - /* Set the correct page map */ - err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - return err; - - if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2) - return -EINVAL; - - if ((val >= INITIAL_MAX_GAIN * 2 * 2) && - (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2)) - tmp = (1 << 10) | (val << 9) | - (val << 8) | (val / 8); - else if ((val >= INITIAL_MAX_GAIN * 2) && - (val < INITIAL_MAX_GAIN * 2 * 2)) - tmp = (1 << 9) | (1 << 8) | (val / 4); - else if ((val >= INITIAL_MAX_GAIN) && - (val < INITIAL_MAX_GAIN * 2)) - tmp = (1 << 8) | (val / 2); - else - tmp = val; - - data[1] = (tmp & 0xff); - data[0] = (tmp & 0xff00) >> 8; - PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, - data[1], data[0]); - - err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, - data, 2); - - return err; -} - -static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[GREEN_BALANCE_IDX] = val; - data[1] = (val & 0xff); - data[0] = (val & 0xff00) >> 8; - - PDEBUG(D_V4L2, "Set green balance %d", val); - err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, - data, 2); - if (err < 0) - return err; - - return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN, - data, 2); -} - -static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GREEN_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read green balance %d", *val); - return 0; -} - -static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[BLUE_BALANCE_IDX] = val; - data[1] = (val & 0xff); - data[0] = (val & 0xff00) >> 8; - - PDEBUG(D_V4L2, "Set blue balance %d", val); - - return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, - data, 2); -} - -static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue balance %d", *val); - return 0; -} - -static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[RED_BALANCE_IDX] = val; - data[1] = (val & 0xff); - data[0] = (val & 0xff00) >> 8; - - PDEBUG(D_V4L2, "Set red balance %d", val); - - return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, - data, 2); -} - -static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red balance %d", *val); - return 0; -} - -static void mt9m111_dump_registers(struct sd *sd) -{ - u8 address, value[2] = {0x00, 0x00}; - - pr_info("Dumping the mt9m111 register state\n"); - - pr_info("Dumping the mt9m111 sensor core registers\n"); - value[1] = MT9M111_SENSOR_CORE; - m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - m5602_read_sensor(sd, address, value, 2); - pr_info("register 0x%x contains 0x%x%x\n", - address, value[0], value[1]); - } - - pr_info("Dumping the mt9m111 color pipeline registers\n"); - value[1] = MT9M111_COLORPIPE; - m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - m5602_read_sensor(sd, address, value, 2); - pr_info("register 0x%x contains 0x%x%x\n", - address, value[0], value[1]); - } - - pr_info("Dumping the mt9m111 camera control registers\n"); - value[1] = MT9M111_CAMERA_CONTROL; - m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - m5602_read_sensor(sd, address, value, 2); - pr_info("register 0x%x contains 0x%x%x\n", - address, value[0], value[1]); - } - - pr_info("mt9m111 register state dump complete\n"); -} diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h deleted file mode 100644 index 8c672b5c8c6a..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Driver for the mt9m111 sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * Some defines taken from the mt9m111 sensor driver - * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_MT9M111_H_ -#define M5602_MT9M111_H_ - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define MT9M111_SC_CHIPVER 0x00 -#define MT9M111_SC_ROWSTART 0x01 -#define MT9M111_SC_COLSTART 0x02 -#define MT9M111_SC_WINDOW_HEIGHT 0x03 -#define MT9M111_SC_WINDOW_WIDTH 0x04 -#define MT9M111_SC_HBLANK_CONTEXT_B 0x05 -#define MT9M111_SC_VBLANK_CONTEXT_B 0x06 -#define MT9M111_SC_HBLANK_CONTEXT_A 0x07 -#define MT9M111_SC_VBLANK_CONTEXT_A 0x08 -#define MT9M111_SC_SHUTTER_WIDTH 0x09 -#define MT9M111_SC_ROW_SPEED 0x0a -#define MT9M111_SC_EXTRA_DELAY 0x0b -#define MT9M111_SC_SHUTTER_DELAY 0x0c -#define MT9M111_SC_RESET 0x0d -#define MT9M111_SC_R_MODE_CONTEXT_B 0x20 -#define MT9M111_SC_R_MODE_CONTEXT_A 0x21 -#define MT9M111_SC_FLASH_CONTROL 0x23 -#define MT9M111_SC_GREEN_1_GAIN 0x2b -#define MT9M111_SC_BLUE_GAIN 0x2c -#define MT9M111_SC_RED_GAIN 0x2d -#define MT9M111_SC_GREEN_2_GAIN 0x2e -#define MT9M111_SC_GLOBAL_GAIN 0x2f - -#define MT9M111_CONTEXT_CONTROL 0xc8 -#define MT9M111_PAGE_MAP 0xf0 -#define MT9M111_BYTEWISE_ADDRESS 0xf1 - -#define MT9M111_CP_OPERATING_MODE_CTL 0x06 -#define MT9M111_CP_LUMA_OFFSET 0x34 -#define MT9M111_CP_LUMA_CLIP 0x35 -#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A 0x3a -#define MT9M111_CP_LENS_CORRECTION_1 0x3b -#define MT9M111_CP_DEFECT_CORR_CONTEXT_A 0x4c -#define MT9M111_CP_DEFECT_CORR_CONTEXT_B 0x4d -#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B 0x9b -#define MT9M111_CP_GLOBAL_CLK_CONTROL 0xb3 - -#define MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18 0x65 -#define MT9M111_CC_AWB_PARAMETER_7 0x28 - -#define MT9M111_SENSOR_CORE 0x00 -#define MT9M111_COLORPIPE 0x01 -#define MT9M111_CAMERA_CONTROL 0x02 - -#define MT9M111_RESET (1 << 0) -#define MT9M111_RESTART (1 << 1) -#define MT9M111_ANALOG_STANDBY (1 << 2) -#define MT9M111_CHIP_ENABLE (1 << 3) -#define MT9M111_CHIP_DISABLE (0 << 3) -#define MT9M111_OUTPUT_DISABLE (1 << 4) -#define MT9M111_SHOW_BAD_FRAMES (1 << 0) -#define MT9M111_RESTART_BAD_FRAMES (1 << 1) -#define MT9M111_SYNCHRONIZE_CHANGES (1 << 7) - -#define MT9M111_RMB_OVER_SIZED (1 << 0) -#define MT9M111_RMB_MIRROR_ROWS (1 << 0) -#define MT9M111_RMB_MIRROR_COLS (1 << 1) -#define MT9M111_RMB_ROW_SKIP_2X (1 << 2) -#define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3) -#define MT9M111_RMB_ROW_SKIP_4X (1 << 4) -#define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5) - -#define MT9M111_COLOR_MATRIX_BYPASS (1 << 4) -#define MT9M111_SEL_CONTEXT_B (1 << 3) - -#define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1) -#define MT9M111_SOC_SOFT_STANDBY (1 << 0) - -#define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) - -#define INITIAL_MAX_GAIN 64 -#define MT9M111_DEFAULT_GAIN 283 -#define MT9M111_GREEN_GAIN_DEFAULT 0x20 -#define MT9M111_BLUE_GAIN_DEFAULT 0x20 -#define MT9M111_RED_GAIN_DEFAULT 0x20 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int mt9m111_probe(struct sd *sd); -int mt9m111_init(struct sd *sd); -int mt9m111_start(struct sd *sd); -void mt9m111_disconnect(struct sd *sd); - -static const struct m5602_sensor mt9m111 = { - .name = "MT9M111", - - .i2c_slave_id = 0xba, - .i2c_regW = 2, - - .probe = mt9m111_probe, - .init = mt9m111_init, - .disconnect = mt9m111_disconnect, - .start = mt9m111_start, -}; - -static const unsigned char preinit_mt9m111[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, - MT9M111_RESET | - MT9M111_RESTART | - MT9M111_ANALOG_STANDBY | - MT9M111_CHIP_DISABLE, - MT9M111_SHOW_BAD_FRAMES | - MT9M111_RESTART_BAD_FRAMES | - MT9M111_SYNCHRONIZE_CHANGES}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00} -}; - -static const unsigned char init_mt9m111[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, - MT9M111_CP_OPERATING_MODE_CTL}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, - MT9M111_2D_DEFECT_CORRECTION_ENABLE}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, - MT9M111_2D_DEFECT_CORRECTION_ENABLE}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - {SENSOR, 0xcd, 0x00, 0x0e}, - {SENSOR, 0xd0, 0x00, 0x40}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */ - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */ - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */ - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */ - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */ - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */ - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */ - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */ - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */ - {SENSOR, 0x30, 0x04, 0x00}, - /* Set number of blank rows chosen to 400 */ - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, -}; - -static const unsigned char start_mt9m111[][4] = { - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c deleted file mode 100644 index 9a14835c128f..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Driver for the ov7660 sensor - * - * Copyright (C) 2009 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_ov7660.h" - -static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); - -static const struct ctrl ov7660_ctrls[] = { -#define GAIN_IDX 1 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = OV7660_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov7660_set_gain, - .get = ov7660_get_gain - }, -#define BLUE_BALANCE_IDX 2 -#define RED_BALANCE_IDX 3 -#define AUTO_WHITE_BALANCE_IDX 4 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_white_balance, - .get = ov7660_get_auto_white_balance - }, -#define AUTO_GAIN_CTRL_IDX 5 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto gain control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_gain, - .get = ov7660_get_auto_gain - }, -#define AUTO_EXPOSURE_IDX 6 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov7660_set_auto_exposure, - .get = ov7660_get_auto_exposure - }, -#define HFLIP_IDX 7 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov7660_set_hflip, - .get = ov7660_get_hflip - }, -#define VFLIP_IDX 8 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov7660_set_vflip, - .get = ov7660_get_vflip - }, - -}; - -static struct v4l2_pix_format ov7660_modes[] = { - { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static void ov7660_dump_registers(struct sd *sd); - -int ov7660_probe(struct sd *sd) -{ - int err = 0, i; - u8 prod_id = 0, ver_id = 0; - - s32 *sensor_settings; - - if (force_sensor) { - if (force_sensor == OV7660_SENSOR) { - pr_info("Forcing an %s sensor\n", ov7660.name); - goto sensor_found; - } - /* If we want to force another sensor, - don't try to probe this one */ - return -ENODEV; - } - - /* Do the preinit */ - for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { - u8 data[2]; - - if (preinit_ov7660[i][0] == BRIDGE) { - err = m5602_write_bridge(sd, - preinit_ov7660[i][1], - preinit_ov7660[i][2]); - } else { - data[0] = preinit_ov7660[i][2]; - err = m5602_write_sensor(sd, - preinit_ov7660[i][1], data, 1); - } - } - if (err < 0) - return err; - - if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) - return -ENODEV; - - if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) - return -ENODEV; - - pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id); - - if ((prod_id == 0x76) && (ver_id == 0x60)) { - pr_info("Detected a ov7660 sensor\n"); - goto sensor_found; - } - return -ENODEV; - -sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = ov7660_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); - sd->desc->ctrls = ov7660_ctrls; - sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); - - for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) - sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; - - return 0; -} - -int ov7660_init(struct sd *sd) -{ - int i, err = 0; - s32 *sensor_settings = sd->sensor_priv; - - /* Init the sensor */ - for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { - u8 data[2]; - - if (init_ov7660[i][0] == BRIDGE) { - err = m5602_write_bridge(sd, - init_ov7660[i][1], - init_ov7660[i][2]); - } else { - data[0] = init_ov7660[i][2]; - err = m5602_write_sensor(sd, - init_ov7660[i][1], data, 1); - } - } - - if (dump_sensor) - ov7660_dump_registers(sd); - - err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = ov7660_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov7660_set_auto_gain(&sd->gspca_dev, - sensor_settings[AUTO_GAIN_CTRL_IDX]); - if (err < 0) - return err; - - err = ov7660_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - if (err < 0) - return err; - err = ov7660_set_hflip(&sd->gspca_dev, - sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = ov7660_set_vflip(&sd->gspca_dev, - sensor_settings[VFLIP_IDX]); - - return err; -} - -int ov7660_start(struct sd *sd) -{ - return 0; -} - -int ov7660_stop(struct sd *sd) -{ - return 0; -} - -void ov7660_disconnect(struct sd *sd) -{ - ov7660_stop(sd); - - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - return 0; -} - -static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Setting gain to %d", val); - - sensor_settings[GAIN_IDX] = val; - - err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); - return err; -} - - -static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - return 0; -} - -static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto white balance to %d", val); - - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; - err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); - err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); - - return err; -} - -static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; - PDEBUG(D_V4L2, "Read auto gain control %d", *val); - return 0; -} - -static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto gain control to %d", val); - - sensor_settings[AUTO_GAIN_CTRL_IDX] = val; - err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); - - return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); -} - -static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read auto exposure control %d", *val); - return 0; -} - -static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, - __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto exposure control to %d", val); - - sensor_settings[AUTO_EXPOSURE_IDX] = val; - err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); - - return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); -} - -static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return 0; -} - -static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - - sensor_settings[HFLIP_IDX] = val; - - i2c_data = ((val & 0x01) << 5) | - (sensor_settings[VFLIP_IDX] << 4); - - err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); - - return err; -} - -static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - sensor_settings[VFLIP_IDX] = val; - - i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); - err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); - if (err < 0) - return err; - - /* When vflip is toggled we need to readjust the bridge hsync/vsync */ - if (gspca_dev->streaming) - err = ov7660_start(sd); - - return err; -} - -static void ov7660_dump_registers(struct sd *sd) -{ - int address; - pr_info("Dumping the ov7660 register state\n"); - for (address = 0; address < 0xa9; address++) { - u8 value; - m5602_read_sensor(sd, address, &value, 1); - pr_info("register 0x%x contains 0x%x\n", address, value); - } - - pr_info("ov7660 register state dump complete\n"); - - pr_info("Probing for which registers that are read/write\n"); - for (address = 0; address < 0xff; address++) { - u8 old_value, ctrl_value; - u8 test_value[2] = {0xff, 0xff}; - - m5602_read_sensor(sd, address, &old_value, 1); - m5602_write_sensor(sd, address, test_value, 1); - m5602_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value[0]) - pr_info("register 0x%x is writeable\n", address); - else - pr_info("register 0x%x is read only\n", address); - - /* Restore original value */ - m5602_write_sensor(sd, address, &old_value, 1); - } -} diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h deleted file mode 100644 index 2b6a13b508f7..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Driver for the ov7660 sensor - * - * Copyright (C) 2009 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_OV7660_H_ -#define M5602_OV7660_H_ - -#include "m5602_sensor.h" - -#define OV7660_GAIN 0x00 -#define OV7660_BLUE_GAIN 0x01 -#define OV7660_RED_GAIN 0x02 -#define OV7660_VREF 0x03 -#define OV7660_COM1 0x04 -#define OV7660_BAVE 0x05 -#define OV7660_GEAVE 0x06 -#define OV7660_AECHH 0x07 -#define OV7660_RAVE 0x08 -#define OV7660_COM2 0x09 -#define OV7660_PID 0x0a -#define OV7660_VER 0x0b -#define OV7660_COM3 0x0c -#define OV7660_COM4 0x0d -#define OV7660_COM5 0x0e -#define OV7660_COM6 0x0f -#define OV7660_AECH 0x10 -#define OV7660_CLKRC 0x11 -#define OV7660_COM7 0x12 -#define OV7660_COM8 0x13 -#define OV7660_COM9 0x14 -#define OV7660_COM10 0x15 -#define OV7660_RSVD16 0x16 -#define OV7660_HSTART 0x17 -#define OV7660_HSTOP 0x18 -#define OV7660_VSTART 0x19 -#define OV7660_VSTOP 0x1a -#define OV7660_PSHFT 0x1b -#define OV7660_MIDH 0x1c -#define OV7660_MIDL 0x1d -#define OV7660_MVFP 0x1e -#define OV7660_LAEC 0x1f -#define OV7660_BOS 0x20 -#define OV7660_GBOS 0x21 -#define OV7660_GROS 0x22 -#define OV7660_ROS 0x23 -#define OV7660_AEW 0x24 -#define OV7660_AEB 0x25 -#define OV7660_VPT 0x26 -#define OV7660_BBIAS 0x27 -#define OV7660_GbBIAS 0x28 -#define OV7660_RSVD29 0x29 -#define OV7660_RBIAS 0x2c -#define OV7660_HREF 0x32 -#define OV7660_ADC 0x37 -#define OV7660_OFON 0x39 -#define OV7660_TSLB 0x3a -#define OV7660_COM12 0x3c -#define OV7660_COM13 0x3d -#define OV7660_LCC1 0x62 -#define OV7660_LCC2 0x63 -#define OV7660_LCC3 0x64 -#define OV7660_LCC4 0x65 -#define OV7660_LCC5 0x66 -#define OV7660_HV 0x69 -#define OV7660_RSVDA1 0xa1 - -#define OV7660_DEFAULT_GAIN 0x0e -#define OV7660_DEFAULT_RED_GAIN 0x80 -#define OV7660_DEFAULT_BLUE_GAIN 0x80 -#define OV7660_DEFAULT_SATURATION 0x00 -#define OV7660_DEFAULT_EXPOSURE 0x20 - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int ov7660_probe(struct sd *sd); -int ov7660_init(struct sd *sd); -int ov7660_start(struct sd *sd); -int ov7660_stop(struct sd *sd); -void ov7660_disconnect(struct sd *sd); - -static const struct m5602_sensor ov7660 = { - .name = "ov7660", - .i2c_slave_id = 0x42, - .i2c_regW = 1, - .probe = ov7660_probe, - .init = ov7660_init, - .start = ov7660_start, - .stop = ov7660_stop, - .disconnect = ov7660_disconnect, -}; - -static const unsigned char preinit_ov7660[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - - {SENSOR, OV7660_OFON, 0x0c}, - {SENSOR, OV7660_COM2, 0x11}, - {SENSOR, OV7660_COM7, 0x05}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} -}; - -static const unsigned char init_ov7660[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, - {SENSOR, OV7660_COM7, 0x80}, - {SENSOR, OV7660_CLKRC, 0x80}, - {SENSOR, OV7660_COM9, 0x4c}, - {SENSOR, OV7660_OFON, 0x43}, - {SENSOR, OV7660_COM12, 0x28}, - {SENSOR, OV7660_COM8, 0x00}, - {SENSOR, OV7660_COM10, 0x40}, - {SENSOR, OV7660_HSTART, 0x0c}, - {SENSOR, OV7660_HSTOP, 0x61}, - {SENSOR, OV7660_HREF, 0xa4}, - {SENSOR, OV7660_PSHFT, 0x0b}, - {SENSOR, OV7660_VSTART, 0x01}, - {SENSOR, OV7660_VSTOP, 0x7a}, - {SENSOR, OV7660_VSTOP, 0x00}, - {SENSOR, OV7660_COM7, 0x05}, - {SENSOR, OV7660_COM6, 0x42}, - {SENSOR, OV7660_BBIAS, 0x94}, - {SENSOR, OV7660_GbBIAS, 0x94}, - {SENSOR, OV7660_RSVD29, 0x94}, - {SENSOR, OV7660_RBIAS, 0x94}, - {SENSOR, OV7660_COM1, 0x00}, - {SENSOR, OV7660_AECH, 0x00}, - {SENSOR, OV7660_AECHH, 0x00}, - {SENSOR, OV7660_ADC, 0x05}, - {SENSOR, OV7660_COM13, 0x00}, - {SENSOR, OV7660_RSVDA1, 0x23}, - {SENSOR, OV7660_TSLB, 0x0d}, - {SENSOR, OV7660_HV, 0x80}, - {SENSOR, OV7660_LCC1, 0x00}, - {SENSOR, OV7660_LCC2, 0x00}, - {SENSOR, OV7660_LCC3, 0x10}, - {SENSOR, OV7660_LCC4, 0x40}, - {SENSOR, OV7660_LCC5, 0x01}, - - {SENSOR, OV7660_AECH, 0x20}, - {SENSOR, OV7660_COM1, 0x00}, - {SENSOR, OV7660_OFON, 0x0c}, - {SENSOR, OV7660_COM2, 0x11}, - {SENSOR, OV7660_COM7, 0x05}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, - {SENSOR, OV7660_AECH, 0x5f}, - {SENSOR, OV7660_COM1, 0x03}, - {SENSOR, OV7660_OFON, 0x0c}, - {SENSOR, OV7660_COM2, 0x11}, - {SENSOR, OV7660_COM7, 0x05}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_SIG_INI, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x08}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x27}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c deleted file mode 100644 index 2114a8b90ec9..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Driver for the ov9650 sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_ov9650.h" - -static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); -static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); - -/* Vertically and horizontally flips the image if matched, needed for machines - where the sensor is mounted upside down */ -static - const - struct dmi_system_id ov9650_flip_dmi_table[] = { - { - .ident = "ASUS A6Ja", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6J") - } - }, - { - .ident = "ASUS A6JC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") - } - }, - { - .ident = "ASUS A6K", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6K") - } - }, - { - .ident = "ASUS A6Kt", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") - } - }, - { - .ident = "ASUS A6VA", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") - } - }, - { - - .ident = "ASUS A6VC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") - } - }, - { - .ident = "ASUS A6VM", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") - } - }, - { - .ident = "ASUS A7V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A7V") - } - }, - { - .ident = "Alienware Aurora m9700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") - } - }, - {} -}; - -static const struct ctrl ov9650_ctrls[] = { -#define EXPOSURE_IDX 0 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0x1ff, - .step = 0x4, - .default_value = EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_exposure, - .get = ov9650_get_exposure - }, -#define GAIN_IDX 1 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0x3ff, - .step = 0x1, - .default_value = GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_gain, - .get = ov9650_get_gain - }, -#define RED_BALANCE_IDX 2 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_red_balance, - .get = ov9650_get_red_balance - }, -#define BLUE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_blue_balance, - .get = ov9650_get_blue_balance - }, -#define HFLIP_IDX 4 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_hflip, - .get = ov9650_get_hflip - }, -#define VFLIP_IDX 5 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_vflip, - .get = ov9650_get_vflip - }, -#define AUTO_WHITE_BALANCE_IDX 6 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_white_balance, - .get = ov9650_get_auto_white_balance - }, -#define AUTO_GAIN_CTRL_IDX 7 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto gain control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_gain, - .get = ov9650_get_auto_gain - }, -#define AUTO_EXPOSURE_IDX 8 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = ov9650_set_auto_exposure, - .get = ov9650_get_auto_exposure - } - -}; - -static struct v4l2_pix_format ov9650_modes[] = { - { - 176, - 144, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 176 * 144, - .bytesperline = 176, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 9 - }, { - 320, - 240, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 320 * 240, - .bytesperline = 320, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 8 - }, { - 352, - 288, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 352 * 288, - .bytesperline = 352, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 9 - }, { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 9 - } -}; - -static void ov9650_dump_registers(struct sd *sd); - -int ov9650_probe(struct sd *sd) -{ - int err = 0; - u8 prod_id = 0, ver_id = 0, i; - s32 *sensor_settings; - - if (force_sensor) { - if (force_sensor == OV9650_SENSOR) { - pr_info("Forcing an %s sensor\n", ov9650.name); - goto sensor_found; - } - /* If we want to force another sensor, - don't try to probe this one */ - return -ENODEV; - } - - PDEBUG(D_PROBE, "Probing for an ov9650 sensor"); - - /* Run the pre-init before probing the sensor */ - for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { - u8 data = preinit_ov9650[i][2]; - if (preinit_ov9650[i][0] == SENSOR) - err = m5602_write_sensor(sd, - preinit_ov9650[i][1], &data, 1); - else - err = m5602_write_bridge(sd, - preinit_ov9650[i][1], data); - } - - if (err < 0) - return err; - - if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1)) - return -ENODEV; - - if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1)) - return -ENODEV; - - if ((prod_id == 0x96) && (ver_id == 0x52)) { - pr_info("Detected an ov9650 sensor\n"); - goto sensor_found; - } - return -ENODEV; - -sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = ov9650_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes); - sd->desc->ctrls = ov9650_ctrls; - sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls); - - for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) - sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; - return 0; -} - -int ov9650_init(struct sd *sd) -{ - int i, err = 0; - u8 data; - s32 *sensor_settings = sd->sensor_priv; - - if (dump_sensor) - ov9650_dump_registers(sd); - - for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { - data = init_ov9650[i][2]; - if (init_ov9650[i][0] == SENSOR) - err = m5602_write_sensor(sd, init_ov9650[i][1], - &data, 1); - else - err = m5602_write_bridge(sd, init_ov9650[i][1], data); - } - - err = ov9650_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = ov9650_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - err = ov9650_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; - - err = ov9650_set_auto_gain(&sd->gspca_dev, - sensor_settings[AUTO_GAIN_CTRL_IDX]); - return err; -} - -int ov9650_start(struct sd *sd) -{ - u8 data; - int i, err = 0; - struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; - - int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; - int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; - int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - int hor_offs = OV9650_LEFT_OFFSET; - - if ((!dmi_check_system(ov9650_flip_dmi_table) && - sensor_settings[VFLIP_IDX]) || - (dmi_check_system(ov9650_flip_dmi_table) && - !sensor_settings[VFLIP_IDX])) - ver_offs--; - - if (width <= 320) - hor_offs /= 2; - - /* Synthesize the vsync/hsync setup */ - for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { - if (res_init_ov9650[i][0] == BRIDGE) - err = m5602_write_bridge(sd, res_init_ov9650[i][1], - res_init_ov9650[i][2]); - else if (res_init_ov9650[i][0] == SENSOR) { - data = res_init_ov9650[i][2]; - err = m5602_write_sensor(sd, - res_init_ov9650[i][1], &data, 1); - } - } - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, - ((ver_offs >> 8) & 0xff)); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); - if (err < 0) - return err; - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, - (hor_offs >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, - ((width + hor_offs) >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, - ((width + hor_offs) & 0xff)); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - if (err < 0) - return err; - - switch (width) { - case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); - - data = OV9650_VGA_SELECT | OV9650_RGB_SELECT | - OV9650_RAW_RGB_SELECT; - err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); - break; - - case 352: - PDEBUG(D_V4L2, "Configuring camera for CIF mode"); - - data = OV9650_CIF_SELECT | OV9650_RGB_SELECT | - OV9650_RAW_RGB_SELECT; - err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); - break; - - case 320: - PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); - - data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT | - OV9650_RAW_RGB_SELECT; - err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); - break; - - case 176: - PDEBUG(D_V4L2, "Configuring camera for QCIF mode"); - - data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT | - OV9650_RAW_RGB_SELECT; - err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); - break; - } - return err; -} - -int ov9650_stop(struct sd *sd) -{ - u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X; - return m5602_write_sensor(sd, OV9650_COM2, &data, 1); -} - -void ov9650_disconnect(struct sd *sd) -{ - ov9650_stop(sd); - - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read exposure %d", *val); - return 0; -} - -static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - PDEBUG(D_V4L2, "Set exposure to %d", val); - - sensor_settings[EXPOSURE_IDX] = val; - /* The 6 MSBs */ - i2c_data = (val >> 10) & 0x3f; - err = m5602_write_sensor(sd, OV9650_AECHM, - &i2c_data, 1); - if (err < 0) - return err; - - /* The 8 middle bits */ - i2c_data = (val >> 2) & 0xff; - err = m5602_write_sensor(sd, OV9650_AECH, - &i2c_data, 1); - if (err < 0) - return err; - - /* The 2 LSBs */ - i2c_data = val & 0x03; - err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1); - return err; -} - -static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - return 0; -} - -static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Setting gain to %d", val); - - sensor_settings[GAIN_IDX] = val; - - /* The 2 MSB */ - /* Read the OV9650_VREF register first to avoid - corrupting the VREF high and low bits */ - err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); - if (err < 0) - return err; - - /* Mask away all uninteresting bits */ - i2c_data = ((val & 0x0300) >> 2) | - (i2c_data & 0x3f); - err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); - if (err < 0) - return err; - - /* The 8 LSBs */ - i2c_data = val & 0xff; - err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); - return err; -} - -static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red gain %d", *val); - return 0; -} - -static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set red gain to %d", val); - - sensor_settings[RED_BALANCE_IDX] = val; - - i2c_data = val & 0xff; - err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); - return err; -} - -static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue gain %d", *val); - - return 0; -} - -static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set blue gain to %d", val); - - sensor_settings[BLUE_BALANCE_IDX] = val; - - i2c_data = val & 0xff; - err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); - return err; -} - -static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return 0; -} - -static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - - sensor_settings[HFLIP_IDX] = val; - - if (!dmi_check_system(ov9650_flip_dmi_table)) - i2c_data = ((val & 0x01) << 5) | - (sensor_settings[VFLIP_IDX] << 4); - else - i2c_data = ((val & 0x01) << 5) | - (!sensor_settings[VFLIP_IDX] << 4); - - err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); - - return err; -} - -static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - sensor_settings[VFLIP_IDX] = val; - - if (dmi_check_system(ov9650_flip_dmi_table)) - val = !val; - - i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); - err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); - if (err < 0) - return err; - - /* When vflip is toggled we need to readjust the bridge hsync/vsync */ - if (gspca_dev->streaming) - err = ov9650_start(sd); - - return err; -} - -static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read auto exposure control %d", *val); - return 0; -} - -static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, - __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto exposure control to %d", val); - - sensor_settings[AUTO_EXPOSURE_IDX] = val; - err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); - - return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); -} - -static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - return 0; -} - -static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto white balance to %d", val); - - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; - err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); - err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); - - return err; -} - -static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; - PDEBUG(D_V4L2, "Read auto gain control %d", *val); - return 0; -} - -static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - PDEBUG(D_V4L2, "Set auto gain control to %d", val); - - sensor_settings[AUTO_GAIN_CTRL_IDX] = val; - err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); - - return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); -} - -static void ov9650_dump_registers(struct sd *sd) -{ - int address; - pr_info("Dumping the ov9650 register state\n"); - for (address = 0; address < 0xa9; address++) { - u8 value; - m5602_read_sensor(sd, address, &value, 1); - pr_info("register 0x%x contains 0x%x\n", address, value); - } - - pr_info("ov9650 register state dump complete\n"); - - pr_info("Probing for which registers that are read/write\n"); - for (address = 0; address < 0xff; address++) { - u8 old_value, ctrl_value; - u8 test_value[2] = {0xff, 0xff}; - - m5602_read_sensor(sd, address, &old_value, 1); - m5602_write_sensor(sd, address, test_value, 1); - m5602_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value[0]) - pr_info("register 0x%x is writeable\n", address); - else - pr_info("register 0x%x is read only\n", address); - - /* Restore original value */ - m5602_write_sensor(sd, address, &old_value, 1); - } -} diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h deleted file mode 100644 index f7aa5bf68983..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Driver for the ov9650 sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_OV9650_H_ -#define M5602_OV9650_H_ - -#include <linux/dmi.h> -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define OV9650_GAIN 0x00 -#define OV9650_BLUE 0x01 -#define OV9650_RED 0x02 -#define OV9650_VREF 0x03 -#define OV9650_COM1 0x04 -#define OV9650_BAVE 0x05 -#define OV9650_GEAVE 0x06 -#define OV9650_RSVD7 0x07 -#define OV9650_COM2 0x09 -#define OV9650_PID 0x0a -#define OV9650_VER 0x0b -#define OV9650_COM3 0x0c -#define OV9650_COM4 0x0d -#define OV9650_COM5 0x0e -#define OV9650_COM6 0x0f -#define OV9650_AECH 0x10 -#define OV9650_CLKRC 0x11 -#define OV9650_COM7 0x12 -#define OV9650_COM8 0x13 -#define OV9650_COM9 0x14 -#define OV9650_COM10 0x15 -#define OV9650_RSVD16 0x16 -#define OV9650_HSTART 0x17 -#define OV9650_HSTOP 0x18 -#define OV9650_VSTRT 0x19 -#define OV9650_VSTOP 0x1a -#define OV9650_PSHFT 0x1b -#define OV9650_MVFP 0x1e -#define OV9650_AEW 0x24 -#define OV9650_AEB 0x25 -#define OV9650_VPT 0x26 -#define OV9650_BBIAS 0x27 -#define OV9650_GbBIAS 0x28 -#define OV9650_Gr_COM 0x29 -#define OV9650_RBIAS 0x2c -#define OV9650_HREF 0x32 -#define OV9650_CHLF 0x33 -#define OV9650_ARBLM 0x34 -#define OV9650_RSVD35 0x35 -#define OV9650_RSVD36 0x36 -#define OV9650_ADC 0x37 -#define OV9650_ACOM38 0x38 -#define OV9650_OFON 0x39 -#define OV9650_TSLB 0x3a -#define OV9650_COM12 0x3c -#define OV9650_COM13 0x3d -#define OV9650_COM15 0x40 -#define OV9650_COM16 0x41 -#define OV9650_LCC1 0x62 -#define OV9650_LCC2 0x63 -#define OV9650_LCC3 0x64 -#define OV9650_LCC4 0x65 -#define OV9650_LCC5 0x66 -#define OV9650_HV 0x69 -#define OV9650_DBLV 0x6b -#define OV9650_COM21 0x8b -#define OV9650_COM22 0x8c -#define OV9650_COM24 0x8e -#define OV9650_DBLC1 0x8f -#define OV9650_RSVD94 0x94 -#define OV9650_RSVD95 0x95 -#define OV9650_RSVD96 0x96 -#define OV9650_LCCFB 0x9d -#define OV9650_LCCFR 0x9e -#define OV9650_AECHM 0xa1 -#define OV9650_COM26 0xa5 -#define OV9650_ACOMA8 0xa8 -#define OV9650_ACOMA9 0xa9 - -#define OV9650_REGISTER_RESET (1 << 7) -#define OV9650_VGA_SELECT (1 << 6) -#define OV9650_CIF_SELECT (1 << 5) -#define OV9650_QVGA_SELECT (1 << 4) -#define OV9650_QCIF_SELECT (1 << 3) -#define OV9650_RGB_SELECT (1 << 2) -#define OV9650_RAW_RGB_SELECT (1 << 0) - -#define OV9650_FAST_AGC_AEC (1 << 7) -#define OV9650_AEC_UNLIM_STEP_SIZE (1 << 6) -#define OV9650_BANDING (1 << 5) -#define OV9650_AGC_EN (1 << 2) -#define OV9650_AWB_EN (1 << 1) -#define OV9650_AEC_EN (1 << 0) - -#define OV9650_VARIOPIXEL (1 << 2) -#define OV9650_SYSTEM_CLK_SEL (1 << 7) -#define OV9650_SLAM_MODE (1 << 4) - -#define OV9650_QVGA_VARIOPIXEL (1 << 7) - -#define OV9650_VFLIP (1 << 4) -#define OV9650_HFLIP (1 << 5) - -#define OV9650_SOFT_SLEEP (1 << 4) -#define OV9650_OUTPUT_DRIVE_2X (1 << 0) - -#define OV9650_DENOISE_ENABLE (1 << 5) -#define OV9650_WHITE_PIXEL_ENABLE (1 << 1) -#define OV9650_WHITE_PIXEL_OPTION (1 << 0) - -#define OV9650_LEFT_OFFSET 0x62 - -#define GAIN_DEFAULT 0x14 -#define RED_GAIN_DEFAULT 0x70 -#define BLUE_GAIN_DEFAULT 0x20 -#define EXPOSURE_DEFAULT 0x1ff - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int ov9650_probe(struct sd *sd); -int ov9650_init(struct sd *sd); -int ov9650_start(struct sd *sd); -int ov9650_stop(struct sd *sd); -void ov9650_disconnect(struct sd *sd); - -static const struct m5602_sensor ov9650 = { - .name = "OV9650", - .i2c_slave_id = 0x60, - .i2c_regW = 1, - .probe = ov9650_probe, - .init = ov9650_init, - .start = ov9650_start, - .stop = ov9650_stop, - .disconnect = ov9650_disconnect, -}; - -static const unsigned char preinit_ov9650[][3] = { - /* [INITCAM] */ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, - /* Reset chip */ - {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, - /* Enable double clock */ - {SENSOR, OV9650_CLKRC, 0x80}, - /* Do something out of spec with the power */ - {SENSOR, OV9650_OFON, 0x40} -}; - -static const unsigned char init_ov9650[][3] = { - /* [INITCAM] */ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, - - /* Reset chip */ - {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, - /* One extra reset is needed in order to make the sensor behave - properly when resuming from ram, could be a timing issue */ - {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, - - /* Enable double clock */ - {SENSOR, OV9650_CLKRC, 0x80}, - /* Do something out of spec with the power */ - {SENSOR, OV9650_OFON, 0x40}, - - /* Set fast AGC/AEC algorithm with unlimited step size */ - {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | - OV9650_AEC_UNLIM_STEP_SIZE}, - - {SENSOR, OV9650_CHLF, 0x10}, - {SENSOR, OV9650_ARBLM, 0xbf}, - {SENSOR, OV9650_ACOM38, 0x81}, - /* Turn off color matrix coefficient double option */ - {SENSOR, OV9650_COM16, 0x00}, - /* Enable color matrix for RGB/YUV, Delay Y channel, - set output Y/UV delay to 1 */ - {SENSOR, OV9650_COM13, 0x19}, - /* Enable digital BLC, Set output mode to U Y V Y */ - {SENSOR, OV9650_TSLB, 0x0c}, - /* Limit the AGC/AEC stable upper region */ - {SENSOR, OV9650_COM24, 0x00}, - /* Enable HREF and some out of spec things */ - {SENSOR, OV9650_COM12, 0x73}, - /* Set all DBLC offset signs to positive and - do some out of spec stuff */ - {SENSOR, OV9650_DBLC1, 0xdf}, - {SENSOR, OV9650_COM21, 0x06}, - {SENSOR, OV9650_RSVD35, 0x91}, - /* Necessary, no camera stream without it */ - {SENSOR, OV9650_RSVD16, 0x06}, - {SENSOR, OV9650_RSVD94, 0x99}, - {SENSOR, OV9650_RSVD95, 0x99}, - {SENSOR, OV9650_RSVD96, 0x04}, - /* Enable full range output */ - {SENSOR, OV9650_COM15, 0x0}, - /* Enable HREF at optical black, enable ADBLC bias, - enable ADBLC, reset timings at format change */ - {SENSOR, OV9650_COM6, 0x4b}, - /* Subtract 32 from the B channel bias */ - {SENSOR, OV9650_BBIAS, 0xa0}, - /* Subtract 32 from the Gb channel bias */ - {SENSOR, OV9650_GbBIAS, 0xa0}, - /* Do not bypass the analog BLC and to some out of spec stuff */ - {SENSOR, OV9650_Gr_COM, 0x00}, - /* Subtract 32 from the R channel bias */ - {SENSOR, OV9650_RBIAS, 0xa0}, - /* Subtract 32 from the R channel bias */ - {SENSOR, OV9650_RBIAS, 0x0}, - {SENSOR, OV9650_COM26, 0x80}, - {SENSOR, OV9650_ACOMA9, 0x98}, - /* Set the AGC/AEC stable region upper limit */ - {SENSOR, OV9650_AEW, 0x68}, - /* Set the AGC/AEC stable region lower limit */ - {SENSOR, OV9650_AEB, 0x5c}, - /* Set the high and low limit nibbles to 3 */ - {SENSOR, OV9650_VPT, 0xc3}, - /* Set the Automatic Gain Ceiling (AGC) to 128x, - drop VSYNC at frame drop, - limit exposure timing, - drop frame when the AEC step is larger than the exposure gap */ - {SENSOR, OV9650_COM9, 0x6e}, - /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync) - and set PWDN to SLVS (slave mode vertical sync) */ - {SENSOR, OV9650_COM10, 0x42}, - /* Set horizontal column start high to default value */ - {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */ - /* Set horizontal column end */ - {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */ - /* Complementing register to the two writes above */ - {SENSOR, OV9650_HREF, 0xb2}, - /* Set vertical row start high bits */ - {SENSOR, OV9650_VSTRT, 0x02}, - /* Set vertical row end low bits */ - {SENSOR, OV9650_VSTOP, 0x7e}, - /* Set complementing vertical frame control */ - {SENSOR, OV9650_VREF, 0x10}, - {SENSOR, OV9650_ADC, 0x04}, - {SENSOR, OV9650_HV, 0x40}, - - /* Enable denoise, and white-pixel erase */ - {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE | - OV9650_WHITE_PIXEL_ENABLE | - OV9650_WHITE_PIXEL_OPTION}, - - /* Enable VARIOPIXEL */ - {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, - {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL}, - - /* Put the sensor in soft sleep mode */ - {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, -}; - -static const unsigned char res_init_ov9650[][3] = { - {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, - - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01} -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c deleted file mode 100644 index b8771698cbcb..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ /dev/null @@ -1,763 +0,0 @@ -/* - * Driver for the po1030 sensor - * - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_po1030.h" - -static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val); -static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val); -static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, - __s32 val); -static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, - __s32 *val); - -static struct v4l2_pix_format po1030_modes[] = { - { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2 - } -}; - -static const struct ctrl po1030_ctrls[] = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0x4f, - .step = 0x1, - .default_value = PO1030_GLOBAL_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_gain, - .get = po1030_get_gain - }, -#define EXPOSURE_IDX 1 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0x02ff, - .step = 0x1, - .default_value = PO1030_EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_exposure, - .get = po1030_get_exposure - }, -#define RED_BALANCE_IDX 2 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_red_balance, - .get = po1030_get_red_balance - }, -#define BLUE_BALANCE_IDX 3 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_blue_balance, - .get = po1030_get_blue_balance - }, -#define HFLIP_IDX 4 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_hflip, - .get = po1030_get_hflip - }, -#define VFLIP_IDX 5 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_vflip, - .get = po1030_get_vflip - }, -#define AUTO_WHITE_BALANCE_IDX 6 - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_auto_white_balance, - .get = po1030_get_auto_white_balance - }, -#define AUTO_EXPOSURE_IDX 7 - { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set = po1030_set_auto_exposure, - .get = po1030_get_auto_exposure - }, -#define GREEN_BALANCE_IDX 8 - { - { - .id = M5602_V4L2_CID_GREEN_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "green balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_GREEN_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_green_balance, - .get = po1030_get_green_balance - }, -}; - -static void po1030_dump_registers(struct sd *sd); - -int po1030_probe(struct sd *sd) -{ - u8 dev_id_h = 0, i; - s32 *sensor_settings; - - if (force_sensor) { - if (force_sensor == PO1030_SENSOR) { - pr_info("Forcing a %s sensor\n", po1030.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - PDEBUG(D_PROBE, "Probing for a po1030 sensor"); - - /* Run the pre-init to actually probe the unit */ - for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { - u8 data = preinit_po1030[i][2]; - if (preinit_po1030[i][0] == SENSOR) - m5602_write_sensor(sd, - preinit_po1030[i][1], &data, 1); - else - m5602_write_bridge(sd, preinit_po1030[i][1], data); - } - - if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) - return -ENODEV; - - if (dev_id_h == 0x30) { - pr_info("Detected a po1030 sensor\n"); - goto sensor_found; - } - return -ENODEV; - -sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = po1030_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); - sd->desc->ctrls = po1030_ctrls; - sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); - - for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) - sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; - - return 0; -} - -int po1030_init(struct sd *sd) -{ - s32 *sensor_settings = sd->sensor_priv; - int i, err = 0; - - /* Init the sensor */ - for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_po1030[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_po1030[i][1], - init_po1030[i][2]); - break; - - case SENSOR: - data[0] = init_po1030[i][2]; - err = m5602_write_sensor(sd, - init_po1030[i][1], data, 1); - break; - - default: - pr_info("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - if (err < 0) - return err; - - if (dump_sensor) - po1030_dump_registers(sd); - - err = po1030_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - err = po1030_set_red_balance(&sd->gspca_dev, - sensor_settings[RED_BALANCE_IDX]); - if (err < 0) - return err; - - err = po1030_set_blue_balance(&sd->gspca_dev, - sensor_settings[BLUE_BALANCE_IDX]); - if (err < 0) - return err; - - err = po1030_set_green_balance(&sd->gspca_dev, - sensor_settings[GREEN_BALANCE_IDX]); - if (err < 0) - return err; - - err = po1030_set_auto_white_balance(&sd->gspca_dev, - sensor_settings[AUTO_WHITE_BALANCE_IDX]); - if (err < 0) - return err; - - err = po1030_set_auto_exposure(&sd->gspca_dev, - sensor_settings[AUTO_EXPOSURE_IDX]); - return err; -} - -int po1030_start(struct sd *sd) -{ - struct cam *cam = &sd->gspca_dev.cam; - int i, err = 0; - int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; - int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; - int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - u8 data; - - switch (width) { - case 320: - data = PO1030_SUBSAMPLING; - err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); - if (err < 0) - return err; - - data = ((width + 3) >> 8) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); - if (err < 0) - return err; - - data = (width + 3) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); - if (err < 0) - return err; - - data = ((height + 1) >> 8) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); - if (err < 0) - return err; - - data = (height + 1) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); - - height += 6; - width -= 1; - break; - - case 640: - data = 0; - err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); - if (err < 0) - return err; - - data = ((width + 7) >> 8) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); - if (err < 0) - return err; - - data = (width + 7) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); - if (err < 0) - return err; - - data = ((height + 3) >> 8) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); - if (err < 0) - return err; - - data = (height + 3) & 0xff; - err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); - - height += 12; - width -= 2; - break; - } - err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, - ((ver_offs >> 8) & 0xff)); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); - if (err < 0) - return err; - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); - if (err < 0) - return err; - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - - for (i = 0; i < 2 && !err; i++) - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff)); - if (err < 0) - return err; - - err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); - return err; -} - -static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Exposure read as %d", *val); - return 0; -} - -static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[EXPOSURE_IDX] = val; - PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); - - i2c_data = ((val & 0xff00) >> 8); - PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", - i2c_data); - - err = m5602_write_sensor(sd, PO1030_INTEGLINES_H, - &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = (val & 0xff); - PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", - i2c_data); - err = m5602_write_sensor(sd, PO1030_INTEGLINES_M, - &i2c_data, 1); - - return err; -} - -static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read global gain %d", *val); - return 0; -} - -static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[GAIN_IDX] = val; - - i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); - err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, - &i2c_data, 1); - return err; -} - -static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read hflip %d", *val); - - return 0; -} - -static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[HFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set hflip %d", val); - err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); - - err = m5602_write_sensor(sd, PO1030_CONTROL2, - &i2c_data, 1); - - return err; -} - -static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vflip %d", *val); - - return 0; -} - -static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[VFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set vflip %d", val); - err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); - if (err < 0) - return err; - - i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); - - err = m5602_write_sensor(sd, PO1030_CONTROL2, - &i2c_data, 1); - - return err; -} - -static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[RED_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read red gain %d", *val); - return 0; -} - -static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[RED_BALANCE_IDX] = val; - - i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); - err = m5602_write_sensor(sd, PO1030_RED_GAIN, - &i2c_data, 1); - return err; -} - -static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BLUE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read blue gain %d", *val); - - return 0; -} - -static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[BLUE_BALANCE_IDX] = val; - - i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); - err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, - &i2c_data, 1); - - return err; -} - -static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GREEN_BALANCE_IDX]; - PDEBUG(D_V4L2, "Read green gain %d", *val); - - return 0; -} - -static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[GREEN_BALANCE_IDX] = val; - i2c_data = val & 0xff; - PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); - - err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN, - &i2c_data, 1); - if (err < 0) - return err; - - return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN, - &i2c_data, 1); -} - -static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; - PDEBUG(D_V4L2, "Auto white balancing is %d", *val); - - return 0; -} - -static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, - __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; - - err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); - if (err < 0) - return err; - - PDEBUG(D_V4L2, "Set auto white balance to %d", val); - i2c_data = (i2c_data & 0xfe) | (val & 0x01); - err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); - return err; -} - -static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, - __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[AUTO_EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Auto exposure is %d", *val); - return 0; -} - -static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, - __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 i2c_data; - int err; - - sensor_settings[AUTO_EXPOSURE_IDX] = val; - err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); - if (err < 0) - return err; - - PDEBUG(D_V4L2, "Set auto exposure to %d", val); - i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); - return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); -} - -void po1030_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static void po1030_dump_registers(struct sd *sd) -{ - int address; - u8 value = 0; - - pr_info("Dumping the po1030 sensor core registers\n"); - for (address = 0; address < 0x7f; address++) { - m5602_read_sensor(sd, address, &value, 1); - pr_info("register 0x%x contains 0x%x\n", address, value); - } - - pr_info("po1030 register state dump complete\n"); - - pr_info("Probing for which registers that are read/write\n"); - for (address = 0; address < 0xff; address++) { - u8 old_value, ctrl_value; - u8 test_value[2] = {0xff, 0xff}; - - m5602_read_sensor(sd, address, &old_value, 1); - m5602_write_sensor(sd, address, test_value, 1); - m5602_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value[0]) - pr_info("register 0x%x is writeable\n", address); - else - pr_info("register 0x%x is read only\n", address); - - /* Restore original value */ - m5602_write_sensor(sd, address, &old_value, 1); - } -} diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h deleted file mode 100644 index 81a2bcb88fe3..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Driver for the po1030 sensor. - * - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * Register defines taken from Pascal Stangs Procyon Armlib - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_PO1030_H_ -#define M5602_PO1030_H_ - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define PO1030_DEVID_H 0x00 -#define PO1030_DEVID_L 0x01 -#define PO1030_FRAMEWIDTH_H 0x04 -#define PO1030_FRAMEWIDTH_L 0x05 -#define PO1030_FRAMEHEIGHT_H 0x06 -#define PO1030_FRAMEHEIGHT_L 0x07 -#define PO1030_WINDOWX_H 0x08 -#define PO1030_WINDOWX_L 0x09 -#define PO1030_WINDOWY_H 0x0a -#define PO1030_WINDOWY_L 0x0b -#define PO1030_WINDOWWIDTH_H 0x0c -#define PO1030_WINDOWWIDTH_L 0x0d -#define PO1030_WINDOWHEIGHT_H 0x0e -#define PO1030_WINDOWHEIGHT_L 0x0f - -#define PO1030_GLOBALIBIAS 0x12 -#define PO1030_PIXELIBIAS 0x13 - -#define PO1030_GLOBALGAIN 0x15 -#define PO1030_RED_GAIN 0x16 -#define PO1030_GREEN_1_GAIN 0x17 -#define PO1030_BLUE_GAIN 0x18 -#define PO1030_GREEN_2_GAIN 0x19 - -#define PO1030_INTEGLINES_H 0x1a -#define PO1030_INTEGLINES_M 0x1b -#define PO1030_INTEGLINES_L 0x1c - -#define PO1030_CONTROL1 0x1d -#define PO1030_CONTROL2 0x1e -#define PO1030_CONTROL3 0x1f -#define PO1030_CONTROL4 0x20 - -#define PO1030_PERIOD50_H 0x23 -#define PO1030_PERIOD50_L 0x24 -#define PO1030_PERIOD60_H 0x25 -#define PO1030_PERIOD60_L 0x26 -#define PO1030_REGCLK167 0x27 -#define PO1030_FLICKER_DELTA50 0x28 -#define PO1030_FLICKERDELTA60 0x29 - -#define PO1030_ADCOFFSET 0x2c - -/* Gamma Correction Coeffs */ -#define PO1030_GC0 0x2d -#define PO1030_GC1 0x2e -#define PO1030_GC2 0x2f -#define PO1030_GC3 0x30 -#define PO1030_GC4 0x31 -#define PO1030_GC5 0x32 -#define PO1030_GC6 0x33 -#define PO1030_GC7 0x34 - -/* Color Transform Matrix */ -#define PO1030_CT0 0x35 -#define PO1030_CT1 0x36 -#define PO1030_CT2 0x37 -#define PO1030_CT3 0x38 -#define PO1030_CT4 0x39 -#define PO1030_CT5 0x3a -#define PO1030_CT6 0x3b -#define PO1030_CT7 0x3c -#define PO1030_CT8 0x3d - -#define PO1030_AUTOCTRL1 0x3e -#define PO1030_AUTOCTRL2 0x3f - -#define PO1030_YTARGET 0x40 -#define PO1030_GLOBALGAINMIN 0x41 -#define PO1030_GLOBALGAINMAX 0x42 - -#define PO1030_AWB_RED_TUNING 0x47 -#define PO1030_AWB_BLUE_TUNING 0x48 - -/* Output format control */ -#define PO1030_OUTFORMCTRL1 0x5a -#define PO1030_OUTFORMCTRL2 0x5b -#define PO1030_OUTFORMCTRL3 0x5c -#define PO1030_OUTFORMCTRL4 0x5d -#define PO1030_OUTFORMCTRL5 0x5e - -#define PO1030_EDGE_ENH_OFF 0x5f -#define PO1030_EGA 0x60 - -#define PO1030_Cb_U_GAIN 0x63 -#define PO1030_Cr_V_GAIN 0x64 - -#define PO1030_YCONTRAST 0x74 -#define PO1030_YSATURATION 0x75 - -#define PO1030_HFLIP (1 << 7) -#define PO1030_VFLIP (1 << 6) - -#define PO1030_HREF_ENABLE (1 << 6) - -#define PO1030_RAW_RGB_BAYER 0x4 - -#define PO1030_FRAME_EQUAL (1 << 3) -#define PO1030_AUTO_SUBSAMPLING (1 << 4) - -#define PO1030_WEIGHT_WIN_2X (1 << 3) - -#define PO1030_SHUTTER_MODE (1 << 6) -#define PO1030_AUTO_SUBSAMPLING (1 << 4) -#define PO1030_FRAME_EQUAL (1 << 3) - -#define PO1030_SENSOR_RESET (1 << 5) - -#define PO1030_SUBSAMPLING (1 << 6) - -/*****************************************************************************/ - -#define PO1030_GLOBAL_GAIN_DEFAULT 0x12 -#define PO1030_EXPOSURE_DEFAULT 0x0085 -#define PO1030_BLUE_GAIN_DEFAULT 0x36 -#define PO1030_RED_GAIN_DEFAULT 0x36 -#define PO1030_GREEN_GAIN_DEFAULT 0x40 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int po1030_probe(struct sd *sd); -int po1030_init(struct sd *sd); -int po1030_start(struct sd *sd); -void po1030_disconnect(struct sd *sd); - -static const struct m5602_sensor po1030 = { - .name = "PO1030", - - .i2c_slave_id = 0xdc, - .i2c_regW = 1, - - .probe = po1030_probe, - .init = po1030_init, - .start = po1030_start, - .disconnect = po1030_disconnect, -}; - -static const unsigned char preinit_po1030[][3] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - - {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00} -}; - -static const unsigned char init_po1030[][3] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - - {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - - {SENSOR, PO1030_AUTOCTRL2, 0x04}, - - {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER}, - {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X}, - - {SENSOR, PO1030_CONTROL2, 0x03}, - {SENSOR, 0x21, 0x90}, - {SENSOR, PO1030_YTARGET, 0x60}, - {SENSOR, 0x59, 0x13}, - {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE}, - {SENSOR, PO1030_EDGE_ENH_OFF, 0x00}, - {SENSOR, PO1030_EGA, 0x80}, - {SENSOR, 0x78, 0x14}, - {SENSOR, 0x6f, 0x01}, - {SENSOR, PO1030_GLOBALGAINMAX, 0x14}, - {SENSOR, PO1030_Cb_U_GAIN, 0x38}, - {SENSOR, PO1030_Cr_V_GAIN, 0x38}, - {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE | - PO1030_AUTO_SUBSAMPLING | - PO1030_FRAME_EQUAL}, - {SENSOR, PO1030_GC0, 0x10}, - {SENSOR, PO1030_GC1, 0x20}, - {SENSOR, PO1030_GC2, 0x40}, - {SENSOR, PO1030_GC3, 0x60}, - {SENSOR, PO1030_GC4, 0x80}, - {SENSOR, PO1030_GC5, 0xa0}, - {SENSOR, PO1030_GC6, 0xc0}, - {SENSOR, PO1030_GC7, 0xff}, - - /* Set the width to 751 */ - {SENSOR, PO1030_FRAMEWIDTH_H, 0x02}, - {SENSOR, PO1030_FRAMEWIDTH_L, 0xef}, - - /* Set the height to 540 */ - {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02}, - {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c}, - - /* Set the x window to 1 */ - {SENSOR, PO1030_WINDOWX_H, 0x00}, - {SENSOR, PO1030_WINDOWX_L, 0x01}, - - /* Set the y window to 1 */ - {SENSOR, PO1030_WINDOWY_H, 0x00}, - {SENSOR, PO1030_WINDOWY_L, 0x01}, - - /* with a very low lighted environment increase the exposure but - * decrease the FPS (Frame Per Second) */ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c deleted file mode 100644 index cc8ec3f7e8dc..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ /dev/null @@ -1,726 +0,0 @@ -/* - * Driver for the s5k4aa sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "m5602_s5k4aa.h" - -static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); -static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val); - -static - const - struct dmi_system_id s5k4aa_vflip_dmi_table[] = { - { - .ident = "BRUNEINIT", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "BRUNENIT"), - DMI_MATCH(DMI_PRODUCT_NAME, "BRUNENIT"), - DMI_MATCH(DMI_BOARD_VERSION, "00030D0000000001") - } - }, { - .ident = "Fujitsu-Siemens Amilo Xa 2528", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528") - } - }, { - .ident = "Fujitsu-Siemens Amilo Xi 2428", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428") - } - }, { - .ident = "Fujitsu-Siemens Amilo Xi 2528", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2528") - } - }, { - .ident = "Fujitsu-Siemens Amilo Xi 2550", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550") - } - }, { - .ident = "Fujitsu-Siemens Amilo Pa 2548", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548") - } - }, { - .ident = "MSI GX700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX700"), - DMI_MATCH(DMI_BIOS_DATE, "12/02/2008") - } - }, { - .ident = "MSI GX700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX700"), - DMI_MATCH(DMI_BIOS_DATE, "07/26/2007") - } - }, { - .ident = "MSI GX700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX700"), - DMI_MATCH(DMI_BIOS_DATE, "07/19/2007") - } - }, { - .ident = "MSI GX700/GX705/EX700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") - } - }, { - .ident = "MSI L735", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X") - } - }, { - .ident = "Lenovo Y300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"), - DMI_MATCH(DMI_PRODUCT_NAME, "Y300") - } - }, - { } -}; - -static struct v4l2_pix_format s5k4aa_modes[] = { - { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, - { - 1280, - 1024, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 1280 * 1024, - .bytesperline = 1280, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static const struct ctrl s5k4aa_ctrls[] = { -#define VFLIP_IDX 0 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_vflip, - .get = s5k4aa_get_vflip - }, -#define HFLIP_IDX 1 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_hflip, - .get = s5k4aa_get_hflip - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = S5K4AA_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_gain, - .get = s5k4aa_get_gain - }, -#define EXPOSURE_IDX 3 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 13, - .maximum = 0xfff, - .step = 1, - .default_value = 0x100, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_exposure, - .get = s5k4aa_get_exposure - }, -#define NOISE_SUPP_IDX 4 - { - { - .id = V4L2_CID_PRIVATE_BASE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Noise suppression (smoothing)", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - .set = s5k4aa_set_noise, - .get = s5k4aa_get_noise - }, -#define BRIGHTNESS_IDX 5 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 0x1f, - .step = 1, - .default_value = S5K4AA_DEFAULT_BRIGHTNESS, - }, - .set = s5k4aa_set_brightness, - .get = s5k4aa_get_brightness - }, - -}; - -static void s5k4aa_dump_registers(struct sd *sd); - -int s5k4aa_probe(struct sd *sd) -{ - u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; - int i, err = 0; - s32 *sensor_settings; - - if (force_sensor) { - if (force_sensor == S5K4AA_SENSOR) { - pr_info("Forcing a %s sensor\n", s5k4aa.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - PDEBUG(D_PROBE, "Probing for a s5k4aa sensor"); - - /* Preinit the sensor */ - for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (preinit_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - preinit_s5k4aa[i][1], - preinit_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = preinit_s5k4aa[i][2]; - err = m5602_write_sensor(sd, - preinit_s5k4aa[i][1], - data, 1); - break; - - case SENSOR_LONG: - data[0] = preinit_s5k4aa[i][2]; - data[1] = preinit_s5k4aa[i][3]; - err = m5602_write_sensor(sd, - preinit_s5k4aa[i][1], - data, 2); - break; - default: - pr_info("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - - /* Test some registers, but we don't know their exact meaning yet */ - if (m5602_read_sensor(sd, 0x00, prod_id, 2)) - return -ENODEV; - if (m5602_read_sensor(sd, 0x02, prod_id+2, 2)) - return -ENODEV; - if (m5602_read_sensor(sd, 0x04, prod_id+4, 2)) - return -ENODEV; - - if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) - return -ENODEV; - else - pr_info("Detected a s5k4aa sensor\n"); - -sensor_found: - sensor_settings = kmalloc( - ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = s5k4aa_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); - sd->desc->ctrls = s5k4aa_ctrls; - sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); - - for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) - sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; - - return 0; -} - -int s5k4aa_start(struct sd *sd) -{ - int i, err = 0; - u8 data[2]; - struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; - - switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { - case 1280: - PDEBUG(D_V4L2, "Configuring camera for SXGA mode"); - - for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) { - switch (SXGA_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - SXGA_s5k4aa[i][1], - SXGA_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = SXGA_s5k4aa[i][2]; - err = m5602_write_sensor(sd, - SXGA_s5k4aa[i][1], - data, 1); - break; - - case SENSOR_LONG: - data[0] = SXGA_s5k4aa[i][2]; - data[1] = SXGA_s5k4aa[i][3]; - err = m5602_write_sensor(sd, - SXGA_s5k4aa[i][1], - data, 2); - break; - - default: - pr_err("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - err = s5k4aa_set_noise(&sd->gspca_dev, 0); - if (err < 0) - return err; - break; - - case 640: - PDEBUG(D_V4L2, "Configuring camera for VGA mode"); - - for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) { - switch (VGA_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - VGA_s5k4aa[i][1], - VGA_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = VGA_s5k4aa[i][2]; - err = m5602_write_sensor(sd, - VGA_s5k4aa[i][1], - data, 1); - break; - - case SENSOR_LONG: - data[0] = VGA_s5k4aa[i][2]; - data[1] = VGA_s5k4aa[i][3]; - err = m5602_write_sensor(sd, - VGA_s5k4aa[i][1], - data, 2); - break; - - default: - pr_err("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - err = s5k4aa_set_noise(&sd->gspca_dev, 1); - if (err < 0) - return err; - break; - } - if (err < 0) - return err; - - err = s5k4aa_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_brightness(&sd->gspca_dev, - sensor_settings[BRIGHTNESS_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); - if (err < 0) - return err; - - err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - if (err < 0) - return err; - - return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); -} - -int s5k4aa_init(struct sd *sd) -{ - int i, err = 0; - - for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_s5k4aa[i][1], - init_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = init_s5k4aa[i][2]; - err = m5602_write_sensor(sd, - init_s5k4aa[i][1], data, 1); - break; - - case SENSOR_LONG: - data[0] = init_s5k4aa[i][2]; - data[1] = init_s5k4aa[i][3]; - err = m5602_write_sensor(sd, - init_s5k4aa[i][1], data, 2); - break; - default: - pr_info("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - - if (dump_sensor) - s5k4aa_dump_registers(sd); - - return err; -} - -static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - PDEBUG(D_V4L2, "Read exposure %d", *val); - - return 0; -} - -static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[EXPOSURE_IDX] = val; - PDEBUG(D_V4L2, "Set exposure to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - data = (val >> 8) & 0xff; - err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); - if (err < 0) - return err; - data = val & 0xff; - err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); - - return err; -} - -static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[VFLIP_IDX]; - PDEBUG(D_V4L2, "Read vertical flip %d", *val); - - return 0; -} - -static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[VFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - return err; - - if (dmi_check_system(s5k4aa_vflip_dmi_table)) - val = !val; - - data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7)); - err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - if (err < 0) - return err; - if (val) - data &= 0xfe; - else - data |= 0x01; - err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - return err; -} - -static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[HFLIP_IDX]; - PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - - return 0; -} - -static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[HFLIP_IDX] = val; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - return err; - - if (dmi_check_system(s5k4aa_vflip_dmi_table)) - val = !val; - - data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); - err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - return err; - - err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - if (err < 0) - return err; - if (val) - data &= 0xfe; - else - data |= 0x01; - err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - return err; -} - -static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - PDEBUG(D_V4L2, "Read gain %d", *val); - return 0; -} - -static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[GAIN_IDX] = val; - - PDEBUG(D_V4L2, "Set gain to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - data = val & 0xff; - err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1); - - return err; -} - -static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BRIGHTNESS_IDX]; - PDEBUG(D_V4L2, "Read brightness %d", *val); - return 0; -} - -static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[BRIGHTNESS_IDX] = val; - - PDEBUG(D_V4L2, "Set brightness to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - data = val & 0xff; - return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1); -} - -static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[NOISE_SUPP_IDX]; - PDEBUG(D_V4L2, "Read noise %d", *val); - return 0; -} - -static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - sensor_settings[NOISE_SUPP_IDX] = val; - - PDEBUG(D_V4L2, "Set noise to %d", val); - err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - return err; - - data = val & 0x01; - return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); -} - -void s5k4aa_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static void s5k4aa_dump_registers(struct sd *sd) -{ - int address; - u8 page, old_page; - m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); - for (page = 0; page < 16; page++) { - m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); - pr_info("Dumping the s5k4aa register state for page 0x%x\n", - page); - for (address = 0; address <= 0xff; address++) { - u8 value = 0; - m5602_read_sensor(sd, address, &value, 1); - pr_info("register 0x%x contains 0x%x\n", - address, value); - } - } - pr_info("s5k4aa register state dump complete\n"); - - for (page = 0; page < 16; page++) { - m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); - pr_info("Probing for which registers that are read/write for page 0x%x\n", - page); - for (address = 0; address <= 0xff; address++) { - u8 old_value, ctrl_value, test_value = 0xff; - - m5602_read_sensor(sd, address, &old_value, 1); - m5602_write_sensor(sd, address, &test_value, 1); - m5602_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value) - pr_info("register 0x%x is writeable\n", - address); - else - pr_info("register 0x%x is read only\n", - address); - - /* Restore original value */ - m5602_write_sensor(sd, address, &old_value, 1); - } - } - pr_info("Read/write register probing complete\n"); - m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); -} diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h deleted file mode 100644 index 8e0035e731c7..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Driver for the s5k4aa sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_S5K4AA_H_ -#define M5602_S5K4AA_H_ - -#include <linux/dmi.h> - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define S5K4AA_PAGE_MAP 0xec - -#define S5K4AA_PAGE_MAP_0 0x00 -#define S5K4AA_PAGE_MAP_1 0x01 -#define S5K4AA_PAGE_MAP_2 0x02 - -/* Sensor register definitions for page 0x02 */ -#define S5K4AA_READ_MODE 0x03 -#define S5K4AA_ROWSTART_HI 0x04 -#define S5K4AA_ROWSTART_LO 0x05 -#define S5K4AA_COLSTART_HI 0x06 -#define S5K4AA_COLSTART_LO 0x07 -#define S5K4AA_WINDOW_HEIGHT_HI 0x08 -#define S5K4AA_WINDOW_HEIGHT_LO 0x09 -#define S5K4AA_WINDOW_WIDTH_HI 0x0a -#define S5K4AA_WINDOW_WIDTH_LO 0x0b -#define S5K4AA_GLOBAL_GAIN__ 0x0f -/* sync lost, if too low, reduces frame rate if too high */ -#define S5K4AA_H_BLANK_HI__ 0x1d -#define S5K4AA_H_BLANK_LO__ 0x1e -#define S5K4AA_EXPOSURE_HI 0x17 -#define S5K4AA_EXPOSURE_LO 0x18 -#define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */ -#define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */ -#define S5K4AA_NOISE_SUPP 0x37 - -#define S5K4AA_RM_ROW_SKIP_4X 0x08 -#define S5K4AA_RM_ROW_SKIP_2X 0x04 -#define S5K4AA_RM_COL_SKIP_4X 0x02 -#define S5K4AA_RM_COL_SKIP_2X 0x01 -#define S5K4AA_RM_H_FLIP 0x40 -#define S5K4AA_RM_V_FLIP 0x80 - -#define S5K4AA_DEFAULT_GAIN 0x5f -#define S5K4AA_DEFAULT_BRIGHTNESS 0x10 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int s5k4aa_probe(struct sd *sd); -int s5k4aa_init(struct sd *sd); -int s5k4aa_start(struct sd *sd); -void s5k4aa_disconnect(struct sd *sd); - -static const struct m5602_sensor s5k4aa = { - .name = "S5K4AA", - .i2c_slave_id = 0x5a, - .i2c_regW = 2, - - .probe = s5k4aa_probe, - .init = s5k4aa_init, - .start = s5k4aa_start, - .disconnect = s5k4aa_disconnect, -}; - -static const unsigned char preinit_s5k4aa[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00} -}; - -static const unsigned char init_s5k4aa[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00}, - {SENSOR, 0x36, 0x01, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, 0x0c, 0x05, 0x00}, - {SENSOR, 0x02, 0x0e, 0x00}, - {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, - {SENSOR, 0x37, 0x00, 0x00}, -}; - -static const unsigned char VGA_s5k4aa[][4] = { - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ - - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X - | S5K4AA_RM_COL_SKIP_2X, 0x00}, - /* 0x37 : Fix image stability when light is too bright and improves - * image quality in 640x480, but worsens it in 1280x1024 */ - {SENSOR, 0x37, 0x01, 0x00}, - /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ - {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00}, - {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, - /* window_height_hi, window_height_lo : 960 = 0x03c0 */ - {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00}, - /* window_width_hi, window_width_lo : 1280 = 0x0500 */ - {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ - {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, - {SENSOR, 0x11, 0x04, 0x00}, - {SENSOR, 0x12, 0xc3, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, 0x02, 0x0e, 0x00}, -}; - -static const unsigned char SXGA_s5k4aa[][4] = { - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */ - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */ - {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ - - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00}, - {SENSOR, 0x37, 0x01, 0x00}, - {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00}, - {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00}, - {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, - {SENSOR, 0x11, 0x04, 0x00}, - {SENSOR, 0x12, 0xc3, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, 0x02, 0x0e, 0x00}, -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c deleted file mode 100644 index 1de743a02b02..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Driver for the s5k83a sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kthread.h> -#include "m5602_s5k83a.h" - -static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); - -static struct v4l2_pix_format s5k83a_modes[] = { - { - 640, - 480, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - 640 * 480, - .bytesperline = 640, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static const struct ctrl s5k83a_ctrls[] = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_gain, - .get = s5k83a_get_gain - - }, -#define BRIGHTNESS_IDX 1 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_BRIGHTNESS, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_brightness, - .get = s5k83a_get_brightness, - }, -#define EXPOSURE_IDX 2 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = S5K83A_MAXIMUM_EXPOSURE, - .step = 0x01, - .default_value = S5K83A_DEFAULT_EXPOSURE, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_exposure, - .get = s5k83a_get_exposure - }, -#define HFLIP_IDX 3 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_hflip, - .get = s5k83a_get_hflip - }, -#define VFLIP_IDX 4 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_vflip, - .get = s5k83a_get_vflip - } -}; - -static void s5k83a_dump_registers(struct sd *sd); -static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); -static int s5k83a_set_led_indication(struct sd *sd, u8 val); -static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, - __s32 vflip, __s32 hflip); - -int s5k83a_probe(struct sd *sd) -{ - struct s5k83a_priv *sens_priv; - u8 prod_id = 0, ver_id = 0; - int i, err = 0; - - if (force_sensor) { - if (force_sensor == S5K83A_SENSOR) { - pr_info("Forcing a %s sensor\n", s5k83a.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - PDEBUG(D_PROBE, "Probing for a s5k83a sensor"); - - /* Preinit the sensor */ - for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { - u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; - if (preinit_s5k83a[i][0] == SENSOR) - err = m5602_write_sensor(sd, preinit_s5k83a[i][1], - data, 2); - else - err = m5602_write_bridge(sd, preinit_s5k83a[i][1], - data[0]); - } - - /* We don't know what register (if any) that contain the product id - * Just pick the first addresses that seem to produce the same results - * on multiple machines */ - if (m5602_read_sensor(sd, 0x00, &prod_id, 1)) - return -ENODEV; - - if (m5602_read_sensor(sd, 0x01, &ver_id, 1)) - return -ENODEV; - - if ((prod_id == 0xff) || (ver_id == 0xff)) - return -ENODEV; - else - pr_info("Detected a s5k83a sensor\n"); - -sensor_found: - sens_priv = kmalloc( - sizeof(struct s5k83a_priv), GFP_KERNEL); - if (!sens_priv) - return -ENOMEM; - - sens_priv->settings = - kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); - if (!sens_priv->settings) { - kfree(sens_priv); - return -ENOMEM; - } - - sd->gspca_dev.cam.cam_mode = s5k83a_modes; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); - sd->desc->ctrls = s5k83a_ctrls; - sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); - - /* null the pointer! thread is't running now */ - sens_priv->rotation_thread = NULL; - - for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) - sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; - - sd->sensor_priv = sens_priv; - return 0; -} - -int s5k83a_init(struct sd *sd) -{ - int i, err = 0; - s32 *sensor_settings = - ((struct s5k83a_priv *) sd->sensor_priv)->settings; - - for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_s5k83a[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_s5k83a[i][1], - init_s5k83a[i][2]); - break; - - case SENSOR: - data[0] = init_s5k83a[i][2]; - err = m5602_write_sensor(sd, - init_s5k83a[i][1], data, 1); - break; - - case SENSOR_LONG: - data[0] = init_s5k83a[i][2]; - data[1] = init_s5k83a[i][3]; - err = m5602_write_sensor(sd, - init_s5k83a[i][1], data, 2); - break; - default: - pr_info("Invalid stream command, exiting init\n"); - return -EINVAL; - } - } - - if (dump_sensor) - s5k83a_dump_registers(sd); - - err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - err = s5k83a_set_brightness(&sd->gspca_dev, - sensor_settings[BRIGHTNESS_IDX]); - if (err < 0) - return err; - - err = s5k83a_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - if (err < 0) - return err; - - err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); - - return err; -} - -static int rotation_thread_function(void *data) -{ - struct sd *sd = (struct sd *) data; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - u8 reg, previous_rotation = 0; - __s32 vflip, hflip; - - set_current_state(TASK_INTERRUPTIBLE); - while (!schedule_timeout(100)) { - if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock)) - break; - - s5k83a_get_rotation(sd, ®); - if (previous_rotation != reg) { - previous_rotation = reg; - pr_info("Camera was flipped\n"); - - s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); - s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); - - if (reg) { - vflip = !vflip; - hflip = !hflip; - } - s5k83a_set_flip_real((struct gspca_dev *) sd, - vflip, hflip); - } - - mutex_unlock(&sd->gspca_dev.usb_lock); - set_current_state(TASK_INTERRUPTIBLE); - } - - /* return to "front" flip */ - if (previous_rotation) { - s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); - s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); - s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); - } - - sens_priv->rotation_thread = NULL; - return 0; -} - -int s5k83a_start(struct sd *sd) -{ - int i, err = 0; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - /* Create another thread, polling the GPIO ports of the camera to check - if it got rotated. This is how the windows driver does it so we have - to assume that there is no better way of accomplishing this */ - sens_priv->rotation_thread = kthread_create(rotation_thread_function, - sd, "rotation thread"); - wake_up_process(sens_priv->rotation_thread); - - /* Preinit the sensor */ - for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { - u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]}; - if (start_s5k83a[i][0] == SENSOR) - err = m5602_write_sensor(sd, start_s5k83a[i][1], - data, 2); - else - err = m5602_write_bridge(sd, start_s5k83a[i][1], - data[0]); - } - if (err < 0) - return err; - - return s5k83a_set_led_indication(sd, 1); -} - -int s5k83a_stop(struct sd *sd) -{ - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - if (sens_priv->rotation_thread) - kthread_stop(sens_priv->rotation_thread); - - return s5k83a_set_led_indication(sd, 0); -} - -void s5k83a_disconnect(struct sd *sd) -{ - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - s5k83a_stop(sd); - - sd->sensor = NULL; - kfree(sens_priv->settings); - kfree(sens_priv); -} - -static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[GAIN_IDX]; - return 0; -} - -static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[GAIN_IDX] = val; - - data[0] = 0x00; - data[1] = 0x20; - err = m5602_write_sensor(sd, 0x14, data, 2); - if (err < 0) - return err; - - data[0] = 0x01; - data[1] = 0x00; - err = m5602_write_sensor(sd, 0x0d, data, 2); - if (err < 0) - return err; - - /* FIXME: This is not sane, we need to figure out the composition - of these registers */ - data[0] = val >> 3; /* gain, high 5 bits */ - data[1] = val >> 1; /* gain, high 7 bits */ - err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); - - return err; -} - -static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[BRIGHTNESS_IDX]; - return 0; -} - -static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[BRIGHTNESS_IDX] = val; - data[0] = val; - err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); - return err; -} - -static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[EXPOSURE_IDX]; - return 0; -} - -static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[EXPOSURE_IDX] = val; - data[0] = 0; - data[1] = val; - err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); - return err; -} - -static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[VFLIP_IDX]; - return 0; -} - -static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, - __s32 vflip, __s32 hflip) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x05; - err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); - if (err < 0) - return err; - - /* six bit is vflip, seven is hflip */ - data[0] = S5K83A_FLIP_MASK; - data[0] = (vflip) ? data[0] | 0x40 : data[0]; - data[0] = (hflip) ? data[0] | 0x80 : data[0]; - - err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); - if (err < 0) - return err; - - data[0] = (vflip) ? 0x0b : 0x0a; - err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); - if (err < 0) - return err; - - data[0] = (hflip) ? 0x0a : 0x0b; - err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); - return err; -} - -static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 reg; - __s32 hflip; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[VFLIP_IDX] = val; - - s5k83a_get_hflip(gspca_dev, &hflip); - - err = s5k83a_get_rotation(sd, ®); - if (err < 0) - return err; - if (reg) { - val = !val; - hflip = !hflip; - } - - err = s5k83a_set_flip_real(gspca_dev, val, hflip); - return err; -} - -static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - *val = sens_priv->settings[HFLIP_IDX]; - return 0; -} - -static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 reg; - __s32 vflip; - struct sd *sd = (struct sd *) gspca_dev; - struct s5k83a_priv *sens_priv = sd->sensor_priv; - - sens_priv->settings[HFLIP_IDX] = val; - - s5k83a_get_vflip(gspca_dev, &vflip); - - err = s5k83a_get_rotation(sd, ®); - if (err < 0) - return err; - if (reg) { - val = !val; - vflip = !vflip; - } - - err = s5k83a_set_flip_real(gspca_dev, vflip, val); - return err; -} - -static int s5k83a_set_led_indication(struct sd *sd, u8 val) -{ - int err = 0; - u8 data[1]; - - err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data); - if (err < 0) - return err; - - if (val) - data[0] = data[0] | S5K83A_GPIO_LED_MASK; - else - data[0] = data[0] & ~S5K83A_GPIO_LED_MASK; - - err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); - - return err; -} - -/* Get camera rotation on Acer notebooks */ -static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) -{ - int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); - *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; - return err; -} - -static void s5k83a_dump_registers(struct sd *sd) -{ - int address; - u8 page, old_page; - m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); - - for (page = 0; page < 16; page++) { - m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); - pr_info("Dumping the s5k83a register state for page 0x%x\n", - page); - for (address = 0; address <= 0xff; address++) { - u8 val = 0; - m5602_read_sensor(sd, address, &val, 1); - pr_info("register 0x%x contains 0x%x\n", address, val); - } - } - pr_info("s5k83a register state dump complete\n"); - - for (page = 0; page < 16; page++) { - m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); - pr_info("Probing for which registers that are read/write for page 0x%x\n", - page); - for (address = 0; address <= 0xff; address++) { - u8 old_val, ctrl_val, test_val = 0xff; - - m5602_read_sensor(sd, address, &old_val, 1); - m5602_write_sensor(sd, address, &test_val, 1); - m5602_read_sensor(sd, address, &ctrl_val, 1); - - if (ctrl_val == test_val) - pr_info("register 0x%x is writeable\n", - address); - else - pr_info("register 0x%x is read only\n", - address); - - /* Restore original val */ - m5602_write_sensor(sd, address, &old_val, 1); - } - } - pr_info("Read/write register probing complete\n"); - m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); -} diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h deleted file mode 100644 index 79952247b534..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Driver for the s5k83a sensor - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_S5K83A_H_ -#define M5602_S5K83A_H_ - -#include "m5602_sensor.h" - -#define S5K83A_FLIP 0x01 -#define S5K83A_HFLIP_TUNE 0x03 -#define S5K83A_VFLIP_TUNE 0x05 -#define S5K83A_BRIGHTNESS 0x0a -#define S5K83A_EXPOSURE 0x18 -#define S5K83A_GAIN 0x1b -#define S5K83A_PAGE_MAP 0xec - -#define S5K83A_DEFAULT_GAIN 0x71 -#define S5K83A_DEFAULT_BRIGHTNESS 0x7e -#define S5K83A_DEFAULT_EXPOSURE 0x00 -#define S5K83A_MAXIMUM_EXPOSURE 0x3c -#define S5K83A_FLIP_MASK 0x10 -#define S5K83A_GPIO_LED_MASK 0x10 -#define S5K83A_GPIO_ROTATION_MASK 0x40 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern bool dump_sensor; - -int s5k83a_probe(struct sd *sd); -int s5k83a_init(struct sd *sd); -int s5k83a_start(struct sd *sd); -int s5k83a_stop(struct sd *sd); -void s5k83a_disconnect(struct sd *sd); - -static const struct m5602_sensor s5k83a = { - .name = "S5K83A", - .probe = s5k83a_probe, - .init = s5k83a_init, - .start = s5k83a_start, - .stop = s5k83a_stop, - .disconnect = s5k83a_disconnect, - .i2c_slave_id = 0x5a, - .i2c_regW = 2, -}; - -struct s5k83a_priv { - /* We use another thread periodically - probing the orientation of the camera */ - struct task_struct *rotation_thread; - s32 *settings; -}; - -static const unsigned char preinit_s5k83a[][4] = { - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, -}; - -/* This could probably be considerably shortened. - I don't have the hardware to experiment with it, patches welcome -*/ -static const unsigned char init_s5k83a[][4] = { - /* The following sequence is useless after a clean boot - but is necessary after resume from suspend */ - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, - {SENSOR, 0xaf, 0x01, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x01, 0x50, 0x00}, - {SENSOR, 0x12, 0x20, 0x00}, - {SENSOR, 0x17, 0x40, 0x00}, - {SENSOR, 0x1c, 0x00, 0x00}, - {SENSOR, 0x02, 0x70, 0x00}, - {SENSOR, 0x03, 0x0b, 0x00}, - {SENSOR, 0x04, 0xf0, 0x00}, - {SENSOR, 0x05, 0x0b, 0x00}, - {SENSOR, 0x06, 0x71, 0x00}, - {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */ - {SENSOR, 0x08, 0x02, 0x00}, - {SENSOR, 0x09, 0x88, 0x00}, /* 648 */ - {SENSOR, 0x14, 0x00, 0x00}, - {SENSOR, 0x15, 0x20, 0x00}, /* 32 */ - {SENSOR, 0x19, 0x00, 0x00}, - {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */ - {SENSOR, 0x0f, 0x02, 0x00}, - {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */ - /* normal colors - (this is value after boot, but after tries can be different) */ - {SENSOR, 0x00, 0x06, 0x00}, -}; - -static const unsigned char start_s5k83a[][4] = { - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */ - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */ - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, -}; -#endif diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h deleted file mode 100644 index edff4f1f586f..000000000000 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andrén - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_SENSOR_H_ -#define M5602_SENSOR_H_ - -#include "m5602_bridge.h" - -#define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0) -#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1) - -/* Enumerates all supported sensors */ -enum sensors { - OV9650_SENSOR = 1, - S5K83A_SENSOR = 2, - S5K4AA_SENSOR = 3, - MT9M111_SENSOR = 4, - PO1030_SENSOR = 5, - OV7660_SENSOR = 6, -}; - -/* Enumerates all possible instruction types */ -enum instruction { - BRIDGE, - SENSOR, - SENSOR_LONG -}; - -struct m5602_sensor { - /* Defines the name of a sensor */ - char name[32]; - - /* What i2c address the sensor is connected to */ - u8 i2c_slave_id; - - /* Width of each i2c register (in bytes) */ - u8 i2c_regW; - - /* Probes if the sensor is connected */ - int (*probe)(struct sd *sd); - - /* Performs a initialization sequence */ - int (*init)(struct sd *sd); - - /* Executed when the camera starts to send data */ - int (*start)(struct sd *sd); - - /* Executed when the camera ends to send data */ - int (*stop)(struct sd *sd); - - /* Executed when the device is disconnected */ - void (*disconnect)(struct sd *sd); -}; - -#endif diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c deleted file mode 100644 index ff2c5abf115b..000000000000 --- a/drivers/media/video/gspca/mars.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Mars-Semi MR97311A library - * Copyright (C) 2005 <bradlch@hotmail.com> - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "mars" - -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define QUALITY 50 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *saturation; - struct v4l2_ctrl *sharpness; - struct v4l2_ctrl *gamma; - struct { /* illuminator control cluster */ - struct v4l2_ctrl *illum_top; - struct v4l2_ctrl *illum_bottom; - }; - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -/* V4L2 controls supported by the driver */ -static void setbrightness(struct gspca_dev *gspca_dev, s32 val); -static void setcolors(struct gspca_dev *gspca_dev, s32 val); -static void setgamma(struct gspca_dev *gspca_dev, s32 val); -static void setsharpness(struct gspca_dev *gspca_dev, s32 val); - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -}; - -static const __u8 mi_data[0x20] = { -/* 01 02 03 04 05 06 07 08 */ - 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00, -/* 09 0a 0b 0c 0d 0e 0f 10 */ - 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, -/* 11 12 13 14 15 16 17 18 */ - 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02, -/* 19 1a 1b 1c 1d 1e 1f 20 */ - 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00 -}; - -/* write <len> bytes from gspca_dev->usb_buf */ -static void reg_w(struct gspca_dev *gspca_dev, - int len) -{ - int alen, ret; - - if (gspca_dev->usb_err < 0) - return; - - ret = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, - len, - &alen, - 500); /* timeout in milliseconds */ - if (ret < 0) { - pr_err("reg write [%02x] error %d\n", - gspca_dev->usb_buf[0], ret); - gspca_dev->usb_err = ret; - } -} - -static void mi_w(struct gspca_dev *gspca_dev, - u8 addr, - u8 value) -{ - gspca_dev->usb_buf[0] = 0x1f; - gspca_dev->usb_buf[1] = 0; /* control byte */ - gspca_dev->usb_buf[2] = addr; - gspca_dev->usb_buf[3] = value; - - reg_w(gspca_dev, 4); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - gspca_dev->usb_buf[0] = 0x61; - gspca_dev->usb_buf[1] = val; - reg_w(gspca_dev, 2); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - gspca_dev->usb_buf[0] = 0x5f; - gspca_dev->usb_buf[1] = val << 3; - gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04; - reg_w(gspca_dev, 3); -} - -static void setgamma(struct gspca_dev *gspca_dev, s32 val) -{ - gspca_dev->usb_buf[0] = 0x06; - gspca_dev->usb_buf[1] = val * 0x40; - reg_w(gspca_dev, 2); -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - gspca_dev->usb_buf[0] = 0x67; - gspca_dev->usb_buf[1] = val * 4 + 3; - reg_w(gspca_dev, 2); -} - -static void setilluminators(struct gspca_dev *gspca_dev, bool top, bool bottom) -{ - /* both are off if not streaming */ - gspca_dev->usb_buf[0] = 0x22; - if (top) - gspca_dev->usb_buf[1] = 0x76; - else if (bottom) - gspca_dev->usb_buf[1] = 0x7a; - else - gspca_dev->usb_buf[1] = 0x7e; - reg_w(gspca_dev, 2); -} - -static int mars_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_ILLUMINATORS_1) { - /* only one can be on at a time */ - if (ctrl->is_new && ctrl->val) - sd->illum_bottom->val = 0; - if (sd->illum_bottom->is_new && sd->illum_bottom->val) - sd->illum_top->val = 0; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAMMA: - setgamma(gspca_dev, ctrl->val); - break; - case V4L2_CID_ILLUMINATORS_1: - setilluminators(gspca_dev, sd->illum_top->val, - sd->illum_bottom->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - default: - return -EINVAL; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops mars_ctrl_ops = { - .s_ctrl = mars_s_ctrl, -}; - -/* this function is called at probe time */ -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 6); - sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 30, 1, 15); - sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 200); - sd->gamma = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_GAMMA, 0, 3, 1, 1); - sd->sharpness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 2, 1, 1); - sd->illum_top = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); - sd->illum_top->flags |= V4L2_CTRL_FLAG_UPDATE; - sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops, - V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); - sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE; - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_cluster(2, &sd->illum_top); - return 0; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 *data; - int i; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - jpeg_set_qual(sd->jpeg_hdr, QUALITY); - - data = gspca_dev->usb_buf; - - data[0] = 0x01; /* address */ - data[1] = 0x01; - reg_w(gspca_dev, 2); - - /* - Initialize the MR97113 chip register - */ - data[0] = 0x00; /* address */ - data[1] = 0x0c | 0x01; /* reg 0 */ - data[2] = 0x01; /* reg 1 */ - data[3] = gspca_dev->width / 8; /* h_size , reg 2 */ - data[4] = gspca_dev->height / 8; /* v_size , reg 3 */ - data[5] = 0x30; /* reg 4, MI, PAS5101 : - * 0x30 for 24mhz , 0x28 for 12mhz */ - data[6] = 0x02; /* reg 5, H start - was 0x04 */ - data[7] = v4l2_ctrl_g_ctrl(sd->gamma) * 0x40; /* reg 0x06: gamma */ - data[8] = 0x01; /* reg 7, V start - was 0x03 */ -/* if (h_size == 320 ) */ -/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ -/* else */ - data[9] = 0x52; /* reg 8, 24MHz, no scale down */ -/*jfm: from win trace*/ - data[10] = 0x18; - - reg_w(gspca_dev, 11); - - data[0] = 0x23; /* address */ - data[1] = 0x09; /* reg 35, append frame header */ - - reg_w(gspca_dev, 2); - - data[0] = 0x3c; /* address */ -/* if (gspca_dev->width == 1280) */ -/* data[1] = 200; * reg 60, pc-cam frame size - * (unit: 4KB) 800KB */ -/* else */ - data[1] = 50; /* 50 reg 60, pc-cam frame size - * (unit: 4KB) 200KB */ - reg_w(gspca_dev, 2); - - /* auto dark-gain */ - data[0] = 0x5e; /* address */ - data[1] = 0; /* reg 94, Y Gain (auto) */ -/*jfm: from win trace*/ - /* reg 0x5f/0x60 (LE) = saturation */ - /* h (60): xxxx x100 - * l (5f): xxxx x000 */ - data[2] = v4l2_ctrl_g_ctrl(sd->saturation) << 3; - data[3] = ((v4l2_ctrl_g_ctrl(sd->saturation) >> 2) & 0xf8) | 0x04; - data[4] = v4l2_ctrl_g_ctrl(sd->brightness); /* reg 0x61 = brightness */ - data[5] = 0x00; - - reg_w(gspca_dev, 6); - - data[0] = 0x67; -/*jfm: from win trace*/ - data[1] = v4l2_ctrl_g_ctrl(sd->sharpness) * 4 + 3; - data[2] = 0x14; - reg_w(gspca_dev, 3); - - data[0] = 0x69; - data[1] = 0x2f; - data[2] = 0x28; - data[3] = 0x42; - reg_w(gspca_dev, 4); - - data[0] = 0x63; - data[1] = 0x07; - reg_w(gspca_dev, 2); -/*jfm: win trace - many writes here to reg 0x64*/ - - /* initialize the MI sensor */ - for (i = 0; i < sizeof mi_data; i++) - mi_w(gspca_dev, i + 1, mi_data[i]); - - data[0] = 0x00; - data[1] = 0x4d; /* ISOC transferring enable... */ - reg_w(gspca_dev, 2); - - setilluminators(gspca_dev, v4l2_ctrl_g_ctrl(sd->illum_top), - v4l2_ctrl_g_ctrl(sd->illum_bottom)); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (v4l2_ctrl_g_ctrl(sd->illum_top) || - v4l2_ctrl_g_ctrl(sd->illum_bottom)) { - setilluminators(gspca_dev, false, false); - msleep(20); - } - - gspca_dev->usb_buf[0] = 1; - gspca_dev->usb_buf[1] = 0; - reg_w(gspca_dev, 2); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int p; - - if (len < 6) { -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - } - for (p = 0; p < len - 6; p++) { - if (data[0 + p] == 0xff - && data[1 + p] == 0xff - && data[2 + p] == 0x00 - && data[3 + p] == 0xff - && data[4 + p] == 0x96) { - if (data[5 + p] == 0x64 - || data[5 + p] == 0x65 - || data[5 + p] == 0x66 - || data[5 + p] == 0x67) { - PDEBUG(D_PACK, "sof offset: %d len: %d", - p, len); - gspca_frame_add(gspca_dev, LAST_PACKET, - data, p); - - /* put the JPEG header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - data += p + 16; - len -= p + 16; - break; - } - } - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x050f)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c deleted file mode 100644 index 8f4714df5990..000000000000 --- a/drivers/media/video/gspca/mr97310a.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * Mars MR97310A library - * - * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is - * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> - * - * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+ - * and for the routines for detecting and classifying these various cameras, - * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> - * - * Support for the control settings for the CIF cameras is - * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and - * Thomas Kaiser <thomas@kaiser-linux.li> - * - * Support for the control settings for the VGA cameras is - * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> - * - * Several previously unsupported cameras are owned and have been tested by - * Hans de Goede <hdegoede@redhat.com> and - * Thomas Kaiser <thomas@kaiser-linux.li> and - * Theodore Kilgore <kilgota@auburn.edu> and - * Edmond Rodriguez <erodrig_97@yahoo.com> and - * Aurelien Jacobs <aurel@gnuage.org> - * - * The MR97311A support in gspca/mars.c has been helpful in understanding some - * of the registers in these cameras. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "mr97310a" - -#include "gspca.h" - -#define CAM_TYPE_CIF 0 -#define CAM_TYPE_VGA 1 - -#define MR97310A_BRIGHTNESS_DEFAULT 0 - -#define MR97310A_EXPOSURE_MIN 0 -#define MR97310A_EXPOSURE_MAX 4095 -#define MR97310A_EXPOSURE_DEFAULT 1000 - -#define MR97310A_GAIN_MIN 0 -#define MR97310A_GAIN_MAX 31 -#define MR97310A_GAIN_DEFAULT 25 - -#define MR97310A_CONTRAST_MIN 0 -#define MR97310A_CONTRAST_MAX 31 -#define MR97310A_CONTRAST_DEFAULT 23 - -#define MR97310A_CS_GAIN_MIN 0 -#define MR97310A_CS_GAIN_MAX 0x7ff -#define MR97310A_CS_GAIN_DEFAULT 0x110 - -#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000) -#define MR97310A_MIN_CLOCKDIV_MIN 3 -#define MR97310A_MIN_CLOCKDIV_MAX 8 -#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 - -MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," - "Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* global parameters */ -static int force_sensor_type = -1; -module_param(force_sensor_type, int, 0644); -MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct { /* exposure/min_clockdiv control cluster */ - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *min_clockdiv; - }; - u8 sof_read; - u8 cam_type; /* 0 is CIF and 1 is VGA */ - u8 sensor_type; /* We use 0 and 1 here, too. */ - u8 do_lcd_stop; - u8 adj_colors; -}; - -struct sensor_w_data { - u8 reg; - u8 flags; - u8 data[16]; - int len; -}; - -static void sd_stopN(struct gspca_dev *gspca_dev); - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, - {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* the bytes to write are in gspca_dev->usb_buf */ -static int mr_write(struct gspca_dev *gspca_dev, int len) -{ - int rc; - - rc = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, len, NULL, 500); - if (rc < 0) - pr_err("reg write [%02x] error %d\n", - gspca_dev->usb_buf[0], rc); - return rc; -} - -/* the bytes are read into gspca_dev->usb_buf */ -static int mr_read(struct gspca_dev *gspca_dev, int len) -{ - int rc; - - rc = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 3), - gspca_dev->usb_buf, len, NULL, 500); - if (rc < 0) - pr_err("reg read [%02x] error %d\n", - gspca_dev->usb_buf[0], rc); - return rc; -} - -static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags, - const u8 *data, int len) -{ - gspca_dev->usb_buf[0] = 0x1f; - gspca_dev->usb_buf[1] = flags; - gspca_dev->usb_buf[2] = reg; - memcpy(gspca_dev->usb_buf + 3, data, len); - - return mr_write(gspca_dev, len + 3); -} - -static int sensor_write_regs(struct gspca_dev *gspca_dev, - const struct sensor_w_data *data, int len) -{ - int i, rc; - - for (i = 0; i < len; i++) { - rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags, - data[i].data, data[i].len); - if (rc < 0) - return rc; - } - - return 0; -} - -static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 buf, confirm_reg; - int rc; - - buf = data; - if (sd->cam_type == CAM_TYPE_CIF) { - rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1); - confirm_reg = sd->sensor_type ? 0x13 : 0x11; - } else { - rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1); - confirm_reg = 0x11; - } - if (rc < 0) - return rc; - - buf = 0x01; - rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); - if (rc < 0) - return rc; - - return 0; -} - -static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose) -{ - int err_code; - - gspca_dev->usb_buf[0] = reg; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; - - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; - - if (verbose) - PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg, - gspca_dev->usb_buf[0], - gspca_dev->usb_buf[1], - gspca_dev->usb_buf[2]); - - return 0; -} - -static int zero_the_pointer(struct gspca_dev *gspca_dev) -{ - __u8 *data = gspca_dev->usb_buf; - int err_code; - u8 status = 0; - int tries = 0; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x51; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0xba; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - if (err_code < 0) - return err_code; - - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - while (status != 0x0a && tries < 256) { - err_code = cam_get_response16(gspca_dev, 0x21, 0); - status = data[0]; - tries++; - if (err_code < 0) - return err_code; - } - if (status != 0x0a) - PDEBUG(D_ERR, "status is %02x", status); - - tries = 0; - while (tries < 4) { - data[0] = 0x19; - data[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - - err_code = cam_get_response16(gspca_dev, 0x21, 0); - status = data[0]; - tries++; - if (err_code < 0) - return err_code; - } - - data[0] = 0x19; - err_code = mr_write(gspca_dev, 1); - if (err_code < 0) - return err_code; - - err_code = mr_read(gspca_dev, 16); - if (err_code < 0) - return err_code; - - return 0; -} - -static int stream_start(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x01; - gspca_dev->usb_buf[1] = 0x01; - return mr_write(gspca_dev, 2); -} - -static void stream_stop(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x01; - gspca_dev->usb_buf[1] = 0x00; - if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "Stream Stop failed"); -} - -static void lcd_stop(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x19; - gspca_dev->usb_buf[1] = 0x54; - if (mr_write(gspca_dev, 2) < 0) - PDEBUG(D_ERR, "LCD Stop failed"); -} - -static int isoc_enable(struct gspca_dev *gspca_dev) -{ - gspca_dev->usb_buf[0] = 0x00; - gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */ - return mr_write(gspca_dev, 2); -} - -/* This function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int err_code; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - sd->do_lcd_stop = 0; - - /* Several of the supported CIF cameras share the same USB ID but - * require different initializations and different control settings. - * The same is true of the VGA cameras. Therefore, we are forced - * to start the initialization process in order to determine which - * camera is present. Some of the supported cameras require the - * memory pointer to be set to 0 as the very first item of business - * or else they will not stream. So we do that immediately. - */ - err_code = zero_the_pointer(gspca_dev); - if (err_code < 0) - return err_code; - - err_code = stream_start(gspca_dev); - if (err_code < 0) - return err_code; - - /* Now, the query for sensor type. */ - err_code = cam_get_response16(gspca_dev, 0x07, 1); - if (err_code < 0) - return err_code; - - if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { - sd->cam_type = CAM_TYPE_CIF; - cam->nmodes--; - /* - * All but one of the known CIF cameras share the same USB ID, - * but two different init routines are in use, and the control - * settings are different, too. We need to detect which camera - * of the two known varieties is connected! - * - * A list of known CIF cameras follows. They all report either - * 0200 for type 0 or 0300 for type 1. - * If you have another to report, please do - * - * Name sd->sensor_type reported by - * - * Sakar 56379 Spy-shot 0 T. Kilgore - * Innovage 0 T. Kilgore - * Vivitar Mini 0 H. De Goede - * Vivitar Mini 0 E. Rodriguez - * Vivitar Mini 1 T. Kilgore - * Elta-Media 8212dc 1 T. Kaiser - * Philips dig. keych. 1 T. Kilgore - * Trust Spyc@m 100 1 A. Jacobs - */ - switch (gspca_dev->usb_buf[0]) { - case 2: - sd->sensor_type = 0; - break; - case 3: - sd->sensor_type = 1; - break; - default: - pr_err("Unknown CIF Sensor id : %02x\n", - gspca_dev->usb_buf[1]); - return -ENODEV; - } - PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d", - sd->sensor_type); - } else { - sd->cam_type = CAM_TYPE_VGA; - - /* - * Here is a table of the responses to the query for sensor - * type, from the known MR97310A VGA cameras. Six different - * cameras of which five share the same USB ID. - * - * Name gspca_dev->usb_buf[] sd->sensor_type - * sd->do_lcd_stop - * Aiptek Pencam VGA+ 0300 0 1 - * ION digital 0300 0 1 - * Argus DC-1620 0450 1 0 - * Argus QuickClix 0420 1 1 - * Sakar 77379 Digital 0350 0 1 - * Sakar 1638x CyberPix 0120 0 2 - * - * Based upon these results, we assume default settings - * and then correct as necessary, as follows. - * - */ - - sd->sensor_type = 1; - sd->do_lcd_stop = 0; - sd->adj_colors = 0; - if (gspca_dev->usb_buf[0] == 0x01) { - sd->sensor_type = 2; - } else if ((gspca_dev->usb_buf[0] != 0x03) && - (gspca_dev->usb_buf[0] != 0x04)) { - pr_err("Unknown VGA Sensor id Byte 0: %02x\n", - gspca_dev->usb_buf[0]); - pr_err("Defaults assumed, may not work\n"); - pr_err("Please report this\n"); - } - /* Sakar Digital color needs to be adjusted. */ - if ((gspca_dev->usb_buf[0] == 0x03) && - (gspca_dev->usb_buf[1] == 0x50)) - sd->adj_colors = 1; - if (gspca_dev->usb_buf[0] == 0x04) { - sd->do_lcd_stop = 1; - switch (gspca_dev->usb_buf[1]) { - case 0x50: - sd->sensor_type = 0; - PDEBUG(D_PROBE, "sensor_type corrected to 0"); - break; - case 0x20: - /* Nothing to do here. */ - break; - default: - pr_err("Unknown VGA Sensor id Byte 1: %02x\n", - gspca_dev->usb_buf[1]); - pr_err("Defaults assumed, may not work\n"); - pr_err("Please report this\n"); - } - } - PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", - sd->sensor_type); - } - /* Stop streaming as we've started it only to probe the sensor type. */ - sd_stopN(gspca_dev); - - if (force_sensor_type != -1) { - sd->sensor_type = !!force_sensor_type; - PDEBUG(D_PROBE, "Forcing sensor type to: %d", - sd->sensor_type); - } - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int start_cif_cam(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *data = gspca_dev->usb_buf; - int err_code; - static const __u8 startup_string[] = { - 0x00, - 0x0d, - 0x01, - 0x00, /* Hsize/8 for 352 or 320 */ - 0x00, /* Vsize/4 for 288 or 240 */ - 0x13, /* or 0xbb, depends on sensor */ - 0x00, /* Hstart, depends on res. */ - 0x00, /* reserved ? */ - 0x00, /* Vstart, depends on res. and sensor */ - 0x50, /* 0x54 to get 176 or 160 */ - 0xc0 - }; - - /* Note: Some of the above descriptions guessed from MR97113A driver */ - - memcpy(data, startup_string, 11); - if (sd->sensor_type) - data[5] = 0xbb; - - switch (gspca_dev->width) { - case 160: - data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */ - /* fall thru */ - case 320: - default: - data[3] = 0x28; /* reg 2, H size/8 */ - data[4] = 0x3c; /* reg 3, V size/4 */ - data[6] = 0x14; /* reg 5, H start */ - data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */ - break; - case 176: - data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */ - /* fall thru */ - case 352: - data[3] = 0x2c; /* reg 2, H size/8 */ - data[4] = 0x48; /* reg 3, V size/4 */ - data[6] = 0x06; /* reg 5, H start */ - data[8] = 0x06 - sd->sensor_type; /* reg 7, V start */ - break; - } - err_code = mr_write(gspca_dev, 11); - if (err_code < 0) - return err_code; - - if (!sd->sensor_type) { - static const struct sensor_w_data cif_sensor0_init_data[] = { - {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01, - 0x0f, 0x14, 0x0f, 0x10}, 8}, - {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5}, - {0x12, 0x00, {0x07}, 1}, - {0x1f, 0x00, {0x06}, 1}, - {0x27, 0x00, {0x04}, 1}, - {0x29, 0x00, {0x0c}, 1}, - {0x40, 0x00, {0x40, 0x00, 0x04}, 3}, - {0x50, 0x00, {0x60}, 1}, - {0x60, 0x00, {0x06}, 1}, - {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6}, - {0x72, 0x00, {0x1e, 0x56}, 2}, - {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02, - 0x31, 0x80, 0x00}, 9}, - {0x11, 0x00, {0x01}, 1}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data, - ARRAY_SIZE(cif_sensor0_init_data)); - } else { /* sd->sensor_type = 1 */ - static const struct sensor_w_data cif_sensor1_init_data[] = { - /* Reg 3,4, 7,8 get set by the controls */ - {0x02, 0x00, {0x10}, 1}, - {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */ - {0x06, 0x01, {0x00}, 1}, - {0x09, 0x02, {0x0e}, 1}, - {0x0a, 0x02, {0x05}, 1}, - {0x0b, 0x02, {0x05}, 1}, - {0x0c, 0x02, {0x0f}, 1}, - {0x0d, 0x02, {0x07}, 1}, - {0x0e, 0x02, {0x0c}, 1}, - {0x0f, 0x00, {0x00}, 1}, - {0x10, 0x00, {0x06}, 1}, - {0x11, 0x00, {0x07}, 1}, - {0x12, 0x00, {0x00}, 1}, - {0x13, 0x00, {0x01}, 1}, - {0, 0, {0}, 0} - }; - /* Without this command the cam won't work with USB-UHCI */ - gspca_dev->usb_buf[0] = 0x0a; - gspca_dev->usb_buf[1] = 0x00; - err_code = mr_write(gspca_dev, 2); - if (err_code < 0) - return err_code; - err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, - ARRAY_SIZE(cif_sensor1_init_data)); - } - return err_code; -} - -static int start_vga_cam(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *data = gspca_dev->usb_buf; - int err_code; - static const __u8 startup_string[] = - {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, - 0x00, 0x50, 0xc0}; - /* What some of these mean is explained in start_cif_cam(), above */ - - memcpy(data, startup_string, 11); - if (!sd->sensor_type) { - data[5] = 0x00; - data[10] = 0x91; - } - if (sd->sensor_type == 2) { - data[5] = 0x00; - data[10] = 0x18; - } - - switch (gspca_dev->width) { - case 160: - data[9] |= 0x0c; /* reg 8, 4:1 scale down */ - /* fall thru */ - case 320: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 640: - default: - data[3] = 0x50; /* reg 2, H size/8 */ - data[4] = 0x78; /* reg 3, V size/4 */ - data[6] = 0x04; /* reg 5, H start */ - data[8] = 0x03; /* reg 7, V start */ - if (sd->sensor_type == 2) { - data[6] = 2; - data[8] = 1; - } - if (sd->do_lcd_stop) - data[8] = 0x04; /* Bayer tile shifted */ - break; - - case 176: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 352: - data[3] = 0x2c; /* reg 2, H size */ - data[4] = 0x48; /* reg 3, V size */ - data[6] = 0x94; /* reg 5, H start */ - data[8] = 0x63; /* reg 7, V start */ - if (sd->do_lcd_stop) - data[8] = 0x64; /* Bayer tile shifted */ - break; - } - - err_code = mr_write(gspca_dev, 11); - if (err_code < 0) - return err_code; - - if (!sd->sensor_type) { - static const struct sensor_w_data vga_sensor0_init_data[] = { - {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, - {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, - {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4}, - {0x25, 0x00, {0x03, 0xa9, 0x80}, 3}, - {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, - ARRAY_SIZE(vga_sensor0_init_data)); - } else if (sd->sensor_type == 1) { - static const struct sensor_w_data color_adj[] = { - {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, - /* adjusted blue, green, red gain correct - too much blue from the Sakar Digital */ - 0x05, 0x01, 0x04}, 8} - }; - - static const struct sensor_w_data color_no_adj[] = { - {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, - /* default blue, green, red gain settings */ - 0x07, 0x00, 0x01}, 8} - }; - - static const struct sensor_w_data vga_sensor1_init_data[] = { - {0x11, 0x04, {0x01}, 1}, - {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, - /* These settings may be better for some cameras */ - /* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */ - 0x00, 0x0a}, 7}, - {0x11, 0x04, {0x01}, 1}, - {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6}, - {0x11, 0x04, {0x01}, 1}, - {0, 0, {0}, 0} - }; - - if (sd->adj_colors) - err_code = sensor_write_regs(gspca_dev, color_adj, - ARRAY_SIZE(color_adj)); - else - err_code = sensor_write_regs(gspca_dev, color_no_adj, - ARRAY_SIZE(color_no_adj)); - - if (err_code < 0) - return err_code; - - err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, - ARRAY_SIZE(vga_sensor1_init_data)); - } else { /* sensor type == 2 */ - static const struct sensor_w_data vga_sensor2_init_data[] = { - - {0x01, 0x00, {0x48}, 1}, - {0x02, 0x00, {0x22}, 1}, - /* Reg 3 msb and 4 is lsb of the exposure setting*/ - {0x05, 0x00, {0x10}, 1}, - {0x06, 0x00, {0x00}, 1}, - {0x07, 0x00, {0x00}, 1}, - {0x08, 0x00, {0x00}, 1}, - {0x09, 0x00, {0x00}, 1}, - /* The following are used in the gain control - * which is BTW completely borked in the OEM driver - * The values for each color go from 0 to 0x7ff - *{0x0a, 0x00, {0x01}, 1}, green1 gain msb - *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb - *{0x0c, 0x00, {0x01}, 1}, red gain msb - *{0x0d, 0x00, {0x10}, 1}, red gain lsb - *{0x0e, 0x00, {0x01}, 1}, blue gain msb - *{0x0f, 0x00, {0x10}, 1}, blue gain lsb - *{0x10, 0x00, {0x01}, 1}, green2 gain msb - *{0x11, 0x00, {0x10}, 1}, green2 gain lsb - */ - {0x12, 0x00, {0x00}, 1}, - {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */ - {0x14, 0x00, {0x00}, 1}, - {0x15, 0x00, {0x06}, 1}, - {0x16, 0x00, {0x01}, 1}, - {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */ - {0x18, 0x00, {0x02}, 1}, - {0x19, 0x00, {0x82}, 1}, /* don't mess with */ - {0x1a, 0x00, {0x00}, 1}, - {0x1b, 0x00, {0x20}, 1}, - /* {0x1c, 0x00, {0x17}, 1}, contrast control */ - {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */ - {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */ - {0x1f, 0x00, {0x0c}, 1}, - {0x20, 0x00, {0x00}, 1}, - {0, 0, {0}, 0} - }; - err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data, - ARRAY_SIZE(vga_sensor2_init_data)); - } - return err_code; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err_code; - - sd->sof_read = 0; - - /* Some of the VGA cameras require the memory pointer - * to be set to 0 again. We have been forced to start the - * stream in sd_config() to detect the hardware, and closed it. - * Thus, we need here to do a completely fresh and clean start. */ - err_code = zero_the_pointer(gspca_dev); - if (err_code < 0) - return err_code; - - err_code = stream_start(gspca_dev); - if (err_code < 0) - return err_code; - - if (sd->cam_type == CAM_TYPE_CIF) { - err_code = start_cif_cam(gspca_dev); - } else { - err_code = start_vga_cam(gspca_dev); - } - if (err_code < 0) - return err_code; - - return isoc_enable(gspca_dev); -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - stream_stop(gspca_dev); - /* Not all the cams need this, but even if not, probably a good idea */ - zero_the_pointer(gspca_dev); - if (sd->do_lcd_stop) - lcd_stop(gspca_dev); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 sign_reg = 7; /* This reg and the next one used on CIF cams. */ - u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */ - static const u8 quick_clix_table[] = - /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ - { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15}; - if (sd->cam_type == CAM_TYPE_VGA) { - sign_reg += 4; - value_reg += 4; - } - - /* Note register 7 is also seen as 0x8x or 0xCx in some dumps */ - if (val > 0) { - sensor_write1(gspca_dev, sign_reg, 0x00); - } else { - sensor_write1(gspca_dev, sign_reg, 0x01); - val = 257 - val; - } - /* Use lookup table for funky Argus QuickClix brightness */ - if (sd->do_lcd_stop) - val = quick_clix_table[val]; - - sensor_write1(gspca_dev, value_reg, val); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv) -{ - struct sd *sd = (struct sd *) gspca_dev; - int exposure = MR97310A_EXPOSURE_DEFAULT; - u8 buf[2]; - - if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { - /* This cam does not like exposure settings < 300, - so scale 0 - 4095 to 300 - 4095 */ - exposure = (expo * 9267) / 10000 + 300; - sensor_write1(gspca_dev, 3, exposure >> 4); - sensor_write1(gspca_dev, 4, exposure & 0x0f); - } else if (sd->sensor_type == 2) { - exposure = expo; - exposure >>= 3; - sensor_write1(gspca_dev, 3, exposure >> 8); - sensor_write1(gspca_dev, 4, exposure & 0xff); - } else { - /* We have both a clock divider and an exposure register. - We first calculate the clock divider, as that determines - the maximum exposure and then we calculate the exposure - register setting (which goes from 0 - 511). - - Note our 0 - 4095 exposure is mapped to 0 - 511 - milliseconds exposure time */ - u8 clockdiv = (60 * expo + 7999) / 8000; - - /* Limit framerate to not exceed usb bandwidth */ - if (clockdiv < min_clockdiv && gspca_dev->width >= 320) - clockdiv = min_clockdiv; - else if (clockdiv < 2) - clockdiv = 2; - - if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4) - clockdiv = 4; - - /* Frame exposure time in ms = 1000 * clockdiv / 60 -> - exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ - exposure = (60 * 511 * expo) / (8000 * clockdiv); - if (exposure > 511) - exposure = 511; - - /* exposure register value is reversed! */ - exposure = 511 - exposure; - - buf[0] = exposure & 0xff; - buf[1] = exposure >> 8; - sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2); - sensor_write1(gspca_dev, 0x02, clockdiv); - } -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 gainreg; - - if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) - sensor_write1(gspca_dev, 0x0e, val); - else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2) - for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) { - sensor_write1(gspca_dev, gainreg, val >> 8); - sensor_write1(gspca_dev, gainreg + 1, val & 0xff); - } - else - sensor_write1(gspca_dev, 0x10, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - sensor_write1(gspca_dev, 0x1c, val); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, sd->exposure->val, - sd->min_clockdiv ? sd->min_clockdiv->val : 0); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - static const struct v4l2_ctrl_config clockdiv = { - .ops = &sd_ctrl_ops, - .id = MR97310A_CID_CLOCKDIV, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Minimum Clock Divider", - .min = MR97310A_MIN_CLOCKDIV_MIN, - .max = MR97310A_MIN_CLOCKDIV_MAX, - .step = 1, - .def = MR97310A_MIN_CLOCKDIV_DEFAULT, - }; - bool has_brightness = false; - bool has_argus_brightness = false; - bool has_contrast = false; - bool has_gain = false; - bool has_cs_gain = false; - bool has_exposure = false; - bool has_clockdiv = false; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - - /* Setup controls depending on camera type */ - if (sd->cam_type == CAM_TYPE_CIF) { - /* No brightness for sensor_type 0 */ - if (sd->sensor_type == 0) - has_exposure = has_gain = has_clockdiv = true; - else - has_exposure = has_gain = has_brightness = true; - } else { - /* All controls need to be disabled if VGA sensor_type is 0 */ - if (sd->sensor_type == 0) - ; /* no controls! */ - else if (sd->sensor_type == 2) - has_exposure = has_cs_gain = has_contrast = true; - else if (sd->do_lcd_stop) - has_exposure = has_gain = has_argus_brightness = - has_clockdiv = true; - else - has_exposure = has_gain = has_brightness = - has_clockdiv = true; - } - - /* Separate brightness control description for Argus QuickClix as it has - * different limits from the other mr97310a cameras, and separate gain - * control for Sakar CyberPix camera. */ - /* - * This control is disabled for CIF type 1 and VGA type 0 cameras. - * It does not quite act linearly for the Argus QuickClix camera, - * but it does control brightness. The values are 0 - 15 only, and - * the table above makes them act consecutively. - */ - if (has_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, -254, 255, 1, - MR97310A_BRIGHTNESS_DEFAULT); - else if (has_argus_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 15, 1, - MR97310A_BRIGHTNESS_DEFAULT); - if (has_contrast) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN, - MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT); - if (has_gain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX, - 1, MR97310A_GAIN_DEFAULT); - else if (has_cs_gain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN, - MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX, - 1, MR97310A_CS_GAIN_DEFAULT); - if (has_exposure) - sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN, - MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT); - if (has_clockdiv) - sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (has_exposure && has_clockdiv) - v4l2_ctrl_cluster(2, &sd->exposure); - return 0; -} - -/* Include pac common sof detection functions */ -#include "pac_common.h" - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned char *sof; - - sof = pac_find_sof(&sd->sof_read, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sizeof pac_sof_marker) - n -= sizeof pac_sof_marker; - else - n = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, - data, n); - /* Start next frame. */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - pac_sof_marker, sizeof pac_sof_marker); - len -= sof - data; - data = sof; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */ - {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ - {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ - {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c deleted file mode 100644 index 44c9964b1b3e..000000000000 --- a/drivers/media/video/gspca/nw80x.c +++ /dev/null @@ -1,2110 +0,0 @@ -/* - * DivIO nw80x subdriver - * - * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr) - * Copyright (C) 2003 Sylvain Munaut <tnt@246tNt.com> - * Kjell Claesson <keyson@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "nw80x" - -#include "gspca.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("NW80x USB Camera Driver"); -MODULE_LICENSE("GPL"); - -static int webcam; - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - u32 ae_res; - s8 ag_cnt; -#define AG_CNT_START 13 - u8 exp_too_low_cnt; - u8 exp_too_high_cnt; - - u8 bridge; - u8 webcam; -}; - -enum bridges { - BRIDGE_NW800, /* and et31x110 */ - BRIDGE_NW801, - BRIDGE_NW802, -}; -enum webcams { - Generic800, - SpaceCam, /* Trust 120 SpaceCam */ - SpaceCam2, /* other Trust 120 SpaceCam */ - Cvideopro, /* Conceptronic Video Pro */ - Dlink350c, - DS3303u, - Kr651us, - Kritter, - Mustek300, - Proscope, - Twinkle, - DvcV6, - P35u, - Generic802, - NWEBCAMS /* number of webcams */ -}; - -static const u8 webcam_chip[NWEBCAMS] = { - [Generic800] = BRIDGE_NW800, /* 06a5:0000 - * Typhoon Webcam 100 USB */ - - [SpaceCam] = BRIDGE_NW800, /* 06a5:d800 - * Trust SpaceCam120 or SpaceCam100 PORTABLE */ - - [SpaceCam2] = BRIDGE_NW800, /* 06a5:d800 - pas106 - * other Trust SpaceCam120 or SpaceCam100 PORTABLE */ - - [Cvideopro] = BRIDGE_NW802, /* 06a5:d001 - * Conceptronic Video Pro 'CVIDEOPRO USB Webcam CCD' */ - - [Dlink350c] = BRIDGE_NW802, /* 06a5:d001 - * D-Link NetQam Pro 250plus */ - - [DS3303u] = BRIDGE_NW801, /* 06a5:d001 - * Plustek Opticam 500U or ProLink DS3303u */ - - [Kr651us] = BRIDGE_NW802, /* 06a5:d001 - * Panasonic GP-KR651US */ - - [Kritter] = BRIDGE_NW802, /* 06a5:d001 - * iRez Kritter cam */ - - [Mustek300] = BRIDGE_NW802, /* 055f:d001 - * Mustek Wcam 300 mini */ - - [Proscope] = BRIDGE_NW802, /* 06a5:d001 - * Scalar USB Microscope (ProScope) */ - - [Twinkle] = BRIDGE_NW800, /* 06a5:d800 - hv7121b? (seems pas106) - * Divio Chicony TwinkleCam - * DSB-C110 */ - - [DvcV6] = BRIDGE_NW802, /* 0502:d001 - * DVC V6 */ - - [P35u] = BRIDGE_NW801, /* 052b:d001, 06a5:d001 and 06be:d001 - * EZCam Pro p35u */ - - [Generic802] = BRIDGE_NW802, -}; -/* - * other webcams: - * - nw801 046d:d001 - * Logitech QuickCam Pro (dark focus ring) - * - nw801 0728:d001 - * AVerMedia Camguard - * - nw??? 06a5:d001 - * D-Link NetQam Pro 250plus - * - nw800 065a:d800 - * Showcam NGS webcam - * - nw??? ????:???? - * Sceptre svc300 - */ - -/* - * registers - * nw800/et31x110 nw801 nw802 - * 0000..009e 0000..00a1 0000..009e - * 0200..0211 id id - * 0300..0302 id id - * 0400..0406 (inex) 0400..0406 - * 0500..0505 0500..0506 (inex) - * 0600..061a 0600..0601 0600..0601 - * 0800..0814 id id - * 1000..109c 1000..10a1 1000..109a - */ - -/* resolutions - * nw800: 320x240, 352x288 - * nw801/802: 320x240, 640x480 - */ -static const struct v4l2_pix_format cif_mode[] = { - {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8, - .colorspace = V4L2_COLORSPACE_JPEG}, - {352, 288, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 4 / 8, - .colorspace = V4L2_COLORSPACE_JPEG} -}; -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8, - .colorspace = V4L2_COLORSPACE_JPEG}, - {640, 480, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8, - .colorspace = V4L2_COLORSPACE_JPEG}, -}; - -/* - * The sequences below contain: - * - 1st and 2nd bytes: either - * - register number (BE) - * - I2C0 + i2c address - * - 3rd byte: data length (=0 for end of sequence) - * - n bytes: data - */ -#define I2C0 0xff - -static const u8 nw800_init[] = { - 0x04, 0x05, 0x01, 0x61, - 0x04, 0x04, 0x01, 0x01, - 0x04, 0x06, 0x01, 0x04, - 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, - 0x05, 0x05, 0x01, 0x00, - 0, 0, 0 -}; -static const u8 nw800_start[] = { - 0x04, 0x06, 0x01, 0xc0, - 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f, - 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24, - 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08, - 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04, - 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0, - 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20, - 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62, - 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20, - 0x01, 0x60, 0x01, 0x00, 0x00, - - 0x04, 0x04, 0x01, 0xff, - 0x04, 0x06, 0x01, 0xc4, - - 0x04, 0x06, 0x01, 0xc0, - 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f, - 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24, - 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08, - 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04, - 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0, - 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20, - 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62, - 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20, - 0x01, 0x60, 0x01, 0x00, 0x00, - - 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00, - 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65, - 0x40, - 0x00, 0x80, 0x01, 0xa0, - 0x10, 0x1a, 0x01, 0x00, - 0x00, 0x91, 0x02, 0x6c, 0x01, - 0x00, 0x03, 0x02, 0xc8, 0x01, - 0x10, 0x1a, 0x01, 0x00, - 0x10, 0x00, 0x01, 0x83, - 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, - 0x20, 0x01, 0x60, 0x01, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x10, 0x1b, 0x02, 0x69, 0x00, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x05, 0x02, 0x01, 0x02, - 0x06, 0x00, 0x02, 0x04, 0xd9, - 0x05, 0x05, 0x01, 0x20, - 0x05, 0x05, 0x01, 0x21, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83, - 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0, - 0xea, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x13, 0x13, - 0x10, 0x03, 0x01, 0x14, - 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83, - 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0, - 0xea, - 0x10, 0x0b, 0x01, 0x14, - 0x10, 0x0d, 0x01, 0x20, - 0x10, 0x0c, 0x01, 0x34, - 0x04, 0x06, 0x01, 0xc3, - 0x04, 0x04, 0x01, 0x00, - 0x05, 0x02, 0x01, 0x02, - 0x06, 0x00, 0x02, 0x00, 0x48, - 0x05, 0x05, 0x01, 0x20, - 0x05, 0x05, 0x01, 0x21, - 0, 0, 0 -}; - -/* 06a5:d001 - nw801 - Panasonic - * P35u */ -static const u8 nw801_start_1[] = { - 0x05, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e, - 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x69, 0xa8, 0x1f, 0x00, - 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00, - 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00, - 0x36, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x22, 0x02, 0x80, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0a, 0x15, 0x08, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x35, 0xfd, 0x07, 0x3d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x02, - 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7, - 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80, - 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, 0xa4, - 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, 0xcf, - 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, - 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, - 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x82, 0x02, - 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01, - 0xf0, 0x00, - 0, 0, 0, -}; -static const u8 nw801_start_qvga[] = { - 0x02, 0x00, 0x10, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x18, 0x0b, 0x06, 0xa2, 0x86, 0x78, - 0x02, 0x0f, 0x01, 0x6b, - 0x10, 0x1a, 0x01, 0x15, - 0x00, 0x00, 0x01, 0x1e, - 0x10, 0x00, 0x01, 0x2f, - 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00, - /* AE window */ - 0, 0, 0, -}; -static const u8 nw801_start_vga[] = { - 0x02, 0x00, 0x10, 0x78, 0xa0, 0x97, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xf0, - 0x02, 0x0f, 0x01, 0xd5, - 0x10, 0x1a, 0x01, 0x15, - 0x00, 0x00, 0x01, 0x0e, - 0x10, 0x00, 0x01, 0x22, - 0x10, 0x8c, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01, - 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01, - 0, 0, 0, -}; -static const u8 nw801_start_2[] = { - 0x10, 0x04, 0x01, 0x1a, - 0x10, 0x19, 0x01, 0x09, /* clock */ - 0x10, 0x24, 0x06, 0xc0, 0x00, 0x3f, 0x02, 0x00, 0x01, - /* .. gain .. */ - 0x00, 0x03, 0x02, 0x92, 0x03, - 0x00, 0x1d, 0x04, 0xf2, 0x00, 0x24, 0x07, - 0x00, 0x7b, 0x01, 0xcf, - 0x10, 0x94, 0x01, 0x07, - 0x05, 0x05, 0x01, 0x01, - 0x05, 0x04, 0x01, 0x01, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8, - 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0, - 0xf0, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x0c, 0x0c, - 0x10, 0x03, 0x01, 0x08, - 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8, - 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0, - 0xf0, - 0x10, 0x0b, 0x01, 0x0b, - 0x10, 0x0d, 0x01, 0x0b, - 0x10, 0x0c, 0x01, 0x1f, - 0x05, 0x06, 0x01, 0x03, - 0, 0, 0 -}; - -/* nw802 (sharp IR3Y38M?) */ -static const u8 nw802_start[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x4d, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x08, 0x00, 0x18, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x1d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0xff, 0x01, 0xc0, 0x00, 0x14, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78, - 0x40, - 0x10, 0x1a, 0x01, 0x00, - 0x10, 0x00, 0x01, 0xad, - 0x00, 0x00, 0x01, 0x08, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00, - 0x10, 0x1d, 0x08, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, - 0x10, 0x0e, 0x01, 0x27, - 0x10, 0x41, 0x11, 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b, - 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2, - 0xd8, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x14, 0x14, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x41, 0x11, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, 0x74, - 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, 0xf1, - 0xff, -/* 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b, - * 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2, - * 0xd8, */ - 0x10, 0x0b, 0x01, 0x10, - 0x10, 0x0d, 0x01, 0x11, - 0x10, 0x0c, 0x01, 0x1c, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; -/* et31x110 - Trust 120 SpaceCam */ -static const u8 spacecam_init[] = { - 0x04, 0x05, 0x01, 0x01, - 0x04, 0x04, 0x01, 0x01, - 0x04, 0x06, 0x01, 0x04, - 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, - 0x05, 0x05, 0x01, 0x00, - 0, 0, 0 -}; -static const u8 spacecam_start[] = { - 0x04, 0x06, 0x01, 0x44, - 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f, - 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24, - 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08, - 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04, - 0x00, 0x4b, 0x00, 0x7c, 0x00, 0x80, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62, - 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20, - 0x01, 0x60, 0x01, 0x00, 0x00, - 0x04, 0x06, 0x01, 0xc0, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00, - 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65, - 0x40, - 0x00, 0x80, 0x01, 0xa0, - 0x10, 0x1a, 0x01, 0x00, - 0x00, 0x91, 0x02, 0x32, 0x01, - 0x00, 0x03, 0x02, 0x08, 0x02, - 0x10, 0x00, 0x01, 0x83, - 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, - 0x20, 0x01, 0x60, 0x01, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9, - 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x13, 0x13, - 0x10, 0x03, 0x01, 0x06, - 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9, - 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, - 0x10, 0x0b, 0x01, 0x08, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1f, - 0x04, 0x06, 0x01, 0xc3, - 0x04, 0x05, 0x01, 0x40, - 0x04, 0x04, 0x01, 0x40, - 0, 0, 0 -}; -/* et31x110 - pas106 - other Trust SpaceCam120 */ -static const u8 spacecam2_start[] = { - 0x04, 0x06, 0x01, 0x44, - 0x04, 0x06, 0x01, 0x00, - 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f, - 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc, - 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03, - 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04, - 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00, - 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, - 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20, - 0x01, 0x60, 0x01, 0x00, 0x00, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x04, 0x04, 0x01, 0x40, - 0x04, 0x04, 0x01, 0x00, - I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x05, 0x05, - I2C0, 0x40, 0x02, 0x11, 0x06, - I2C0, 0x40, 0x02, 0x14, 0x00, - I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */ - 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00, - 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65, - 0x40, - I2C0, 0x40, 0x02, 0x02, 0x0c, /* pixel clock */ - I2C0, 0x40, 0x02, 0x0f, 0x00, - I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */ - 0x10, 0x00, 0x01, 0x01, - 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, - 0x20, 0x01, 0x60, 0x01, - I2C0, 0x40, 0x02, 0x05, 0x0f, /* exposure */ - I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */ - I2C0, 0x40, 0x07, 0x09, 0x0b, 0x0f, 0x05, 0x05, 0x0f, 0x00, - /* gains */ - I2C0, 0x40, 0x03, 0x12, 0x04, 0x01, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7, - 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7, - 0xf9, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x13, 0x13, - 0x10, 0x03, 0x01, 0x06, - 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7, - 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7, - 0xf9, - 0x10, 0x0b, 0x01, 0x11, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x14, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x05, 0x01, 0x61, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* nw802 - Conceptronic Video Pro */ -static const u8 cvideopro_start[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4, - 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54, - 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, - 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30, - 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f, - 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c, - 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0, - 0x40, - 0x10, 0x1a, 0x01, 0x03, - 0x10, 0x00, 0x01, 0xac, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x3b, 0x01, - 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00, - 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x1d, 0x02, 0x40, 0x06, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0, - 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc, - 0xdc, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x12, 0x12, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0, - 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc, - 0xdc, - 0x10, 0x0b, 0x01, 0x09, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x2f, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* nw802 - D-link dru-350c cam */ -static const u8 dlink_start[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78, - 0x40, - 0x10, 0x1a, 0x01, 0x00, - 0x10, 0x00, 0x01, 0xad, - 0x00, 0x00, 0x01, 0x08, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00, - 0x10, 0x1d, 0x08, 0x40, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x0e, 0x01, 0x20, - 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f, - 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf, - 0xea, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x11, 0x11, - 0x10, 0x03, 0x01, 0x10, - 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f, - 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf, - 0xea, - 0x10, 0x0b, 0x01, 0x19, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1e, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* 06a5:d001 - nw801 - Sony - * Plustek Opticam 500U or ProLink DS3303u (Hitachi HD49322BF) */ -/*fixme: 320x240 only*/ -static const u8 ds3303_start[] = { - 0x05, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x16, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e, - 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa9, 0xa8, 0x1f, 0x00, - 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00, - 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00, - 0x36, 0x00, - 0x02, 0x00, 0x12, 0x03, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0x50, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x2f, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a, - 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4, - 0x00, 0x01, 0x15, 0xfd, 0x07, 0x3d, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x8c, 0x04, 0x01, 0x20, - 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7, - 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80, - 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f, 0x88, - 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4, 0xcb, - 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, - 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, - 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f, 0x01, - 0x00, 0x00, 0xef, 0x00, 0x02, 0x0a, 0x82, 0x02, - 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01, - 0xf0, 0x00, - - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x3f, 0x00, 0xf2, 0x8f, 0x81, - 0x40, - 0x10, 0x1a, 0x01, 0x15, - 0x10, 0x00, 0x01, 0x2f, - 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00, - 0x10, 0x26, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x24, 0x02, 0x40, 0x06, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6, - 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x16, 0x16, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6, - 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, - 0x10, 0x0b, 0x01, 0x26, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1c, - 0x05, 0x06, 0x01, 0x03, - 0x05, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* 06a5:d001 - nw802 - Panasonic - * GP-KR651US (Philips TDA8786) */ -static const u8 kr651_start_1[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x48, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4, - 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54, - 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, - 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30, - 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f, - 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x02, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c, - 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0, 0, 0 -}; -static const u8 kr651_start_qvga[] = { - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78, - 0x40, - 0x10, 0x1a, 0x01, 0x03, - 0x10, 0x00, 0x01, 0xac, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00, - 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00, - 0x10, 0x1d, 0x02, 0x28, 0x01, - 0, 0, 0 -}; -static const u8 kr651_start_vga[] = { - 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x30, 0x03, 0x01, 0x82, 0x82, 0x98, - 0x80, - 0x10, 0x1a, 0x01, 0x03, - 0x10, 0x00, 0x01, 0xa0, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01, - 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00, - 0x10, 0x1d, 0x02, 0x68, 0x00, -}; -static const u8 kr651_start_2[] = { - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8, - 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdc, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x0c, 0x0c, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8, - 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdc, - 0x10, 0x0b, 0x01, 0x10, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x2d, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* nw802 - iRez Kritter cam */ -static const u8 kritter_start[] = { - 0x04, 0x06, 0x01, 0x06, - 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0x94, 0x03, 0x18, 0x00, 0x48, - 0x0f, 0x1e, 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x0a, 0x01, 0x28, - 0x07, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54, - 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, - 0x00, 0x5d, 0x00, 0x0e, 0x00, 0x7e, 0x00, 0x30, - 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f, - 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0b, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x02, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c, - 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0, - 0x40, - 0x10, 0x1a, 0x01, 0x03, - 0x10, 0x00, 0x01, 0xaf, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x3b, 0x01, - 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00, - 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00, - 0x10, 0x1d, 0x02, 0x00, 0x00, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86, - 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4, - 0xcb, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x0d, 0x0d, - 0x10, 0x03, 0x01, 0x02, - 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86, - 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4, - 0xcb, - 0x10, 0x0b, 0x01, 0x17, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1e, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* nw802 - Mustek Wcam 300 mini */ -static const u8 mustek_start[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94, - 0x00, 0x10, 0x06, 0xfc, 0x05, 0x0c, 0x06, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78, - 0x40, - 0x10, 0x1a, 0x01, 0x00, - 0x10, 0x00, 0x01, 0xad, - 0x00, 0x00, 0x01, 0x08, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1d, 0x08, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x10, 0x0e, 0x01, 0x0f, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e, - 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9, - 0xff, - 0x10, 0x0f, 0x02, 0x11, 0x11, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e, - 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9, - 0xff, - 0x10, 0x0b, 0x01, 0x1c, - 0x10, 0x0d, 0x01, 0x1a, - 0x10, 0x0c, 0x01, 0x34, - 0x04, 0x05, 0x01, 0x61, - 0x04, 0x04, 0x01, 0x40, - 0x04, 0x06, 0x01, 0x03, - 0, 0, 0 -}; - -/* nw802 - Scope USB Microscope M2 (ProScope) (Hitachi HD49322BF) */ -static const u8 proscope_init[] = { - 0x04, 0x05, 0x01, 0x21, - 0x04, 0x04, 0x01, 0x01, - 0, 0, 0 -}; -static const u8 proscope_start_1[] = { - 0x04, 0x06, 0x01, 0x04, - 0x00, 0x00, 0x40, 0x10, 0x01, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x04, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x08, 0x00, 0x17, 0x00, 0xce, 0x00, 0xf4, - 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0xce, 0x00, 0xf8, 0x03, 0x3e, 0x00, 0x86, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0xb6, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xf6, 0x03, 0x34, 0x04, 0xf6, 0x03, 0x34, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xe8, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x1f, 0x0f, 0x08, 0x20, 0xa8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xad, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a, - 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x8c, 0x04, 0x01, - 0x20, 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f, - 0x88, 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4, - 0xcb, 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f, - 0x01, 0x00, 0x00, 0xef, 0x00, 0x09, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0, 0, 0 -}; -static const u8 proscope_start_qvga[] = { - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78, - 0x40, - 0x10, 0x1a, 0x01, 0x06, - 0x00, 0x03, 0x02, 0xf9, 0x02, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x0e, 0x01, 0x10, - 0, 0, 0 -}; -static const u8 proscope_start_vga[] = { - 0x00, 0x03, 0x02, 0xf9, 0x02, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01, - 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x16, 0x00, 0x00, 0x82, 0x84, 0x00, - 0x80, - 0x10, 0x1a, 0x01, 0x06, - 0x10, 0x00, 0x01, 0xa1, - 0x10, 0x1b, 0x02, 0x00, 0x00, - 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01, - 0x10, 0x0e, 0x01, 0x10, - 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae, - 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2, - 0xf9, - 0x10, 0x03, 0x01, 0x00, - 0, 0, 0 -}; -static const u8 proscope_start_2[] = { - 0x10, 0x0f, 0x02, 0x0c, 0x0c, - 0x10, 0x03, 0x01, 0x0c, - 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae, - 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2, - 0xf9, - 0x10, 0x0b, 0x01, 0x0b, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1b, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x05, 0x01, 0x21, - 0x04, 0x04, 0x01, 0x00, - 0, 0, 0 -}; - -/* nw800 - hv7121b? (seems pas106) - Divio Chicony TwinkleCam */ -static const u8 twinkle_start[] = { - 0x04, 0x06, 0x01, 0x44, - 0x04, 0x06, 0x01, 0x00, - 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f, - 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc, - 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86, - 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, - 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78, - 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46, - 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, - 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e, - 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03, - 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04, - 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00, - 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x10, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x00, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, - 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20, - 0x01, 0x60, 0x01, 0x00, 0x00, - - 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - 0x04, 0x04, 0x01, 0x10, - 0x04, 0x04, 0x01, 0x00, - 0x04, 0x05, 0x01, 0x61, - 0x04, 0x04, 0x01, 0x01, - I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0a, - I2C0, 0x40, 0x02, 0x11, 0x06, - I2C0, 0x40, 0x02, 0x14, 0x00, - I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */ - I2C0, 0x40, 0x02, 0x07, 0x01, - 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00, - 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65, - 0x40, - I2C0, 0x40, 0x02, 0x02, 0x0c, - I2C0, 0x40, 0x02, 0x13, 0x01, - 0x10, 0x00, 0x01, 0x01, - 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, - 0x20, 0x01, 0x60, 0x01, - I2C0, 0x40, 0x02, 0x05, 0x0f, - I2C0, 0x40, 0x02, 0x13, 0x01, - I2C0, 0x40, 0x08, 0x08, 0x04, 0x0b, 0x01, 0x01, 0x02, 0x00, 0x17, - I2C0, 0x40, 0x03, 0x12, 0x00, 0x01, - 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01, - I2C0, 0x40, 0x02, 0x12, 0x00, - I2C0, 0x40, 0x02, 0x0e, 0x00, - I2C0, 0x40, 0x02, 0x11, 0x06, - 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7, - 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7, - 0xf9, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x0c, 0x0c, - 0x10, 0x03, 0x01, 0x06, - 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7, - 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7, - 0xf9, - 0x10, 0x0b, 0x01, 0x19, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x0d, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x05, 0x01, 0x61, - 0x04, 0x04, 0x01, 0x41, - 0, 0, 0 -}; - -/* nw802 dvc-v6 */ -static const u8 dvcv6_start[] = { - 0x04, 0x06, 0x01, 0x06, - 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c, - 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19, - 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, - 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4, - 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54, - 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, - 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30, - 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f, - 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11, - 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94, - 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00, - 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0, - 0x40, 0x20, - 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x06, 0x00, 0x02, 0x09, 0x99, - 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c, - 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, - 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, - 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, - 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, - 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, - 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, - 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, - 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, - 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, - 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, - 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82, - 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, - 0x01, 0xf0, 0x00, - 0x00, 0x03, 0x02, 0x94, 0x03, - 0x00, 0x1d, 0x04, 0x0a, 0x01, 0x28, 0x07, - 0x00, 0x7b, 0x02, 0xe0, 0x00, - 0x10, 0x8d, 0x01, 0x00, - 0x00, 0x09, 0x04, 0x1e, 0x00, 0x0c, 0x02, - 0x00, 0x91, 0x02, 0x0b, 0x02, - 0x10, 0x00, 0x01, 0xaf, - 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8f, 0x3c, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0, - 0x40, - 0x10, 0x1a, 0x01, 0x02, - 0x10, 0x00, 0x01, 0xaf, - 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00, - 0x10, 0x1b, 0x02, 0x07, 0x01, - 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00, - 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00, - 0x10, 0x1d, 0x02, 0x40, 0x06, - 0x10, 0x0e, 0x01, 0x08, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa, - 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc, - 0xdc, - 0x10, 0x03, 0x01, 0x00, - 0x10, 0x0f, 0x02, 0x12, 0x12, - 0x10, 0x03, 0x01, 0x11, - 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa, - 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc, - 0xdc, - 0x10, 0x0b, 0x01, 0x16, - 0x10, 0x0d, 0x01, 0x10, - 0x10, 0x0c, 0x01, 0x1a, - 0x04, 0x06, 0x01, 0x03, - 0x04, 0x04, 0x01, 0x00, -}; - -static const u8 *webcam_start[] = { - [Generic800] = nw800_start, - [SpaceCam] = spacecam_start, - [SpaceCam2] = spacecam2_start, - [Cvideopro] = cvideopro_start, - [Dlink350c] = dlink_start, - [DS3303u] = ds3303_start, - [Kr651us] = kr651_start_1, - [Kritter] = kritter_start, - [Mustek300] = mustek_start, - [Proscope] = proscope_start_1, - [Twinkle] = twinkle_start, - [DvcV6] = dvcv6_start, - [P35u] = nw801_start_1, - [Generic802] = nw802_start, -}; - -/* -- write a register -- */ -static void reg_w(struct gspca_dev *gspca_dev, - u16 index, - const u8 *data, - int len) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - if (len == 1) - PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data); - else - PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...", - index, *data, data[1]); - memcpy(gspca_dev->usb_buf, data, len); - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x00, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, /* value */ - index, - gspca_dev->usb_buf, - len, - 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* -- read registers in usb_buf -- */ -static void reg_r(struct gspca_dev *gspca_dev, - u16 index, - int len) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x00, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, index, - gspca_dev->usb_buf, len, 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - return; - } - if (len == 1) - PDEBUG(D_USBI, "GET 00 0000 %04x %02x", - index, gspca_dev->usb_buf[0]); - else - PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..", - index, gspca_dev->usb_buf[0], - gspca_dev->usb_buf[1]); -} - -static void i2c_w(struct gspca_dev *gspca_dev, - u8 i2c_addr, - const u8 *data, - int len) -{ - u8 val[2]; - int i; - - reg_w(gspca_dev, 0x0600, data + 1, len - 1); - reg_w(gspca_dev, 0x0600, data, len); - val[0] = len; - val[1] = i2c_addr; - reg_w(gspca_dev, 0x0502, val, 2); - val[0] = 0x01; - reg_w(gspca_dev, 0x0501, val, 1); - for (i = 5; --i >= 0; ) { - msleep(4); - reg_r(gspca_dev, 0x0505, 1); - if (gspca_dev->usb_err < 0) - return; - if (gspca_dev->usb_buf[0] == 0) - return; - } - gspca_dev->usb_err = -ETIME; -} - -static void reg_w_buf(struct gspca_dev *gspca_dev, - const u8 *cmd) -{ - u16 reg; - int len; - - for (;;) { - reg = *cmd++ << 8; - reg += *cmd++; - len = *cmd++; - if (len == 0) - break; - if (cmd[-3] != I2C0) - reg_w(gspca_dev, reg, cmd, len); - else - i2c_w(gspca_dev, reg, cmd, len); - cmd += len; - } -} - -static int swap_bits(int v) -{ - int r, i; - - r = 0; - for (i = 0; i < 8; i++) { - r <<= 1; - if (v & 1) - r++; - v >>= 1; - } - return r; -} - -static void setgain(struct gspca_dev *gspca_dev, u8 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 v[2]; - - switch (sd->webcam) { - case P35u: - reg_w(gspca_dev, 0x1026, &val, 1); - break; - case Kr651us: - /* 0 - 253 */ - val = swap_bits(val); - v[0] = val << 3; - v[1] = val >> 5; - reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */ - break; - } -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 v[2]; - - switch (sd->webcam) { - case P35u: - v[0] = ((9 - val) << 3) | 0x01; - reg_w(gspca_dev, 0x1019, v, 1); - break; - case Cvideopro: - case DvcV6: - case Kritter: - case Kr651us: - v[0] = val; - v[1] = val >> 8; - reg_w(gspca_dev, 0x101b, v, 2); - break; - } -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int w, h; - - if (!val) { - sd->ag_cnt = -1; - return; - } - sd->ag_cnt = AG_CNT_START; - - reg_r(gspca_dev, 0x1004, 1); - if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */ - sd->ae_res = gspca_dev->width * gspca_dev->height; - } else { /* get the AE window size */ - reg_r(gspca_dev, 0x1011, 8); - w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0] - - (gspca_dev->usb_buf[3] << 8) - gspca_dev->usb_buf[2]; - h = (gspca_dev->usb_buf[5] << 8) + gspca_dev->usb_buf[4] - - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6]; - sd->ae_res = h * w; - if (sd->ae_res == 0) - sd->ae_res = gspca_dev->width * gspca_dev->height; - } -} - -static int nw802_test_reg(struct gspca_dev *gspca_dev, - u16 index, - u8 value) -{ - /* write the value */ - reg_w(gspca_dev, index, &value, 1); - - /* read it */ - reg_r(gspca_dev, index, 1); - - return gspca_dev->usb_buf[0] == value; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if ((unsigned) webcam >= NWEBCAMS) - webcam = 0; - sd->webcam = webcam; - gspca_dev->cam.needs_full_bandwidth = 1; - sd->ag_cnt = -1; - - /* - * Autodetect sequence inspired from some log. - * We try to detect what registers exist or not. - * If 0x0500 does not exist => NW802 - * If it does, test 0x109b. If it doesn't exist, - * then it's a NW801. Else, a NW800 - * If a et31x110 (nw800 and 06a5:d800) - * get the sensor ID - */ - if (!nw802_test_reg(gspca_dev, 0x0500, 0x55)) { - sd->bridge = BRIDGE_NW802; - if (sd->webcam == Generic800) - sd->webcam = Generic802; - } else if (!nw802_test_reg(gspca_dev, 0x109b, 0xaa)) { - sd->bridge = BRIDGE_NW801; - if (sd->webcam == Generic800) - sd->webcam = P35u; - } else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) { - reg_r(gspca_dev, 0x0403, 1); /* GPIO */ - PDEBUG(D_PROBE, "et31x110 sensor type %02x", - gspca_dev->usb_buf[0]); - switch (gspca_dev->usb_buf[0] >> 1) { - case 0x00: /* ?? */ - if (sd->webcam == Generic800) - sd->webcam = SpaceCam; - break; - case 0x01: /* Hynix? */ - if (sd->webcam == Generic800) - sd->webcam = Twinkle; - break; - case 0x0a: /* Pixart */ - if (sd->webcam == Generic800) - sd->webcam = SpaceCam2; - break; - } - } - if (webcam_chip[sd->webcam] != sd->bridge) { - pr_err("Bad webcam type %d for NW80%d\n", - sd->webcam, sd->bridge); - gspca_dev->usb_err = -ENODEV; - return gspca_dev->usb_err; - } - PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam); - - if (sd->bridge == BRIDGE_NW800) { - switch (sd->webcam) { - case DS3303u: - gspca_dev->cam.cam_mode = cif_mode; /* qvga */ - break; - default: - gspca_dev->cam.cam_mode = &cif_mode[1]; /* cif */ - break; - } - gspca_dev->cam.nmodes = 1; - } else { - gspca_dev->cam.cam_mode = vga_mode; - switch (sd->webcam) { - case Kr651us: - case Proscope: - case P35u: - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - break; - default: - gspca_dev->cam.nmodes = 1; /* qvga only */ - break; - } - } - - return gspca_dev->usb_err; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - case BRIDGE_NW800: - switch (sd->webcam) { - case SpaceCam: - reg_w_buf(gspca_dev, spacecam_init); - break; - default: - reg_w_buf(gspca_dev, nw800_init); - break; - } - break; - default: - switch (sd->webcam) { - case Mustek300: - case P35u: - case Proscope: - reg_w_buf(gspca_dev, proscope_init); - break; - } - break; - } - return gspca_dev->usb_err; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - const u8 *cmd; - - cmd = webcam_start[sd->webcam]; - reg_w_buf(gspca_dev, cmd); - switch (sd->webcam) { - case P35u: - if (gspca_dev->width == 320) - reg_w_buf(gspca_dev, nw801_start_qvga); - else - reg_w_buf(gspca_dev, nw801_start_vga); - reg_w_buf(gspca_dev, nw801_start_2); - break; - case Kr651us: - if (gspca_dev->width == 320) - reg_w_buf(gspca_dev, kr651_start_qvga); - else - reg_w_buf(gspca_dev, kr651_start_vga); - reg_w_buf(gspca_dev, kr651_start_2); - break; - case Proscope: - if (gspca_dev->width == 320) - reg_w_buf(gspca_dev, proscope_start_qvga); - else - reg_w_buf(gspca_dev, proscope_start_vga); - reg_w_buf(gspca_dev, proscope_start_2); - break; - } - - sd->exp_too_high_cnt = 0; - sd->exp_too_low_cnt = 0; - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 value; - - /* 'go' off */ - if (sd->bridge != BRIDGE_NW801) { - value = 0x02; - reg_w(gspca_dev, 0x0406, &value, 1); - } - - /* LED off */ - switch (sd->webcam) { - case Cvideopro: - case Kr651us: - case DvcV6: - case Kritter: - value = 0xff; - break; - case Dlink350c: - value = 0x21; - break; - case SpaceCam: - case SpaceCam2: - case Proscope: - case Twinkle: - value = 0x01; - break; - default: - return; - } - reg_w(gspca_dev, 0x0404, &value, 1); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - /* - * frame header = '00 00 hh ww ss xx ff ff' - * with: - * - 'hh': height / 4 - * - 'ww': width / 4 - * - 'ss': frame sequence number c0..dd - */ - if (data[0] == 0x00 && data[1] == 0x00 - && data[6] == 0xff && data[7] == 0xff) { - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, data + 8, len - 8); - } else { - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - } -} - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int luma; - - if (sd->ag_cnt < 0) - return; - if (--sd->ag_cnt >= 0) - return; - sd->ag_cnt = AG_CNT_START; - - /* get the average luma */ - reg_r(gspca_dev, sd->bridge == BRIDGE_NW801 ? 0x080d : 0x080c, 4); - luma = (gspca_dev->usb_buf[3] << 24) + (gspca_dev->usb_buf[2] << 16) - + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; - luma /= sd->ae_res; - - switch (sd->webcam) { - case P35u: - gspca_coarse_grained_expo_autogain(gspca_dev, luma, 100, 5); - break; - default: - gspca_expo_autogain(gspca_dev, luma, 100, 5, 230, 0); - break; - } -} - - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - /* autogain/gain/exposure control cluster */ - case V4L2_CID_AUTOGAIN: - if (ctrl->is_new) - setautogain(gspca_dev, ctrl->val); - if (!ctrl->val) { - if (gspca_dev->gain->is_new) - setgain(gspca_dev, gspca_dev->gain->val); - if (gspca_dev->exposure->is_new) - setexposure(gspca_dev, - gspca_dev->exposure->val); - } - break; - /* Some webcams only have exposure, so handle that separately from the - autogain/gain/exposure cluster in the previous case. */ - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, gspca_dev->exposure->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 3); - switch (sd->webcam) { - case P35u: - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - /* For P35u choose coarse expo auto gain function gain minimum, - * to avoid a large settings jump the first auto adjustment */ - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 127, 1, 127 / 5 * 2); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 9, 1, 9); - break; - case Kr651us: - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 253, 1, 128); - /* fall through */ - case Cvideopro: - case DvcV6: - case Kritter: - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 315, 1, 150); - break; - default: - break; - } - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (gspca_dev->autogain) - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0xd001)}, - {USB_DEVICE(0x0502, 0xd001)}, - {USB_DEVICE(0x052b, 0xd001)}, - {USB_DEVICE(0x055f, 0xd001)}, - {USB_DEVICE(0x06a5, 0x0000)}, - {USB_DEVICE(0x06a5, 0xd001)}, - {USB_DEVICE(0x06a5, 0xd800)}, - {USB_DEVICE(0x06be, 0xd001)}, - {USB_DEVICE(0x0728, 0xd001)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(webcam, int, 0644); -MODULE_PARM_DESC(webcam, - "Webcam type\n" - "0: generic\n" - "1: Trust 120 SpaceCam\n" - "2: other Trust 120 SpaceCam\n" - "3: Conceptronic Video Pro\n" - "4: D-link dru-350c\n" - "5: Plustek Opticam 500U\n" - "6: Panasonic GP-KR651US\n" - "7: iRez Kritter\n" - "8: Mustek Wcam 300 mini\n" - "9: Scalar USB Microscope M2 (Proscope)\n" - "10: Divio Chicony TwinkleCam\n" - "11: DVC-V6\n"); diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c deleted file mode 100644 index bfc7cefa59f8..000000000000 --- a/drivers/media/video/gspca/ov519.c +++ /dev/null @@ -1,4991 +0,0 @@ -/** - * OV519 driver - * - * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr> - * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> - * - * This module is adapted from the ov51x-jpeg package, which itself - * was adapted from the ov511 driver. - * - * Original copyright for the ov511 driver is: - * - * Copyright (c) 1999-2006 Mark W. McClelland - * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach - * Many improvements by Bret Wallach <bwallac1@san.rr.com> - * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000) - * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org> - * Changes by Claudio Matsuoka <claudio@conectiva.com> - * - * ov51x-jpeg original copyright is: - * - * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org> - * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "ov519" - -#include <linux/input.h> -#include "gspca.h" - -/* The jpeg_hdr is used by w996Xcf only */ -/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */ -#define CONEX_CAM -#include "jpeg.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("OV519 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* global parameters */ -static int frame_rate; - -/* Number of times to retry a failed I2C transaction. Increase this if you - * are getting "Failed to read sensor ID..." */ -static int i2c_detect_tries = 10; - -/* ov519 device descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl *jpegqual; - struct v4l2_ctrl *freq; - struct { /* h/vflip control cluster */ - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - }; - struct { /* autobrightness/brightness control cluster */ - struct v4l2_ctrl *autobright; - struct v4l2_ctrl *brightness; - }; - - u8 packet_nr; - - char bridge; -#define BRIDGE_OV511 0 -#define BRIDGE_OV511PLUS 1 -#define BRIDGE_OV518 2 -#define BRIDGE_OV518PLUS 3 -#define BRIDGE_OV519 4 /* = ov530 */ -#define BRIDGE_OVFX2 5 -#define BRIDGE_W9968CF 6 -#define BRIDGE_MASK 7 - - char invert_led; -#define BRIDGE_INVERT_LED 8 - - char snapshot_pressed; - char snapshot_needs_reset; - - /* Determined by sensor type */ - u8 sif; - -#define QUALITY_MIN 50 -#define QUALITY_MAX 70 -#define QUALITY_DEF 50 - - u8 stopped; /* Streaming is temporarily paused */ - u8 first_frame; - - u8 frame_rate; /* current Framerate */ - u8 clockdiv; /* clockdiv override */ - - s8 sensor; /* Type of image sensor chip (SEN_*) */ - - u8 sensor_addr; - u16 sensor_width; - u16 sensor_height; - s16 sensor_reg_cache[256]; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; -enum sensors { - SEN_OV2610, - SEN_OV2610AE, - SEN_OV3610, - SEN_OV6620, - SEN_OV6630, - SEN_OV66308AF, - SEN_OV7610, - SEN_OV7620, - SEN_OV7620AE, - SEN_OV7640, - SEN_OV7648, - SEN_OV7660, - SEN_OV7670, - SEN_OV76BE, - SEN_OV8610, - SEN_OV9600, -}; - -/* Note this is a bit of a hack, but the w9968cf driver needs the code for all - the ov sensors which is already present here. When we have the time we - really should move the sensor drivers to v4l2 sub drivers. */ -#include "w996Xcf.c" - -/* table of the disabled controls */ -struct ctrl_valid { - int has_brightness:1; - int has_contrast:1; - int has_exposure:1; - int has_autogain:1; - int has_sat:1; - int has_hvflip:1; - int has_autobright:1; - int has_freq:1; -}; - -static const struct ctrl_valid valid_controls[] = { - [SEN_OV2610] = { - .has_exposure = 1, - .has_autogain = 1, - }, - [SEN_OV2610AE] = { - .has_exposure = 1, - .has_autogain = 1, - }, - [SEN_OV3610] = { - /* No controls */ - }, - [SEN_OV6620] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV6630] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV66308AF] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV7610] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV7620] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV7620AE] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV7640] = { - .has_brightness = 1, - .has_sat = 1, - .has_freq = 1, - }, - [SEN_OV7648] = { - .has_brightness = 1, - .has_sat = 1, - .has_freq = 1, - }, - [SEN_OV7660] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_hvflip = 1, - .has_freq = 1, - }, - [SEN_OV7670] = { - .has_brightness = 1, - .has_contrast = 1, - .has_hvflip = 1, - .has_freq = 1, - }, - [SEN_OV76BE] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - .has_freq = 1, - }, - [SEN_OV8610] = { - .has_brightness = 1, - .has_contrast = 1, - .has_sat = 1, - .has_autobright = 1, - }, - [SEN_OV9600] = { - .has_exposure = 1, - .has_autogain = 1, - }, -}; - -static const struct v4l2_pix_format ov519_vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; -static const struct v4l2_pix_format ov519_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* Note some of the sizeimage values for the ov511 / ov518 may seem - larger then necessary, however they need to be this big as the ov511 / - ov518 always fills the entire isoc frame, using 0 padding bytes when - it doesn't have any data. So with low framerates the amount of data - transferred can become quite large (libv4l will remove all the 0 padding - in userspace). */ -static const struct v4l2_pix_format ov518_vga_mode[] = { - {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; -static const struct v4l2_pix_format ov518_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const struct v4l2_pix_format ov511_vga_mode[] = { - {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; -static const struct v4l2_pix_format ov511_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const struct v4l2_pix_format ovfx2_vga_mode[] = { - {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format ovfx2_cif_mode[] = { - {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { - {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1600, - .sizeimage = 1600 * 1200, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; -static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1024, - .sizeimage = 1024 * 768, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1600, - .sizeimage = 1600 * 1200, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 2048, - .sizeimage = 2048 * 1536, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format ovfx2_ov9600_mode[] = { - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; - -/* Registers common to OV511 / OV518 */ -#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ -#define R51x_SYS_RESET 0x50 - /* Reset type flags */ - #define OV511_RESET_OMNICE 0x08 -#define R51x_SYS_INIT 0x53 -#define R51x_SYS_SNAP 0x52 -#define R51x_SYS_CUST_ID 0x5f -#define R51x_COMP_LUT_BEGIN 0x80 - -/* OV511 Camera interface register numbers */ -#define R511_CAM_DELAY 0x10 -#define R511_CAM_EDGE 0x11 -#define R511_CAM_PXCNT 0x12 -#define R511_CAM_LNCNT 0x13 -#define R511_CAM_PXDIV 0x14 -#define R511_CAM_LNDIV 0x15 -#define R511_CAM_UV_EN 0x16 -#define R511_CAM_LINE_MODE 0x17 -#define R511_CAM_OPTS 0x18 - -#define R511_SNAP_FRAME 0x19 -#define R511_SNAP_PXCNT 0x1a -#define R511_SNAP_LNCNT 0x1b -#define R511_SNAP_PXDIV 0x1c -#define R511_SNAP_LNDIV 0x1d -#define R511_SNAP_UV_EN 0x1e -#define R511_SNAP_OPTS 0x1f - -#define R511_DRAM_FLOW_CTL 0x20 -#define R511_FIFO_OPTS 0x31 -#define R511_I2C_CTL 0x40 -#define R511_SYS_LED_CTL 0x55 /* OV511+ only */ -#define R511_COMP_EN 0x78 -#define R511_COMP_LUT_EN 0x79 - -/* OV518 Camera interface register numbers */ -#define R518_GPIO_OUT 0x56 /* OV518(+) only */ -#define R518_GPIO_CTL 0x57 /* OV518(+) only */ - -/* OV519 Camera interface register numbers */ -#define OV519_R10_H_SIZE 0x10 -#define OV519_R11_V_SIZE 0x11 -#define OV519_R12_X_OFFSETL 0x12 -#define OV519_R13_X_OFFSETH 0x13 -#define OV519_R14_Y_OFFSETL 0x14 -#define OV519_R15_Y_OFFSETH 0x15 -#define OV519_R16_DIVIDER 0x16 -#define OV519_R20_DFR 0x20 -#define OV519_R25_FORMAT 0x25 - -/* OV519 System Controller register numbers */ -#define OV519_R51_RESET1 0x51 -#define OV519_R54_EN_CLK1 0x54 -#define OV519_R57_SNAPSHOT 0x57 - -#define OV519_GPIO_DATA_OUT0 0x71 -#define OV519_GPIO_IO_CTRL0 0x72 - -/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */ - -/* - * The FX2 chip does not give us a zero length read at end of frame. - * It does, however, give a short read at the end of a frame, if - * necessary, rather than run two frames together. - * - * By choosing the right bulk transfer size, we are guaranteed to always - * get a short read for the last read of each frame. Frame sizes are - * always a composite number (width * height, or a multiple) so if we - * choose a prime number, we are guaranteed that the last read of a - * frame will be short. - * - * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB, - * otherwise EOVERFLOW "babbling" errors occur. I have not been able - * to figure out why. [PMiller] - * - * The constant (13 * 4096) is the largest "prime enough" number less than 64KB. - * - * It isn't enough to know the number of bytes per frame, in case we - * have data dropouts or buffer overruns (even though the FX2 double - * buffers, there are some pretty strict real time constraints for - * isochronous transfer for larger frame sizes). - */ -/*jfm: this value does not work for 800x600 - see isoc_init */ -#define OVFX2_BULK_SIZE (13 * 4096) - -/* I2C registers */ -#define R51x_I2C_W_SID 0x41 -#define R51x_I2C_SADDR_3 0x42 -#define R51x_I2C_SADDR_2 0x43 -#define R51x_I2C_R_SID 0x44 -#define R51x_I2C_DATA 0x45 -#define R518_I2C_CTL 0x47 /* OV518(+) only */ -#define OVFX2_I2C_ADDR 0x00 - -/* I2C ADDRESSES */ -#define OV7xx0_SID 0x42 -#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */ -#define OV8xx0_SID 0xa0 -#define OV6xx0_SID 0xc0 - -/* OV7610 registers */ -#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ -#define OV7610_REG_BLUE 0x01 /* blue channel balance */ -#define OV7610_REG_RED 0x02 /* red channel balance */ -#define OV7610_REG_SAT 0x03 /* saturation */ -#define OV8610_REG_HUE 0x04 /* 04 reserved */ -#define OV7610_REG_CNT 0x05 /* Y contrast */ -#define OV7610_REG_BRT 0x06 /* Y brightness */ -#define OV7610_REG_COM_C 0x14 /* misc common regs */ -#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */ -#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ -#define OV7610_REG_COM_I 0x29 /* misc settings */ - -/* OV7660 and OV7670 registers */ -#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ -#define OV7670_R01_BLUE 0x01 /* blue gain */ -#define OV7670_R02_RED 0x02 /* red gain */ -#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ -#define OV7670_R04_COM1 0x04 /* Control 1 */ -/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */ -#define OV7670_R0C_COM3 0x0c /* Control 3 */ -#define OV7670_R0D_COM4 0x0d /* Control 4 */ -#define OV7670_R0E_COM5 0x0e /* All "reserved" */ -#define OV7670_R0F_COM6 0x0f /* Control 6 */ -#define OV7670_R10_AECH 0x10 /* More bits of AEC value */ -#define OV7670_R11_CLKRC 0x11 /* Clock control */ -#define OV7670_R12_COM7 0x12 /* Control 7 */ -#define OV7670_COM7_FMT_VGA 0x00 -/*#define OV7670_COM7_YUV 0x00 * YUV */ -#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ -#define OV7670_COM7_FMT_MASK 0x38 -#define OV7670_COM7_RESET 0x80 /* Register reset */ -#define OV7670_R13_COM8 0x13 /* Control 8 */ -#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ -#define OV7670_COM8_AWB 0x02 /* White balance enable */ -#define OV7670_COM8_AGC 0x04 /* Auto gain enable */ -#define OV7670_COM8_BFILT 0x20 /* Band filter enable */ -#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ -#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ -#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */ -#define OV7670_R15_COM10 0x15 /* Control 10 */ -#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */ -#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */ -#define OV7670_R19_VSTART 0x19 /* Vert start high bits */ -#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */ -#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */ -#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ -#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ -#define OV7670_R24_AEW 0x24 /* AGC upper limit */ -#define OV7670_R25_AEB 0x25 /* AGC lower limit */ -#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */ -#define OV7670_R32_HREF 0x32 /* HREF pieces */ -#define OV7670_R3A_TSLB 0x3a /* lots of stuff */ -#define OV7670_R3B_COM11 0x3b /* Control 11 */ -#define OV7670_COM11_EXP 0x02 -#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ -#define OV7670_R3C_COM12 0x3c /* Control 12 */ -#define OV7670_R3D_COM13 0x3d /* Control 13 */ -#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ -#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ -#define OV7670_R3E_COM14 0x3e /* Control 14 */ -#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */ -#define OV7670_R40_COM15 0x40 /* Control 15 */ -/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */ -#define OV7670_R41_COM16 0x41 /* Control 16 */ -#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ -/* end of ov7660 common registers */ -#define OV7670_R55_BRIGHT 0x55 /* Brightness */ -#define OV7670_R56_CONTRAS 0x56 /* Contrast control */ -#define OV7670_R69_GFIX 0x69 /* Fix gain control */ -/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */ -#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */ -#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ -#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */ -#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ -#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ -#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ -#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ -#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */ -#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */ - -struct ov_regvals { - u8 reg; - u8 val; -}; -struct ov_i2c_regvals { - u8 reg; - u8 val; -}; - -/* Settings for OV2610 camera chip */ -static const struct ov_i2c_regvals norm_2610[] = { - { 0x12, 0x80 }, /* reset */ -}; - -static const struct ov_i2c_regvals norm_2610ae[] = { - {0x12, 0x80}, /* reset */ - {0x13, 0xcd}, - {0x09, 0x01}, - {0x0d, 0x00}, - {0x11, 0x80}, - {0x12, 0x20}, /* 1600x1200 */ - {0x33, 0x0c}, - {0x35, 0x90}, - {0x36, 0x37}, -/* ms-win traces */ - {0x11, 0x83}, /* clock / 3 ? */ - {0x2d, 0x00}, /* 60 Hz filter */ - {0x24, 0xb0}, /* normal colors */ - {0x25, 0x90}, - {0x10, 0x43}, -}; - -static const struct ov_i2c_regvals norm_3620b[] = { - /* - * From the datasheet: "Note that after writing to register COMH - * (0x12) to change the sensor mode, registers related to the - * sensor’s cropping window will be reset back to their default - * values." - * - * "wait 4096 external clock ... to make sure the sensor is - * stable and ready to access registers" i.e. 160us at 24MHz - */ - { 0x12, 0x80 }, /* COMH reset */ - { 0x12, 0x00 }, /* QXGA, master */ - - /* - * 11 CLKRC "Clock Rate Control" - * [7] internal frequency doublers: on - * [6] video port mode: master - * [5:0] clock divider: 1 - */ - { 0x11, 0x80 }, - - /* - * 13 COMI "Common Control I" - * = 192 (0xC0) 11000000 - * COMI[7] "AEC speed selection" - * = 1 (0x01) 1....... "Faster AEC correction" - * COMI[6] "AEC speed step selection" - * = 1 (0x01) .1...... "Big steps, fast" - * COMI[5] "Banding filter on off" - * = 0 (0x00) ..0..... "Off" - * COMI[4] "Banding filter option" - * = 0 (0x00) ...0.... "Main clock is 48 MHz and - * the PLL is ON" - * COMI[3] "Reserved" - * = 0 (0x00) ....0... - * COMI[2] "AGC auto manual control selection" - * = 0 (0x00) .....0.. "Manual" - * COMI[1] "AWB auto manual control selection" - * = 0 (0x00) ......0. "Manual" - * COMI[0] "Exposure control" - * = 0 (0x00) .......0 "Manual" - */ - { 0x13, 0xc0 }, - - /* - * 09 COMC "Common Control C" - * = 8 (0x08) 00001000 - * COMC[7:5] "Reserved" - * = 0 (0x00) 000..... - * COMC[4] "Sleep Mode Enable" - * = 0 (0x00) ...0.... "Normal mode" - * COMC[3:2] "Sensor sampling reset timing selection" - * = 2 (0x02) ....10.. "Longer reset time" - * COMC[1:0] "Output drive current select" - * = 0 (0x00) ......00 "Weakest" - */ - { 0x09, 0x08 }, - - /* - * 0C COMD "Common Control D" - * = 8 (0x08) 00001000 - * COMD[7] "Reserved" - * = 0 (0x00) 0....... - * COMD[6] "Swap MSB and LSB at the output port" - * = 0 (0x00) .0...... "False" - * COMD[5:3] "Reserved" - * = 1 (0x01) ..001... - * COMD[2] "Output Average On Off" - * = 0 (0x00) .....0.. "Output Normal" - * COMD[1] "Sensor precharge voltage selection" - * = 0 (0x00) ......0. "Selects internal - * reference precharge - * voltage" - * COMD[0] "Snapshot option" - * = 0 (0x00) .......0 "Enable live video output - * after snapshot sequence" - */ - { 0x0c, 0x08 }, - - /* - * 0D COME "Common Control E" - * = 161 (0xA1) 10100001 - * COME[7] "Output average option" - * = 1 (0x01) 1....... "Output average of 4 pixels" - * COME[6] "Anti-blooming control" - * = 0 (0x00) .0...... "Off" - * COME[5:3] "Reserved" - * = 4 (0x04) ..100... - * COME[2] "Clock output power down pin status" - * = 0 (0x00) .....0.. "Tri-state data output pin - * on power down" - * COME[1] "Data output pin status selection at power down" - * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK, - * HREF, and CHSYNC pins on - * power down" - * COME[0] "Auto zero circuit select" - * = 1 (0x01) .......1 "On" - */ - { 0x0d, 0xa1 }, - - /* - * 0E COMF "Common Control F" - * = 112 (0x70) 01110000 - * COMF[7] "System clock selection" - * = 0 (0x00) 0....... "Use 24 MHz system clock" - * COMF[6:4] "Reserved" - * = 7 (0x07) .111.... - * COMF[3] "Manual auto negative offset canceling selection" - * = 0 (0x00) ....0... "Auto detect negative - * offset and cancel it" - * COMF[2:0] "Reserved" - * = 0 (0x00) .....000 - */ - { 0x0e, 0x70 }, - - /* - * 0F COMG "Common Control G" - * = 66 (0x42) 01000010 - * COMG[7] "Optical black output selection" - * = 0 (0x00) 0....... "Disable" - * COMG[6] "Black level calibrate selection" - * = 1 (0x01) .1...... "Use optical black pixels - * to calibrate" - * COMG[5:4] "Reserved" - * = 0 (0x00) ..00.... - * COMG[3] "Channel offset adjustment" - * = 0 (0x00) ....0... "Disable offset adjustment" - * COMG[2] "ADC black level calibration option" - * = 0 (0x00) .....0.. "Use B/G line and G/R - * line to calibrate each - * channel's black level" - * COMG[1] "Reserved" - * = 1 (0x01) ......1. - * COMG[0] "ADC black level calibration enable" - * = 0 (0x00) .......0 "Disable" - */ - { 0x0f, 0x42 }, - - /* - * 14 COMJ "Common Control J" - * = 198 (0xC6) 11000110 - * COMJ[7:6] "AGC gain ceiling" - * = 3 (0x03) 11...... "8x" - * COMJ[5:4] "Reserved" - * = 0 (0x00) ..00.... - * COMJ[3] "Auto banding filter" - * = 0 (0x00) ....0... "Banding filter is always - * on off depending on - * COMI[5] setting" - * COMJ[2] "VSYNC drop option" - * = 1 (0x01) .....1.. "SYNC is dropped if frame - * data is dropped" - * COMJ[1] "Frame data drop" - * = 1 (0x01) ......1. "Drop frame data if - * exposure is not within - * tolerance. In AEC mode, - * data is normally dropped - * when data is out of - * range." - * COMJ[0] "Reserved" - * = 0 (0x00) .......0 - */ - { 0x14, 0xc6 }, - - /* - * 15 COMK "Common Control K" - * = 2 (0x02) 00000010 - * COMK[7] "CHSYNC pin output swap" - * = 0 (0x00) 0....... "CHSYNC" - * COMK[6] "HREF pin output swap" - * = 0 (0x00) .0...... "HREF" - * COMK[5] "PCLK output selection" - * = 0 (0x00) ..0..... "PCLK always output" - * COMK[4] "PCLK edge selection" - * = 0 (0x00) ...0.... "Data valid on falling edge" - * COMK[3] "HREF output polarity" - * = 0 (0x00) ....0... "positive" - * COMK[2] "Reserved" - * = 0 (0x00) .....0.. - * COMK[1] "VSYNC polarity" - * = 1 (0x01) ......1. "negative" - * COMK[0] "HSYNC polarity" - * = 0 (0x00) .......0 "positive" - */ - { 0x15, 0x02 }, - - /* - * 33 CHLF "Current Control" - * = 9 (0x09) 00001001 - * CHLF[7:6] "Sensor current control" - * = 0 (0x00) 00...... - * CHLF[5] "Sensor current range control" - * = 0 (0x00) ..0..... "normal range" - * CHLF[4] "Sensor current" - * = 0 (0x00) ...0.... "normal current" - * CHLF[3] "Sensor buffer current control" - * = 1 (0x01) ....1... "half current" - * CHLF[2] "Column buffer current control" - * = 0 (0x00) .....0.. "normal current" - * CHLF[1] "Analog DSP current control" - * = 0 (0x00) ......0. "normal current" - * CHLF[1] "ADC current control" - * = 0 (0x00) ......0. "normal current" - */ - { 0x33, 0x09 }, - - /* - * 34 VBLM "Blooming Control" - * = 80 (0x50) 01010000 - * VBLM[7] "Hard soft reset switch" - * = 0 (0x00) 0....... "Hard reset" - * VBLM[6:4] "Blooming voltage selection" - * = 5 (0x05) .101.... - * VBLM[3:0] "Sensor current control" - * = 0 (0x00) ....0000 - */ - { 0x34, 0x50 }, - - /* - * 36 VCHG "Sensor Precharge Voltage Control" - * = 0 (0x00) 00000000 - * VCHG[7] "Reserved" - * = 0 (0x00) 0....... - * VCHG[6:4] "Sensor precharge voltage control" - * = 0 (0x00) .000.... - * VCHG[3:0] "Sensor array common reference" - * = 0 (0x00) ....0000 - */ - { 0x36, 0x00 }, - - /* - * 37 ADC "ADC Reference Control" - * = 4 (0x04) 00000100 - * ADC[7:4] "Reserved" - * = 0 (0x00) 0000.... - * ADC[3] "ADC input signal range" - * = 0 (0x00) ....0... "Input signal 1.0x" - * ADC[2:0] "ADC range control" - * = 4 (0x04) .....100 - */ - { 0x37, 0x04 }, - - /* - * 38 ACOM "Analog Common Ground" - * = 82 (0x52) 01010010 - * ACOM[7] "Analog gain control" - * = 0 (0x00) 0....... "Gain 1x" - * ACOM[6] "Analog black level calibration" - * = 1 (0x01) .1...... "On" - * ACOM[5:0] "Reserved" - * = 18 (0x12) ..010010 - */ - { 0x38, 0x52 }, - - /* - * 3A FREFA "Internal Reference Adjustment" - * = 0 (0x00) 00000000 - * FREFA[7:0] "Range" - * = 0 (0x00) 00000000 - */ - { 0x3a, 0x00 }, - - /* - * 3C FVOPT "Internal Reference Adjustment" - * = 31 (0x1F) 00011111 - * FVOPT[7:0] "Range" - * = 31 (0x1F) 00011111 - */ - { 0x3c, 0x1f }, - - /* - * 44 Undocumented = 0 (0x00) 00000000 - * 44[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x44, 0x00 }, - - /* - * 40 Undocumented = 0 (0x00) 00000000 - * 40[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x40, 0x00 }, - - /* - * 41 Undocumented = 0 (0x00) 00000000 - * 41[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x41, 0x00 }, - - /* - * 42 Undocumented = 0 (0x00) 00000000 - * 42[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x42, 0x00 }, - - /* - * 43 Undocumented = 0 (0x00) 00000000 - * 43[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x43, 0x00 }, - - /* - * 45 Undocumented = 128 (0x80) 10000000 - * 45[7:0] "It's a secret" - * = 128 (0x80) 10000000 - */ - { 0x45, 0x80 }, - - /* - * 48 Undocumented = 192 (0xC0) 11000000 - * 48[7:0] "It's a secret" - * = 192 (0xC0) 11000000 - */ - { 0x48, 0xc0 }, - - /* - * 49 Undocumented = 25 (0x19) 00011001 - * 49[7:0] "It's a secret" - * = 25 (0x19) 00011001 - */ - { 0x49, 0x19 }, - - /* - * 4B Undocumented = 128 (0x80) 10000000 - * 4B[7:0] "It's a secret" - * = 128 (0x80) 10000000 - */ - { 0x4b, 0x80 }, - - /* - * 4D Undocumented = 196 (0xC4) 11000100 - * 4D[7:0] "It's a secret" - * = 196 (0xC4) 11000100 - */ - { 0x4d, 0xc4 }, - - /* - * 35 VREF "Reference Voltage Control" - * = 76 (0x4c) 01001100 - * VREF[7:5] "Column high reference control" - * = 2 (0x02) 010..... "higher voltage" - * VREF[4:2] "Column low reference control" - * = 3 (0x03) ...011.. "Highest voltage" - * VREF[1:0] "Reserved" - * = 0 (0x00) ......00 - */ - { 0x35, 0x4c }, - - /* - * 3D Undocumented = 0 (0x00) 00000000 - * 3D[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x3d, 0x00 }, - - /* - * 3E Undocumented = 0 (0x00) 00000000 - * 3E[7:0] "It's a secret" - * = 0 (0x00) 00000000 - */ - { 0x3e, 0x00 }, - - /* - * 3B FREFB "Internal Reference Adjustment" - * = 24 (0x18) 00011000 - * FREFB[7:0] "Range" - * = 24 (0x18) 00011000 - */ - { 0x3b, 0x18 }, - - /* - * 33 CHLF "Current Control" - * = 25 (0x19) 00011001 - * CHLF[7:6] "Sensor current control" - * = 0 (0x00) 00...... - * CHLF[5] "Sensor current range control" - * = 0 (0x00) ..0..... "normal range" - * CHLF[4] "Sensor current" - * = 1 (0x01) ...1.... "double current" - * CHLF[3] "Sensor buffer current control" - * = 1 (0x01) ....1... "half current" - * CHLF[2] "Column buffer current control" - * = 0 (0x00) .....0.. "normal current" - * CHLF[1] "Analog DSP current control" - * = 0 (0x00) ......0. "normal current" - * CHLF[1] "ADC current control" - * = 0 (0x00) ......0. "normal current" - */ - { 0x33, 0x19 }, - - /* - * 34 VBLM "Blooming Control" - * = 90 (0x5A) 01011010 - * VBLM[7] "Hard soft reset switch" - * = 0 (0x00) 0....... "Hard reset" - * VBLM[6:4] "Blooming voltage selection" - * = 5 (0x05) .101.... - * VBLM[3:0] "Sensor current control" - * = 10 (0x0A) ....1010 - */ - { 0x34, 0x5a }, - - /* - * 3B FREFB "Internal Reference Adjustment" - * = 0 (0x00) 00000000 - * FREFB[7:0] "Range" - * = 0 (0x00) 00000000 - */ - { 0x3b, 0x00 }, - - /* - * 33 CHLF "Current Control" - * = 9 (0x09) 00001001 - * CHLF[7:6] "Sensor current control" - * = 0 (0x00) 00...... - * CHLF[5] "Sensor current range control" - * = 0 (0x00) ..0..... "normal range" - * CHLF[4] "Sensor current" - * = 0 (0x00) ...0.... "normal current" - * CHLF[3] "Sensor buffer current control" - * = 1 (0x01) ....1... "half current" - * CHLF[2] "Column buffer current control" - * = 0 (0x00) .....0.. "normal current" - * CHLF[1] "Analog DSP current control" - * = 0 (0x00) ......0. "normal current" - * CHLF[1] "ADC current control" - * = 0 (0x00) ......0. "normal current" - */ - { 0x33, 0x09 }, - - /* - * 34 VBLM "Blooming Control" - * = 80 (0x50) 01010000 - * VBLM[7] "Hard soft reset switch" - * = 0 (0x00) 0....... "Hard reset" - * VBLM[6:4] "Blooming voltage selection" - * = 5 (0x05) .101.... - * VBLM[3:0] "Sensor current control" - * = 0 (0x00) ....0000 - */ - { 0x34, 0x50 }, - - /* - * 12 COMH "Common Control H" - * = 64 (0x40) 01000000 - * COMH[7] "SRST" - * = 0 (0x00) 0....... "No-op" - * COMH[6:4] "Resolution selection" - * = 4 (0x04) .100.... "XGA" - * COMH[3] "Master slave selection" - * = 0 (0x00) ....0... "Master mode" - * COMH[2] "Internal B/R channel option" - * = 0 (0x00) .....0.. "B/R use same channel" - * COMH[1] "Color bar test pattern" - * = 0 (0x00) ......0. "Off" - * COMH[0] "Reserved" - * = 0 (0x00) .......0 - */ - { 0x12, 0x40 }, - - /* - * 17 HREFST "Horizontal window start" - * = 31 (0x1F) 00011111 - * HREFST[7:0] "Horizontal window start, 8 MSBs" - * = 31 (0x1F) 00011111 - */ - { 0x17, 0x1f }, - - /* - * 18 HREFEND "Horizontal window end" - * = 95 (0x5F) 01011111 - * HREFEND[7:0] "Horizontal Window End, 8 MSBs" - * = 95 (0x5F) 01011111 - */ - { 0x18, 0x5f }, - - /* - * 19 VSTRT "Vertical window start" - * = 0 (0x00) 00000000 - * VSTRT[7:0] "Vertical Window Start, 8 MSBs" - * = 0 (0x00) 00000000 - */ - { 0x19, 0x00 }, - - /* - * 1A VEND "Vertical window end" - * = 96 (0x60) 01100000 - * VEND[7:0] "Vertical Window End, 8 MSBs" - * = 96 (0x60) 01100000 - */ - { 0x1a, 0x60 }, - - /* - * 32 COMM "Common Control M" - * = 18 (0x12) 00010010 - * COMM[7:6] "Pixel clock divide option" - * = 0 (0x00) 00...... "/1" - * COMM[5:3] "Horizontal window end position, 3 LSBs" - * = 2 (0x02) ..010... - * COMM[2:0] "Horizontal window start position, 3 LSBs" - * = 2 (0x02) .....010 - */ - { 0x32, 0x12 }, - - /* - * 03 COMA "Common Control A" - * = 74 (0x4A) 01001010 - * COMA[7:4] "AWB Update Threshold" - * = 4 (0x04) 0100.... - * COMA[3:2] "Vertical window end line control 2 LSBs" - * = 2 (0x02) ....10.. - * COMA[1:0] "Vertical window start line control 2 LSBs" - * = 2 (0x02) ......10 - */ - { 0x03, 0x4a }, - - /* - * 11 CLKRC "Clock Rate Control" - * = 128 (0x80) 10000000 - * CLKRC[7] "Internal frequency doublers on off seclection" - * = 1 (0x01) 1....... "On" - * CLKRC[6] "Digital video master slave selection" - * = 0 (0x00) .0...... "Master mode, sensor - * provides PCLK" - * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }" - * = 0 (0x00) ..000000 - */ - { 0x11, 0x80 }, - - /* - * 12 COMH "Common Control H" - * = 0 (0x00) 00000000 - * COMH[7] "SRST" - * = 0 (0x00) 0....... "No-op" - * COMH[6:4] "Resolution selection" - * = 0 (0x00) .000.... "QXGA" - * COMH[3] "Master slave selection" - * = 0 (0x00) ....0... "Master mode" - * COMH[2] "Internal B/R channel option" - * = 0 (0x00) .....0.. "B/R use same channel" - * COMH[1] "Color bar test pattern" - * = 0 (0x00) ......0. "Off" - * COMH[0] "Reserved" - * = 0 (0x00) .......0 - */ - { 0x12, 0x00 }, - - /* - * 12 COMH "Common Control H" - * = 64 (0x40) 01000000 - * COMH[7] "SRST" - * = 0 (0x00) 0....... "No-op" - * COMH[6:4] "Resolution selection" - * = 4 (0x04) .100.... "XGA" - * COMH[3] "Master slave selection" - * = 0 (0x00) ....0... "Master mode" - * COMH[2] "Internal B/R channel option" - * = 0 (0x00) .....0.. "B/R use same channel" - * COMH[1] "Color bar test pattern" - * = 0 (0x00) ......0. "Off" - * COMH[0] "Reserved" - * = 0 (0x00) .......0 - */ - { 0x12, 0x40 }, - - /* - * 17 HREFST "Horizontal window start" - * = 31 (0x1F) 00011111 - * HREFST[7:0] "Horizontal window start, 8 MSBs" - * = 31 (0x1F) 00011111 - */ - { 0x17, 0x1f }, - - /* - * 18 HREFEND "Horizontal window end" - * = 95 (0x5F) 01011111 - * HREFEND[7:0] "Horizontal Window End, 8 MSBs" - * = 95 (0x5F) 01011111 - */ - { 0x18, 0x5f }, - - /* - * 19 VSTRT "Vertical window start" - * = 0 (0x00) 00000000 - * VSTRT[7:0] "Vertical Window Start, 8 MSBs" - * = 0 (0x00) 00000000 - */ - { 0x19, 0x00 }, - - /* - * 1A VEND "Vertical window end" - * = 96 (0x60) 01100000 - * VEND[7:0] "Vertical Window End, 8 MSBs" - * = 96 (0x60) 01100000 - */ - { 0x1a, 0x60 }, - - /* - * 32 COMM "Common Control M" - * = 18 (0x12) 00010010 - * COMM[7:6] "Pixel clock divide option" - * = 0 (0x00) 00...... "/1" - * COMM[5:3] "Horizontal window end position, 3 LSBs" - * = 2 (0x02) ..010... - * COMM[2:0] "Horizontal window start position, 3 LSBs" - * = 2 (0x02) .....010 - */ - { 0x32, 0x12 }, - - /* - * 03 COMA "Common Control A" - * = 74 (0x4A) 01001010 - * COMA[7:4] "AWB Update Threshold" - * = 4 (0x04) 0100.... - * COMA[3:2] "Vertical window end line control 2 LSBs" - * = 2 (0x02) ....10.. - * COMA[1:0] "Vertical window start line control 2 LSBs" - * = 2 (0x02) ......10 - */ - { 0x03, 0x4a }, - - /* - * 02 RED "Red Gain Control" - * = 175 (0xAF) 10101111 - * RED[7] "Action" - * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" - * RED[6:0] "Value" - * = 47 (0x2F) .0101111 - */ - { 0x02, 0xaf }, - - /* - * 2D ADDVSL "VSYNC Pulse Width" - * = 210 (0xD2) 11010010 - * ADDVSL[7:0] "VSYNC pulse width, LSB" - * = 210 (0xD2) 11010010 - */ - { 0x2d, 0xd2 }, - - /* - * 00 GAIN = 24 (0x18) 00011000 - * GAIN[7:6] "Reserved" - * = 0 (0x00) 00...... - * GAIN[5] "Double" - * = 0 (0x00) ..0..... "False" - * GAIN[4] "Double" - * = 1 (0x01) ...1.... "True" - * GAIN[3:0] "Range" - * = 8 (0x08) ....1000 - */ - { 0x00, 0x18 }, - - /* - * 01 BLUE "Blue Gain Control" - * = 240 (0xF0) 11110000 - * BLUE[7] "Action" - * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" - * BLUE[6:0] "Value" - * = 112 (0x70) .1110000 - */ - { 0x01, 0xf0 }, - - /* - * 10 AEC "Automatic Exposure Control" - * = 10 (0x0A) 00001010 - * AEC[7:0] "Automatic Exposure Control, 8 MSBs" - * = 10 (0x0A) 00001010 - */ - { 0x10, 0x0a }, - - { 0xe1, 0x67 }, - { 0xe3, 0x03 }, - { 0xe4, 0x26 }, - { 0xe5, 0x3e }, - { 0xf8, 0x01 }, - { 0xff, 0x01 }, -}; - -static const struct ov_i2c_regvals norm_6x20[] = { - { 0x12, 0x80 }, /* reset */ - { 0x11, 0x01 }, - { 0x03, 0x60 }, - { 0x05, 0x7f }, /* For when autoadjust is off */ - { 0x07, 0xa8 }, - /* The ratio of 0x0c and 0x0d controls the white point */ - { 0x0c, 0x24 }, - { 0x0d, 0x24 }, - { 0x0f, 0x15 }, /* COMS */ - { 0x10, 0x75 }, /* AEC Exposure time */ - { 0x12, 0x24 }, /* Enable AGC */ - { 0x14, 0x04 }, - /* 0x16: 0x06 helps frame stability with moving objects */ - { 0x16, 0x06 }, -/* { 0x20, 0x30 }, * Aperture correction enable */ - { 0x26, 0xb2 }, /* BLC enable */ - /* 0x28: 0x05 Selects RGB format if RGB on */ - { 0x28, 0x05 }, - { 0x2a, 0x04 }, /* Disable framerate adjust */ -/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ - { 0x2d, 0x85 }, - { 0x33, 0xa0 }, /* Color Processing Parameter */ - { 0x34, 0xd2 }, /* Max A/D range */ - { 0x38, 0x8b }, - { 0x39, 0x40 }, - - { 0x3c, 0x39 }, /* Enable AEC mode changing */ - { 0x3c, 0x3c }, /* Change AEC mode */ - { 0x3c, 0x24 }, /* Disable AEC mode changing */ - - { 0x3d, 0x80 }, - /* These next two registers (0x4a, 0x4b) are undocumented. - * They control the color balance */ - { 0x4a, 0x80 }, - { 0x4b, 0x80 }, - { 0x4d, 0xd2 }, /* This reduces noise a bit */ - { 0x4e, 0xc1 }, - { 0x4f, 0x04 }, -/* Do 50-53 have any effect? */ -/* Toggle 0x12[2] off and on here? */ -}; - -static const struct ov_i2c_regvals norm_6x30[] = { - { 0x12, 0x80 }, /* Reset */ - { 0x00, 0x1f }, /* Gain */ - { 0x01, 0x99 }, /* Blue gain */ - { 0x02, 0x7c }, /* Red gain */ - { 0x03, 0xc0 }, /* Saturation */ - { 0x05, 0x0a }, /* Contrast */ - { 0x06, 0x95 }, /* Brightness */ - { 0x07, 0x2d }, /* Sharpness */ - { 0x0c, 0x20 }, - { 0x0d, 0x20 }, - { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */ - { 0x0f, 0x05 }, - { 0x10, 0x9a }, - { 0x11, 0x00 }, /* Pixel clock = fastest */ - { 0x12, 0x24 }, /* Enable AGC and AWB */ - { 0x13, 0x21 }, - { 0x14, 0x80 }, - { 0x15, 0x01 }, - { 0x16, 0x03 }, - { 0x17, 0x38 }, - { 0x18, 0xea }, - { 0x19, 0x04 }, - { 0x1a, 0x93 }, - { 0x1b, 0x00 }, - { 0x1e, 0xc4 }, - { 0x1f, 0x04 }, - { 0x20, 0x20 }, - { 0x21, 0x10 }, - { 0x22, 0x88 }, - { 0x23, 0xc0 }, /* Crystal circuit power level */ - { 0x25, 0x9a }, /* Increase AEC black ratio */ - { 0x26, 0xb2 }, /* BLC enable */ - { 0x27, 0xa2 }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x84 }, /* 60 Hz power */ - { 0x2b, 0xa8 }, /* 60 Hz power */ - { 0x2c, 0xa0 }, - { 0x2d, 0x95 }, /* Enable auto-brightness */ - { 0x2e, 0x88 }, - { 0x33, 0x26 }, - { 0x34, 0x03 }, - { 0x36, 0x8f }, - { 0x37, 0x80 }, - { 0x38, 0x83 }, - { 0x39, 0x80 }, - { 0x3a, 0x0f }, - { 0x3b, 0x3c }, - { 0x3c, 0x1a }, - { 0x3d, 0x80 }, - { 0x3e, 0x80 }, - { 0x3f, 0x0e }, - { 0x40, 0x00 }, /* White bal */ - { 0x41, 0x00 }, /* White bal */ - { 0x42, 0x80 }, - { 0x43, 0x3f }, /* White bal */ - { 0x44, 0x80 }, - { 0x45, 0x20 }, - { 0x46, 0x20 }, - { 0x47, 0x80 }, - { 0x48, 0x7f }, - { 0x49, 0x00 }, - { 0x4a, 0x00 }, - { 0x4b, 0x80 }, - { 0x4c, 0xd0 }, - { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ - { 0x4e, 0x40 }, - { 0x4f, 0x07 }, /* UV avg., col. killer: max */ - { 0x50, 0xff }, - { 0x54, 0x23 }, /* Max AGC gain: 18dB */ - { 0x55, 0xff }, - { 0x56, 0x12 }, - { 0x57, 0x81 }, - { 0x58, 0x75 }, - { 0x59, 0x01 }, /* AGC dark current comp.: +1 */ - { 0x5a, 0x2c }, - { 0x5b, 0x0f }, /* AWB chrominance levels */ - { 0x5c, 0x10 }, - { 0x3d, 0x80 }, - { 0x27, 0xa6 }, - { 0x12, 0x20 }, /* Toggle AWB */ - { 0x12, 0x24 }, -}; - -/* Lawrence Glaister <lg@jfm.bc.ca> reports: - * - * Register 0x0f in the 7610 has the following effects: - * - * 0x85 (AEC method 1): Best overall, good contrast range - * 0x45 (AEC method 2): Very overexposed - * 0xa5 (spec sheet default): Ok, but the black level is - * shifted resulting in loss of contrast - * 0x05 (old driver setting): very overexposed, too much - * contrast - */ -static const struct ov_i2c_regvals norm_7610[] = { - { 0x10, 0xff }, - { 0x16, 0x06 }, - { 0x28, 0x24 }, - { 0x2b, 0xac }, - { 0x12, 0x00 }, - { 0x38, 0x81 }, - { 0x28, 0x24 }, /* 0c */ - { 0x0f, 0x85 }, /* lg's setting */ - { 0x15, 0x01 }, - { 0x20, 0x1c }, - { 0x23, 0x2a }, - { 0x24, 0x10 }, - { 0x25, 0x8a }, - { 0x26, 0xa2 }, - { 0x27, 0xc2 }, - { 0x2a, 0x04 }, - { 0x2c, 0xfe }, - { 0x2d, 0x93 }, - { 0x30, 0x71 }, - { 0x31, 0x60 }, - { 0x32, 0x26 }, - { 0x33, 0x20 }, - { 0x34, 0x48 }, - { 0x12, 0x24 }, - { 0x11, 0x01 }, - { 0x0c, 0x24 }, - { 0x0d, 0x24 }, -}; - -static const struct ov_i2c_regvals norm_7620[] = { - { 0x12, 0x80 }, /* reset */ - { 0x00, 0x00 }, /* gain */ - { 0x01, 0x80 }, /* blue gain */ - { 0x02, 0x80 }, /* red gain */ - { 0x03, 0xc0 }, /* OV7670_R03_VREF */ - { 0x06, 0x60 }, - { 0x07, 0x00 }, - { 0x0c, 0x24 }, - { 0x0c, 0x24 }, - { 0x0d, 0x24 }, - { 0x11, 0x01 }, - { 0x12, 0x24 }, - { 0x13, 0x01 }, - { 0x14, 0x84 }, - { 0x15, 0x01 }, - { 0x16, 0x03 }, - { 0x17, 0x2f }, - { 0x18, 0xcf }, - { 0x19, 0x06 }, - { 0x1a, 0xf5 }, - { 0x1b, 0x00 }, - { 0x20, 0x18 }, - { 0x21, 0x80 }, - { 0x22, 0x80 }, - { 0x23, 0x00 }, - { 0x26, 0xa2 }, - { 0x27, 0xea }, - { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */ - { 0x29, 0x00 }, - { 0x2a, 0x10 }, - { 0x2b, 0x00 }, - { 0x2c, 0x88 }, - { 0x2d, 0x91 }, - { 0x2e, 0x80 }, - { 0x2f, 0x44 }, - { 0x60, 0x27 }, - { 0x61, 0x02 }, - { 0x62, 0x5f }, - { 0x63, 0xd5 }, - { 0x64, 0x57 }, - { 0x65, 0x83 }, - { 0x66, 0x55 }, - { 0x67, 0x92 }, - { 0x68, 0xcf }, - { 0x69, 0x76 }, - { 0x6a, 0x22 }, - { 0x6b, 0x00 }, - { 0x6c, 0x02 }, - { 0x6d, 0x44 }, - { 0x6e, 0x80 }, - { 0x6f, 0x1d }, - { 0x70, 0x8b }, - { 0x71, 0x00 }, - { 0x72, 0x14 }, - { 0x73, 0x54 }, - { 0x74, 0x00 }, - { 0x75, 0x8e }, - { 0x76, 0x00 }, - { 0x77, 0xff }, - { 0x78, 0x80 }, - { 0x79, 0x80 }, - { 0x7a, 0x80 }, - { 0x7b, 0xe2 }, - { 0x7c, 0x00 }, -}; - -/* 7640 and 7648. The defaults should be OK for most registers. */ -static const struct ov_i2c_regvals norm_7640[] = { - { 0x12, 0x80 }, - { 0x12, 0x14 }, -}; - -static const struct ov_regvals init_519_ov7660[] = { - { 0x5d, 0x03 }, /* Turn off suspend mode */ - { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */ - { 0x54, 0x0f }, /* bit2 (jpeg enable) */ - { 0xa2, 0x20 }, /* a2-a5 are undocumented */ - { 0xa3, 0x18 }, - { 0xa4, 0x04 }, - { 0xa5, 0x28 }, - { 0x37, 0x00 }, /* SetUsbInit */ - { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ - /* Enable both fields, YUV Input, disable defect comp (why?) */ - { 0x20, 0x0c }, /* 0x0d does U <-> V swap */ - { 0x21, 0x38 }, - { 0x22, 0x1d }, - { 0x17, 0x50 }, /* undocumented */ - { 0x37, 0x00 }, /* undocumented */ - { 0x40, 0xff }, /* I2C timeout counter */ - { 0x46, 0x00 }, /* I2C clock prescaler */ -}; -static const struct ov_i2c_regvals norm_7660[] = { - {OV7670_R12_COM7, OV7670_COM7_RESET}, - {OV7670_R11_CLKRC, 0x81}, - {0x92, 0x00}, /* DM_LNL */ - {0x93, 0x00}, /* DM_LNH */ - {0x9d, 0x4c}, /* BD50ST */ - {0x9e, 0x3f}, /* BD60ST */ - {OV7670_R3B_COM11, 0x02}, - {OV7670_R13_COM8, 0xf5}, - {OV7670_R10_AECH, 0x00}, - {OV7670_R00_GAIN, 0x00}, - {OV7670_R01_BLUE, 0x7c}, - {OV7670_R02_RED, 0x9d}, - {OV7670_R12_COM7, 0x00}, - {OV7670_R04_COM1, 00}, - {OV7670_R18_HSTOP, 0x01}, - {OV7670_R17_HSTART, 0x13}, - {OV7670_R32_HREF, 0x92}, - {OV7670_R19_VSTART, 0x02}, - {OV7670_R1A_VSTOP, 0x7a}, - {OV7670_R03_VREF, 0x00}, - {OV7670_R0E_COM5, 0x04}, - {OV7670_R0F_COM6, 0x62}, - {OV7670_R15_COM10, 0x00}, - {0x16, 0x02}, /* RSVD */ - {0x1b, 0x00}, /* PSHFT */ - {OV7670_R1E_MVFP, 0x01}, - {0x29, 0x3c}, /* RSVD */ - {0x33, 0x00}, /* CHLF */ - {0x34, 0x07}, /* ARBLM */ - {0x35, 0x84}, /* RSVD */ - {0x36, 0x00}, /* RSVD */ - {0x37, 0x04}, /* ADC */ - {0x39, 0x43}, /* OFON */ - {OV7670_R3A_TSLB, 0x00}, - {OV7670_R3C_COM12, 0x6c}, - {OV7670_R3D_COM13, 0x98}, - {OV7670_R3F_EDGE, 0x23}, - {OV7670_R40_COM15, 0xc1}, - {OV7670_R41_COM16, 0x22}, - {0x6b, 0x0a}, /* DBLV */ - {0xa1, 0x08}, /* RSVD */ - {0x69, 0x80}, /* HV */ - {0x43, 0xf0}, /* RSVD.. */ - {0x44, 0x10}, - {0x45, 0x78}, - {0x46, 0xa8}, - {0x47, 0x60}, - {0x48, 0x80}, - {0x59, 0xba}, - {0x5a, 0x9a}, - {0x5b, 0x22}, - {0x5c, 0xb9}, - {0x5d, 0x9b}, - {0x5e, 0x10}, - {0x5f, 0xe0}, - {0x60, 0x85}, - {0x61, 0x60}, - {0x9f, 0x9d}, /* RSVD */ - {0xa0, 0xa0}, /* DSPC2 */ - {0x4f, 0x60}, /* matrix */ - {0x50, 0x64}, - {0x51, 0x04}, - {0x52, 0x18}, - {0x53, 0x3c}, - {0x54, 0x54}, - {0x55, 0x40}, - {0x56, 0x40}, - {0x57, 0x40}, - {0x58, 0x0d}, /* matrix sign */ - {0x8b, 0xcc}, /* RSVD */ - {0x8c, 0xcc}, - {0x8d, 0xcf}, - {0x6c, 0x40}, /* gamma curve */ - {0x6d, 0xe0}, - {0x6e, 0xa0}, - {0x6f, 0x80}, - {0x70, 0x70}, - {0x71, 0x80}, - {0x72, 0x60}, - {0x73, 0x60}, - {0x74, 0x50}, - {0x75, 0x40}, - {0x76, 0x38}, - {0x77, 0x3c}, - {0x78, 0x32}, - {0x79, 0x1a}, - {0x7a, 0x28}, - {0x7b, 0x24}, - {0x7c, 0x04}, /* gamma curve */ - {0x7d, 0x12}, - {0x7e, 0x26}, - {0x7f, 0x46}, - {0x80, 0x54}, - {0x81, 0x64}, - {0x82, 0x70}, - {0x83, 0x7c}, - {0x84, 0x86}, - {0x85, 0x8e}, - {0x86, 0x9c}, - {0x87, 0xab}, - {0x88, 0xc4}, - {0x89, 0xd1}, - {0x8a, 0xe5}, - {OV7670_R14_COM9, 0x1e}, - {OV7670_R24_AEW, 0x80}, - {OV7670_R25_AEB, 0x72}, - {OV7670_R26_VPT, 0xb3}, - {0x62, 0x80}, /* LCC1 */ - {0x63, 0x80}, /* LCC2 */ - {0x64, 0x06}, /* LCC3 */ - {0x65, 0x00}, /* LCC4 */ - {0x66, 0x01}, /* LCC5 */ - {0x94, 0x0e}, /* RSVD.. */ - {0x95, 0x14}, - {OV7670_R13_COM8, OV7670_COM8_FASTAEC - | OV7670_COM8_AECSTEP - | OV7670_COM8_BFILT - | 0x10 - | OV7670_COM8_AGC - | OV7670_COM8_AWB - | OV7670_COM8_AEC}, - {0xa1, 0xc8} -}; -static const struct ov_i2c_regvals norm_9600[] = { - {0x12, 0x80}, - {0x0c, 0x28}, - {0x11, 0x80}, - {0x13, 0xb5}, - {0x14, 0x3e}, - {0x1b, 0x04}, - {0x24, 0xb0}, - {0x25, 0x90}, - {0x26, 0x94}, - {0x35, 0x90}, - {0x37, 0x07}, - {0x38, 0x08}, - {0x01, 0x8e}, - {0x02, 0x85} -}; - -/* 7670. Defaults taken from OmniVision provided data, -* as provided by Jonathan Corbet of OLPC */ -static const struct ov_i2c_regvals norm_7670[] = { - { OV7670_R12_COM7, OV7670_COM7_RESET }, - { OV7670_R3A_TSLB, 0x04 }, /* OV */ - { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ - { OV7670_R11_CLKRC, 0x01 }, -/* - * Set the hardware window. These values from OV don't entirely - * make sense - hstop is less than hstart. But they work... - */ - { OV7670_R17_HSTART, 0x13 }, - { OV7670_R18_HSTOP, 0x01 }, - { OV7670_R32_HREF, 0xb6 }, - { OV7670_R19_VSTART, 0x02 }, - { OV7670_R1A_VSTOP, 0x7a }, - { OV7670_R03_VREF, 0x0a }, - - { OV7670_R0C_COM3, 0x00 }, - { OV7670_R3E_COM14, 0x00 }, -/* Mystery scaling numbers */ - { 0x70, 0x3a }, - { 0x71, 0x35 }, - { 0x72, 0x11 }, - { 0x73, 0xf0 }, - { 0xa2, 0x02 }, -/* { OV7670_R15_COM10, 0x0 }, */ - -/* Gamma curve values */ - { 0x7a, 0x20 }, - { 0x7b, 0x10 }, - { 0x7c, 0x1e }, - { 0x7d, 0x35 }, - { 0x7e, 0x5a }, - { 0x7f, 0x69 }, - { 0x80, 0x76 }, - { 0x81, 0x80 }, - { 0x82, 0x88 }, - { 0x83, 0x8f }, - { 0x84, 0x96 }, - { 0x85, 0xa3 }, - { 0x86, 0xaf }, - { 0x87, 0xc4 }, - { 0x88, 0xd7 }, - { 0x89, 0xe8 }, - -/* AGC and AEC parameters. Note we start by disabling those features, - then turn them only after tweaking the values. */ - { OV7670_R13_COM8, OV7670_COM8_FASTAEC - | OV7670_COM8_AECSTEP - | OV7670_COM8_BFILT }, - { OV7670_R00_GAIN, 0x00 }, - { OV7670_R10_AECH, 0x00 }, - { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */ - { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ - { OV7670_RA5_BD50MAX, 0x05 }, - { OV7670_RAB_BD60MAX, 0x07 }, - { OV7670_R24_AEW, 0x95 }, - { OV7670_R25_AEB, 0x33 }, - { OV7670_R26_VPT, 0xe3 }, - { OV7670_R9F_HAECC1, 0x78 }, - { OV7670_RA0_HAECC2, 0x68 }, - { 0xa1, 0x03 }, /* magic */ - { OV7670_RA6_HAECC3, 0xd8 }, - { OV7670_RA7_HAECC4, 0xd8 }, - { OV7670_RA8_HAECC5, 0xf0 }, - { OV7670_RA9_HAECC6, 0x90 }, - { OV7670_RAA_HAECC7, 0x94 }, - { OV7670_R13_COM8, OV7670_COM8_FASTAEC - | OV7670_COM8_AECSTEP - | OV7670_COM8_BFILT - | OV7670_COM8_AGC - | OV7670_COM8_AEC }, - -/* Almost all of these are magic "reserved" values. */ - { OV7670_R0E_COM5, 0x61 }, - { OV7670_R0F_COM6, 0x4b }, - { 0x16, 0x02 }, - { OV7670_R1E_MVFP, 0x07 }, - { 0x21, 0x02 }, - { 0x22, 0x91 }, - { 0x29, 0x07 }, - { 0x33, 0x0b }, - { 0x35, 0x0b }, - { 0x37, 0x1d }, - { 0x38, 0x71 }, - { 0x39, 0x2a }, - { OV7670_R3C_COM12, 0x78 }, - { 0x4d, 0x40 }, - { 0x4e, 0x20 }, - { OV7670_R69_GFIX, 0x00 }, - { 0x6b, 0x4a }, - { 0x74, 0x10 }, - { 0x8d, 0x4f }, - { 0x8e, 0x00 }, - { 0x8f, 0x00 }, - { 0x90, 0x00 }, - { 0x91, 0x00 }, - { 0x96, 0x00 }, - { 0x9a, 0x00 }, - { 0xb0, 0x84 }, - { 0xb1, 0x0c }, - { 0xb2, 0x0e }, - { 0xb3, 0x82 }, - { 0xb8, 0x0a }, - -/* More reserved magic, some of which tweaks white balance */ - { 0x43, 0x0a }, - { 0x44, 0xf0 }, - { 0x45, 0x34 }, - { 0x46, 0x58 }, - { 0x47, 0x28 }, - { 0x48, 0x3a }, - { 0x59, 0x88 }, - { 0x5a, 0x88 }, - { 0x5b, 0x44 }, - { 0x5c, 0x67 }, - { 0x5d, 0x49 }, - { 0x5e, 0x0e }, - { 0x6c, 0x0a }, - { 0x6d, 0x55 }, - { 0x6e, 0x11 }, - { 0x6f, 0x9f }, /* "9e for advance AWB" */ - { 0x6a, 0x40 }, - { OV7670_R01_BLUE, 0x40 }, - { OV7670_R02_RED, 0x60 }, - { OV7670_R13_COM8, OV7670_COM8_FASTAEC - | OV7670_COM8_AECSTEP - | OV7670_COM8_BFILT - | OV7670_COM8_AGC - | OV7670_COM8_AEC - | OV7670_COM8_AWB }, - -/* Matrix coefficients */ - { 0x4f, 0x80 }, - { 0x50, 0x80 }, - { 0x51, 0x00 }, - { 0x52, 0x22 }, - { 0x53, 0x5e }, - { 0x54, 0x80 }, - { 0x58, 0x9e }, - - { OV7670_R41_COM16, OV7670_COM16_AWBGAIN }, - { OV7670_R3F_EDGE, 0x00 }, - { 0x75, 0x05 }, - { 0x76, 0xe1 }, - { 0x4c, 0x00 }, - { 0x77, 0x01 }, - { OV7670_R3D_COM13, OV7670_COM13_GAMMA - | OV7670_COM13_UVSAT - | 2}, /* was 3 */ - { 0x4b, 0x09 }, - { 0xc9, 0x60 }, - { OV7670_R41_COM16, 0x38 }, - { 0x56, 0x40 }, - - { 0x34, 0x11 }, - { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, - { 0xa4, 0x88 }, - { 0x96, 0x00 }, - { 0x97, 0x30 }, - { 0x98, 0x20 }, - { 0x99, 0x30 }, - { 0x9a, 0x84 }, - { 0x9b, 0x29 }, - { 0x9c, 0x03 }, - { 0x9d, 0x4c }, - { 0x9e, 0x3f }, - { 0x78, 0x04 }, - -/* Extra-weird stuff. Some sort of multiplexor register */ - { 0x79, 0x01 }, - { 0xc8, 0xf0 }, - { 0x79, 0x0f }, - { 0xc8, 0x00 }, - { 0x79, 0x10 }, - { 0xc8, 0x7e }, - { 0x79, 0x0a }, - { 0xc8, 0x80 }, - { 0x79, 0x0b }, - { 0xc8, 0x01 }, - { 0x79, 0x0c }, - { 0xc8, 0x0f }, - { 0x79, 0x0d }, - { 0xc8, 0x20 }, - { 0x79, 0x09 }, - { 0xc8, 0x80 }, - { 0x79, 0x02 }, - { 0xc8, 0xc0 }, - { 0x79, 0x03 }, - { 0xc8, 0x40 }, - { 0x79, 0x05 }, - { 0xc8, 0x30 }, - { 0x79, 0x26 }, -}; - -static const struct ov_i2c_regvals norm_8610[] = { - { 0x12, 0x80 }, - { 0x00, 0x00 }, - { 0x01, 0x80 }, - { 0x02, 0x80 }, - { 0x03, 0xc0 }, - { 0x04, 0x30 }, - { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */ - { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */ - { 0x0a, 0x86 }, - { 0x0b, 0xb0 }, - { 0x0c, 0x20 }, - { 0x0d, 0x20 }, - { 0x11, 0x01 }, - { 0x12, 0x25 }, - { 0x13, 0x01 }, - { 0x14, 0x04 }, - { 0x15, 0x01 }, /* Lin and Win think different about UV order */ - { 0x16, 0x03 }, - { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */ - { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */ - { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */ - { 0x1a, 0xf5 }, - { 0x1b, 0x00 }, - { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */ - { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */ - { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */ - { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */ - { 0x26, 0xa2 }, - { 0x27, 0xea }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x80 }, - { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */ - { 0x2c, 0xac }, - { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */ - { 0x2e, 0x80 }, - { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */ - { 0x4c, 0x00 }, - { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */ - { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */ - { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */ - { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */ - { 0x63, 0xff }, - { 0x64, 0x53 }, /* new windrv 090403 says 0x57, - * maybe thats wrong */ - { 0x65, 0x00 }, - { 0x66, 0x55 }, - { 0x67, 0xb0 }, - { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */ - { 0x69, 0x02 }, - { 0x6a, 0x22 }, - { 0x6b, 0x00 }, - { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but - * deleting bit7 colors the first images red */ - { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */ - { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */ - { 0x6f, 0x01 }, - { 0x70, 0x8b }, - { 0x71, 0x00 }, - { 0x72, 0x14 }, - { 0x73, 0x54 }, - { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */ - { 0x75, 0x0e }, - { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */ - { 0x77, 0xff }, - { 0x78, 0x80 }, - { 0x79, 0x80 }, - { 0x7a, 0x80 }, - { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */ - { 0x7c, 0x00 }, - { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */ - { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */ - { 0x7f, 0xfb }, - { 0x80, 0x28 }, - { 0x81, 0x00 }, - { 0x82, 0x23 }, - { 0x83, 0x0b }, - { 0x84, 0x00 }, - { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */ - { 0x86, 0xc9 }, - { 0x87, 0x00 }, - { 0x88, 0x00 }, - { 0x89, 0x01 }, - { 0x12, 0x20 }, - { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */ -}; - -static unsigned char ov7670_abs_to_sm(unsigned char v) -{ - if (v > 127) - return v & 0x7f; - return (128 - v) | 0x80; -} - -/* Write a OV519 register */ -static void reg_w(struct sd *sd, u16 index, u16 value) -{ - int ret, req = 0; - - if (sd->gspca_dev.usb_err < 0) - return; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - req = 2; - break; - case BRIDGE_OVFX2: - req = 0x0a; - /* fall through */ - case BRIDGE_W9968CF: - PDEBUG(D_USBO, "SET %02x %04x %04x", - req, value, index); - ret = usb_control_msg(sd->gspca_dev.dev, - usb_sndctrlpipe(sd->gspca_dev.dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - goto leave; - default: - req = 1; - } - - PDEBUG(D_USBO, "SET %02x 0000 %04x %02x", - req, index, value); - sd->gspca_dev.usb_buf[0] = value; - ret = usb_control_msg(sd->gspca_dev.dev, - usb_sndctrlpipe(sd->gspca_dev.dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, - sd->gspca_dev.usb_buf, 1, 500); -leave: - if (ret < 0) { - pr_err("reg_w %02x failed %d\n", index, ret); - sd->gspca_dev.usb_err = ret; - return; - } -} - -/* Read from a OV519 register, note not valid for the w9968cf!! */ -/* returns: negative is error, pos or zero is data */ -static int reg_r(struct sd *sd, u16 index) -{ - int ret; - int req; - - if (sd->gspca_dev.usb_err < 0) - return -1; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - req = 3; - break; - case BRIDGE_OVFX2: - req = 0x0b; - break; - default: - req = 1; - } - - ret = usb_control_msg(sd->gspca_dev.dev, - usb_rcvctrlpipe(sd->gspca_dev.dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, sd->gspca_dev.usb_buf, 1, 500); - - if (ret >= 0) { - ret = sd->gspca_dev.usb_buf[0]; - PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", - req, index, ret); - } else { - pr_err("reg_r %02x failed %d\n", index, ret); - sd->gspca_dev.usb_err = ret; - } - - return ret; -} - -/* Read 8 values from a OV519 register */ -static int reg_r8(struct sd *sd, - u16 index) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return -1; - - ret = usb_control_msg(sd->gspca_dev.dev, - usb_rcvctrlpipe(sd->gspca_dev.dev, 0), - 1, /* REQ_IO */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, sd->gspca_dev.usb_buf, 8, 500); - - if (ret >= 0) { - ret = sd->gspca_dev.usb_buf[0]; - } else { - pr_err("reg_r8 %02x failed %d\n", index, ret); - sd->gspca_dev.usb_err = ret; - } - - return ret; -} - -/* - * Writes bits at positions specified by mask to an OV51x reg. Bits that are in - * the same position as 1's in "mask" are cleared and set to "value". Bits - * that are in the same position as 0's in "mask" are preserved, regardless - * of their respective state in "value". - */ -static void reg_w_mask(struct sd *sd, - u16 index, - u8 value, - u8 mask) -{ - int ret; - u8 oldval; - - if (mask != 0xff) { - value &= mask; /* Enforce mask on value */ - ret = reg_r(sd, index); - if (ret < 0) - return; - - oldval = ret & ~mask; /* Clear the masked bits */ - value |= oldval; /* Set the desired bits */ - } - reg_w(sd, index, value); -} - -/* - * Writes multiple (n) byte value to a single register. Only valid with certain - * registers (0x30 and 0xc4 - 0xce). - */ -static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return; - - *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); - - ret = usb_control_msg(sd->gspca_dev.dev, - usb_sndctrlpipe(sd->gspca_dev.dev, 0), - 1 /* REG_IO */, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, - sd->gspca_dev.usb_buf, n, 500); - if (ret < 0) { - pr_err("reg_w32 %02x failed %d\n", index, ret); - sd->gspca_dev.usb_err = ret; - } -} - -static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value) -{ - int rc, retries; - - PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value); - - /* Three byte write cycle */ - for (retries = 6; ; ) { - /* Select camera register */ - reg_w(sd, R51x_I2C_SADDR_3, reg); - - /* Write "value" to I2C data port of OV511 */ - reg_w(sd, R51x_I2C_DATA, value); - - /* Initiate 3-byte write cycle */ - reg_w(sd, R511_I2C_CTL, 0x01); - - do { - rc = reg_r(sd, R511_I2C_CTL); - } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return; - - if ((rc & 2) == 0) /* Ack? */ - break; - if (--retries < 0) { - PDEBUG(D_USBO, "i2c write retries exhausted"); - return; - } - } -} - -static int ov511_i2c_r(struct sd *sd, u8 reg) -{ - int rc, value, retries; - - /* Two byte write cycle */ - for (retries = 6; ; ) { - /* Select camera register */ - reg_w(sd, R51x_I2C_SADDR_2, reg); - - /* Initiate 2-byte write cycle */ - reg_w(sd, R511_I2C_CTL, 0x03); - - do { - rc = reg_r(sd, R511_I2C_CTL); - } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return rc; - - if ((rc & 2) == 0) /* Ack? */ - break; - - /* I2C abort */ - reg_w(sd, R511_I2C_CTL, 0x10); - - if (--retries < 0) { - PDEBUG(D_USBI, "i2c write retries exhausted"); - return -1; - } - } - - /* Two byte read cycle */ - for (retries = 6; ; ) { - /* Initiate 2-byte read cycle */ - reg_w(sd, R511_I2C_CTL, 0x05); - - do { - rc = reg_r(sd, R511_I2C_CTL); - } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return rc; - - if ((rc & 2) == 0) /* Ack? */ - break; - - /* I2C abort */ - reg_w(sd, R511_I2C_CTL, 0x10); - - if (--retries < 0) { - PDEBUG(D_USBI, "i2c read retries exhausted"); - return -1; - } - } - - value = reg_r(sd, R51x_I2C_DATA); - - PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value); - - /* This is needed to make i2c_w() work */ - reg_w(sd, R511_I2C_CTL, 0x05); - - return value; -} - -/* - * The OV518 I2C I/O procedure is different, hence, this function. - * This is normally only called from i2c_w(). Note that this function - * always succeeds regardless of whether the sensor is present and working. - */ -static void ov518_i2c_w(struct sd *sd, - u8 reg, - u8 value) -{ - PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value); - - /* Select camera register */ - reg_w(sd, R51x_I2C_SADDR_3, reg); - - /* Write "value" to I2C data port of OV511 */ - reg_w(sd, R51x_I2C_DATA, value); - - /* Initiate 3-byte write cycle */ - reg_w(sd, R518_I2C_CTL, 0x01); - - /* wait for write complete */ - msleep(4); - reg_r8(sd, R518_I2C_CTL); -} - -/* - * returns: negative is error, pos or zero is data - * - * The OV518 I2C I/O procedure is different, hence, this function. - * This is normally only called from i2c_r(). Note that this function - * always succeeds regardless of whether the sensor is present and working. - */ -static int ov518_i2c_r(struct sd *sd, u8 reg) -{ - int value; - - /* Select camera register */ - reg_w(sd, R51x_I2C_SADDR_2, reg); - - /* Initiate 2-byte write cycle */ - reg_w(sd, R518_I2C_CTL, 0x03); - reg_r8(sd, R518_I2C_CTL); - - /* Initiate 2-byte read cycle */ - reg_w(sd, R518_I2C_CTL, 0x05); - reg_r8(sd, R518_I2C_CTL); - - value = reg_r(sd, R51x_I2C_DATA); - PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value); - return value; -} - -static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return; - - ret = usb_control_msg(sd->gspca_dev.dev, - usb_sndctrlpipe(sd->gspca_dev.dev, 0), - 0x02, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - (u16) value, (u16) reg, NULL, 0, 500); - - if (ret < 0) { - pr_err("ovfx2_i2c_w %02x failed %d\n", reg, ret); - sd->gspca_dev.usb_err = ret; - } - - PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value); -} - -static int ovfx2_i2c_r(struct sd *sd, u8 reg) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return -1; - - ret = usb_control_msg(sd->gspca_dev.dev, - usb_rcvctrlpipe(sd->gspca_dev.dev, 0), - 0x03, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500); - - if (ret >= 0) { - ret = sd->gspca_dev.usb_buf[0]; - PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret); - } else { - pr_err("ovfx2_i2c_r %02x failed %d\n", reg, ret); - sd->gspca_dev.usb_err = ret; - } - - return ret; -} - -static void i2c_w(struct sd *sd, u8 reg, u8 value) -{ - if (sd->sensor_reg_cache[reg] == value) - return; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ov511_i2c_w(sd, reg, value); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - case BRIDGE_OV519: - ov518_i2c_w(sd, reg, value); - break; - case BRIDGE_OVFX2: - ovfx2_i2c_w(sd, reg, value); - break; - case BRIDGE_W9968CF: - w9968cf_i2c_w(sd, reg, value); - break; - } - - if (sd->gspca_dev.usb_err >= 0) { - /* Up on sensor reset empty the register cache */ - if (reg == 0x12 && (value & 0x80)) - memset(sd->sensor_reg_cache, -1, - sizeof(sd->sensor_reg_cache)); - else - sd->sensor_reg_cache[reg] = value; - } -} - -static int i2c_r(struct sd *sd, u8 reg) -{ - int ret = -1; - - if (sd->sensor_reg_cache[reg] != -1) - return sd->sensor_reg_cache[reg]; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ret = ov511_i2c_r(sd, reg); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - case BRIDGE_OV519: - ret = ov518_i2c_r(sd, reg); - break; - case BRIDGE_OVFX2: - ret = ovfx2_i2c_r(sd, reg); - break; - case BRIDGE_W9968CF: - ret = w9968cf_i2c_r(sd, reg); - break; - } - - if (ret >= 0) - sd->sensor_reg_cache[reg] = ret; - - return ret; -} - -/* Writes bits at positions specified by mask to an I2C reg. Bits that are in - * the same position as 1's in "mask" are cleared and set to "value". Bits - * that are in the same position as 0's in "mask" are preserved, regardless - * of their respective state in "value". - */ -static void i2c_w_mask(struct sd *sd, - u8 reg, - u8 value, - u8 mask) -{ - int rc; - u8 oldval; - - value &= mask; /* Enforce mask on value */ - rc = i2c_r(sd, reg); - if (rc < 0) - return; - oldval = rc & ~mask; /* Clear the masked bits */ - value |= oldval; /* Set the desired bits */ - i2c_w(sd, reg, value); -} - -/* Temporarily stops OV511 from functioning. Must do this before changing - * registers while the camera is streaming */ -static inline void ov51x_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "stopping"); - sd->stopped = 1; - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - reg_w(sd, R51x_SYS_RESET, 0x3d); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); - break; - case BRIDGE_OV519: - reg_w(sd, OV519_R51_RESET1, 0x0f); - reg_w(sd, OV519_R51_RESET1, 0x00); - reg_w(sd, 0x22, 0x00); /* FRAR */ - break; - case BRIDGE_OVFX2: - reg_w_mask(sd, 0x0f, 0x00, 0x02); - break; - case BRIDGE_W9968CF: - reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ - break; - } -} - -/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not - * actually stopped (for performance). */ -static inline void ov51x_restart(struct sd *sd) -{ - PDEBUG(D_STREAM, "restarting"); - if (!sd->stopped) - return; - sd->stopped = 0; - - /* Reinitialize the stream */ - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - reg_w(sd, R51x_SYS_RESET, 0x00); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - reg_w(sd, 0x2f, 0x80); - reg_w(sd, R51x_SYS_RESET, 0x00); - break; - case BRIDGE_OV519: - reg_w(sd, OV519_R51_RESET1, 0x0f); - reg_w(sd, OV519_R51_RESET1, 0x00); - reg_w(sd, 0x22, 0x1d); /* FRAR */ - break; - case BRIDGE_OVFX2: - reg_w_mask(sd, 0x0f, 0x02, 0x02); - break; - case BRIDGE_W9968CF: - reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ - break; - } -} - -static void ov51x_set_slave_ids(struct sd *sd, u8 slave); - -/* This does an initial reset of an OmniVision sensor and ensures that I2C - * is synchronized. Returns <0 on failure. - */ -static int init_ov_sensor(struct sd *sd, u8 slave) -{ - int i; - - ov51x_set_slave_ids(sd, slave); - - /* Reset the sensor */ - i2c_w(sd, 0x12, 0x80); - - /* Wait for it to initialize */ - msleep(150); - - for (i = 0; i < i2c_detect_tries; i++) { - if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && - i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { - PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i); - return 0; - } - - /* Reset the sensor */ - i2c_w(sd, 0x12, 0x80); - - /* Wait for it to initialize */ - msleep(150); - - /* Dummy read to sync I2C */ - if (i2c_r(sd, 0x00) < 0) - return -1; - } - return -1; -} - -/* Set the read and write slave IDs. The "slave" argument is the write slave, - * and the read slave will be set to (slave + 1). - * This should not be called from outside the i2c I/O functions. - * Sets I2C read and write slave IDs. Returns <0 for error - */ -static void ov51x_set_slave_ids(struct sd *sd, - u8 slave) -{ - switch (sd->bridge) { - case BRIDGE_OVFX2: - reg_w(sd, OVFX2_I2C_ADDR, slave); - return; - case BRIDGE_W9968CF: - sd->sensor_addr = slave; - return; - } - - reg_w(sd, R51x_I2C_W_SID, slave); - reg_w(sd, R51x_I2C_R_SID, slave + 1); -} - -static void write_regvals(struct sd *sd, - const struct ov_regvals *regvals, - int n) -{ - while (--n >= 0) { - reg_w(sd, regvals->reg, regvals->val); - regvals++; - } -} - -static void write_i2c_regvals(struct sd *sd, - const struct ov_i2c_regvals *regvals, - int n) -{ - while (--n >= 0) { - i2c_w(sd, regvals->reg, regvals->val); - regvals++; - } -} - -/**************************************************************************** - * - * OV511 and sensor configuration - * - ***************************************************************************/ - -/* This initializes the OV2x10 / OV3610 / OV3620 / OV9600 */ -static void ov_hires_configure(struct sd *sd) -{ - int high, low; - - if (sd->bridge != BRIDGE_OVFX2) { - pr_err("error hires sensors only supported with ovfx2\n"); - return; - } - - PDEBUG(D_PROBE, "starting ov hires configuration"); - - /* Detect sensor (sub)type */ - high = i2c_r(sd, 0x0a); - low = i2c_r(sd, 0x0b); - /* info("%x, %x", high, low); */ - switch (high) { - case 0x96: - switch (low) { - case 0x40: - PDEBUG(D_PROBE, "Sensor is a OV2610"); - sd->sensor = SEN_OV2610; - return; - case 0x41: - PDEBUG(D_PROBE, "Sensor is a OV2610AE"); - sd->sensor = SEN_OV2610AE; - return; - case 0xb1: - PDEBUG(D_PROBE, "Sensor is a OV9600"); - sd->sensor = SEN_OV9600; - return; - } - break; - case 0x36: - if ((low & 0x0f) == 0x00) { - PDEBUG(D_PROBE, "Sensor is a OV3610"); - sd->sensor = SEN_OV3610; - return; - } - break; - } - pr_err("Error unknown sensor type: %02x%02x\n", high, low); -} - -/* This initializes the OV8110, OV8610 sensor. The OV8110 uses - * the same register settings as the OV8610, since they are very similar. - */ -static void ov8xx0_configure(struct sd *sd) -{ - int rc; - - PDEBUG(D_PROBE, "starting ov8xx0 configuration"); - - /* Detect sensor (sub)type */ - rc = i2c_r(sd, OV7610_REG_COM_I); - if (rc < 0) { - PDEBUG(D_ERR, "Error detecting sensor type"); - return; - } - if ((rc & 3) == 1) - sd->sensor = SEN_OV8610; - else - pr_err("Unknown image sensor version: %d\n", rc & 3); -} - -/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses - * the same register settings as the OV7610, since they are very similar. - */ -static void ov7xx0_configure(struct sd *sd) -{ - int rc, high, low; - - PDEBUG(D_PROBE, "starting OV7xx0 configuration"); - - /* Detect sensor (sub)type */ - rc = i2c_r(sd, OV7610_REG_COM_I); - - /* add OV7670 here - * it appears to be wrongly detected as a 7610 by default */ - if (rc < 0) { - pr_err("Error detecting sensor type\n"); - return; - } - if ((rc & 3) == 3) { - /* quick hack to make OV7670s work */ - high = i2c_r(sd, 0x0a); - low = i2c_r(sd, 0x0b); - /* info("%x, %x", high, low); */ - if (high == 0x76 && (low & 0xf0) == 0x70) { - PDEBUG(D_PROBE, "Sensor is an OV76%02x", low); - sd->sensor = SEN_OV7670; - } else { - PDEBUG(D_PROBE, "Sensor is an OV7610"); - sd->sensor = SEN_OV7610; - } - } else if ((rc & 3) == 1) { - /* I don't know what's different about the 76BE yet. */ - if (i2c_r(sd, 0x15) & 1) { - PDEBUG(D_PROBE, "Sensor is an OV7620AE"); - sd->sensor = SEN_OV7620AE; - } else { - PDEBUG(D_PROBE, "Sensor is an OV76BE"); - sd->sensor = SEN_OV76BE; - } - } else if ((rc & 3) == 0) { - /* try to read product id registers */ - high = i2c_r(sd, 0x0a); - if (high < 0) { - pr_err("Error detecting camera chip PID\n"); - return; - } - low = i2c_r(sd, 0x0b); - if (low < 0) { - pr_err("Error detecting camera chip VER\n"); - return; - } - if (high == 0x76) { - switch (low) { - case 0x30: - pr_err("Sensor is an OV7630/OV7635\n"); - pr_err("7630 is not supported by this driver\n"); - return; - case 0x40: - PDEBUG(D_PROBE, "Sensor is an OV7645"); - sd->sensor = SEN_OV7640; /* FIXME */ - break; - case 0x45: - PDEBUG(D_PROBE, "Sensor is an OV7645B"); - sd->sensor = SEN_OV7640; /* FIXME */ - break; - case 0x48: - PDEBUG(D_PROBE, "Sensor is an OV7648"); - sd->sensor = SEN_OV7648; - break; - case 0x60: - PDEBUG(D_PROBE, "Sensor is a OV7660"); - sd->sensor = SEN_OV7660; - break; - default: - pr_err("Unknown sensor: 0x76%02x\n", low); - return; - } - } else { - PDEBUG(D_PROBE, "Sensor is an OV7620"); - sd->sensor = SEN_OV7620; - } - } else { - pr_err("Unknown image sensor version: %d\n", rc & 3); - } -} - -/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ -static void ov6xx0_configure(struct sd *sd) -{ - int rc; - PDEBUG(D_PROBE, "starting OV6xx0 configuration"); - - /* Detect sensor (sub)type */ - rc = i2c_r(sd, OV7610_REG_COM_I); - if (rc < 0) { - pr_err("Error detecting sensor type\n"); - return; - } - - /* Ugh. The first two bits are the version bits, but - * the entire register value must be used. I guess OVT - * underestimated how many variants they would make. */ - switch (rc) { - case 0x00: - sd->sensor = SEN_OV6630; - pr_warn("WARNING: Sensor is an OV66308. Your camera may have been misdetected in previous driver versions.\n"); - break; - case 0x01: - sd->sensor = SEN_OV6620; - PDEBUG(D_PROBE, "Sensor is an OV6620"); - break; - case 0x02: - sd->sensor = SEN_OV6630; - PDEBUG(D_PROBE, "Sensor is an OV66308AE"); - break; - case 0x03: - sd->sensor = SEN_OV66308AF; - PDEBUG(D_PROBE, "Sensor is an OV66308AF"); - break; - case 0x90: - sd->sensor = SEN_OV6630; - pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n"); - break; - default: - pr_err("FATAL: Unknown sensor version: 0x%02x\n", rc); - return; - } - - /* Set sensor-specific vars */ - sd->sif = 1; -} - -/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ -static void ov51x_led_control(struct sd *sd, int on) -{ - if (sd->invert_led) - on = !on; - - switch (sd->bridge) { - /* OV511 has no LED control */ - case BRIDGE_OV511PLUS: - reg_w(sd, R511_SYS_LED_CTL, on); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02); - break; - case BRIDGE_OV519: - reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1); - break; - } -} - -static void sd_reset_snapshot(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!sd->snapshot_needs_reset) - return; - - /* Note it is important that we clear sd->snapshot_needs_reset, - before actually clearing the snapshot state in the bridge - otherwise we might race with the pkt_scan interrupt handler */ - sd->snapshot_needs_reset = 0; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - reg_w(sd, R51x_SYS_SNAP, 0x02); - reg_w(sd, R51x_SYS_SNAP, 0x00); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */ - reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */ - break; - case BRIDGE_OV519: - reg_w(sd, R51x_SYS_RESET, 0x40); - reg_w(sd, R51x_SYS_RESET, 0x00); - break; - } -} - -static void ov51x_upload_quan_tables(struct sd *sd) -{ - const unsigned char yQuanTable511[] = { - 0, 1, 1, 2, 2, 3, 3, 4, - 1, 1, 1, 2, 2, 3, 4, 4, - 1, 1, 2, 2, 3, 4, 4, 4, - 2, 2, 2, 3, 4, 4, 4, 4, - 2, 2, 3, 4, 4, 5, 5, 5, - 3, 3, 4, 4, 5, 5, 5, 5, - 3, 4, 4, 4, 5, 5, 5, 5, - 4, 4, 4, 4, 5, 5, 5, 5 - }; - - const unsigned char uvQuanTable511[] = { - 0, 2, 2, 3, 4, 4, 4, 4, - 2, 2, 2, 4, 4, 4, 4, 4, - 2, 2, 3, 4, 4, 4, 4, 4, - 3, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4 - }; - - /* OV518 quantization tables are 8x4 (instead of 8x8) */ - const unsigned char yQuanTable518[] = { - 5, 4, 5, 6, 6, 7, 7, 7, - 5, 5, 5, 5, 6, 7, 7, 7, - 6, 6, 6, 6, 7, 7, 7, 8, - 7, 7, 6, 7, 7, 7, 8, 8 - }; - const unsigned char uvQuanTable518[] = { - 6, 6, 6, 7, 7, 7, 7, 7, - 6, 6, 6, 7, 7, 7, 7, 7, - 6, 6, 6, 7, 7, 7, 7, 8, - 7, 7, 7, 7, 7, 7, 8, 8 - }; - - const unsigned char *pYTable, *pUVTable; - unsigned char val0, val1; - int i, size, reg = R51x_COMP_LUT_BEGIN; - - PDEBUG(D_PROBE, "Uploading quantization tables"); - - if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { - pYTable = yQuanTable511; - pUVTable = uvQuanTable511; - size = 32; - } else { - pYTable = yQuanTable518; - pUVTable = uvQuanTable518; - size = 16; - } - - for (i = 0; i < size; i++) { - val0 = *pYTable++; - val1 = *pYTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - reg_w(sd, reg, val0); - - val0 = *pUVTable++; - val1 = *pUVTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - reg_w(sd, reg + size, val0); - - reg++; - } -} - -/* This initializes the OV511/OV511+ and the sensor */ -static void ov511_configure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* For 511 and 511+ */ - const struct ov_regvals init_511[] = { - { R51x_SYS_RESET, 0x7f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x7f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x3f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x3d }, - }; - - const struct ov_regvals norm_511[] = { - { R511_DRAM_FLOW_CTL, 0x01 }, - { R51x_SYS_SNAP, 0x00 }, - { R51x_SYS_SNAP, 0x02 }, - { R51x_SYS_SNAP, 0x00 }, - { R511_FIFO_OPTS, 0x1f }, - { R511_COMP_EN, 0x00 }, - { R511_COMP_LUT_EN, 0x03 }, - }; - - const struct ov_regvals norm_511_p[] = { - { R511_DRAM_FLOW_CTL, 0xff }, - { R51x_SYS_SNAP, 0x00 }, - { R51x_SYS_SNAP, 0x02 }, - { R51x_SYS_SNAP, 0x00 }, - { R511_FIFO_OPTS, 0xff }, - { R511_COMP_EN, 0x00 }, - { R511_COMP_LUT_EN, 0x03 }, - }; - - const struct ov_regvals compress_511[] = { - { 0x70, 0x1f }, - { 0x71, 0x05 }, - { 0x72, 0x06 }, - { 0x73, 0x06 }, - { 0x74, 0x14 }, - { 0x75, 0x03 }, - { 0x76, 0x04 }, - { 0x77, 0x04 }, - }; - - PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); - - write_regvals(sd, init_511, ARRAY_SIZE(init_511)); - - switch (sd->bridge) { - case BRIDGE_OV511: - write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); - break; - case BRIDGE_OV511PLUS: - write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); - break; - } - - /* Init compression */ - write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); - - ov51x_upload_quan_tables(sd); -} - -/* This initializes the OV518/OV518+ and the sensor */ -static void ov518_configure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* For 518 and 518+ */ - const struct ov_regvals init_518[] = { - { R51x_SYS_RESET, 0x40 }, - { R51x_SYS_INIT, 0xe1 }, - { R51x_SYS_RESET, 0x3e }, - { R51x_SYS_INIT, 0xe1 }, - { R51x_SYS_RESET, 0x00 }, - { R51x_SYS_INIT, 0xe1 }, - { 0x46, 0x00 }, - { 0x5d, 0x03 }, - }; - - const struct ov_regvals norm_518[] = { - { R51x_SYS_SNAP, 0x02 }, /* Reset */ - { R51x_SYS_SNAP, 0x01 }, /* Enable */ - { 0x31, 0x0f }, - { 0x5d, 0x03 }, - { 0x24, 0x9f }, - { 0x25, 0x90 }, - { 0x20, 0x00 }, - { 0x51, 0x04 }, - { 0x71, 0x19 }, - { 0x2f, 0x80 }, - }; - - const struct ov_regvals norm_518_p[] = { - { R51x_SYS_SNAP, 0x02 }, /* Reset */ - { R51x_SYS_SNAP, 0x01 }, /* Enable */ - { 0x31, 0x0f }, - { 0x5d, 0x03 }, - { 0x24, 0x9f }, - { 0x25, 0x90 }, - { 0x20, 0x60 }, - { 0x51, 0x02 }, - { 0x71, 0x19 }, - { 0x40, 0xff }, - { 0x41, 0x42 }, - { 0x46, 0x00 }, - { 0x33, 0x04 }, - { 0x21, 0x19 }, - { 0x3f, 0x10 }, - { 0x2f, 0x80 }, - }; - - /* First 5 bits of custom ID reg are a revision ID on OV518 */ - PDEBUG(D_PROBE, "Device revision %d", - 0x1f & reg_r(sd, R51x_SYS_CUST_ID)); - - write_regvals(sd, init_518, ARRAY_SIZE(init_518)); - - /* Set LED GPIO pin to output mode */ - reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); - - switch (sd->bridge) { - case BRIDGE_OV518: - write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); - break; - case BRIDGE_OV518PLUS: - write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); - break; - } - - ov51x_upload_quan_tables(sd); - - reg_w(sd, 0x2f, 0x80); -} - -static void ov519_configure(struct sd *sd) -{ - static const struct ov_regvals init_519[] = { - { 0x5a, 0x6d }, /* EnableSystem */ - { 0x53, 0x9b }, /* don't enable the microcontroller */ - { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */ - { 0x5d, 0x03 }, - { 0x49, 0x01 }, - { 0x48, 0x00 }, - /* Set LED pin to output mode. Bit 4 must be cleared or sensor - * detection will fail. This deserves further investigation. */ - { OV519_GPIO_IO_CTRL0, 0xee }, - { OV519_R51_RESET1, 0x0f }, - { OV519_R51_RESET1, 0x00 }, - { 0x22, 0x00 }, - /* windows reads 0x55 at this point*/ - }; - - write_regvals(sd, init_519, ARRAY_SIZE(init_519)); -} - -static void ovfx2_configure(struct sd *sd) -{ - static const struct ov_regvals init_fx2[] = { - { 0x00, 0x60 }, - { 0x02, 0x01 }, - { 0x0f, 0x1d }, - { 0xe9, 0x82 }, - { 0xea, 0xc7 }, - { 0xeb, 0x10 }, - { 0xec, 0xf6 }, - }; - - sd->stopped = 1; - - write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); -} - -/* set the mode */ -/* This function works for ov7660 only */ -static void ov519_set_mode(struct sd *sd) -{ - static const struct ov_regvals bridge_ov7660[2][10] = { - {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00}, - {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, - {0x25, 0x01}, {0x26, 0x00}}, - {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00}, - {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, - {0x25, 0x03}, {0x26, 0x00}} - }; - static const struct ov_i2c_regvals sensor_ov7660[2][3] = { - {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}}, - {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}} - }; - static const struct ov_i2c_regvals sensor_ov7660_2[] = { - {OV7670_R17_HSTART, 0x13}, - {OV7670_R18_HSTOP, 0x01}, - {OV7670_R32_HREF, 0x92}, - {OV7670_R19_VSTART, 0x02}, - {OV7670_R1A_VSTOP, 0x7a}, - {OV7670_R03_VREF, 0x00}, -/* {0x33, 0x00}, */ -/* {0x34, 0x07}, */ -/* {0x36, 0x00}, */ -/* {0x6b, 0x0a}, */ - }; - - write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode], - ARRAY_SIZE(bridge_ov7660[0])); - write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode], - ARRAY_SIZE(sensor_ov7660[0])); - write_i2c_regvals(sd, sensor_ov7660_2, - ARRAY_SIZE(sensor_ov7660_2)); -} - -/* set the frame rate */ -/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */ -static void ov519_set_fr(struct sd *sd) -{ - int fr; - u8 clock; - /* frame rate table with indices: - * - mode = 0: 320x240, 1: 640x480 - * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5 - * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock) - */ - static const u8 fr_tb[2][6][3] = { - {{0x04, 0xff, 0x00}, - {0x04, 0x1f, 0x00}, - {0x04, 0x1b, 0x00}, - {0x04, 0x15, 0x00}, - {0x04, 0x09, 0x00}, - {0x04, 0x01, 0x00}}, - {{0x0c, 0xff, 0x00}, - {0x0c, 0x1f, 0x00}, - {0x0c, 0x1b, 0x00}, - {0x04, 0xff, 0x01}, - {0x04, 0x1f, 0x01}, - {0x04, 0x1b, 0x01}}, - }; - - if (frame_rate > 0) - sd->frame_rate = frame_rate; - if (sd->frame_rate >= 30) - fr = 0; - else if (sd->frame_rate >= 25) - fr = 1; - else if (sd->frame_rate >= 20) - fr = 2; - else if (sd->frame_rate >= 15) - fr = 3; - else if (sd->frame_rate >= 10) - fr = 4; - else - fr = 5; - reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]); - reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]); - clock = fr_tb[sd->gspca_dev.curr_mode][fr][2]; - if (sd->sensor == SEN_OV7660) - clock |= 0x80; /* enable double clock */ - ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - sd->bridge = id->driver_info & BRIDGE_MASK; - sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - cam->cam_mode = ov511_vga_mode; - cam->nmodes = ARRAY_SIZE(ov511_vga_mode); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - cam->cam_mode = ov518_vga_mode; - cam->nmodes = ARRAY_SIZE(ov518_vga_mode); - break; - case BRIDGE_OV519: - cam->cam_mode = ov519_vga_mode; - cam->nmodes = ARRAY_SIZE(ov519_vga_mode); - break; - case BRIDGE_OVFX2: - cam->cam_mode = ov519_vga_mode; - cam->nmodes = ARRAY_SIZE(ov519_vga_mode); - cam->bulk_size = OVFX2_BULK_SIZE; - cam->bulk_nurbs = MAX_NURBS; - cam->bulk = 1; - break; - case BRIDGE_W9968CF: - cam->cam_mode = w9968cf_vga_mode; - cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); - break; - } - - sd->frame_rate = 15; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ov511_configure(gspca_dev); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - ov518_configure(gspca_dev); - break; - case BRIDGE_OV519: - ov519_configure(sd); - break; - case BRIDGE_OVFX2: - ovfx2_configure(sd); - break; - case BRIDGE_W9968CF: - w9968cf_configure(sd); - break; - } - - /* The OV519 must be more aggressive about sensor detection since - * I2C write will never fail if the sensor is not present. We have - * to try to initialize the sensor to detect its presence */ - sd->sensor = -1; - - /* Test for 76xx */ - if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { - ov7xx0_configure(sd); - - /* Test for 6xx0 */ - } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { - ov6xx0_configure(sd); - - /* Test for 8xx0 */ - } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { - ov8xx0_configure(sd); - - /* Test for 3xxx / 2xxx */ - } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { - ov_hires_configure(sd); - } else { - pr_err("Can't determine sensor slave IDs\n"); - goto error; - } - - if (sd->sensor < 0) - goto error; - - ov51x_led_control(sd, 0); /* turn LED off */ - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - if (sd->sif) { - cam->cam_mode = ov511_sif_mode; - cam->nmodes = ARRAY_SIZE(ov511_sif_mode); - } - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - if (sd->sif) { - cam->cam_mode = ov518_sif_mode; - cam->nmodes = ARRAY_SIZE(ov518_sif_mode); - } - break; - case BRIDGE_OV519: - if (sd->sif) { - cam->cam_mode = ov519_sif_mode; - cam->nmodes = ARRAY_SIZE(ov519_sif_mode); - } - break; - case BRIDGE_OVFX2: - switch (sd->sensor) { - case SEN_OV2610: - case SEN_OV2610AE: - cam->cam_mode = ovfx2_ov2610_mode; - cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); - break; - case SEN_OV3610: - cam->cam_mode = ovfx2_ov3610_mode; - cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); - break; - case SEN_OV9600: - cam->cam_mode = ovfx2_ov9600_mode; - cam->nmodes = ARRAY_SIZE(ovfx2_ov9600_mode); - break; - default: - if (sd->sif) { - cam->cam_mode = ov519_sif_mode; - cam->nmodes = ARRAY_SIZE(ov519_sif_mode); - } - break; - } - break; - case BRIDGE_W9968CF: - if (sd->sif) - cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1; - - /* w9968cf needs initialisation once the sensor is known */ - w9968cf_init(sd); - break; - } - - /* initialize the sensor */ - switch (sd->sensor) { - case SEN_OV2610: - write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)); - - /* Enable autogain, autoexpo, awb, bandfilter */ - i2c_w_mask(sd, 0x13, 0x27, 0x27); - break; - case SEN_OV2610AE: - write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae)); - - /* enable autoexpo */ - i2c_w_mask(sd, 0x13, 0x05, 0x05); - break; - case SEN_OV3610: - write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); - - /* Enable autogain, autoexpo, awb, bandfilter */ - i2c_w_mask(sd, 0x13, 0x27, 0x27); - break; - case SEN_OV6620: - write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)); - break; - case SEN_OV6630: - case SEN_OV66308AF: - write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); - break; - default: -/* case SEN_OV7610: */ -/* case SEN_OV76BE: */ - write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)); - i2c_w_mask(sd, 0x0e, 0x00, 0x40); - break; - case SEN_OV7620: - case SEN_OV7620AE: - write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)); - break; - case SEN_OV7640: - case SEN_OV7648: - write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)); - break; - case SEN_OV7660: - i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET); - msleep(14); - reg_w(sd, OV519_R57_SNAPSHOT, 0x23); - write_regvals(sd, init_519_ov7660, - ARRAY_SIZE(init_519_ov7660)); - write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660)); - sd->gspca_dev.curr_mode = 1; /* 640x480 */ - ov519_set_mode(sd); - ov519_set_fr(sd); - sd_reset_snapshot(gspca_dev); - ov51x_restart(sd); - ov51x_stop(sd); /* not in win traces */ - ov51x_led_control(sd, 0); - break; - case SEN_OV7670: - write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); - break; - case SEN_OV8610: - write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)); - break; - case SEN_OV9600: - write_i2c_regvals(sd, norm_9600, ARRAY_SIZE(norm_9600)); - - /* enable autoexpo */ -/* i2c_w_mask(sd, 0x13, 0x05, 0x05); */ - break; - } - return gspca_dev->usb_err; -error: - PDEBUG(D_ERR, "OV519 Config failed"); - return -EINVAL; -} - -/* function called at start time before URB creation */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - case BRIDGE_OVFX2: - if (gspca_dev->width != 800) - gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE; - else - gspca_dev->cam.bulk_size = 7 * 4096; - break; - } - return 0; -} - -/* Set up the OV511/OV511+ with the given image parameters. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static void ov511_mode_init_regs(struct sd *sd) -{ - int hsegs, vsegs, packet_size, fps, needed; - int interlaced = 0; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - pr_err("Couldn't get altsetting\n"); - sd->gspca_dev.usb_err = -EIO; - return; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5); - - reg_w(sd, R511_CAM_UV_EN, 0x01); - reg_w(sd, R511_SNAP_UV_EN, 0x01); - reg_w(sd, R511_SNAP_OPTS, 0x03); - - /* Here I'm assuming that snapshot size == image size. - * I hope that's always true. --claudio - */ - hsegs = (sd->gspca_dev.width >> 3) - 1; - vsegs = (sd->gspca_dev.height >> 3) - 1; - - reg_w(sd, R511_CAM_PXCNT, hsegs); - reg_w(sd, R511_CAM_LNCNT, vsegs); - reg_w(sd, R511_CAM_PXDIV, 0x00); - reg_w(sd, R511_CAM_LNDIV, 0x00); - - /* YUV420, low pass filter on */ - reg_w(sd, R511_CAM_OPTS, 0x03); - - /* Snapshot additions */ - reg_w(sd, R511_SNAP_PXCNT, hsegs); - reg_w(sd, R511_SNAP_LNCNT, vsegs); - reg_w(sd, R511_SNAP_PXDIV, 0x00); - reg_w(sd, R511_SNAP_LNDIV, 0x00); - - /******** Set the framerate ********/ - if (frame_rate > 0) - sd->frame_rate = frame_rate; - - switch (sd->sensor) { - case SEN_OV6620: - /* No framerate control, doesn't like higher rates yet */ - sd->clockdiv = 3; - break; - - /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed - for more sensors we need to do this for them too */ - case SEN_OV7620: - case SEN_OV7620AE: - case SEN_OV7640: - case SEN_OV7648: - case SEN_OV76BE: - if (sd->gspca_dev.width == 320) - interlaced = 1; - /* Fall through */ - case SEN_OV6630: - case SEN_OV7610: - case SEN_OV7670: - switch (sd->frame_rate) { - case 30: - case 25: - /* Not enough bandwidth to do 640x480 @ 30 fps */ - if (sd->gspca_dev.width != 640) { - sd->clockdiv = 0; - break; - } - /* Fall through for 640x480 case */ - default: -/* case 20: */ -/* case 15: */ - sd->clockdiv = 1; - break; - case 10: - sd->clockdiv = 2; - break; - case 5: - sd->clockdiv = 5; - break; - } - if (interlaced) { - sd->clockdiv = (sd->clockdiv + 1) * 2 - 1; - /* Higher then 10 does not work */ - if (sd->clockdiv > 10) - sd->clockdiv = 10; - } - break; - - case SEN_OV8610: - /* No framerate control ?? */ - sd->clockdiv = 0; - break; - } - - /* Check if we have enough bandwidth to disable compression */ - fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1; - needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2; - /* 1000 isoc packets/sec */ - if (needed > 1000 * packet_size) { - /* Enable Y and UV quantization and compression */ - reg_w(sd, R511_COMP_EN, 0x07); - reg_w(sd, R511_COMP_LUT_EN, 0x03); - } else { - reg_w(sd, R511_COMP_EN, 0x06); - reg_w(sd, R511_COMP_LUT_EN, 0x00); - } - - reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); - reg_w(sd, R51x_SYS_RESET, 0); -} - -/* Sets up the OV518/OV518+ with the given image parameters - * - * OV518 needs a completely different approach, until we can figure out what - * the individual registers do. Also, only 15 FPS is supported now. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static void ov518_mode_init_regs(struct sd *sd) -{ - int hsegs, vsegs, packet_size; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - pr_err("Couldn't get altsetting\n"); - sd->gspca_dev.usb_err = -EIO; - return; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); - - /******** Set the mode ********/ - reg_w(sd, 0x2b, 0); - reg_w(sd, 0x2c, 0); - reg_w(sd, 0x2d, 0); - reg_w(sd, 0x2e, 0); - reg_w(sd, 0x3b, 0); - reg_w(sd, 0x3c, 0); - reg_w(sd, 0x3d, 0); - reg_w(sd, 0x3e, 0); - - if (sd->bridge == BRIDGE_OV518) { - /* Set 8-bit (YVYU) input format */ - reg_w_mask(sd, 0x20, 0x08, 0x08); - - /* Set 12-bit (4:2:0) output format */ - reg_w_mask(sd, 0x28, 0x80, 0xf0); - reg_w_mask(sd, 0x38, 0x80, 0xf0); - } else { - reg_w(sd, 0x28, 0x80); - reg_w(sd, 0x38, 0x80); - } - - hsegs = sd->gspca_dev.width / 16; - vsegs = sd->gspca_dev.height / 4; - - reg_w(sd, 0x29, hsegs); - reg_w(sd, 0x2a, vsegs); - - reg_w(sd, 0x39, hsegs); - reg_w(sd, 0x3a, vsegs); - - /* Windows driver does this here; who knows why */ - reg_w(sd, 0x2f, 0x80); - - /******** Set the framerate ********/ - sd->clockdiv = 1; - - /* Mode independent, but framerate dependent, regs */ - /* 0x51: Clock divider; Only works on some cams which use 2 crystals */ - reg_w(sd, 0x51, 0x04); - reg_w(sd, 0x22, 0x18); - reg_w(sd, 0x23, 0xff); - - if (sd->bridge == BRIDGE_OV518PLUS) { - switch (sd->sensor) { - case SEN_OV7620AE: - if (sd->gspca_dev.width == 320) { - reg_w(sd, 0x20, 0x00); - reg_w(sd, 0x21, 0x19); - } else { - reg_w(sd, 0x20, 0x60); - reg_w(sd, 0x21, 0x1f); - } - break; - case SEN_OV7620: - reg_w(sd, 0x20, 0x00); - reg_w(sd, 0x21, 0x19); - break; - default: - reg_w(sd, 0x21, 0x19); - } - } else - reg_w(sd, 0x71, 0x17); /* Compression-related? */ - - /* FIXME: Sensor-specific */ - /* Bit 5 is what matters here. Of course, it is "reserved" */ - i2c_w(sd, 0x54, 0x23); - - reg_w(sd, 0x2f, 0x80); - - if (sd->bridge == BRIDGE_OV518PLUS) { - reg_w(sd, 0x24, 0x94); - reg_w(sd, 0x25, 0x90); - ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ - ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */ - ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */ - ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */ - ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */ - ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */ - ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */ - ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */ - ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */ - } else { - reg_w(sd, 0x24, 0x9f); - reg_w(sd, 0x25, 0x90); - ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ - ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */ - ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */ - ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */ - ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */ - ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */ - ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */ - ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */ - ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */ - } - - reg_w(sd, 0x2f, 0x80); -} - -/* Sets up the OV519 with the given image parameters - * - * OV519 needs a completely different approach, until we can figure out what - * the individual registers do. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static void ov519_mode_init_regs(struct sd *sd) -{ - static const struct ov_regvals mode_init_519_ov7670[] = { - { 0x5d, 0x03 }, /* Turn off suspend mode */ - { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ - { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ - { 0xa2, 0x20 }, /* a2-a5 are undocumented */ - { 0xa3, 0x18 }, - { 0xa4, 0x04 }, - { 0xa5, 0x28 }, - { 0x37, 0x00 }, /* SetUsbInit */ - { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ - /* Enable both fields, YUV Input, disable defect comp (why?) */ - { 0x20, 0x0c }, - { 0x21, 0x38 }, - { 0x22, 0x1d }, - { 0x17, 0x50 }, /* undocumented */ - { 0x37, 0x00 }, /* undocumented */ - { 0x40, 0xff }, /* I2C timeout counter */ - { 0x46, 0x00 }, /* I2C clock prescaler */ - { 0x59, 0x04 }, /* new from windrv 090403 */ - { 0xff, 0x00 }, /* undocumented */ - /* windows reads 0x55 at this point, why? */ - }; - - static const struct ov_regvals mode_init_519[] = { - { 0x5d, 0x03 }, /* Turn off suspend mode */ - { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ - { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ - { 0xa2, 0x20 }, /* a2-a5 are undocumented */ - { 0xa3, 0x18 }, - { 0xa4, 0x04 }, - { 0xa5, 0x28 }, - { 0x37, 0x00 }, /* SetUsbInit */ - { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ - /* Enable both fields, YUV Input, disable defect comp (why?) */ - { 0x22, 0x1d }, - { 0x17, 0x50 }, /* undocumented */ - { 0x37, 0x00 }, /* undocumented */ - { 0x40, 0xff }, /* I2C timeout counter */ - { 0x46, 0x00 }, /* I2C clock prescaler */ - { 0x59, 0x04 }, /* new from windrv 090403 */ - { 0xff, 0x00 }, /* undocumented */ - /* windows reads 0x55 at this point, why? */ - }; - - /******** Set the mode ********/ - switch (sd->sensor) { - default: - write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519)); - if (sd->sensor == SEN_OV7640 || - sd->sensor == SEN_OV7648) { - /* Select 8-bit input mode */ - reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); - } - break; - case SEN_OV7660: - return; /* done by ov519_set_mode/fr() */ - case SEN_OV7670: - write_regvals(sd, mode_init_519_ov7670, - ARRAY_SIZE(mode_init_519_ov7670)); - break; - } - - reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); - reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3); - if (sd->sensor == SEN_OV7670 && - sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) - reg_w(sd, OV519_R12_X_OFFSETL, 0x04); - else if (sd->sensor == SEN_OV7648 && - sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) - reg_w(sd, OV519_R12_X_OFFSETL, 0x01); - else - reg_w(sd, OV519_R12_X_OFFSETL, 0x00); - reg_w(sd, OV519_R13_X_OFFSETH, 0x00); - reg_w(sd, OV519_R14_Y_OFFSETL, 0x00); - reg_w(sd, OV519_R15_Y_OFFSETH, 0x00); - reg_w(sd, OV519_R16_DIVIDER, 0x00); - reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */ - reg_w(sd, 0x26, 0x00); /* Undocumented */ - - /******** Set the framerate ********/ - if (frame_rate > 0) - sd->frame_rate = frame_rate; - -/* FIXME: These are only valid at the max resolution. */ - sd->clockdiv = 0; - switch (sd->sensor) { - case SEN_OV7640: - case SEN_OV7648: - switch (sd->frame_rate) { - default: -/* case 30: */ - reg_w(sd, 0xa4, 0x0c); - reg_w(sd, 0x23, 0xff); - break; - case 25: - reg_w(sd, 0xa4, 0x0c); - reg_w(sd, 0x23, 0x1f); - break; - case 20: - reg_w(sd, 0xa4, 0x0c); - reg_w(sd, 0x23, 0x1b); - break; - case 15: - reg_w(sd, 0xa4, 0x04); - reg_w(sd, 0x23, 0xff); - sd->clockdiv = 1; - break; - case 10: - reg_w(sd, 0xa4, 0x04); - reg_w(sd, 0x23, 0x1f); - sd->clockdiv = 1; - break; - case 5: - reg_w(sd, 0xa4, 0x04); - reg_w(sd, 0x23, 0x1b); - sd->clockdiv = 1; - break; - } - break; - case SEN_OV8610: - switch (sd->frame_rate) { - default: /* 15 fps */ -/* case 15: */ - reg_w(sd, 0xa4, 0x06); - reg_w(sd, 0x23, 0xff); - break; - case 10: - reg_w(sd, 0xa4, 0x06); - reg_w(sd, 0x23, 0x1f); - break; - case 5: - reg_w(sd, 0xa4, 0x06); - reg_w(sd, 0x23, 0x1b); - break; - } - break; - case SEN_OV7670: /* guesses, based on 7640 */ - PDEBUG(D_STREAM, "Setting framerate to %d fps", - (sd->frame_rate == 0) ? 15 : sd->frame_rate); - reg_w(sd, 0xa4, 0x10); - switch (sd->frame_rate) { - case 30: - reg_w(sd, 0x23, 0xff); - break; - case 20: - reg_w(sd, 0x23, 0x1b); - break; - default: -/* case 15: */ - reg_w(sd, 0x23, 0xff); - sd->clockdiv = 1; - break; - } - break; - } -} - -static void mode_init_ov_sensor_regs(struct sd *sd) -{ - struct gspca_dev *gspca_dev; - int qvga, xstart, xend, ystart, yend; - u8 v; - - gspca_dev = &sd->gspca_dev; - qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; - - /******** Mode (VGA/QVGA) and sensor specific regs ********/ - switch (sd->sensor) { - case SEN_OV2610: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); - i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); - i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); - i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); - i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); - i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); - return; - case SEN_OV2610AE: { - u8 v; - - /* frame rates: - * 10fps / 5 fps for 1600x1200 - * 40fps / 20fps for 800x600 - */ - v = 80; - if (qvga) { - if (sd->frame_rate < 25) - v = 0x81; - } else { - if (sd->frame_rate < 10) - v = 0x81; - } - i2c_w(sd, 0x11, v); - i2c_w(sd, 0x12, qvga ? 0x60 : 0x20); - return; - } - case SEN_OV3610: - if (qvga) { - xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); - ystart = (776 - gspca_dev->height) / 2; - } else { - xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4); - ystart = (1544 - gspca_dev->height) / 2; - } - xend = xstart + gspca_dev->width; - yend = ystart + gspca_dev->height; - /* Writing to the COMH register resets the other windowing regs - to their default values, so we must do this first. */ - i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0); - i2c_w_mask(sd, 0x32, - (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7), - 0x3f); - i2c_w_mask(sd, 0x03, - (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3), - 0x0f); - i2c_w(sd, 0x17, xstart >> 4); - i2c_w(sd, 0x18, xend >> 4); - i2c_w(sd, 0x19, ystart >> 3); - i2c_w(sd, 0x1a, yend >> 3); - return; - case SEN_OV8610: - /* For OV8610 qvga means qsvga */ - i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); - i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ - i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ - i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */ - i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */ - break; - case SEN_OV7610: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); - i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ - i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ - break; - case SEN_OV7620: - case SEN_OV7620AE: - case SEN_OV76BE: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); - i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); - i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); - i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); - i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); - i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ - i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ - if (sd->sensor == SEN_OV76BE) - i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); - break; - case SEN_OV7640: - case SEN_OV7648: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); - /* Setting this undocumented bit in qvga mode removes a very - annoying vertical shaking of the image */ - i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); - /* Unknown */ - i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); - /* Allow higher automatic gain (to allow higher framerates) */ - i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ - break; - case SEN_OV7670: - /* set COM7_FMT_VGA or COM7_FMT_QVGA - * do we need to set anything else? - * HSTART etc are set in set_ov_sensor_window itself */ - i2c_w_mask(sd, OV7670_R12_COM7, - qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, - OV7670_COM7_FMT_MASK); - i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ - i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB, - OV7670_COM8_AWB); - if (qvga) { /* QVGA from ov7670.c by - * Jonathan Corbet */ - xstart = 164; - xend = 28; - ystart = 14; - yend = 494; - } else { /* VGA */ - xstart = 158; - xend = 14; - ystart = 10; - yend = 490; - } - /* OV7670 hardware window registers are split across - * multiple locations */ - i2c_w(sd, OV7670_R17_HSTART, xstart >> 3); - i2c_w(sd, OV7670_R18_HSTOP, xend >> 3); - v = i2c_r(sd, OV7670_R32_HREF); - v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); - msleep(10); /* need to sleep between read and write to - * same reg! */ - i2c_w(sd, OV7670_R32_HREF, v); - - i2c_w(sd, OV7670_R19_VSTART, ystart >> 2); - i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2); - v = i2c_r(sd, OV7670_R03_VREF); - v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); - msleep(10); /* need to sleep between read and write to - * same reg! */ - i2c_w(sd, OV7670_R03_VREF, v); - break; - case SEN_OV6620: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ - i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ - break; - case SEN_OV6630: - case SEN_OV66308AF: - i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); - i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ - break; - case SEN_OV9600: { - const struct ov_i2c_regvals *vals; - static const struct ov_i2c_regvals sxga_15[] = { - {0x11, 0x80}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75} - }; - static const struct ov_i2c_regvals sxga_7_5[] = { - {0x11, 0x81}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75} - }; - static const struct ov_i2c_regvals vga_30[] = { - {0x11, 0x81}, {0x14, 0x7e}, {0x24, 0x70}, {0x25, 0x60} - }; - static const struct ov_i2c_regvals vga_15[] = { - {0x11, 0x83}, {0x14, 0x3e}, {0x24, 0x80}, {0x25, 0x70} - }; - - /* frame rates: - * 15fps / 7.5 fps for 1280x1024 - * 30fps / 15fps for 640x480 - */ - i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0x40); - if (qvga) - vals = sd->frame_rate < 30 ? vga_15 : vga_30; - else - vals = sd->frame_rate < 15 ? sxga_7_5 : sxga_15; - write_i2c_regvals(sd, vals, ARRAY_SIZE(sxga_15)); - return; - } - default: - return; - } - - /******** Clock programming ********/ - i2c_w(sd, 0x11, sd->clockdiv); -} - -/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ -static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->gspca_dev.streaming) - reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ - i2c_w_mask(sd, OV7670_R1E_MVFP, - OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip, - OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); - if (sd->gspca_dev.streaming) - reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ -} - -static void set_ov_sensor_window(struct sd *sd) -{ - struct gspca_dev *gspca_dev; - int qvga, crop; - int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; - - /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ - switch (sd->sensor) { - case SEN_OV2610: - case SEN_OV2610AE: - case SEN_OV3610: - case SEN_OV7670: - case SEN_OV9600: - mode_init_ov_sensor_regs(sd); - return; - case SEN_OV7660: - ov519_set_mode(sd); - ov519_set_fr(sd); - return; - } - - gspca_dev = &sd->gspca_dev; - qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; - crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2; - - /* The different sensor ICs handle setting up of window differently. - * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ - switch (sd->sensor) { - case SEN_OV8610: - hwsbase = 0x1e; - hwebase = 0x1e; - vwsbase = 0x02; - vwebase = 0x02; - break; - case SEN_OV7610: - case SEN_OV76BE: - hwsbase = 0x38; - hwebase = 0x3a; - vwsbase = vwebase = 0x05; - break; - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV66308AF: - hwsbase = 0x38; - hwebase = 0x3a; - vwsbase = 0x05; - vwebase = 0x06; - if (sd->sensor == SEN_OV66308AF && qvga) - /* HDG: this fixes U and V getting swapped */ - hwsbase++; - if (crop) { - hwsbase += 8; - hwebase += 8; - vwsbase += 11; - vwebase += 11; - } - break; - case SEN_OV7620: - case SEN_OV7620AE: - hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ - hwebase = 0x2f; - vwsbase = vwebase = 0x05; - break; - case SEN_OV7640: - case SEN_OV7648: - hwsbase = 0x1a; - hwebase = 0x1a; - vwsbase = vwebase = 0x03; - break; - default: - return; - } - - switch (sd->sensor) { - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV66308AF: - if (qvga) { /* QCIF */ - hwscale = 0; - vwscale = 0; - } else { /* CIF */ - hwscale = 1; - vwscale = 1; /* The datasheet says 0; - * it's wrong */ - } - break; - case SEN_OV8610: - if (qvga) { /* QSVGA */ - hwscale = 1; - vwscale = 1; - } else { /* SVGA */ - hwscale = 2; - vwscale = 2; - } - break; - default: /* SEN_OV7xx0 */ - if (qvga) { /* QVGA */ - hwscale = 1; - vwscale = 0; - } else { /* VGA */ - hwscale = 2; - vwscale = 1; - } - } - - mode_init_ov_sensor_regs(sd); - - i2c_w(sd, 0x17, hwsbase); - i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); - i2c_w(sd, 0x19, vwsbase); - i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Default for most bridges, allow bridge_mode_init_regs to override */ - sd->sensor_width = sd->gspca_dev.width; - sd->sensor_height = sd->gspca_dev.height; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ov511_mode_init_regs(sd); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - ov518_mode_init_regs(sd); - break; - case BRIDGE_OV519: - ov519_mode_init_regs(sd); - break; - /* case BRIDGE_OVFX2: nothing to do */ - case BRIDGE_W9968CF: - w9968cf_mode_init_regs(sd); - break; - } - - set_ov_sensor_window(sd); - - /* Force clear snapshot state in case the snapshot button was - pressed while we weren't streaming */ - sd->snapshot_needs_reset = 1; - sd_reset_snapshot(gspca_dev); - - sd->first_frame = 3; - - ov51x_restart(sd); - ov51x_led_control(sd, 1); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - ov51x_stop(sd); - ov51x_led_control(sd, 0); -} - -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!sd->gspca_dev.present) - return; - if (sd->bridge == BRIDGE_W9968CF) - w9968cf_stop0(sd); - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - /* If the last button state is pressed, release it now! */ - if (sd->snapshot_pressed) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - sd->snapshot_pressed = 0; - } -#endif - if (sd->bridge == BRIDGE_OV519) - reg_w(sd, OV519_R57_SNAPSHOT, 0x23); -} - -static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->snapshot_pressed != state) { -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - input_report_key(gspca_dev->input_dev, KEY_CAMERA, state); - input_sync(gspca_dev->input_dev); -#endif - if (state) - sd->snapshot_needs_reset = 1; - - sd->snapshot_pressed = state; - } else { - /* On the ov511 / ov519 we need to reset the button state - multiple times, as resetting does not work as long as the - button stays pressed */ - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - case BRIDGE_OV519: - if (state) - sd->snapshot_needs_reset = 1; - break; - } - } -} - -static void ov511_pkt_scan(struct gspca_dev *gspca_dev, - u8 *in, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th - * byte non-zero. The EOF packet has image width/height in the - * 10th and 11th bytes. The 9th byte is given as follows: - * - * bit 7: EOF - * 6: compression enabled - * 5: 422/420/400 modes - * 4: 422/420/400 modes - * 3: 1 - * 2: snapshot button on - * 1: snapshot frame - * 0: even/odd field - */ - if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && - (in[8] & 0x08)) { - ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1); - if (in[8] & 0x80) { - /* Frame end */ - if ((in[9] + 1) * 8 != gspca_dev->width || - (in[10] + 1) * 8 != gspca_dev->height) { - PDEBUG(D_ERR, "Invalid frame size, got: %dx%d," - " requested: %dx%d\n", - (in[9] + 1) * 8, (in[10] + 1) * 8, - gspca_dev->width, gspca_dev->height); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - /* Add 11 byte footer to frame, might be useful */ - gspca_frame_add(gspca_dev, LAST_PACKET, in, 11); - return; - } else { - /* Frame start */ - gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0); - sd->packet_nr = 0; - } - } - - /* Ignore the packet number */ - len--; - - /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, in, len); -} - -static void ov518_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* A false positive here is likely, until OVT gives me - * the definitive SOF/EOF format */ - if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { - ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1); - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - sd->packet_nr = 0; - } - - if (gspca_dev->last_packet_type == DISCARD_PACKET) - return; - - /* Does this device use packet numbers ? */ - if (len & 7) { - len--; - if (sd->packet_nr == data[len]) - sd->packet_nr++; - /* The last few packets of the frame (which are all 0's - except that they may contain part of the footer), are - numbered 0 */ - else if (sd->packet_nr == 0 || data[len]) { - PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)", - (int)data[len], (int)sd->packet_nr); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - } - - /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void ov519_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - /* Header of ov519 is 16 bytes: - * Byte Value Description - * 0 0xff magic - * 1 0xff magic - * 2 0xff magic - * 3 0xXX 0x50 = SOF, 0x51 = EOF - * 9 0xXX 0x01 initial frame without data, - * 0x00 standard frame with image - * 14 Lo in EOF: length of image data / 8 - * 15 Hi - */ - - if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { - switch (data[3]) { - case 0x50: /* start of frame */ - /* Don't check the button state here, as the state - usually (always ?) changes at EOF and checking it - here leads to unnecessary snapshot state resets. */ -#define HDRSZ 16 - data += HDRSZ; - len -= HDRSZ; -#undef HDRSZ - if (data[0] == 0xff || data[1] == 0xd8) - gspca_frame_add(gspca_dev, FIRST_PACKET, - data, len); - else - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - case 0x51: /* end of frame */ - ov51x_handle_button(gspca_dev, data[11] & 1); - if (data[9] != 0) - gspca_dev->last_packet_type = DISCARD_PACKET; - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - return; - } - } - - /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - - /* A short read signals EOF */ - if (len < gspca_dev->cam.bulk_size) { - /* If the frame is short, and it is one of the first ones - the sensor and bridge are still syncing, so drop it. */ - if (sd->first_frame) { - sd->first_frame--; - if (gspca_dev->image_len < - sd->gspca_dev.width * sd->gspca_dev.height) - gspca_dev->last_packet_type = DISCARD_PACKET; - } - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - } -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ov511_pkt_scan(gspca_dev, data, len); - break; - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - ov518_pkt_scan(gspca_dev, data, len); - break; - case BRIDGE_OV519: - ov519_pkt_scan(gspca_dev, data, len); - break; - case BRIDGE_OVFX2: - ovfx2_pkt_scan(gspca_dev, data, len); - break; - case BRIDGE_W9968CF: - w9968cf_pkt_scan(gspca_dev, data, len); - break; - } -} - -/* -- management routines -- */ - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct ov_i2c_regvals brit_7660[][7] = { - {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, - {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, - {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1}, - {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}}, - {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2}, - {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}}, - {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3}, - {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}}, - {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3}, - {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}}, - {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3}, - {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}}, - {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4}, - {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} - }; - - switch (sd->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV66308AF: - case SEN_OV7640: - case SEN_OV7648: - i2c_w(sd, OV7610_REG_BRT, val); - break; - case SEN_OV7620: - case SEN_OV7620AE: - i2c_w(sd, OV7610_REG_BRT, val); - break; - case SEN_OV7660: - write_i2c_regvals(sd, brit_7660[val], - ARRAY_SIZE(brit_7660[0])); - break; - case SEN_OV7670: -/*win trace - * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */ - i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val)); - break; - } -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct ov_i2c_regvals contrast_7660[][31] = { - {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, - {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, - {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24}, - {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34}, - {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65}, - {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83}, - {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f}, - {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}}, - {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94}, - {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30}, - {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24}, - {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31}, - {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62}, - {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81}, - {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1}, - {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}}, - {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84}, - {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40}, - {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24}, - {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34}, - {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d}, - {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81}, - {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e}, - {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}}, - {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70}, - {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48}, - {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34}, - {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22}, - {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58}, - {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80}, - {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9}, - {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}}, - {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80}, - {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60}, - {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38}, - {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e}, - {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46}, - {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c}, - {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4}, - {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}}, - {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80}, - {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30}, - {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50}, - {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08}, - {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a}, - {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b}, - {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3}, - {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}}, - {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60}, - {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8}, - {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c}, - {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04}, - {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22}, - {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b}, - {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde}, - {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, - }; - - switch (sd->sensor) { - case SEN_OV7610: - case SEN_OV6620: - i2c_w(sd, OV7610_REG_CNT, val); - break; - case SEN_OV6630: - case SEN_OV66308AF: - i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); - break; - case SEN_OV8610: { - static const u8 ctab[] = { - 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f - }; - - /* Use Y gamma control instead. Bit 0 enables it. */ - i2c_w(sd, 0x64, ctab[val >> 5]); - break; - } - case SEN_OV7620: - case SEN_OV7620AE: { - static const u8 ctab[] = { - 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, - 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff - }; - - /* Use Y gamma control instead. Bit 0 enables it. */ - i2c_w(sd, 0x64, ctab[val >> 4]); - break; - } - case SEN_OV7660: - write_i2c_regvals(sd, contrast_7660[val], - ARRAY_SIZE(contrast_7660[0])); - break; - case SEN_OV7670: - /* check that this isn't just the same as ov7610 */ - i2c_w(sd, OV7670_R56_CONTRAS, val >> 1); - break; - } -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w(sd, 0x10, val); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct ov_i2c_regvals colors_7660[][6] = { - {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, - {0x53, 0x19}, {0x54, 0x23}}, - {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11}, - {0x53, 0x2c}, {0x54, 0x3e}}, - {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19}, - {0x53, 0x40}, {0x54, 0x59}}, - {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20}, - {0x53, 0x53}, {0x54, 0x73}}, - {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28}, - {0x53, 0x66}, {0x54, 0x8e}}, - }; - - switch (sd->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV66308AF: - i2c_w(sd, OV7610_REG_SAT, val); - break; - case SEN_OV7620: - case SEN_OV7620AE: - /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ -/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); - if (rc < 0) - goto out; */ - i2c_w(sd, OV7610_REG_SAT, val); - break; - case SEN_OV7640: - case SEN_OV7648: - i2c_w(sd, OV7610_REG_SAT, val & 0xf0); - break; - case SEN_OV7660: - write_i2c_regvals(sd, colors_7660[val], - ARRAY_SIZE(colors_7660[0])); - break; - case SEN_OV7670: - /* supported later once I work out how to do it - * transparently fail now! */ - /* set REG_COM13 values for UV sat auto mode */ - break; - } -} - -static void setautobright(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10); -} - -static void setfreq_i(struct sd *sd, s32 val) -{ - if (sd->sensor == SEN_OV7660 - || sd->sensor == SEN_OV7670) { - switch (val) { - case 0: /* Banding filter disabled */ - i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); - break; - case 1: /* 50 hz */ - i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18); - break; - case 2: /* 60 hz */ - i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18); - break; - case 3: /* Auto hz - ov7670 only */ - i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO, - 0x18); - break; - } - } else { - switch (val) { - case 0: /* Banding filter disabled */ - i2c_w_mask(sd, 0x2d, 0x00, 0x04); - i2c_w_mask(sd, 0x2a, 0x00, 0x80); - break; - case 1: /* 50 hz (filter on and framerate adj) */ - i2c_w_mask(sd, 0x2d, 0x04, 0x04); - i2c_w_mask(sd, 0x2a, 0x80, 0x80); - /* 20 fps -> 16.667 fps */ - if (sd->sensor == SEN_OV6620 || - sd->sensor == SEN_OV6630 || - sd->sensor == SEN_OV66308AF) - i2c_w(sd, 0x2b, 0x5e); - else - i2c_w(sd, 0x2b, 0xac); - break; - case 2: /* 60 hz (filter on, ...) */ - i2c_w_mask(sd, 0x2d, 0x04, 0x04); - if (sd->sensor == SEN_OV6620 || - sd->sensor == SEN_OV6630 || - sd->sensor == SEN_OV66308AF) { - /* 20 fps -> 15 fps */ - i2c_w_mask(sd, 0x2a, 0x80, 0x80); - i2c_w(sd, 0x2b, 0xa8); - } else { - /* no framerate adj. */ - i2c_w_mask(sd, 0x2a, 0x00, 0x80); - } - break; - } - } -} - -static void setfreq(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - setfreq_i(sd, val); - - /* Ugly but necessary */ - if (sd->bridge == BRIDGE_W9968CF) - w9968cf_set_crop_window(sd); -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->bridge != BRIDGE_W9968CF) - return -ENOTTY; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | - V4L2_JPEG_MARKER_DRI; - return 0; -} - -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->bridge != BRIDGE_W9968CF) - return -ENOTTY; - - v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); - return 0; -} - -static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - gspca_dev->exposure->val = i2c_r(sd, 0x10); - break; - } - return 0; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setfreq(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOBRIGHTNESS: - if (ctrl->is_new) - setautobright(gspca_dev, ctrl->val); - if (!ctrl->val && sd->brightness->is_new) - setbrightness(gspca_dev, sd->brightness->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_HFLIP: - sethvflip(gspca_dev, ctrl->val, sd->vflip->val); - break; - case V4L2_CID_AUTOGAIN: - if (ctrl->is_new) - setautogain(gspca_dev, ctrl->val); - if (!ctrl->val && gspca_dev->exposure->is_new) - setexposure(gspca_dev, gspca_dev->exposure->val); - break; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - return -EBUSY; /* Should never happen, as we grab the ctrl */ - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .g_volatile_ctrl = sd_g_volatile_ctrl, - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 10); - if (valid_controls[sd->sensor].has_brightness) - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, - sd->sensor == SEN_OV7660 ? 6 : 255, 1, - sd->sensor == SEN_OV7660 ? 3 : 127); - if (valid_controls[sd->sensor].has_contrast) { - if (sd->sensor == SEN_OV7660) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 6, 1, 3); - else - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, - (sd->sensor == SEN_OV6630 || - sd->sensor == SEN_OV66308AF) ? 200 : 127); - } - if (valid_controls[sd->sensor].has_sat) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, - sd->sensor == SEN_OV7660 ? 4 : 255, 1, - sd->sensor == SEN_OV7660 ? 2 : 127); - if (valid_controls[sd->sensor].has_exposure) - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 255, 1, 127); - if (valid_controls[sd->sensor].has_hvflip) { - sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - } - if (valid_controls[sd->sensor].has_autobright) - sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1); - if (valid_controls[sd->sensor].has_autogain) - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - if (valid_controls[sd->sensor].has_freq) { - if (sd->sensor == SEN_OV7670) - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, - V4L2_CID_POWER_LINE_FREQUENCY_AUTO); - else - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); - } - if (sd->bridge == BRIDGE_W9968CF) - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, - QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (gspca_dev->autogain) - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true); - if (sd->autobright) - v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false); - if (sd->hflip) - v4l2_ctrl_cluster(2, &sd->hflip); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_reset_snapshot, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF }, - {USB_DEVICE(0x041e, 0x4052), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, - {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x045e, 0x028c), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, - {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, - {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, - {USB_DEVICE(0x05a9, 0x0519), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, - {USB_DEVICE(0x05a9, 0x0530), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, - {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 }, - {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, - {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, - {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, - {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, - {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, - {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, - {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 }, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(frame_rate, int, 0644); -MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c deleted file mode 100644 index bb09d7884b89..000000000000 --- a/drivers/media/video/gspca/ov534.c +++ /dev/null @@ -1,1544 +0,0 @@ -/* - * ov534-ov7xxx gspca driver - * - * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> - * Copyright (C) 2008 Jim Paris <jim@jtan.com> - * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr - * - * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> - * USB protocol reverse engineered by Jim Paris <jim@jtan.com> - * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ - * - * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr - * PS3 Eye camera - brightness, contrast, awb, agc, aec controls - * added by Max Thrun <bear24rw@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "ov534" - -#include "gspca.h" - -#include <linux/fixp-arith.h> -#include <media/v4l2-ctrls.h> - -#define OV534_REG_ADDRESS 0xf1 /* sensor address */ -#define OV534_REG_SUBADDR 0xf2 -#define OV534_REG_WRITE 0xf3 -#define OV534_REG_READ 0xf4 -#define OV534_REG_OPERATION 0xf5 -#define OV534_REG_STATUS 0xf6 - -#define OV534_OP_WRITE_3 0x37 -#define OV534_OP_WRITE_2 0x33 -#define OV534_OP_READ_2 0xf9 - -#define CTRL_TIMEOUT 500 - -MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); -MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_ctrl *hue; - struct v4l2_ctrl *saturation; - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *contrast; - struct { /* gain control cluster */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *gain; - }; - struct v4l2_ctrl *autowhitebalance; - struct { /* exposure control cluster */ - struct v4l2_ctrl *autoexposure; - struct v4l2_ctrl *exposure; - }; - struct v4l2_ctrl *sharpness; - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - struct v4l2_ctrl *plfreq; - - __u32 last_pts; - u16 last_fid; - u8 frame_rate; - - u8 sensor; -}; -enum sensors { - SENSOR_OV767x, - SENSOR_OV772x, - NSENSORS -}; - -static int sd_start(struct gspca_dev *gspca_dev); -static void sd_stopN(struct gspca_dev *gspca_dev); - - -static const struct v4l2_pix_format ov772x_mode[] = { - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format ov767x_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -}; - -static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30}; -static const u8 vga_rates[] = {60, 50, 40, 30, 15}; - -static const struct framerates ov772x_framerates[] = { - { /* 320x240 */ - .rates = qvga_rates, - .nrates = ARRAY_SIZE(qvga_rates), - }, - { /* 640x480 */ - .rates = vga_rates, - .nrates = ARRAY_SIZE(vga_rates), - }, -}; - -struct reg_array { - const u8 (*val)[2]; - int len; -}; - -static const u8 bridge_init_767x[][2] = { -/* comments from the ms-win file apollo7670.set */ -/* str1 */ - {0xf1, 0x42}, - {0x88, 0xf8}, - {0x89, 0xff}, - {0x76, 0x03}, - {0x92, 0x03}, - {0x95, 0x10}, - {0xe2, 0x00}, - {0xe7, 0x3e}, - {0x8d, 0x1c}, - {0x8e, 0x00}, - {0x8f, 0x00}, - {0x1f, 0x00}, - {0xc3, 0xf9}, - {0x89, 0xff}, - {0x88, 0xf8}, - {0x76, 0x03}, - {0x92, 0x01}, - {0x93, 0x18}, - {0x1c, 0x00}, - {0x1d, 0x48}, - {0x1d, 0x00}, - {0x1d, 0xff}, - {0x1d, 0x02}, - {0x1d, 0x58}, - {0x1d, 0x00}, - {0x1c, 0x0a}, - {0x1d, 0x0a}, - {0x1d, 0x0e}, - {0xc0, 0x50}, /* HSize 640 */ - {0xc1, 0x3c}, /* VSize 480 */ - {0x34, 0x05}, /* enable Audio Suspend mode */ - {0xc2, 0x0c}, /* Input YUV */ - {0xc3, 0xf9}, /* enable PRE */ - {0x34, 0x05}, /* enable Audio Suspend mode */ - {0xe7, 0x2e}, /* this solves failure of "SuspendResumeTest" */ - {0x31, 0xf9}, /* enable 1.8V Suspend */ - {0x35, 0x02}, /* turn on JPEG */ - {0xd9, 0x10}, - {0x25, 0x42}, /* GPIO[8]:Input */ - {0x94, 0x11}, /* If the default setting is loaded when - * system boots up, this flag is closed here */ -}; -static const u8 sensor_init_767x[][2] = { - {0x12, 0x80}, - {0x11, 0x03}, - {0x3a, 0x04}, - {0x12, 0x00}, - {0x17, 0x13}, - {0x18, 0x01}, - {0x32, 0xb6}, - {0x19, 0x02}, - {0x1a, 0x7a}, - {0x03, 0x0a}, - {0x0c, 0x00}, - {0x3e, 0x00}, - {0x70, 0x3a}, - {0x71, 0x35}, - {0x72, 0x11}, - {0x73, 0xf0}, - {0xa2, 0x02}, - {0x7a, 0x2a}, /* set Gamma=1.6 below */ - {0x7b, 0x12}, - {0x7c, 0x1d}, - {0x7d, 0x2d}, - {0x7e, 0x45}, - {0x7f, 0x50}, - {0x80, 0x59}, - {0x81, 0x62}, - {0x82, 0x6b}, - {0x83, 0x73}, - {0x84, 0x7b}, - {0x85, 0x8a}, - {0x86, 0x98}, - {0x87, 0xb2}, - {0x88, 0xca}, - {0x89, 0xe0}, - {0x13, 0xe0}, - {0x00, 0x00}, - {0x10, 0x00}, - {0x0d, 0x40}, - {0x14, 0x38}, /* gain max 16x */ - {0xa5, 0x05}, - {0xab, 0x07}, - {0x24, 0x95}, - {0x25, 0x33}, - {0x26, 0xe3}, - {0x9f, 0x78}, - {0xa0, 0x68}, - {0xa1, 0x03}, - {0xa6, 0xd8}, - {0xa7, 0xd8}, - {0xa8, 0xf0}, - {0xa9, 0x90}, - {0xaa, 0x94}, - {0x13, 0xe5}, - {0x0e, 0x61}, - {0x0f, 0x4b}, - {0x16, 0x02}, - {0x21, 0x02}, - {0x22, 0x91}, - {0x29, 0x07}, - {0x33, 0x0b}, - {0x35, 0x0b}, - {0x37, 0x1d}, - {0x38, 0x71}, - {0x39, 0x2a}, - {0x3c, 0x78}, - {0x4d, 0x40}, - {0x4e, 0x20}, - {0x69, 0x00}, - {0x6b, 0x4a}, - {0x74, 0x10}, - {0x8d, 0x4f}, - {0x8e, 0x00}, - {0x8f, 0x00}, - {0x90, 0x00}, - {0x91, 0x00}, - {0x96, 0x00}, - {0x9a, 0x80}, - {0xb0, 0x84}, - {0xb1, 0x0c}, - {0xb2, 0x0e}, - {0xb3, 0x82}, - {0xb8, 0x0a}, - {0x43, 0x0a}, - {0x44, 0xf0}, - {0x45, 0x34}, - {0x46, 0x58}, - {0x47, 0x28}, - {0x48, 0x3a}, - {0x59, 0x88}, - {0x5a, 0x88}, - {0x5b, 0x44}, - {0x5c, 0x67}, - {0x5d, 0x49}, - {0x5e, 0x0e}, - {0x6c, 0x0a}, - {0x6d, 0x55}, - {0x6e, 0x11}, - {0x6f, 0x9f}, - {0x6a, 0x40}, - {0x01, 0x40}, - {0x02, 0x40}, - {0x13, 0xe7}, - {0x4f, 0x80}, - {0x50, 0x80}, - {0x51, 0x00}, - {0x52, 0x22}, - {0x53, 0x5e}, - {0x54, 0x80}, - {0x58, 0x9e}, - {0x41, 0x08}, - {0x3f, 0x00}, - {0x75, 0x04}, - {0x76, 0xe1}, - {0x4c, 0x00}, - {0x77, 0x01}, - {0x3d, 0xc2}, - {0x4b, 0x09}, - {0xc9, 0x60}, - {0x41, 0x38}, /* jfm: auto sharpness + auto de-noise */ - {0x56, 0x40}, - {0x34, 0x11}, - {0x3b, 0xc2}, - {0xa4, 0x8a}, /* Night mode trigger point */ - {0x96, 0x00}, - {0x97, 0x30}, - {0x98, 0x20}, - {0x99, 0x20}, - {0x9a, 0x84}, - {0x9b, 0x29}, - {0x9c, 0x03}, - {0x9d, 0x4c}, - {0x9e, 0x3f}, - {0x78, 0x04}, - {0x79, 0x01}, - {0xc8, 0xf0}, - {0x79, 0x0f}, - {0xc8, 0x00}, - {0x79, 0x10}, - {0xc8, 0x7e}, - {0x79, 0x0a}, - {0xc8, 0x80}, - {0x79, 0x0b}, - {0xc8, 0x01}, - {0x79, 0x0c}, - {0xc8, 0x0f}, - {0x79, 0x0d}, - {0xc8, 0x20}, - {0x79, 0x09}, - {0xc8, 0x80}, - {0x79, 0x02}, - {0xc8, 0xc0}, - {0x79, 0x03}, - {0xc8, 0x20}, - {0x79, 0x26}, -}; -static const u8 bridge_start_vga_767x[][2] = { -/* str59 JPG */ - {0x94, 0xaa}, - {0xf1, 0x42}, - {0xe5, 0x04}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0xc2, 0x0c}, - {0x35, 0x02}, /* turn on JPEG */ - {0xd9, 0x10}, - {0xda, 0x00}, /* for higher clock rate(30fps) */ - {0x34, 0x05}, /* enable Audio Suspend mode */ - {0xc3, 0xf9}, /* enable PRE */ - {0x8c, 0x00}, /* CIF VSize LSB[2:0] */ - {0x8d, 0x1c}, /* output YUV */ -/* {0x34, 0x05}, * enable Audio Suspend mode (?) */ - {0x50, 0x00}, /* H/V divider=0 */ - {0x51, 0xa0}, /* input H=640/4 */ - {0x52, 0x3c}, /* input V=480/4 */ - {0x53, 0x00}, /* offset X=0 */ - {0x54, 0x00}, /* offset Y=0 */ - {0x55, 0x00}, /* H/V size[8]=0 */ - {0x57, 0x00}, /* H-size[9]=0 */ - {0x5c, 0x00}, /* output size[9:8]=0 */ - {0x5a, 0xa0}, /* output H=640/4 */ - {0x5b, 0x78}, /* output V=480/4 */ - {0x1c, 0x0a}, - {0x1d, 0x0a}, - {0x94, 0x11}, -}; -static const u8 sensor_start_vga_767x[][2] = { - {0x11, 0x01}, - {0x1e, 0x04}, - {0x19, 0x02}, - {0x1a, 0x7a}, -}; -static const u8 bridge_start_qvga_767x[][2] = { -/* str86 JPG */ - {0x94, 0xaa}, - {0xf1, 0x42}, - {0xe5, 0x04}, - {0xc0, 0x80}, - {0xc1, 0x60}, - {0xc2, 0x0c}, - {0x35, 0x02}, /* turn on JPEG */ - {0xd9, 0x10}, - {0xc0, 0x50}, /* CIF HSize 640 */ - {0xc1, 0x3c}, /* CIF VSize 480 */ - {0x8c, 0x00}, /* CIF VSize LSB[2:0] */ - {0x8d, 0x1c}, /* output YUV */ - {0x34, 0x05}, /* enable Audio Suspend mode */ - {0xc2, 0x4c}, /* output YUV and Enable DCW */ - {0xc3, 0xf9}, /* enable PRE */ - {0x1c, 0x00}, /* indirect addressing */ - {0x1d, 0x48}, /* output YUV422 */ - {0x50, 0x89}, /* H/V divider=/2; plus DCW AVG */ - {0x51, 0xa0}, /* DCW input H=640/4 */ - {0x52, 0x78}, /* DCW input V=480/4 */ - {0x53, 0x00}, /* offset X=0 */ - {0x54, 0x00}, /* offset Y=0 */ - {0x55, 0x00}, /* H/V size[8]=0 */ - {0x57, 0x00}, /* H-size[9]=0 */ - {0x5c, 0x00}, /* DCW output size[9:8]=0 */ - {0x5a, 0x50}, /* DCW output H=320/4 */ - {0x5b, 0x3c}, /* DCW output V=240/4 */ - {0x1c, 0x0a}, - {0x1d, 0x0a}, - {0x94, 0x11}, -}; -static const u8 sensor_start_qvga_767x[][2] = { - {0x11, 0x01}, - {0x1e, 0x04}, - {0x19, 0x02}, - {0x1a, 0x7a}, -}; - -static const u8 bridge_init_772x[][2] = { - { 0xc2, 0x0c }, - { 0x88, 0xf8 }, - { 0xc3, 0x69 }, - { 0x89, 0xff }, - { 0x76, 0x03 }, - { 0x92, 0x01 }, - { 0x93, 0x18 }, - { 0x94, 0x10 }, - { 0x95, 0x10 }, - { 0xe2, 0x00 }, - { 0xe7, 0x3e }, - - { 0x96, 0x00 }, - - { 0x97, 0x20 }, - { 0x97, 0x20 }, - { 0x97, 0x20 }, - { 0x97, 0x0a }, - { 0x97, 0x3f }, - { 0x97, 0x4a }, - { 0x97, 0x20 }, - { 0x97, 0x15 }, - { 0x97, 0x0b }, - - { 0x8e, 0x40 }, - { 0x1f, 0x81 }, - { 0x34, 0x05 }, - { 0xe3, 0x04 }, - { 0x88, 0x00 }, - { 0x89, 0x00 }, - { 0x76, 0x00 }, - { 0xe7, 0x2e }, - { 0x31, 0xf9 }, - { 0x25, 0x42 }, - { 0x21, 0xf0 }, - - { 0x1c, 0x00 }, - { 0x1d, 0x40 }, - { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ - { 0x1d, 0x00 }, /* payload size */ - - { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ - { 0x1d, 0x58 }, /* frame size */ - { 0x1d, 0x00 }, /* frame size */ - - { 0x1c, 0x0a }, - { 0x1d, 0x08 }, /* turn on UVC header */ - { 0x1d, 0x0e }, /* .. */ - - { 0x8d, 0x1c }, - { 0x8e, 0x80 }, - { 0xe5, 0x04 }, - - { 0xc0, 0x50 }, - { 0xc1, 0x3c }, - { 0xc2, 0x0c }, -}; -static const u8 sensor_init_772x[][2] = { - { 0x12, 0x80 }, - { 0x11, 0x01 }, -/*fixme: better have a delay?*/ - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - { 0x11, 0x01 }, - - { 0x3d, 0x03 }, - { 0x17, 0x26 }, - { 0x18, 0xa0 }, - { 0x19, 0x07 }, - { 0x1a, 0xf0 }, - { 0x32, 0x00 }, - { 0x29, 0xa0 }, - { 0x2c, 0xf0 }, - { 0x65, 0x20 }, - { 0x11, 0x01 }, - { 0x42, 0x7f }, - { 0x63, 0xaa }, /* AWB - was e0 */ - { 0x64, 0xff }, - { 0x66, 0x00 }, - { 0x13, 0xf0 }, /* com8 */ - { 0x0d, 0x41 }, - { 0x0f, 0xc5 }, - { 0x14, 0x11 }, - - { 0x22, 0x7f }, - { 0x23, 0x03 }, - { 0x24, 0x40 }, - { 0x25, 0x30 }, - { 0x26, 0xa1 }, - { 0x2a, 0x00 }, - { 0x2b, 0x00 }, - { 0x6b, 0xaa }, - { 0x13, 0xff }, /* AWB */ - - { 0x90, 0x05 }, - { 0x91, 0x01 }, - { 0x92, 0x03 }, - { 0x93, 0x00 }, - { 0x94, 0x60 }, - { 0x95, 0x3c }, - { 0x96, 0x24 }, - { 0x97, 0x1e }, - { 0x98, 0x62 }, - { 0x99, 0x80 }, - { 0x9a, 0x1e }, - { 0x9b, 0x08 }, - { 0x9c, 0x20 }, - { 0x9e, 0x81 }, - - { 0xa6, 0x07 }, - { 0x7e, 0x0c }, - { 0x7f, 0x16 }, - { 0x80, 0x2a }, - { 0x81, 0x4e }, - { 0x82, 0x61 }, - { 0x83, 0x6f }, - { 0x84, 0x7b }, - { 0x85, 0x86 }, - { 0x86, 0x8e }, - { 0x87, 0x97 }, - { 0x88, 0xa4 }, - { 0x89, 0xaf }, - { 0x8a, 0xc5 }, - { 0x8b, 0xd7 }, - { 0x8c, 0xe8 }, - { 0x8d, 0x20 }, - - { 0x0c, 0x90 }, - - { 0x2b, 0x00 }, - { 0x22, 0x7f }, - { 0x23, 0x03 }, - { 0x11, 0x01 }, - { 0x0c, 0xd0 }, - { 0x64, 0xff }, - { 0x0d, 0x41 }, - - { 0x14, 0x41 }, - { 0x0e, 0xcd }, - { 0xac, 0xbf }, - { 0x8e, 0x00 }, /* De-noise threshold */ - { 0x0c, 0xd0 } -}; -static const u8 bridge_start_vga_772x[][2] = { - {0x1c, 0x00}, - {0x1d, 0x40}, - {0x1d, 0x02}, - {0x1d, 0x00}, - {0x1d, 0x02}, - {0x1d, 0x58}, - {0x1d, 0x00}, - {0xc0, 0x50}, - {0xc1, 0x3c}, -}; -static const u8 sensor_start_vga_772x[][2] = { - {0x12, 0x00}, - {0x17, 0x26}, - {0x18, 0xa0}, - {0x19, 0x07}, - {0x1a, 0xf0}, - {0x29, 0xa0}, - {0x2c, 0xf0}, - {0x65, 0x20}, -}; -static const u8 bridge_start_qvga_772x[][2] = { - {0x1c, 0x00}, - {0x1d, 0x40}, - {0x1d, 0x02}, - {0x1d, 0x00}, - {0x1d, 0x01}, - {0x1d, 0x4b}, - {0x1d, 0x00}, - {0xc0, 0x28}, - {0xc1, 0x1e}, -}; -static const u8 sensor_start_qvga_772x[][2] = { - {0x12, 0x40}, - {0x17, 0x3f}, - {0x18, 0x50}, - {0x19, 0x03}, - {0x1a, 0x78}, - {0x29, 0x50}, - {0x2c, 0x78}, - {0x65, 0x2f}, -}; - -static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - - PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val); - gspca_dev->usb_buf[0] = val; - ret = usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - 0x01, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - if (ret < 0) { - pr_err("write failed %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return 0; - ret = usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - 0x01, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]); - if (ret < 0) { - pr_err("read failed %d\n", ret); - gspca_dev->usb_err = ret; - } - return gspca_dev->usb_buf[0]; -} - -/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. - * (direction and output)? */ -static void ov534_set_led(struct gspca_dev *gspca_dev, int status) -{ - u8 data; - - PDEBUG(D_CONF, "led status: %d", status); - - data = ov534_reg_read(gspca_dev, 0x21); - data |= 0x80; - ov534_reg_write(gspca_dev, 0x21, data); - - data = ov534_reg_read(gspca_dev, 0x23); - if (status) - data |= 0x80; - else - data &= ~0x80; - - ov534_reg_write(gspca_dev, 0x23, data); - - if (!status) { - data = ov534_reg_read(gspca_dev, 0x21); - data &= ~0x80; - ov534_reg_write(gspca_dev, 0x21, data); - } -} - -static int sccb_check_status(struct gspca_dev *gspca_dev) -{ - u8 data; - int i; - - for (i = 0; i < 5; i++) { - msleep(10); - data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); - - switch (data) { - case 0x00: - return 1; - case 0x04: - return 0; - case 0x03: - break; - default: - PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", - data, i + 1); - } - } - return 0; -} - -static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) -{ - PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val); - ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); - ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); - - if (!sccb_check_status(gspca_dev)) { - pr_err("sccb_reg_write failed\n"); - gspca_dev->usb_err = -EIO; - } -} - -static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) -{ - ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); - if (!sccb_check_status(gspca_dev)) - pr_err("sccb_reg_read failed 1\n"); - - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); - if (!sccb_check_status(gspca_dev)) - pr_err("sccb_reg_read failed 2\n"); - - return ov534_reg_read(gspca_dev, OV534_REG_READ); -} - -/* output a bridge sequence (reg - val) */ -static void reg_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]); - data++; - } -} - -/* output a sensor sequence (reg - val) */ -static void sccb_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - if ((*data)[0] != 0xff) { - sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]); - } else { - sccb_reg_read(gspca_dev, (*data)[1]); - sccb_reg_write(gspca_dev, 0xff, 0x00); - } - data++; - } -} - -/* ov772x specific controls */ -static void set_frame_rate(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - struct rate_s { - u8 fps; - u8 r11; - u8 r0d; - u8 re5; - }; - const struct rate_s *r; - static const struct rate_s rate_0[] = { /* 640x480 */ - {60, 0x01, 0xc1, 0x04}, - {50, 0x01, 0x41, 0x02}, - {40, 0x02, 0xc1, 0x04}, - {30, 0x04, 0x81, 0x02}, - {15, 0x03, 0x41, 0x04}, - }; - static const struct rate_s rate_1[] = { /* 320x240 */ - {125, 0x02, 0x81, 0x02}, - {100, 0x02, 0xc1, 0x04}, - {75, 0x03, 0xc1, 0x04}, - {60, 0x04, 0xc1, 0x04}, - {50, 0x02, 0x41, 0x04}, - {40, 0x03, 0x41, 0x04}, - {30, 0x04, 0x41, 0x04}, - }; - - if (sd->sensor != SENSOR_OV772x) - return; - if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) { - r = rate_0; - i = ARRAY_SIZE(rate_0); - } else { - r = rate_1; - i = ARRAY_SIZE(rate_1); - } - while (--i > 0) { - if (sd->frame_rate >= r->fps) - break; - r++; - } - - sccb_reg_write(gspca_dev, 0x11, r->r11); - sccb_reg_write(gspca_dev, 0x0d, r->r0d); - ov534_reg_write(gspca_dev, 0xe5, r->re5); - - PDEBUG(D_PROBE, "frame_rate: %d", r->fps); -} - -static void sethue(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) { - /* TBD */ - } else { - s16 huesin; - s16 huecos; - - /* fixp_sin and fixp_cos accept only positive values, while - * our val is between -90 and 90 - */ - val += 360; - - /* According to the datasheet the registers expect HUESIN and - * HUECOS to be the result of the trigonometric functions, - * scaled by 0x80. - * - * The 0x100 here represents the maximun absolute value - * returned byt fixp_sin and fixp_cos, so the scaling will - * consider the result like in the interval [-1.0, 1.0]. - */ - huesin = fixp_sin(val) * 0x80 / 0x100; - huecos = fixp_cos(val) * 0x80 / 0x100; - - if (huesin < 0) { - sccb_reg_write(gspca_dev, 0xab, - sccb_reg_read(gspca_dev, 0xab) | 0x2); - huesin = -huesin; - } else { - sccb_reg_write(gspca_dev, 0xab, - sccb_reg_read(gspca_dev, 0xab) & ~0x2); - - } - sccb_reg_write(gspca_dev, 0xa9, (u8)huecos); - sccb_reg_write(gspca_dev, 0xaa, (u8)huesin); - } -} - -static void setsaturation(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) { - int i; - static u8 color_tb[][6] = { - {0x42, 0x42, 0x00, 0x11, 0x30, 0x41}, - {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52}, - {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66}, - {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80}, - {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a}, - {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8}, - {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd}, - }; - - for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++) - sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]); - } else { - sccb_reg_write(gspca_dev, 0xa7, val); /* U saturation */ - sccb_reg_write(gspca_dev, 0xa8, val); /* V saturation */ - } -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) { - if (val < 0) - val = 0x80 - val; - sccb_reg_write(gspca_dev, 0x55, val); /* bright */ - } else { - sccb_reg_write(gspca_dev, 0x9b, val); - } -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) - sccb_reg_write(gspca_dev, 0x56, val); /* contras */ - else - sccb_reg_write(gspca_dev, 0x9c, val); -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - switch (val & 0x30) { - case 0x00: - val &= 0x0f; - break; - case 0x10: - val &= 0x0f; - val |= 0x30; - break; - case 0x20: - val &= 0x0f; - val |= 0x70; - break; - default: -/* case 0x30: */ - val &= 0x0f; - val |= 0xf0; - break; - } - sccb_reg_write(gspca_dev, 0x00, val); -} - -static s32 getgain(struct gspca_dev *gspca_dev) -{ - return sccb_reg_read(gspca_dev, 0x00); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) { - - /* set only aec[9:2] */ - sccb_reg_write(gspca_dev, 0x10, val); /* aech */ - } else { - - /* 'val' is one byte and represents half of the exposure value - * we are going to set into registers, a two bytes value: - * - * MSB: ((u16) val << 1) >> 8 == val >> 7 - * LSB: ((u16) val << 1) & 0xff == val << 1 - */ - sccb_reg_write(gspca_dev, 0x08, val >> 7); - sccb_reg_write(gspca_dev, 0x10, val << 1); - } -} - -static s32 getexposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV767x) { - /* get only aec[9:2] */ - return sccb_reg_read(gspca_dev, 0x10); /* aech */ - } else { - u8 hi = sccb_reg_read(gspca_dev, 0x08); - u8 lo = sccb_reg_read(gspca_dev, 0x10); - return (hi << 8 | lo) >> 1; - } -} - -static void setagc(struct gspca_dev *gspca_dev, s32 val) -{ - if (val) { - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) | 0x04); - sccb_reg_write(gspca_dev, 0x64, - sccb_reg_read(gspca_dev, 0x64) | 0x03); - } else { - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) & ~0x04); - sccb_reg_write(gspca_dev, 0x64, - sccb_reg_read(gspca_dev, 0x64) & ~0x03); - } -} - -static void setawb(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (val) { - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) | 0x02); - if (sd->sensor == SENSOR_OV772x) - sccb_reg_write(gspca_dev, 0x63, - sccb_reg_read(gspca_dev, 0x63) | 0xc0); - } else { - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) & ~0x02); - if (sd->sensor == SENSOR_OV772x) - sccb_reg_write(gspca_dev, 0x63, - sccb_reg_read(gspca_dev, 0x63) & ~0xc0); - } -} - -static void setaec(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data; - - data = sd->sensor == SENSOR_OV767x ? - 0x05 : /* agc + aec */ - 0x01; /* agc */ - switch (val) { - case V4L2_EXPOSURE_AUTO: - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) | data); - break; - case V4L2_EXPOSURE_MANUAL: - sccb_reg_write(gspca_dev, 0x13, - sccb_reg_read(gspca_dev, 0x13) & ~data); - break; - } -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ - sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ -} - -static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 val; - - if (sd->sensor == SENSOR_OV767x) { - val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */ - val &= ~0x30; - if (hflip) - val |= 0x20; - if (vflip) - val |= 0x10; - sccb_reg_write(gspca_dev, 0x1e, val); - } else { - val = sccb_reg_read(gspca_dev, 0x0c); - val &= ~0xc0; - if (hflip == 0) - val |= 0x40; - if (vflip == 0) - val |= 0x80; - sccb_reg_write(gspca_dev, 0x0c, val); - } -} - -static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - val = val ? 0x9e : 0x00; - if (sd->sensor == SENSOR_OV767x) { - sccb_reg_write(gspca_dev, 0x2a, 0x00); - if (val) - val = 0x9d; /* insert dummy to 25fps for 50Hz */ - } - sccb_reg_write(gspca_dev, 0x2b, val); -} - - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - - cam->cam_mode = ov772x_mode; - cam->nmodes = ARRAY_SIZE(ov772x_mode); - - sd->frame_rate = 30; - - return 0; -} - -static int ov534_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - gspca_dev->usb_err = 0; - if (ctrl->val && sd->gain && gspca_dev->streaming) - sd->gain->val = getgain(gspca_dev); - return gspca_dev->usb_err; - - case V4L2_CID_EXPOSURE_AUTO: - gspca_dev->usb_err = 0; - if (ctrl->val == V4L2_EXPOSURE_AUTO && sd->exposure && - gspca_dev->streaming) - sd->exposure->val = getexposure(gspca_dev); - return gspca_dev->usb_err; - } - return -EINVAL; -} - -static int ov534_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - - gspca_dev->usb_err = 0; - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_HUE: - sethue(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setsaturation(gspca_dev, ctrl->val); - break; - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - /* case V4L2_CID_GAIN: */ - setagc(gspca_dev, ctrl->val); - if (!gspca_dev->usb_err && !ctrl->val && sd->gain) - setgain(gspca_dev, sd->gain->val); - break; - case V4L2_CID_AUTO_WHITE_BALANCE: - setawb(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE_AUTO: - /* case V4L2_CID_EXPOSURE: */ - setaec(gspca_dev, ctrl->val); - if (!gspca_dev->usb_err && ctrl->val == V4L2_EXPOSURE_MANUAL && - sd->exposure) - setexposure(gspca_dev, sd->exposure->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_HFLIP: - sethvflip(gspca_dev, ctrl->val, sd->vflip->val); - break; - case V4L2_CID_VFLIP: - sethvflip(gspca_dev, sd->hflip->val, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setlightfreq(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops ov534_ctrl_ops = { - .g_volatile_ctrl = ov534_g_volatile_ctrl, - .s_ctrl = ov534_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler; - /* parameters with different values between the supported sensors */ - int saturation_min; - int saturation_max; - int saturation_def; - int brightness_min; - int brightness_max; - int brightness_def; - int contrast_max; - int contrast_def; - int exposure_min; - int exposure_max; - int exposure_def; - int hflip_def; - - if (sd->sensor == SENSOR_OV767x) { - saturation_min = 0, - saturation_max = 6, - saturation_def = 3, - brightness_min = -127; - brightness_max = 127; - brightness_def = 0; - contrast_max = 0x80; - contrast_def = 0x40; - exposure_min = 0x08; - exposure_max = 0x60; - exposure_def = 0x13; - hflip_def = 1; - } else { - saturation_min = 0, - saturation_max = 255, - saturation_def = 64, - brightness_min = 0; - brightness_max = 255; - brightness_def = 0; - contrast_max = 255; - contrast_def = 32; - exposure_min = 0; - exposure_max = 255; - exposure_def = 120; - hflip_def = 0; - } - - gspca_dev->vdev.ctrl_handler = hdl; - - v4l2_ctrl_handler_init(hdl, 13); - - if (sd->sensor == SENSOR_OV772x) - sd->hue = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_HUE, -90, 90, 1, 0); - - sd->saturation = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_SATURATION, saturation_min, saturation_max, 1, - saturation_def); - sd->brightness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_BRIGHTNESS, brightness_min, brightness_max, 1, - brightness_def); - sd->contrast = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_CONTRAST, 0, contrast_max, 1, contrast_def); - - if (sd->sensor == SENSOR_OV772x) { - sd->autogain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - sd->gain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_GAIN, 0, 63, 1, 20); - } - - sd->autoexposure = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, - V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, - V4L2_EXPOSURE_AUTO); - sd->exposure = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_EXPOSURE, exposure_min, exposure_max, 1, - exposure_def); - - sd->autowhitebalance = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); - - if (sd->sensor == SENSOR_OV772x) - sd->sharpness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 63, 1, 0); - - sd->hflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, hflip_def); - sd->vflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ, 0, - V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - if (sd->sensor == SENSOR_OV772x) - v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true); - - v4l2_ctrl_auto_cluster(2, &sd->autoexposure, V4L2_EXPOSURE_MANUAL, - true); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 sensor_id; - static const struct reg_array bridge_init[NSENSORS] = { - [SENSOR_OV767x] = {bridge_init_767x, ARRAY_SIZE(bridge_init_767x)}, - [SENSOR_OV772x] = {bridge_init_772x, ARRAY_SIZE(bridge_init_772x)}, - }; - static const struct reg_array sensor_init[NSENSORS] = { - [SENSOR_OV767x] = {sensor_init_767x, ARRAY_SIZE(sensor_init_767x)}, - [SENSOR_OV772x] = {sensor_init_772x, ARRAY_SIZE(sensor_init_772x)}, - }; - - /* reset bridge */ - ov534_reg_write(gspca_dev, 0xe7, 0x3a); - ov534_reg_write(gspca_dev, 0xe0, 0x08); - msleep(100); - - /* initialize the sensor address */ - ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42); - - /* reset sensor */ - sccb_reg_write(gspca_dev, 0x12, 0x80); - msleep(10); - - /* probe the sensor */ - sccb_reg_read(gspca_dev, 0x0a); - sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8; - sccb_reg_read(gspca_dev, 0x0b); - sensor_id |= sccb_reg_read(gspca_dev, 0x0b); - PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); - - if ((sensor_id & 0xfff0) == 0x7670) { - sd->sensor = SENSOR_OV767x; - gspca_dev->cam.cam_mode = ov767x_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); - } else { - sd->sensor = SENSOR_OV772x; - gspca_dev->cam.bulk = 1; - gspca_dev->cam.bulk_size = 16384; - gspca_dev->cam.bulk_nurbs = 2; - gspca_dev->cam.mode_framerates = ov772x_framerates; - } - - /* initialize */ - reg_w_array(gspca_dev, bridge_init[sd->sensor].val, - bridge_init[sd->sensor].len); - ov534_set_led(gspca_dev, 1); - sccb_w_array(gspca_dev, sensor_init[sd->sensor].val, - sensor_init[sd->sensor].len); - if (sd->sensor == SENSOR_OV767x) - sd_start(gspca_dev); - sd_stopN(gspca_dev); -/* set_frame_rate(gspca_dev); */ - - return gspca_dev->usb_err; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int mode; - static const struct reg_array bridge_start[NSENSORS][2] = { - [SENSOR_OV767x] = {{bridge_start_qvga_767x, - ARRAY_SIZE(bridge_start_qvga_767x)}, - {bridge_start_vga_767x, - ARRAY_SIZE(bridge_start_vga_767x)}}, - [SENSOR_OV772x] = {{bridge_start_qvga_772x, - ARRAY_SIZE(bridge_start_qvga_772x)}, - {bridge_start_vga_772x, - ARRAY_SIZE(bridge_start_vga_772x)}}, - }; - static const struct reg_array sensor_start[NSENSORS][2] = { - [SENSOR_OV767x] = {{sensor_start_qvga_767x, - ARRAY_SIZE(sensor_start_qvga_767x)}, - {sensor_start_vga_767x, - ARRAY_SIZE(sensor_start_vga_767x)}}, - [SENSOR_OV772x] = {{sensor_start_qvga_772x, - ARRAY_SIZE(sensor_start_qvga_772x)}, - {sensor_start_vga_772x, - ARRAY_SIZE(sensor_start_vga_772x)}}, - }; - - /* (from ms-win trace) */ - if (sd->sensor == SENSOR_OV767x) - sccb_reg_write(gspca_dev, 0x1e, 0x04); - /* black sun enable ? */ - - mode = gspca_dev->curr_mode; /* 0: 320x240, 1: 640x480 */ - reg_w_array(gspca_dev, bridge_start[sd->sensor][mode].val, - bridge_start[sd->sensor][mode].len); - sccb_w_array(gspca_dev, sensor_start[sd->sensor][mode].val, - sensor_start[sd->sensor][mode].len); - - set_frame_rate(gspca_dev); - - if (sd->hue) - sethue(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue)); - setsaturation(gspca_dev, v4l2_ctrl_g_ctrl(sd->saturation)); - if (sd->autogain) - setagc(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); - setawb(gspca_dev, v4l2_ctrl_g_ctrl(sd->autowhitebalance)); - setaec(gspca_dev, v4l2_ctrl_g_ctrl(sd->autoexposure)); - if (sd->gain) - setgain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); - setbrightness(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness)); - setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast)); - if (sd->sharpness) - setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); - sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), - v4l2_ctrl_g_ctrl(sd->vflip)); - setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq)); - - ov534_set_led(gspca_dev, 1); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - ov534_reg_write(gspca_dev, 0xe0, 0x09); - ov534_set_led(gspca_dev, 0); -} - -/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ -#define UVC_STREAM_EOH (1 << 7) -#define UVC_STREAM_ERR (1 << 6) -#define UVC_STREAM_STI (1 << 5) -#define UVC_STREAM_RES (1 << 4) -#define UVC_STREAM_SCR (1 << 3) -#define UVC_STREAM_PTS (1 << 2) -#define UVC_STREAM_EOF (1 << 1) -#define UVC_STREAM_FID (1 << 0) - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u32 this_pts; - u16 this_fid; - int remaining_len = len; - int payload_len; - - payload_len = gspca_dev->cam.bulk ? 2048 : 2040; - do { - len = min(remaining_len, payload_len); - - /* Payloads are prefixed with a UVC-style header. We - consider a frame to start when the FID toggles, or the PTS - changes. A frame ends when EOF is set, and we've received - the correct number of bytes. */ - - /* Verify UVC header. Header length is always 12 */ - if (data[0] != 12 || len < 12) { - PDEBUG(D_PACK, "bad header"); - goto discard; - } - - /* Check errors */ - if (data[1] & UVC_STREAM_ERR) { - PDEBUG(D_PACK, "payload error"); - goto discard; - } - - /* Extract PTS and FID */ - if (!(data[1] & UVC_STREAM_PTS)) { - PDEBUG(D_PACK, "PTS not present"); - goto discard; - } - this_pts = (data[5] << 24) | (data[4] << 16) - | (data[3] << 8) | data[2]; - this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; - - /* If PTS or FID has changed, start a new frame. */ - if (this_pts != sd->last_pts || this_fid != sd->last_fid) { - if (gspca_dev->last_packet_type == INTER_PACKET) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - sd->last_pts = this_pts; - sd->last_fid = this_fid; - gspca_frame_add(gspca_dev, FIRST_PACKET, - data + 12, len - 12); - /* If this packet is marked as EOF, end the frame */ - } else if (data[1] & UVC_STREAM_EOF) { - sd->last_pts = 0; - if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV - && gspca_dev->image_len + len - 12 != - gspca_dev->width * gspca_dev->height * 2) { - PDEBUG(D_PACK, "wrong sized frame"); - goto discard; - } - gspca_frame_add(gspca_dev, LAST_PACKET, - data + 12, len - 12); - } else { - - /* Add the data from this payload */ - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 12, len - 12); - } - - /* Done this payload */ - goto scan_next; - -discard: - /* Discard data until a new frame starts. */ - gspca_dev->last_packet_type = DISCARD_PACKET; - -scan_next: - remaining_len -= len; - data += len; - } while (remaining_len > 0); -} - -/* get stream parameters (framerate) */ -static void sd_get_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) -{ - struct v4l2_captureparm *cp = &parm->parm.capture; - struct v4l2_fract *tpf = &cp->timeperframe; - struct sd *sd = (struct sd *) gspca_dev; - - cp->capability |= V4L2_CAP_TIMEPERFRAME; - tpf->numerator = 1; - tpf->denominator = sd->frame_rate; -} - -/* set stream parameters (framerate) */ -static void sd_set_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) -{ - struct v4l2_captureparm *cp = &parm->parm.capture; - struct v4l2_fract *tpf = &cp->timeperframe; - struct sd *sd = (struct sd *) gspca_dev; - - /* Set requested framerate */ - sd->frame_rate = tpf->denominator / tpf->numerator; - if (gspca_dev->streaming) - set_frame_rate(gspca_dev); - - /* Return the actual framerate */ - tpf->numerator = 1; - tpf->denominator = sd->frame_rate; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .get_streamparm = sd_get_streamparm, - .set_streamparm = sd_set_streamparm, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x1415, 0x2000)}, - {USB_DEVICE(0x06f8, 0x3002)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c deleted file mode 100644 index c4cd028fe0b4..000000000000 --- a/drivers/media/video/gspca/ov534_9.c +++ /dev/null @@ -1,1500 +0,0 @@ -/* - * ov534-ov9xxx gspca driver - * - * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr - * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> - * Copyright (C) 2008 Jim Paris <jim@jtan.com> - * - * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> - * USB protocol reverse engineered by Jim Paris <jim@jtan.com> - * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "ov534_9" - -#include "gspca.h" - -#define OV534_REG_ADDRESS 0xf1 /* sensor address */ -#define OV534_REG_SUBADDR 0xf2 -#define OV534_REG_WRITE 0xf3 -#define OV534_REG_READ 0xf4 -#define OV534_REG_OPERATION 0xf5 -#define OV534_REG_STATUS 0xf6 - -#define OV534_OP_WRITE_3 0x37 -#define OV534_OP_WRITE_2 0x33 -#define OV534_OP_READ_2 0xf9 - -#define CTRL_TIMEOUT 500 - -MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>"); -MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - __u32 last_pts; - u8 last_fid; - - u8 sensor; -}; -enum sensors { - SENSOR_OV965x, /* ov9657 */ - SENSOR_OV971x, /* ov9712 */ - SENSOR_OV562x, /* ov5621 */ - NSENSORS -}; - -static const struct v4l2_pix_format ov965x_mode[] = { -#define QVGA_MODE 0 - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -#define VGA_MODE 1 - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -#define SVGA_MODE 2 - {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -#define XGA_MODE 3 - {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 1024, - .sizeimage = 1024 * 768 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -#define SXGA_MODE 4 - {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, -}; - -static const struct v4l2_pix_format ov971x_mode[] = { - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB - } -}; - -static const struct v4l2_pix_format ov562x_mode[] = { - {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 2592, - .sizeimage = 2592 * 1680, - .colorspace = V4L2_COLORSPACE_SRGB - } -}; - -static const u8 bridge_init[][2] = { - {0x88, 0xf8}, - {0x89, 0xff}, - {0x76, 0x03}, - {0x92, 0x03}, - {0x95, 0x10}, - {0xe2, 0x00}, - {0xe7, 0x3e}, - {0x8d, 0x1c}, - {0x8e, 0x00}, - {0x8f, 0x00}, - {0x1f, 0x00}, - {0xc3, 0xf9}, - {0x89, 0xff}, - {0x88, 0xf8}, - {0x76, 0x03}, - {0x92, 0x01}, - {0x93, 0x18}, - {0x1c, 0x0a}, - {0x1d, 0x48}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x34, 0x05}, - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0x34, 0x05}, - {0xe7, 0x2e}, - {0x31, 0xf9}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x25, 0x42}, - {0x94, 0x11}, -}; - -static const u8 ov965x_init[][2] = { - {0x12, 0x80}, /* com7 - SSCB reset */ - {0x00, 0x00}, /* gain */ - {0x01, 0x80}, /* blue */ - {0x02, 0x80}, /* red */ - {0x03, 0x1b}, /* vref */ - {0x04, 0x03}, /* com1 - exposure low bits */ - {0x0b, 0x57}, /* ver */ - {0x0e, 0x61}, /* com5 */ - {0x0f, 0x42}, /* com6 */ - {0x11, 0x00}, /* clkrc */ - {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x14, 0x28}, /* com9 */ - {0x16, 0x24}, /* reg16 */ - {0x17, 0x1d}, /* hstart*/ - {0x18, 0xbd}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x81}, /* vstop*/ - {0x1e, 0x04}, /* mvfp */ - {0x24, 0x3c}, /* aew */ - {0x25, 0x36}, /* aeb */ - {0x26, 0x71}, /* vpt */ - {0x27, 0x08}, /* bbias */ - {0x28, 0x08}, /* gbbias */ - {0x29, 0x15}, /* gr com */ - {0x2a, 0x00}, /* exhch */ - {0x2b, 0x00}, /* exhcl */ - {0x2c, 0x08}, /* rbias */ - {0x32, 0xff}, /* href */ - {0x33, 0x00}, /* chlf */ - {0x34, 0x3f}, /* aref1 */ - {0x35, 0x00}, /* aref2 */ - {0x36, 0xf8}, /* aref3 */ - {0x38, 0x72}, /* adc2 */ - {0x39, 0x57}, /* aref4 */ - {0x3a, 0x80}, /* tslb - yuyv */ - {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ - {0x3d, 0x99}, /* com13 */ - {0x3f, 0xc1}, /* edge */ - {0x40, 0xc0}, /* com15 */ - {0x41, 0x40}, /* com16 */ - {0x42, 0xc0}, /* com17 */ - {0x43, 0x0a}, /* rsvd */ - {0x44, 0xf0}, - {0x45, 0x46}, - {0x46, 0x62}, - {0x47, 0x2a}, - {0x48, 0x3c}, - {0x4a, 0xfc}, - {0x4b, 0xfc}, - {0x4c, 0x7f}, - {0x4d, 0x7f}, - {0x4e, 0x7f}, - {0x4f, 0x98}, /* matrix */ - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, /* matrix coef sign */ - {0x59, 0x85}, /* AWB control */ - {0x5a, 0xa9}, - {0x5b, 0x64}, - {0x5c, 0x84}, - {0x5d, 0x53}, - {0x5e, 0x0e}, - {0x5f, 0xf0}, /* AWB blue limit */ - {0x60, 0xf0}, /* AWB red limit */ - {0x61, 0xf0}, /* AWB green limit */ - {0x62, 0x00}, /* lcc1 */ - {0x63, 0x00}, /* lcc2 */ - {0x64, 0x02}, /* lcc3 */ - {0x65, 0x16}, /* lcc4 */ - {0x66, 0x01}, /* lcc5 */ - {0x69, 0x02}, /* hv */ - {0x6b, 0x5a}, /* dbvl */ - {0x6c, 0x04}, - {0x6d, 0x55}, - {0x6e, 0x00}, - {0x6f, 0x9d}, - {0x70, 0x21}, /* dnsth */ - {0x71, 0x78}, - {0x72, 0x00}, /* poidx */ - {0x73, 0x01}, /* pckdv */ - {0x74, 0x3a}, /* xindx */ - {0x75, 0x35}, /* yindx */ - {0x76, 0x01}, - {0x77, 0x02}, - {0x7a, 0x12}, /* gamma curve */ - {0x7b, 0x08}, - {0x7c, 0x16}, - {0x7d, 0x30}, - {0x7e, 0x5e}, - {0x7f, 0x72}, - {0x80, 0x82}, - {0x81, 0x8e}, - {0x82, 0x9a}, - {0x83, 0xa4}, - {0x84, 0xac}, - {0x85, 0xb8}, - {0x86, 0xc3}, - {0x87, 0xd6}, - {0x88, 0xe6}, - {0x89, 0xf2}, - {0x8a, 0x03}, - {0x8c, 0x89}, /* com19 */ - {0x14, 0x28}, /* com9 */ - {0x90, 0x7d}, - {0x91, 0x7b}, - {0x9d, 0x03}, /* lcc6 */ - {0x9e, 0x04}, /* lcc7 */ - {0x9f, 0x7a}, - {0xa0, 0x79}, - {0xa1, 0x40}, /* aechm */ - {0xa4, 0x50}, /* com21 */ - {0xa5, 0x68}, /* com26 */ - {0xa6, 0x4a}, /* AWB green */ - {0xa8, 0xc1}, /* refa8 */ - {0xa9, 0xef}, /* refa9 */ - {0xaa, 0x92}, - {0xab, 0x04}, - {0xac, 0x80}, /* black level control */ - {0xad, 0x80}, - {0xae, 0x80}, - {0xaf, 0x80}, - {0xb2, 0xf2}, - {0xb3, 0x20}, - {0xb4, 0x20}, /* ctrlb4 */ - {0xb5, 0x00}, - {0xb6, 0xaf}, - {0xbb, 0xae}, - {0xbc, 0x7f}, /* ADC channel offsets */ - {0xdb, 0x7f}, - {0xbe, 0x7f}, - {0xbf, 0x7f}, - {0xc0, 0xe2}, - {0xc1, 0xc0}, - {0xc2, 0x01}, - {0xc3, 0x4e}, - {0xc6, 0x85}, - {0xc7, 0x80}, /* com24 */ - {0xc9, 0xe0}, - {0xca, 0xe8}, - {0xcb, 0xf0}, - {0xcc, 0xd8}, - {0xcd, 0xf1}, - {0x4f, 0x98}, /* matrix */ - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, - {0xff, 0x41}, /* read 41, write ff 00 */ - {0x41, 0x40}, /* com16 */ - - {0xc5, 0x03}, /* 60 Hz banding filter */ - {0x6a, 0x02}, /* 50 Hz banding filter */ - - {0x12, 0x62}, /* com7 - 30fps VGA YUV */ - {0x36, 0xfa}, /* aref3 */ - {0x69, 0x0a}, /* hv */ - {0x8c, 0x89}, /* com22 */ - {0x14, 0x28}, /* com9 */ - {0x3e, 0x0c}, - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, - {0x03, 0x12}, /* vref */ - {0x17, 0x16}, /* hstart */ - {0x18, 0x02}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x3d}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xaa}, -}; - -static const u8 bridge_init_2[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0xda, 0x01}, - {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x3c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0xa0}, - {0x5b, 0x78}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x94, 0x11}, -}; - -static const u8 ov965x_init_2[][2] = { - {0x3b, 0xc4}, - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, /* gain */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x03}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x05}, - {0xc5, 0x07}, - {0xa2, 0x4b}, - {0xa3, 0x3e}, - {0x2d, 0x00}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc0}, /* com17 */ - {0x2d, 0x00}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, /* com17 */ -/* sharpness */ - {0x3f, 0x01}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, /* com17 */ -/* saturation */ - {0x4f, 0x98}, /* matrix */ - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, - {0xff, 0x41}, /* read 41, write ff 00 */ - {0x41, 0x40}, /* com16 */ -/* contrast */ - {0x56, 0x40}, -/* brightness */ - {0x55, 0x8f}, -/* expo */ - {0x10, 0x25}, /* aech - exposure high bits */ - {0xff, 0x13}, /* read 13, write ff 00 */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ -}; - -static const u8 ov971x_init[][2] = { - {0x12, 0x80}, - {0x09, 0x10}, - {0x1e, 0x07}, - {0x5f, 0x18}, - {0x69, 0x04}, - {0x65, 0x2a}, - {0x68, 0x0a}, - {0x39, 0x28}, - {0x4d, 0x90}, - {0xc1, 0x80}, - {0x0c, 0x30}, - {0x6d, 0x02}, - {0x96, 0xf1}, - {0xbc, 0x68}, - {0x12, 0x00}, - {0x3b, 0x00}, - {0x97, 0x80}, - {0x17, 0x25}, - {0x18, 0xa2}, - {0x19, 0x01}, - {0x1a, 0xca}, - {0x03, 0x0a}, - {0x32, 0x07}, - {0x98, 0x40}, /*{0x98, 0x00},*/ - {0x99, 0xA0}, /*{0x99, 0x00},*/ - {0x9a, 0x01}, /*{0x9a, 0x00},*/ - {0x57, 0x00}, - {0x58, 0x78}, /*{0x58, 0xc8},*/ - {0x59, 0x50}, /*{0x59, 0xa0},*/ - {0x4c, 0x13}, - {0x4b, 0x36}, - {0x3d, 0x3c}, - {0x3e, 0x03}, - {0xbd, 0x50}, /*{0xbd, 0xa0},*/ - {0xbe, 0x78}, /*{0xbe, 0xc8},*/ - {0x4e, 0x55}, - {0x4f, 0x55}, - {0x50, 0x55}, - {0x51, 0x55}, - {0x24, 0x55}, - {0x25, 0x40}, - {0x26, 0xa1}, - {0x5c, 0x59}, - {0x5d, 0x00}, - {0x11, 0x00}, - {0x2a, 0x98}, - {0x2b, 0x06}, - {0x2d, 0x00}, - {0x2e, 0x00}, - {0x13, 0xa5}, - {0x14, 0x40}, - {0x4a, 0x00}, - {0x49, 0xce}, - {0x22, 0x03}, - {0x09, 0x00} -}; - -static const u8 ov965x_start_1_vga[][2] = { /* same for qvga */ - {0x12, 0x62}, /* com7 - 30fps VGA YUV */ - {0x36, 0xfa}, /* aref3 */ - {0x69, 0x0a}, /* hv */ - {0x8c, 0x89}, /* com22 */ - {0x14, 0x28}, /* com9 */ - {0x3e, 0x0c}, /* com14 */ - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, /* com24 */ - {0x03, 0x12}, /* vref */ - {0x17, 0x16}, /* hstart */ - {0x18, 0x02}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x3d}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xaa}, -}; - -static const u8 ov965x_start_1_svga[][2] = { - {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ - {0x36, 0xf8}, /* aref3 */ - {0x69, 0x02}, /* hv */ - {0x8c, 0x0d}, /* com22 */ - {0x3e, 0x0c}, /* com14 */ - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x01}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, /* com24 */ - {0x03, 0x1b}, /* vref */ - {0x17, 0x1d}, /* hstart */ - {0x18, 0xbd}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x81}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xe2}, -}; - -static const u8 ov965x_start_1_xga[][2] = { - {0x12, 0x02}, /* com7 */ - {0x36, 0xf8}, /* aref3 */ - {0x69, 0x02}, /* hv */ - {0x8c, 0x89}, /* com22 */ - {0x14, 0x28}, /* com9 */ - {0x3e, 0x0c}, /* com14 */ - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x01}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, /* com24 */ - {0x03, 0x1b}, /* vref */ - {0x17, 0x1d}, /* hstart */ - {0x18, 0xbd}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x81}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xe2}, -}; - -static const u8 ov965x_start_1_sxga[][2] = { - {0x12, 0x02}, /* com7 */ - {0x36, 0xf8}, /* aref3 */ - {0x69, 0x02}, /* hv */ - {0x8c, 0x89}, /* com22 */ - {0x14, 0x28}, /* com9 */ - {0x3e, 0x0c}, /* com14 */ - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x01}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, /* com24 */ - {0x03, 0x1b}, /* vref */ - {0x17, 0x1d}, /* hstart */ - {0x18, 0x02}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x81}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xe2}, -}; - -static const u8 bridge_start_qvga[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - - {0xc2, 0x4c}, - {0xc3, 0xf9}, - {0xda, 0x00}, - {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x78}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0x50}, - {0x5b, 0x3c}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x94, 0x11}, -}; - -static const u8 bridge_start_vga[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0xda, 0x01}, - {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x3c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0xa0}, - {0x5b, 0x78}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x94, 0x11}, -}; - -static const u8 bridge_start_svga[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0xa0}, - {0xc1, 0x80}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - {0xc2, 0x4c}, - {0xc3, 0xf9}, - {0x50, 0x00}, - {0x51, 0x40}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0xc8}, - {0x5b, 0x96}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0xda, 0x00}, - {0x94, 0x11}, -}; - -static const u8 bridge_start_xga[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0xa0}, - {0xc1, 0x80}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - {0xc2, 0x4c}, - {0xc3, 0xf9}, - {0x50, 0x00}, - {0x51, 0x40}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x88}, - {0x57, 0x00}, - {0x5c, 0x01}, - {0x5a, 0x00}, - {0x5b, 0xc0}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0xda, 0x01}, - {0x94, 0x11}, -}; - -static const u8 bridge_start_sxga[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0xa0}, - {0xc1, 0x80}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0xda, 0x00}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x94, 0x11}, -}; - -static const u8 ov965x_start_2_qvga[][2] = { - {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x01}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x02}, /* 50 Hz banding filter */ - {0xc5, 0x03}, /* 60 Hz banding filter */ - {0xa2, 0x96}, /* bd50 */ - {0xa3, 0x7d}, /* bd60 */ - - {0xff, 0x13}, /* read 13, write ff 00 */ - {0x13, 0xe7}, - {0x3a, 0x80}, /* tslb - yuyv */ -}; - -static const u8 ov965x_start_2_vga[][2] = { - {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x03}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x05}, /* 50 Hz banding filter */ - {0xc5, 0x07}, /* 60 Hz banding filter */ - {0xa2, 0x4b}, /* bd50 */ - {0xa3, 0x3e}, /* bd60 */ - - {0x2d, 0x00}, /* advfl */ -}; - -static const u8 ov965x_start_2_svga[][2] = { /* same for xga */ - {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x01}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x0c}, /* 50 Hz banding filter */ - {0xc5, 0x0f}, /* 60 Hz banding filter */ - {0xa2, 0x4e}, /* bd50 */ - {0xa3, 0x41}, /* bd60 */ -}; - -static const u8 ov965x_start_2_sxga[][2] = { - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ - {0x1e, 0x04}, /* mvfp */ - {0x11, 0x01}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x0c}, /* 50 Hz banding filter */ - {0xc5, 0x0f}, /* 60 Hz banding filter */ - {0xa2, 0x4e}, /* bd50 */ - {0xa3, 0x41}, /* bd60 */ -}; - -static const u8 ov562x_init[][2] = { - {0x88, 0x20}, - {0x89, 0x0a}, - {0x8a, 0x90}, - {0x8b, 0x06}, - {0x8c, 0x01}, - {0x8d, 0x10}, - {0x1c, 0x00}, - {0x1d, 0x48}, - {0x1d, 0x00}, - {0x1d, 0xff}, - {0x1c, 0x0a}, - {0x1d, 0x2e}, - {0x1d, 0x1e}, -}; - -static const u8 ov562x_init_2[][2] = { - {0x12, 0x80}, - {0x11, 0x41}, - {0x13, 0x00}, - {0x10, 0x1e}, - {0x3b, 0x07}, - {0x5b, 0x40}, - {0x39, 0x07}, - {0x53, 0x02}, - {0x54, 0x60}, - {0x04, 0x20}, - {0x27, 0x04}, - {0x3d, 0x40}, - {0x36, 0x00}, - {0xc5, 0x04}, - {0x4e, 0x00}, - {0x4f, 0x93}, - {0x50, 0x7b}, - {0xca, 0x0c}, - {0xcb, 0x0f}, - {0x39, 0x07}, - {0x4a, 0x10}, - {0x3e, 0x0a}, - {0x3d, 0x00}, - {0x0c, 0x38}, - {0x38, 0x90}, - {0x46, 0x30}, - {0x4f, 0x93}, - {0x50, 0x7b}, - {0xab, 0x00}, - {0xca, 0x0c}, - {0xcb, 0x0f}, - {0x37, 0x02}, - {0x44, 0x48}, - {0x8d, 0x44}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x32, 0x00}, - {0x38, 0x90}, - {0x53, 0x02}, - {0x54, 0x60}, - {0x12, 0x00}, - {0x17, 0x12}, - {0x18, 0xb4}, - {0x19, 0x0c}, - {0x1a, 0xf4}, - {0x03, 0x4a}, - {0x89, 0x20}, - {0x83, 0x80}, - {0xb7, 0x9d}, - {0xb6, 0x11}, - {0xb5, 0x55}, - {0xb4, 0x00}, - {0xa9, 0xf0}, - {0xa8, 0x0a}, - {0xb8, 0xf0}, - {0xb9, 0xf0}, - {0xba, 0xf0}, - {0x81, 0x07}, - {0x63, 0x44}, - {0x13, 0xc7}, - {0x14, 0x60}, - {0x33, 0x75}, - {0x2c, 0x00}, - {0x09, 0x00}, - {0x35, 0x30}, - {0x27, 0x04}, - {0x3c, 0x07}, - {0x3a, 0x0a}, - {0x3b, 0x07}, - {0x01, 0x40}, - {0x02, 0x40}, - {0x16, 0x40}, - {0x52, 0xb0}, - {0x51, 0x83}, - {0x21, 0xbb}, - {0x22, 0x10}, - {0x23, 0x03}, - {0x35, 0x38}, - {0x20, 0x90}, - {0x28, 0x30}, - {0x73, 0xe1}, - {0x6c, 0x00}, - {0x6d, 0x80}, - {0x6e, 0x00}, - {0x70, 0x04}, - {0x71, 0x00}, - {0x8d, 0x04}, - {0x64, 0x00}, - {0x65, 0x00}, - {0x66, 0x00}, - {0x67, 0x00}, - {0x68, 0x00}, - {0x69, 0x00}, - {0x6a, 0x00}, - {0x6b, 0x00}, - {0x71, 0x94}, - {0x74, 0x20}, - {0x80, 0x09}, - {0x85, 0xc0}, -}; - -static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - gspca_dev->usb_buf[0] = val; - ret = usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - 0x01, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - if (ret < 0) { - pr_err("reg_w failed %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val) -{ - PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val); - reg_w_i(gspca_dev, reg, val); -} - -static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return 0; - ret = usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - 0x01, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } - return gspca_dev->usb_buf[0]; -} - -static int sccb_check_status(struct gspca_dev *gspca_dev) -{ - u8 data; - int i; - - for (i = 0; i < 5; i++) { - msleep(10); - data = reg_r(gspca_dev, OV534_REG_STATUS); - - switch (data) { - case 0x00: - return 1; - case 0x04: - return 0; - case 0x03: - break; - default: - PDEBUG(D_USBI|D_USBO, - "sccb status 0x%02x, attempt %d/5", - data, i + 1); - } - } - return 0; -} - -static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) -{ - PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val); - reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg); - reg_w_i(gspca_dev, OV534_REG_WRITE, val); - reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); - - if (!sccb_check_status(gspca_dev)) - pr_err("sccb_write failed\n"); -} - -static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) -{ - reg_w(gspca_dev, OV534_REG_SUBADDR, reg); - reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); - if (!sccb_check_status(gspca_dev)) - pr_err("sccb_read failed 1\n"); - - reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); - if (!sccb_check_status(gspca_dev)) - pr_err("sccb_read failed 2\n"); - - return reg_r(gspca_dev, OV534_REG_READ); -} - -/* output a bridge sequence (reg - val) */ -static void reg_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - reg_w(gspca_dev, (*data)[0], (*data)[1]); - data++; - } -} - -/* output a sensor sequence (reg - val) */ -static void sccb_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - if ((*data)[0] != 0xff) { - sccb_write(gspca_dev, (*data)[0], (*data)[1]); - } else { - sccb_read(gspca_dev, (*data)[1]); - sccb_write(gspca_dev, 0xff, 0x00); - } - data++; - } -} - -/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. - * (direction and output)? */ -static void set_led(struct gspca_dev *gspca_dev, int status) -{ - u8 data; - - PDEBUG(D_CONF, "led status: %d", status); - - data = reg_r(gspca_dev, 0x21); - data |= 0x80; - reg_w(gspca_dev, 0x21, data); - - data = reg_r(gspca_dev, 0x23); - if (status) - data |= 0x80; - else - data &= ~0x80; - - reg_w(gspca_dev, 0x23, data); - - if (!status) { - data = reg_r(gspca_dev, 0x21); - data &= ~0x80; - reg_w(gspca_dev, 0x21, data); - } -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 val; - s8 sval; - - if (sd->sensor == SENSOR_OV562x) { - sval = brightness; - val = 0x76; - val += sval; - sccb_write(gspca_dev, 0x24, val); - val = 0x6a; - val += sval; - sccb_write(gspca_dev, 0x25, val); - if (sval < -40) - val = 0x71; - else if (sval < 20) - val = 0x94; - else - val = 0xe6; - sccb_write(gspca_dev, 0x26, val); - } else { - val = brightness; - if (val < 8) - val = 15 - val; /* f .. 8 */ - else - val = val - 8; /* 0 .. 7 */ - sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ - 0x0f | (val << 4)); - } -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ - val << 4); -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 autogain) -{ - u8 val; - -/*fixme: should adjust agc/awb/aec by different controls */ - val = sccb_read(gspca_dev, 0x13); /* com8 */ - sccb_write(gspca_dev, 0xff, 0x00); - if (autogain) - val |= 0x05; /* agc & aec */ - else - val &= 0xfa; - sccb_write(gspca_dev, 0x13, val); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 exposure) -{ - static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; - u8 val; - - sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */ - - val = sccb_read(gspca_dev, 0x13); /* com8 */ - sccb_write(gspca_dev, 0xff, 0x00); - sccb_write(gspca_dev, 0x13, val); - - val = sccb_read(gspca_dev, 0xa1); /* aech */ - sccb_write(gspca_dev, 0xff, 0x00); - sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - if (val < 0) { /* auto */ - val = sccb_read(gspca_dev, 0x42); /* com17 */ - sccb_write(gspca_dev, 0xff, 0x00); - sccb_write(gspca_dev, 0x42, val | 0x40); - /* Edge enhancement strength auto adjust */ - return; - } - if (val != 0) - val = 1 << (val - 1); - sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ - val); - val = sccb_read(gspca_dev, 0x42); /* com17 */ - sccb_write(gspca_dev, 0xff, 0x00); - sccb_write(gspca_dev, 0x42, val & 0xbf); -} - -static void setsatur(struct gspca_dev *gspca_dev, s32 val) -{ - u8 val1, val2, val3; - static const u8 matrix[5][2] = { - {0x14, 0x38}, - {0x1e, 0x54}, - {0x28, 0x70}, - {0x32, 0x8c}, - {0x48, 0x90} - }; - - val1 = matrix[val][0]; - val2 = matrix[val][1]; - val3 = val1 + val2; - sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ - sccb_write(gspca_dev, 0x50, val3); - sccb_write(gspca_dev, 0x51, 0x00); - sccb_write(gspca_dev, 0x52, val1); - sccb_write(gspca_dev, 0x53, val2); - sccb_write(gspca_dev, 0x54, val3); - sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ - - val1 = sccb_read(gspca_dev, 0x41); /* com16 */ - sccb_write(gspca_dev, 0xff, 0x00); - sccb_write(gspca_dev, 0x41, val1); -} - -static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq) -{ - u8 val; - - val = sccb_read(gspca_dev, 0x13); /* com8 */ - sccb_write(gspca_dev, 0xff, 0x00); - if (freq == 0) { - sccb_write(gspca_dev, 0x13, val & 0xdf); - return; - } - sccb_write(gspca_dev, 0x13, val | 0x20); - - val = sccb_read(gspca_dev, 0x42); /* com17 */ - sccb_write(gspca_dev, 0xff, 0x00); - if (freq == 1) - val |= 0x01; - else - val &= 0xfe; - sccb_write(gspca_dev, 0x42, val); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 sensor_id; - - /* reset bridge */ - reg_w(gspca_dev, 0xe7, 0x3a); - reg_w(gspca_dev, 0xe0, 0x08); - msleep(100); - - /* initialize the sensor address */ - reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60); - - /* reset sensor */ - sccb_write(gspca_dev, 0x12, 0x80); - msleep(10); - - /* probe the sensor */ - sccb_read(gspca_dev, 0x0a); - sensor_id = sccb_read(gspca_dev, 0x0a) << 8; - sccb_read(gspca_dev, 0x0b); - sensor_id |= sccb_read(gspca_dev, 0x0b); - PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); - - /* initialize */ - if ((sensor_id & 0xfff0) == 0x9650) { - sd->sensor = SENSOR_OV965x; - - gspca_dev->cam.cam_mode = ov965x_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode); - - reg_w_array(gspca_dev, bridge_init, - ARRAY_SIZE(bridge_init)); - sccb_w_array(gspca_dev, ov965x_init, - ARRAY_SIZE(ov965x_init)); - reg_w_array(gspca_dev, bridge_init_2, - ARRAY_SIZE(bridge_init_2)); - sccb_w_array(gspca_dev, ov965x_init_2, - ARRAY_SIZE(ov965x_init_2)); - reg_w(gspca_dev, 0xe0, 0x00); - reg_w(gspca_dev, 0xe0, 0x01); - set_led(gspca_dev, 0); - reg_w(gspca_dev, 0xe0, 0x00); - } else if ((sensor_id & 0xfff0) == 0x9710) { - const char *p; - int l; - - sd->sensor = SENSOR_OV971x; - - gspca_dev->cam.cam_mode = ov971x_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); - - gspca_dev->cam.bulk = 1; - gspca_dev->cam.bulk_size = 16384; - gspca_dev->cam.bulk_nurbs = 2; - - sccb_w_array(gspca_dev, ov971x_init, - ARRAY_SIZE(ov971x_init)); - - /* set video format on bridge processor */ - /* access bridge processor's video format registers at: 0x00 */ - reg_w(gspca_dev, 0x1c, 0x00); - /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/ - reg_w(gspca_dev, 0x1d, 0x00); - - /* Will W. specific stuff - * set VSYNC to - * output (0x1f) if first webcam - * input (0x17) if 2nd or 3rd webcam */ - p = video_device_node_name(&gspca_dev->vdev); - l = strlen(p) - 1; - if (p[l] == '0') - reg_w(gspca_dev, 0x56, 0x1f); - else - reg_w(gspca_dev, 0x56, 0x17); - } else if ((sensor_id & 0xfff0) == 0x5620) { - sd->sensor = SENSOR_OV562x; - gspca_dev->cam.cam_mode = ov562x_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); - - reg_w_array(gspca_dev, ov562x_init, - ARRAY_SIZE(ov562x_init)); - sccb_w_array(gspca_dev, ov562x_init_2, - ARRAY_SIZE(ov562x_init_2)); - reg_w(gspca_dev, 0xe0, 0x00); - } else { - pr_err("Unknown sensor %04x", sensor_id); - return -EINVAL; - } - - return gspca_dev->usb_err; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV971x) - return gspca_dev->usb_err; - if (sd->sensor == SENSOR_OV562x) - return gspca_dev->usb_err; - - switch (gspca_dev->curr_mode) { - case QVGA_MODE: /* 320x240 */ - sccb_w_array(gspca_dev, ov965x_start_1_vga, - ARRAY_SIZE(ov965x_start_1_vga)); - reg_w_array(gspca_dev, bridge_start_qvga, - ARRAY_SIZE(bridge_start_qvga)); - sccb_w_array(gspca_dev, ov965x_start_2_qvga, - ARRAY_SIZE(ov965x_start_2_qvga)); - break; - case VGA_MODE: /* 640x480 */ - sccb_w_array(gspca_dev, ov965x_start_1_vga, - ARRAY_SIZE(ov965x_start_1_vga)); - reg_w_array(gspca_dev, bridge_start_vga, - ARRAY_SIZE(bridge_start_vga)); - sccb_w_array(gspca_dev, ov965x_start_2_vga, - ARRAY_SIZE(ov965x_start_2_vga)); - break; - case SVGA_MODE: /* 800x600 */ - sccb_w_array(gspca_dev, ov965x_start_1_svga, - ARRAY_SIZE(ov965x_start_1_svga)); - reg_w_array(gspca_dev, bridge_start_svga, - ARRAY_SIZE(bridge_start_svga)); - sccb_w_array(gspca_dev, ov965x_start_2_svga, - ARRAY_SIZE(ov965x_start_2_svga)); - break; - case XGA_MODE: /* 1024x768 */ - sccb_w_array(gspca_dev, ov965x_start_1_xga, - ARRAY_SIZE(ov965x_start_1_xga)); - reg_w_array(gspca_dev, bridge_start_xga, - ARRAY_SIZE(bridge_start_xga)); - sccb_w_array(gspca_dev, ov965x_start_2_svga, - ARRAY_SIZE(ov965x_start_2_svga)); - break; - default: -/* case SXGA_MODE: * 1280x1024 */ - sccb_w_array(gspca_dev, ov965x_start_1_sxga, - ARRAY_SIZE(ov965x_start_1_sxga)); - reg_w_array(gspca_dev, bridge_start_sxga, - ARRAY_SIZE(bridge_start_sxga)); - sccb_w_array(gspca_dev, ov965x_start_2_sxga, - ARRAY_SIZE(ov965x_start_2_sxga)); - break; - } - - reg_w(gspca_dev, 0xe0, 0x00); - reg_w(gspca_dev, 0xe0, 0x00); - set_led(gspca_dev, 1); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 0xe0, 0x01); - set_led(gspca_dev, 0); - reg_w(gspca_dev, 0xe0, 0x00); -} - -/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ -#define UVC_STREAM_EOH (1 << 7) -#define UVC_STREAM_ERR (1 << 6) -#define UVC_STREAM_STI (1 << 5) -#define UVC_STREAM_RES (1 << 4) -#define UVC_STREAM_SCR (1 << 3) -#define UVC_STREAM_PTS (1 << 2) -#define UVC_STREAM_EOF (1 << 1) -#define UVC_STREAM_FID (1 << 0) - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u32 this_pts; - u8 this_fid; - int remaining_len = len; - int payload_len; - - payload_len = gspca_dev->cam.bulk ? 2048 : 2040; - do { - len = min(remaining_len, payload_len); - - /* Payloads are prefixed with a UVC-style header. We - consider a frame to start when the FID toggles, or the PTS - changes. A frame ends when EOF is set, and we've received - the correct number of bytes. */ - - /* Verify UVC header. Header length is always 12 */ - if (data[0] != 12 || len < 12) { - PDEBUG(D_PACK, "bad header"); - goto discard; - } - - /* Check errors */ - if (data[1] & UVC_STREAM_ERR) { - PDEBUG(D_PACK, "payload error"); - goto discard; - } - - /* Extract PTS and FID */ - if (!(data[1] & UVC_STREAM_PTS)) { - PDEBUG(D_PACK, "PTS not present"); - goto discard; - } - this_pts = (data[5] << 24) | (data[4] << 16) - | (data[3] << 8) | data[2]; - this_fid = data[1] & UVC_STREAM_FID; - - /* If PTS or FID has changed, start a new frame. */ - if (this_pts != sd->last_pts || this_fid != sd->last_fid) { - if (gspca_dev->last_packet_type == INTER_PACKET) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - sd->last_pts = this_pts; - sd->last_fid = this_fid; - gspca_frame_add(gspca_dev, FIRST_PACKET, - data + 12, len - 12); - /* If this packet is marked as EOF, end the frame */ - } else if (data[1] & UVC_STREAM_EOF) { - sd->last_pts = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, - data + 12, len - 12); - } else { - - /* Add the data from this payload */ - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 12, len - 12); - } - - /* Done this payload */ - goto scan_next; - -discard: - /* Discard data until a new frame starts. */ - gspca_dev->last_packet_type = DISCARD_PACKET; - -scan_next: - remaining_len -= len; - data += len; - } while (remaining_len > 0); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setsatur(gspca_dev, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setlightfreq(gspca_dev, ctrl->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - if (ctrl->is_new) - setautogain(gspca_dev, ctrl->val); - if (!ctrl->val && gspca_dev->exposure->is_new) - setexposure(gspca_dev, gspca_dev->exposure->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - if (sd->sensor == SENSOR_OV971x) - return 0; - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 7); - if (sd->sensor == SENSOR_OV562x) { - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, -90, 90, 1, 0); - } else { - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 15, 1, 7); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 15, 1, 3); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 4, 1, 2); - /* -1 = auto */ - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, -1, 4, 1, -1); - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 3, 1, 0); - v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - } - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x05a9, 0x8065)}, - {USB_DEVICE(0x06f8, 0x3003)}, - {USB_DEVICE(0x05a9, 0x1550)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c deleted file mode 100644 index d236d1791f78..000000000000 --- a/drivers/media/video/gspca/pac207.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Pixart PAC207BCA library - * - * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com> - * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li - * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "pac207" - -#include <linux/input.h> -#include "gspca.h" -/* Include pac common sof detection functions */ -#include "pac_common.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Pixart PAC207"); -MODULE_LICENSE("GPL"); - -#define PAC207_CTRL_TIMEOUT 100 /* ms */ - -#define PAC207_BRIGHTNESS_MIN 0 -#define PAC207_BRIGHTNESS_MAX 255 -#define PAC207_BRIGHTNESS_DEFAULT 46 -#define PAC207_BRIGHTNESS_REG 0x08 - -#define PAC207_EXPOSURE_MIN 3 -#define PAC207_EXPOSURE_MAX 90 /* 1 sec expo time / 1 fps */ -#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */ -#define PAC207_EXPOSURE_REG 0x02 - -#define PAC207_GAIN_MIN 0 -#define PAC207_GAIN_MAX 31 -#define PAC207_GAIN_DEFAULT 7 /* power on default: 9 */ -#define PAC207_GAIN_REG 0x0e - -#define PAC207_AUTOGAIN_DEADZONE 30 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl *brightness; - - u8 mode; - u8 sof_read; - u8 header_read; - u8 autogain_ignore_frames; - - atomic_t avg_lum; -}; - -static const struct v4l2_pix_format sif_mode[] = { - {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = (176 + 2) * 144, - /* uncompressed, add 2 bytes / line for line header */ - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, - .bytesperline = 352, - /* compressed, but only when needed (not compressed - when the framerate is low) */ - .sizeimage = (352 + 2) * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -static const __u8 pac207_sensor_init[][8] = { - {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84}, - {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, - {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, - {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00}, -}; - -static void pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, - const u8 *buffer, u16 length) -{ - struct usb_device *udev = gspca_dev->dev; - int err; - - if (gspca_dev->usb_err < 0) - return; - - memcpy(gspca_dev->usb_buf, buffer, length); - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x00, index, - gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); - if (err < 0) { - pr_err("Failed to write registers to index 0x%04X, error %d\n", - index, err); - gspca_dev->usb_err = err; - } -} - -static void pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) -{ - struct usb_device *udev = gspca_dev->dev; - int err; - - if (gspca_dev->usb_err < 0) - return; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, index, NULL, 0, PAC207_CTRL_TIMEOUT); - if (err) { - pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n", - index, value, err); - gspca_dev->usb_err = err; - } -} - -static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) -{ - struct usb_device *udev = gspca_dev->dev; - int res; - - if (gspca_dev->usb_err < 0) - return 0; - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x00, index, - gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT); - if (res < 0) { - pr_err("Failed to read a register (index 0x%04X, error %d)\n", - index, res); - gspca_dev->usb_err = res; - return 0; - } - - return gspca_dev->usb_buf[0]; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - u8 idreg[2]; - - idreg[0] = pac207_read_reg(gspca_dev, 0x0000); - idreg[1] = pac207_read_reg(gspca_dev, 0x0001); - idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4); - idreg[1] = idreg[1] & 0x0f; - PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X", - idreg[0], idreg[1]); - - if (idreg[0] != 0x27) { - PDEBUG(D_PROBE, "Error invalid sensor ID!"); - return -ENODEV; - } - - PDEBUG(D_PROBE, - "Pixart PAC207BCA Image Processor and Control Chip detected" - " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); - - cam = &gspca_dev->cam; - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - pac207_write_reg(gspca_dev, 0x41, 0x00); - /* Bit_0=Image Format, - * Bit_1=LED, - * Bit_2=Compression test mode enable */ - pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ - - return gspca_dev->usb_err; -} - -static void setcontrol(struct gspca_dev *gspca_dev, u16 reg, u16 val) -{ - pac207_write_reg(gspca_dev, reg, val); - pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ - pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { - /* when switching to autogain set defaults to make sure - we are on a valid point of the autogain gain / - exposure knee graph, and give this change time to - take effect before doing autogain. */ - gspca_dev->exposure->val = PAC207_EXPOSURE_DEFAULT; - gspca_dev->gain->val = PAC207_GAIN_DEFAULT; - sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setcontrol(gspca_dev, PAC207_BRIGHTNESS_REG, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) - setcontrol(gspca_dev, PAC207_EXPOSURE_REG, - gspca_dev->exposure->val); - if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) - setcontrol(gspca_dev, PAC207_GAIN_REG, - gspca_dev->gain->val); - break; - default: - return -EINVAL; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -/* this function is called at probe time */ -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, - PAC207_BRIGHTNESS_MIN, PAC207_BRIGHTNESS_MAX, - 1, PAC207_BRIGHTNESS_DEFAULT); - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, - PAC207_EXPOSURE_MIN, PAC207_EXPOSURE_MAX, - 1, PAC207_EXPOSURE_DEFAULT); - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, - PAC207_GAIN_MIN, PAC207_GAIN_MAX, - 1, PAC207_GAIN_DEFAULT); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 mode; - - pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */ - pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8); - pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8); - pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8); - pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8); - - /* Compression Balance */ - if (gspca_dev->width == 176) - pac207_write_reg(gspca_dev, 0x4a, 0xff); - else - pac207_write_reg(gspca_dev, 0x4a, 0x30); - pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */ - pac207_write_reg(gspca_dev, 0x08, v4l2_ctrl_g_ctrl(sd->brightness)); - - /* PGA global gain (Bit 4-0) */ - pac207_write_reg(gspca_dev, 0x0e, - v4l2_ctrl_g_ctrl(gspca_dev->gain)); - pac207_write_reg(gspca_dev, 0x02, - v4l2_ctrl_g_ctrl(gspca_dev->exposure)); /* PXCK = 12MHz /n */ - - mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */ - if (gspca_dev->width == 176) { /* 176x144 */ - mode |= 0x01; - PDEBUG(D_STREAM, "pac207_start mode 176x144"); - } else { /* 352x288 */ - PDEBUG(D_STREAM, "pac207_start mode 352x288"); - } - pac207_write_reg(gspca_dev, 0x41, mode); - - pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ - pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ - msleep(10); - pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ - - sd->sof_read = 0; - sd->autogain_ignore_frames = 0; - atomic_set(&sd->avg_lum, -1); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */ - pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */ - pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ -} - - -static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int avg_lum = atomic_read(&sd->avg_lum); - - if (avg_lum == -1) - return; - - if (sd->autogain_ignore_frames > 0) - sd->autogain_ignore_frames--; - else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, - 90, PAC207_AUTOGAIN_DEADZONE)) - sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned char *sof; - - sof = pac_find_sof(&sd->sof_read, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sizeof pac_sof_marker) - n -= sizeof pac_sof_marker; - else - n = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, - data, n); - sd->header_read = 0; - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - len -= sof - data; - data = sof; - } - if (sd->header_read < 11) { - int needed; - - /* get average lumination from frame header (byte 5) */ - if (sd->header_read < 5) { - needed = 5 - sd->header_read; - if (len >= needed) - atomic_set(&sd->avg_lum, data[needed - 1]); - } - /* skip the rest of the header */ - needed = 11 - sd->header_read; - if (len <= needed) { - sd->header_read += len; - return; - } - data += needed; - len -= needed; - sd->header_read = 11; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrput packet length */ -{ - int ret = -EINVAL; - - if (len == 2 && data[0] == 0x5a && data[1] == 0x5a) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - return ret; -} -#endif - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .dq_callback = pac207_do_auto_gain, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4028)}, - {USB_DEVICE(0x093a, 0x2460)}, - {USB_DEVICE(0x093a, 0x2461)}, - {USB_DEVICE(0x093a, 0x2463)}, - {USB_DEVICE(0x093a, 0x2464)}, - {USB_DEVICE(0x093a, 0x2468)}, - {USB_DEVICE(0x093a, 0x2470)}, - {USB_DEVICE(0x093a, 0x2471)}, - {USB_DEVICE(0x093a, 0x2472)}, - {USB_DEVICE(0x093a, 0x2474)}, - {USB_DEVICE(0x093a, 0x2476)}, - {USB_DEVICE(0x145f, 0x013a)}, - {USB_DEVICE(0x2001, 0xf115)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c deleted file mode 100644 index 4877f7ab3d59..000000000000 --- a/drivers/media/video/gspca/pac7302.c +++ /dev/null @@ -1,932 +0,0 @@ -/* - * Pixart PAC7302 driver - * - * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr> - * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li - * - * Separated from Pixart PAC7311 library by Márton Németh - * Camera button input handling by Márton Németh <nm127@freemail.hu> - * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Some documentation about various registers as determined by trial and error. - * - * Register page 1: - * - * Address Description - * 0x78 Global control, bit 6 controls the LED (inverted) - * 0x80 Compression balance, 2 interesting settings: - * 0x0f Default - * 0x50 Values >= this switch the camera to a lower compression, - * using the same table for both luminance and chrominance. - * This gives a sharper picture. Only usable when running - * at < 15 fps! Note currently the driver does not use this - * as the quality gain is small and the generated JPG-s are - * only understood by v4l-utils >= 0.8.9 - * - * Register page 3: - * - * Address Description - * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on - * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? - * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps - * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps, - * 63 -> ~27 fps, the 2 msb's must always be 1 !! - * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0: - * 1 -> ~30 fps, 2 -> ~20 fps - * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time - * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all - * 0x10 Gain 0-31 - * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an - * amplification value of 1 rather then 0 at its lowest setting - * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused - * 0x80 Another framerate control, best left at 1, moving it from 1 to - * 2 causes the framerate to become 3/4th of what it was, and - * also seems to cause pixel averaging, resulting in an effective - * resolution of 320x240 and thus a much blockier image - * - * The registers are accessed in the following functions: - * - * Page | Register | Function - * -----+------------+--------------------------------------------------- - * 0 | 0x0f..0x20 | setcolors() - * 0 | 0xa2..0xab | setbrightcont() - * 0 | 0xc5 | setredbalance() - * 0 | 0xc6 | setwhitebalance() - * 0 | 0xc7 | setbluebalance() - * 0 | 0xdc | setbrightcont(), setcolors() - * 3 | 0x02 | setexposure() - * 3 | 0x10, 0x12 | setgain() - * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() - * 3 | 0x21 | sethvflip() - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/input.h> -#include <media/v4l2-chip-ident.h> -#include "gspca.h" -/* Include pac common sof detection functions */ -#include "pac_common.h" - -#define PAC7302_GAIN_DEFAULT 15 -#define PAC7302_GAIN_KNEE 42 -#define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */ -#define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " - "Thomas Kaiser thomas@kaiser-linux.li"); -MODULE_DESCRIPTION("Pixart PAC7302"); -MODULE_LICENSE("GPL"); - -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct { /* brightness / contrast cluster */ - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *contrast; - }; - struct v4l2_ctrl *saturation; - struct v4l2_ctrl *white_balance; - struct v4l2_ctrl *red_balance; - struct v4l2_ctrl *blue_balance; - struct { /* flip cluster */ - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - }; - u8 flags; -#define FL_HFLIP 0x01 /* mirrored by default */ -#define FL_VFLIP 0x02 /* vertical flipped by default */ - - u8 sof_read; - s8 autogain_ignore_frames; - - atomic_t avg_lum; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - }, -}; - -#define LOAD_PAGE3 255 -#define END_OF_SEQUENCE 0 - -static const u8 init_7302[] = { -/* index,value */ - 0xff, 0x01, /* page 1 */ - 0x78, 0x00, /* deactivate */ - 0xff, 0x01, - 0x78, 0x40, /* led off */ -}; -static const u8 start_7302[] = { -/* index, len, [value]* */ - 0xff, 1, 0x00, /* page 0 */ - 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, - 0x00, 0x00, 0x00, 0x00, - 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, - 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, - 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, - 0x26, 2, 0xaa, 0xaa, - 0x2e, 1, 0x31, - 0x38, 1, 0x01, - 0x3a, 3, 0x14, 0xff, 0x5a, - 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, - 0x00, 0x54, 0x11, - 0x55, 1, 0x00, - 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, - 0x6b, 1, 0x00, - 0x6e, 3, 0x08, 0x06, 0x00, - 0x72, 3, 0x00, 0xff, 0x00, - 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, - 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, - 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, - 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, - 0xd2, 0xeb, - 0xaf, 1, 0x02, - 0xb5, 2, 0x08, 0x08, - 0xb8, 2, 0x08, 0x88, - 0xc4, 4, 0xae, 0x01, 0x04, 0x01, - 0xcc, 1, 0x00, - 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, - 0xc1, 0xd7, 0xec, - 0xdc, 1, 0x01, - 0xff, 1, 0x01, /* page 1 */ - 0x12, 3, 0x02, 0x00, 0x01, - 0x3e, 2, 0x00, 0x00, - 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, - 0x7c, 1, 0x00, - 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, - 0x02, 0x00, - 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, - 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, - 0xd8, 1, 0x01, - 0xdb, 2, 0x00, 0x01, - 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, - 0xe6, 4, 0x00, 0x00, 0x00, 0x01, - 0xeb, 1, 0x00, - 0xff, 1, 0x02, /* page 2 */ - 0x22, 1, 0x00, - 0xff, 1, 0x03, /* page 3 */ - 0, LOAD_PAGE3, /* load the page 3 */ - 0x11, 1, 0x01, - 0xff, 1, 0x02, /* page 2 */ - 0x13, 1, 0x00, - 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, - 0x27, 2, 0x14, 0x0c, - 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, - 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, - 0x6e, 1, 0x08, - 0xff, 1, 0x01, /* page 1 */ - 0x78, 1, 0x00, - 0, END_OF_SEQUENCE /* end of sequence */ -}; - -#define SKIP 0xaa -/* page 3 - the value SKIP says skip the index - see reg_w_page() */ -static const u8 page3_7302[] = { - 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, - 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, - 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, - 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, - 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, - SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, - 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, - 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, - 0x00 -}; - -static void reg_w_buf(struct gspca_dev *gspca_dev, - u8 index, - const u8 *buffer, int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - memcpy(gspca_dev->usb_buf, buffer, len); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, len, - 500); - if (ret < 0) { - pr_err("reg_w_buf failed i: %02x error %d\n", - index, ret); - gspca_dev->usb_err = ret; - } -} - - -static void reg_w(struct gspca_dev *gspca_dev, - u8 index, - u8 value) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - gspca_dev->usb_buf[0] = value; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w() failed i: %02x v: %02x error %d\n", - index, value, ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w_seq(struct gspca_dev *gspca_dev, - const u8 *seq, int len) -{ - while (--len >= 0) { - reg_w(gspca_dev, seq[0], seq[1]); - seq += 2; - } -} - -/* load the beginning of a page */ -static void reg_w_page(struct gspca_dev *gspca_dev, - const u8 *page, int len) -{ - int index; - int ret = 0; - - if (gspca_dev->usb_err < 0) - return; - for (index = 0; index < len; index++) { - if (page[index] == SKIP) /* skip this index */ - continue; - gspca_dev->usb_buf[0] = page[index]; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w_page() failed i: %02x v: %02x error %d\n", - index, page[index], ret); - gspca_dev->usb_err = ret; - break; - } - } -} - -/* output a variable sequence */ -static void reg_w_var(struct gspca_dev *gspca_dev, - const u8 *seq, - const u8 *page3, unsigned int page3_len) -{ - int index, len; - - for (;;) { - index = *seq++; - len = *seq++; - switch (len) { - case END_OF_SEQUENCE: - return; - case LOAD_PAGE3: - reg_w_page(gspca_dev, page3, page3_len); - break; - default: -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - PDEBUG(D_ERR|D_STREAM, - "Incorrect variable sequence"); - return; - } -#endif - while (len > 0) { - if (len < 8) { - reg_w_buf(gspca_dev, - index, seq, len); - seq += len; - break; - } - reg_w_buf(gspca_dev, index, seq, 8); - seq += 8; - index += 8; - len -= 8; - } - } - } - /* not reached */ -} - -/* this function is called at probe time for pac7302 */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - - cam->cam_mode = vga_mode; /* only 640x480 */ - cam->nmodes = ARRAY_SIZE(vga_mode); - - sd->flags = id->driver_info; - return 0; -} - -static void setbrightcont(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, v; - static const u8 max[10] = - {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, - 0xd4, 0xec}; - static const u8 delta[10] = - {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, - 0x11, 0x0b}; - - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - for (i = 0; i < 10; i++) { - v = max[i]; - v += (sd->brightness->val - sd->brightness->maximum) - * 150 / sd->brightness->maximum; /* 200 ? */ - v -= delta[i] * sd->contrast->val / sd->contrast->maximum; - if (v < 0) - v = 0; - else if (v > 0xff) - v = 0xff; - reg_w(gspca_dev, 0xa2 + i, v); - } - reg_w(gspca_dev, 0xdc, 0x01); -} - -static void setcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, v; - static const int a[9] = - {217, -212, 0, -101, 170, -67, -38, -315, 355}; - static const int b[9] = - {19, 106, 0, 19, 106, 1, 19, 106, 1}; - - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x11, 0x01); - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - for (i = 0; i < 9; i++) { - v = a[i] * sd->saturation->val / sd->saturation->maximum; - v += b[i]; - reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); - reg_w(gspca_dev, 0x0f + 2 * i + 1, v); - } - reg_w(gspca_dev, 0xdc, 0x01); -} - -static void setwhitebalance(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - reg_w(gspca_dev, 0xc6, sd->white_balance->val); - - reg_w(gspca_dev, 0xdc, 0x01); -} - -static void setredbalance(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - reg_w(gspca_dev, 0xc5, sd->red_balance->val); - - reg_w(gspca_dev, 0xdc, 0x01); -} - -static void setbluebalance(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - reg_w(gspca_dev, 0xc7, sd->blue_balance->val); - - reg_w(gspca_dev, 0xdc, 0x01); -} - -static void setgain(struct gspca_dev *gspca_dev) -{ - u8 reg10, reg12; - - if (gspca_dev->gain->val < 32) { - reg10 = gspca_dev->gain->val; - reg12 = 0; - } else { - reg10 = 31; - reg12 = gspca_dev->gain->val - 31; - } - - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x10, reg10); - reg_w(gspca_dev, 0x12, reg12); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -static void setexposure(struct gspca_dev *gspca_dev) -{ - u8 clockdiv; - u16 exposure; - - /* - * Register 2 of frame 3 contains the clock divider configuring the - * no fps according to the formula: 90 / reg. sd->exposure is the - * desired exposure time in 0.5 ms. - */ - clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000; - - /* - * Note clockdiv = 3 also works, but when running at 30 fps, depending - * on the scene being recorded, the camera switches to another - * quantization table for certain JPEG blocks, and we don't know how - * to decompress these blocks. So we cap the framerate at 15 fps. - */ - if (clockdiv < 6) - clockdiv = 6; - else if (clockdiv > 63) - clockdiv = 63; - - /* - * Register 2 MUST be a multiple of 3, except when between 6 and 12? - * Always round up, otherwise we cannot get the desired frametime - * using the partial frame time exposure control. - */ - if (clockdiv < 6 || clockdiv > 12) - clockdiv = ((clockdiv + 2) / 3) * 3; - - /* - * frame exposure time in ms = 1000 * clockdiv / 90 -> - * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) - */ - exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv); - /* 0 = use full frametime, 448 = no exposure, reverse it */ - exposure = 448 - exposure; - - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - reg_w(gspca_dev, 0x02, clockdiv); - reg_w(gspca_dev, 0x0e, exposure & 0xff); - reg_w(gspca_dev, 0x0f, exposure >> 8); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -static void sethvflip(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data, hflip, vflip; - - hflip = sd->hflip->val; - if (sd->flags & FL_HFLIP) - hflip = !hflip; - vflip = sd->vflip->val; - if (sd->flags & FL_VFLIP) - vflip = !vflip; - - reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ - data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); - reg_w(gspca_dev, 0x21, data); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -/* this function is called at probe and resume time for pac7302 */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); - return gspca_dev->usb_err; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { - /* when switching to autogain set defaults to make sure - we are on a valid point of the autogain gain / - exposure knee graph, and give this change time to - take effect before doing autogain. */ - gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT; - gspca_dev->gain->val = PAC7302_GAIN_DEFAULT; - sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightcont(gspca_dev); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev); - break; - case V4L2_CID_WHITE_BALANCE_TEMPERATURE: - setwhitebalance(gspca_dev); - break; - case V4L2_CID_RED_BALANCE: - setredbalance(gspca_dev); - break; - case V4L2_CID_BLUE_BALANCE: - setbluebalance(gspca_dev); - break; - case V4L2_CID_AUTOGAIN: - if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) - setexposure(gspca_dev); - if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) - setgain(gspca_dev); - break; - case V4L2_CID_HFLIP: - sethvflip(gspca_dev); - break; - default: - return -EINVAL; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -/* this function is called at probe time */ -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 11); - - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 32, 1, 16); - sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 127); - - sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 127); - sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_WHITE_BALANCE_TEMPERATURE, - 0, 255, 1, 4); - sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 3, 1, 1); - sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 3, 1, 1); - - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 1023, 1, - PAC7302_EXPOSURE_DEFAULT); - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 62, 1, - PAC7302_GAIN_DEFAULT); - - sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - v4l2_ctrl_cluster(2, &sd->brightness); - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - v4l2_ctrl_cluster(2, &sd->hflip); - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w_var(gspca_dev, start_7302, - page3_7302, sizeof(page3_7302)); - setbrightcont(gspca_dev); - setcolors(gspca_dev); - setwhitebalance(gspca_dev); - setredbalance(gspca_dev); - setbluebalance(gspca_dev); - setexposure(gspca_dev); - setgain(gspca_dev); - sethvflip(gspca_dev); - - sd->sof_read = 0; - sd->autogain_ignore_frames = 0; - atomic_set(&sd->avg_lum, 270 + sd->brightness->val); - - /* start stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x01); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - - /* stop stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x00); -} - -/* called on streamoff with alt 0 and on disconnect for pac7302 */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - if (!gspca_dev->present) - return; - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x40); -} - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int avg_lum = atomic_read(&sd->avg_lum); - int desired_lum; - const int deadzone = 30; - - if (sd->autogain_ignore_frames < 0) - return; - - if (sd->autogain_ignore_frames > 0) { - sd->autogain_ignore_frames--; - } else { - desired_lum = 270 + sd->brightness->val; - - if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum, - deadzone, PAC7302_GAIN_KNEE, - PAC7302_EXPOSURE_KNEE)) - sd->autogain_ignore_frames = - PAC_AUTOGAIN_IGNORE_FRAMES; - } -} - -/* JPEG header */ -static const u8 jpeg_header[] = { - 0xff, 0xd8, /* SOI: Start of Image */ - - 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ - 0x00, 0x11, /* length = 17 bytes (including this length field) */ - 0x08, /* Precision: 8 */ - 0x02, 0x80, /* height = 640 (image rotated) */ - 0x01, 0xe0, /* width = 480 */ - 0x03, /* Number of image components: 3 */ - 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ - 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ - 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ - - 0xff, 0xda, /* SOS: Start Of Scan */ - 0x00, 0x0c, /* length = 12 bytes (including this length field) */ - 0x03, /* number of components: 3 */ - 0x01, 0x00, /* selector 1, table 0x00 */ - 0x02, 0x11, /* selector 2, table 0x11 */ - 0x03, 0x11, /* selector 3, table 0x11 */ - 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ - 0x00 /* Successive approximation: 0 */ -}; - -/* this function is run at interrupt level */ -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 *image; - u8 *sof; - - sof = pac_find_sof(&sd->sof_read, data, len); - if (sof) { - int n, lum_offset, footer_length; - - /* - * 6 bytes after the FF D9 EOF marker a number of lumination - * bytes are send corresponding to different parts of the - * image, the 14th and 15th byte after the EOF seem to - * correspond to the center of the image. - */ - lum_offset = 61 + sizeof pac_sof_marker; - footer_length = 74; - - /* Finish decoding current frame */ - n = (sof - data) - (footer_length + sizeof pac_sof_marker); - if (n < 0) { - gspca_dev->image_len += n; - n = 0; - } else { - gspca_frame_add(gspca_dev, INTER_PACKET, data, n); - } - - image = gspca_dev->image; - if (image != NULL - && image[gspca_dev->image_len - 2] == 0xff - && image[gspca_dev->image_len - 1] == 0xd9) - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - n = sof - data; - len -= n; - data = sof; - - /* Get average lumination */ - if (gspca_dev->last_packet_type == LAST_PACKET && - n >= lum_offset) - atomic_set(&sd->avg_lum, data[-lum_offset] + - data[-lum_offset + 1]); - - /* Start the new frame with the jpeg header */ - /* The PAC7302 has the image rotated 90 degrees */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - jpeg_header, sizeof jpeg_header); - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int sd_dbg_s_register(struct gspca_dev *gspca_dev, - struct v4l2_dbg_register *reg) -{ - u8 index; - u8 value; - - /* - * reg->reg: bit0..15: reserved for register index (wIndex is 16bit - * long on the USB bus) - */ - if (reg->match.type == V4L2_CHIP_MATCH_HOST && - reg->match.addr == 0 && - (reg->reg < 0x000000ff) && - (reg->val <= 0x000000ff) - ) { - /* Currently writing to page 0 is only supported. */ - /* reg_w() only supports 8bit index */ - index = reg->reg; - value = reg->val; - - /* - * Note that there shall be no access to other page - * by any other function between the page switch and - * the actual register write. - */ - reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ - reg_w(gspca_dev, index, value); - - reg_w(gspca_dev, 0xdc, 0x01); - } - return gspca_dev->usb_err; -} - -static int sd_chip_ident(struct gspca_dev *gspca_dev, - struct v4l2_dbg_chip_ident *chip) -{ - int ret = -EINVAL; - - if (chip->match.type == V4L2_CHIP_MATCH_HOST && - chip->match.addr == 0) { - chip->revision = 0; - chip->ident = V4L2_IDENT_UNKNOWN; - ret = 0; - } - return ret; -} -#endif - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrput packet length */ -{ - int ret = -EINVAL; - u8 data0, data1; - - if (len == 2) { - data0 = data[0]; - data1 = data[1]; - if ((data0 == 0x00 && data1 == 0x11) || - (data0 == 0x22 && data1 == 0x33) || - (data0 == 0x44 && data1 == 0x55) || - (data0 == 0x66 && data1 == 0x77) || - (data0 == 0x88 && data1 == 0x99) || - (data0 == 0xaa && data1 == 0xbb) || - (data0 == 0xcc && data1 == 0xdd) || - (data0 == 0xee && data1 == 0xff)) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - } - - return ret; -} -#endif - -/* sub-driver description for pac7302 */ -static const struct sd_desc sd_desc = { - .name = KBUILD_MODNAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .set_register = sd_dbg_s_register, - .get_chip_ident = sd_chip_ident, -#endif -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x06f8, 0x3009)}, - {USB_DEVICE(0x06f8, 0x301b)}, - {USB_DEVICE(0x093a, 0x2620)}, - {USB_DEVICE(0x093a, 0x2621)}, - {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, - {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, - {USB_DEVICE(0x093a, 0x2625)}, - {USB_DEVICE(0x093a, 0x2626)}, - {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP}, - {USB_DEVICE(0x093a, 0x2628)}, - {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, - {USB_DEVICE(0x093a, 0x262a)}, - {USB_DEVICE(0x093a, 0x262c)}, - {USB_DEVICE(0x145f, 0x013c)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = KBUILD_MODNAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c deleted file mode 100644 index ba3558d3f017..000000000000 --- a/drivers/media/video/gspca/pac7311.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * Pixart PAC7311 library - * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Some documentation about various registers as determined by trial and error. - * - * Register page 1: - * - * Address Description - * 0x08 Unknown compressor related, must always be 8 except when not - * in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 ! - * 0x1b Auto white balance related, bit 0 is AWB enable (inverted) - * bits 345 seem to toggle per color gains on/off (inverted) - * 0x78 Global control, bit 6 controls the LED (inverted) - * 0x80 Compression balance, interesting settings: - * 0x01 Use this to allow the camera to switch to higher compr. - * on the fly. Needed to stay within bandwidth @ 640x480@30 - * 0x1c From usb captures under Windows for 640x480 - * 0x2a Values >= this switch the camera to a lower compression, - * using the same table for both luminance and chrominance. - * This gives a sharper picture. Usable only at 640x480@ < - * 15 fps or 320x240 / 160x120. Note currently the driver - * does not use this as the quality gain is small and the - * generated JPG-s are only understood by v4l-utils >= 0.8.9 - * 0x3f From usb captures under Windows for 320x240 - * 0x69 From usb captures under Windows for 160x120 - * - * Register page 4: - * - * Address Description - * 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on - * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? - * 0x0f Master gain 1-245, low value = high gain - * 0x10 Another gain 0-15, limited influence (1-2x gain I guess) - * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused - * Note setting vflip disabled leads to a much lower image quality, - * so we always vflip, and tell userspace to flip it back - * 0x27 Seems to toggle various gains on / off, Setting bit 7 seems to - * completely disable the analog amplification block. Set to 0x68 - * for max gain, 0x14 for minimal gain. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "pac7311" - -#include <linux/input.h> -#include "gspca.h" -/* Include pac common sof detection functions */ -#include "pac_common.h" - -#define PAC7311_GAIN_DEFAULT 122 -#define PAC7311_EXPOSURE_DEFAULT 3 /* 20 fps, avoid using high compr. */ - -MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); -MODULE_DESCRIPTION("Pixart PAC7311"); -MODULE_LICENSE("GPL"); - -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl *contrast; - struct v4l2_ctrl *hflip; - - u8 sof_read; - u8 autogain_ignore_frames; - - atomic_t avg_lum; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -#define LOAD_PAGE4 254 -#define END_OF_SEQUENCE 0 - -static const __u8 init_7311[] = { - 0xff, 0x01, - 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */ - 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */ - 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */ - 0xff, 0x04, - 0x27, 0x80, - 0x28, 0xca, - 0x29, 0x53, - 0x2a, 0x0e, - 0xff, 0x01, - 0x3e, 0x20, -}; - -static const __u8 start_7311[] = { -/* index, len, [value]* */ - 0xff, 1, 0x01, /* page 1 */ - 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00, - 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c, - 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e, - 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49, - 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48, - 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78, - 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b, - 0xd0, 0xff, - 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80, - 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84, - 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14, - 0x18, 0x20, - 0x96, 3, 0x01, 0x08, 0x04, - 0xa0, 4, 0x44, 0x44, 0x44, 0x04, - 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, - 0x3f, 0x00, 0x0a, 0x01, 0x00, - 0xff, 1, 0x04, /* page 4 */ - 0, LOAD_PAGE4, /* load the page 4 */ - 0x11, 1, 0x01, - 0, END_OF_SEQUENCE /* end of sequence */ -}; - -#define SKIP 0xaa -/* page 4 - the value SKIP says skip the index - see reg_w_page() */ -static const __u8 page4_7311[] = { - SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, - 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62, - 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP, - SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68, - 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 -}; - -static void reg_w_buf(struct gspca_dev *gspca_dev, - __u8 index, - const u8 *buffer, int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - memcpy(gspca_dev->usb_buf, buffer, len); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, len, - 500); - if (ret < 0) { - pr_err("reg_w_buf() failed index 0x%02x, error %d\n", - index, ret); - gspca_dev->usb_err = ret; - } -} - - -static void reg_w(struct gspca_dev *gspca_dev, - __u8 index, - __u8 value) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - gspca_dev->usb_buf[0] = value; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n", - index, value, ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w_seq(struct gspca_dev *gspca_dev, - const __u8 *seq, int len) -{ - while (--len >= 0) { - reg_w(gspca_dev, seq[0], seq[1]); - seq += 2; - } -} - -/* load the beginning of a page */ -static void reg_w_page(struct gspca_dev *gspca_dev, - const __u8 *page, int len) -{ - int index; - int ret = 0; - - if (gspca_dev->usb_err < 0) - return; - for (index = 0; index < len; index++) { - if (page[index] == SKIP) /* skip this index */ - continue; - gspca_dev->usb_buf[0] = page[index]; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n", - index, page[index], ret); - gspca_dev->usb_err = ret; - break; - } - } -} - -/* output a variable sequence */ -static void reg_w_var(struct gspca_dev *gspca_dev, - const __u8 *seq, - const __u8 *page4, unsigned int page4_len) -{ - int index, len; - - for (;;) { - index = *seq++; - len = *seq++; - switch (len) { - case END_OF_SEQUENCE: - return; - case LOAD_PAGE4: - reg_w_page(gspca_dev, page4, page4_len); - break; - default: - if (len > USB_BUF_SZ) { - PDEBUG(D_ERR|D_STREAM, - "Incorrect variable sequence"); - return; - } - while (len > 0) { - if (len < 8) { - reg_w_buf(gspca_dev, - index, seq, len); - seq += len; - break; - } - reg_w_buf(gspca_dev, index, seq, 8); - seq += 8; - index += 8; - len -= 8; - } - } - } - /* not reached */ -} - -/* this function is called at probe time for pac7311 */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - cam->input_flags = V4L2_IN_ST_VFLIP; - - return 0; -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x10, val); - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x0e, 0x00); - reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - reg_w(gspca_dev, 0x02, val); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); - - /* - * Page 1 register 8 must always be 0x08 except when not in - * 640x480 mode and page 4 reg 2 <= 3 then it must be 9 - */ - reg_w(gspca_dev, 0xff, 0x01); - if (gspca_dev->width != 640 && val <= 3) - reg_w(gspca_dev, 0x08, 0x09); - else - reg_w(gspca_dev, 0x08, 0x08); - - /* - * Page1 register 80 sets the compression balance, normally we - * want / use 0x1c, but for 640x480@30fps we must allow the - * camera to use higher compression or we may run out of - * bandwidth. - */ - if (gspca_dev->width == 640 && val == 2) - reg_w(gspca_dev, 0x80, 0x01); - else - reg_w(gspca_dev, 0x80, 0x1c); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) -{ - __u8 data; - - reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ - data = (hflip ? 0x04 : 0x00) | - (vflip ? 0x08 : 0x00); - reg_w(gspca_dev, 0x21, data); - - /* load registers to sensor (Bit 0, auto clear) */ - reg_w(gspca_dev, 0x11, 0x01); -} - -/* this function is called at probe and resume time for pac7311 */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); - return gspca_dev->usb_err; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { - /* when switching to autogain set defaults to make sure - we are on a valid point of the autogain gain / - exposure knee graph, and give this change time to - take effect before doing autogain. */ - gspca_dev->exposure->val = PAC7311_EXPOSURE_DEFAULT; - gspca_dev->gain->val = PAC7311_GAIN_DEFAULT; - sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) - setexposure(gspca_dev, gspca_dev->exposure->val); - if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) - setgain(gspca_dev, gspca_dev->gain->val); - break; - case V4L2_CID_HFLIP: - sethvflip(gspca_dev, sd->hflip->val, 1); - break; - default: - return -EINVAL; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -/* this function is called at probe time */ -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - - sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 15, 1, 7); - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 2, 63, 1, - PAC7311_EXPOSURE_DEFAULT); - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 244, 1, - PAC7311_GAIN_DEFAULT); - sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->sof_read = 0; - - reg_w_var(gspca_dev, start_7311, - page4_7311, sizeof(page4_7311)); - setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast)); - setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain)); - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure)); - sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1); - - /* set correct resolution */ - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 2: /* 160x120 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x20); - reg_w(gspca_dev, 0x87, 0x10); - break; - case 1: /* 320x240 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x30); - reg_w(gspca_dev, 0x87, 0x11); - break; - case 0: /* 640x480 */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x17, 0x00); - reg_w(gspca_dev, 0x87, 0x12); - break; - } - - sd->sof_read = 0; - sd->autogain_ignore_frames = 0; - atomic_set(&sd->avg_lum, -1); - - /* start stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x05); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 0xff, 0x04); - reg_w(gspca_dev, 0x27, 0x80); - reg_w(gspca_dev, 0x28, 0xca); - reg_w(gspca_dev, 0x29, 0x53); - reg_w(gspca_dev, 0x2a, 0x0e); - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x3e, 0x20); - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ - reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ -} - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int avg_lum = atomic_read(&sd->avg_lum); - int desired_lum, deadzone; - - if (avg_lum == -1) - return; - - desired_lum = 170; - deadzone = 20; - - if (sd->autogain_ignore_frames > 0) - sd->autogain_ignore_frames--; - else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, - desired_lum, deadzone)) - sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; -} - -/* JPEG header, part 1 */ -static const unsigned char pac_jpeg_header1[] = { - 0xff, 0xd8, /* SOI: Start of Image */ - - 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ - 0x00, 0x11, /* length = 17 bytes (including this length field) */ - 0x08 /* Precision: 8 */ - /* 2 bytes is placed here: number of image lines */ - /* 2 bytes is placed here: samples per line */ -}; - -/* JPEG header, continued */ -static const unsigned char pac_jpeg_header2[] = { - 0x03, /* Number of image components: 3 */ - 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ - 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ - 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ - - 0xff, 0xda, /* SOS: Start Of Scan */ - 0x00, 0x0c, /* length = 12 bytes (including this length field) */ - 0x03, /* number of components: 3 */ - 0x01, 0x00, /* selector 1, table 0x00 */ - 0x02, 0x11, /* selector 2, table 0x11 */ - 0x03, 0x11, /* selector 3, table 0x11 */ - 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ - 0x00 /* Successive approximation: 0 */ -}; - -static void pac_start_frame(struct gspca_dev *gspca_dev, - __u16 lines, __u16 samples_per_line) -{ - unsigned char tmpbuf[4]; - - gspca_frame_add(gspca_dev, FIRST_PACKET, - pac_jpeg_header1, sizeof(pac_jpeg_header1)); - - tmpbuf[0] = lines >> 8; - tmpbuf[1] = lines & 0xff; - tmpbuf[2] = samples_per_line >> 8; - tmpbuf[3] = samples_per_line & 0xff; - - gspca_frame_add(gspca_dev, INTER_PACKET, - tmpbuf, sizeof(tmpbuf)); - gspca_frame_add(gspca_dev, INTER_PACKET, - pac_jpeg_header2, sizeof(pac_jpeg_header2)); -} - -/* this function is run at interrupt level */ -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 *image; - unsigned char *sof; - - sof = pac_find_sof(&sd->sof_read, data, len); - if (sof) { - int n, lum_offset, footer_length; - - /* - * 6 bytes after the FF D9 EOF marker a number of lumination - * bytes are send corresponding to different parts of the - * image, the 14th and 15th byte after the EOF seem to - * correspond to the center of the image. - */ - lum_offset = 24 + sizeof pac_sof_marker; - footer_length = 26; - - /* Finish decoding current frame */ - n = (sof - data) - (footer_length + sizeof pac_sof_marker); - if (n < 0) { - gspca_dev->image_len += n; - n = 0; - } else { - gspca_frame_add(gspca_dev, INTER_PACKET, data, n); - } - image = gspca_dev->image; - if (image != NULL - && image[gspca_dev->image_len - 2] == 0xff - && image[gspca_dev->image_len - 1] == 0xd9) - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - n = sof - data; - len -= n; - data = sof; - - /* Get average lumination */ - if (gspca_dev->last_packet_type == LAST_PACKET && - n >= lum_offset) - atomic_set(&sd->avg_lum, data[-lum_offset] + - data[-lum_offset + 1]); - else - atomic_set(&sd->avg_lum, -1); - - /* Start the new frame with the jpeg header */ - pac_start_frame(gspca_dev, - gspca_dev->height, gspca_dev->width); - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrupt packet length */ -{ - int ret = -EINVAL; - u8 data0, data1; - - if (len == 2) { - data0 = data[0]; - data1 = data[1]; - if ((data0 == 0x00 && data1 == 0x11) || - (data0 == 0x22 && data1 == 0x33) || - (data0 == 0x44 && data1 == 0x55) || - (data0 == 0x66 && data1 == 0x77) || - (data0 == 0x88 && data1 == 0x99) || - (data0 == 0xaa && data1 == 0xbb) || - (data0 == 0xcc && data1 == 0xdd) || - (data0 == 0xee && data1 == 0xff)) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - } - - return ret; -} -#endif - -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x2600)}, - {USB_DEVICE(0x093a, 0x2601)}, - {USB_DEVICE(0x093a, 0x2603)}, - {USB_DEVICE(0x093a, 0x2608)}, - {USB_DEVICE(0x093a, 0x260e)}, - {USB_DEVICE(0x093a, 0x260f)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h deleted file mode 100644 index 8462a7c1a338..000000000000 --- a/drivers/media/video/gspca/pac_common.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Pixart PAC207BCA / PAC73xx common functions - * - * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li - * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* We calculate the autogain at the end of the transfer of a frame, at this - moment a frame with the old settings is being captured and transmitted. So - if we adjust the gain or exposure we must ignore atleast the next frame for - the new settings to come into effect before doing any other adjustments. */ -#define PAC_AUTOGAIN_IGNORE_FRAMES 2 - -static const unsigned char pac_sof_marker[5] = - { 0xff, 0xff, 0x00, 0xff, 0x96 }; - -/* - The following state machine finds the SOF marker sequence - 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream. - - +----------+ - | 0: START |<---------------\ - +----------+<-\ | - | \---/otherwise | - v 0xff | - +----------+ otherwise | - | 1 |--------------->* - | | ^ - +----------+ | - | | - v 0xff | - +----------+<-\0xff | - /->| |--/ | - | | 2 |--------------->* - | | | otherwise ^ - | +----------+ | - | | | - | v 0x00 | - | +----------+ | - | | 3 | | - | | |--------------->* - | +----------+ otherwise ^ - | | | - 0xff | v 0xff | - | +----------+ | - \--| 4 | | - | |----------------/ - +----------+ otherwise - | - v 0x96 - +----------+ - | FOUND | - +----------+ -*/ - -static unsigned char *pac_find_sof(u8 *sof_read, - unsigned char *m, int len) -{ - int i; - - /* Search for the SOF marker (fixed part) in the header */ - for (i = 0; i < len; i++) { - switch (*sof_read) { - case 0: - if (m[i] == 0xff) - *sof_read = 1; - break; - case 1: - if (m[i] == 0xff) - *sof_read = 2; - else - *sof_read = 0; - break; - case 2: - switch (m[i]) { - case 0x00: - *sof_read = 3; - break; - case 0xff: - /* stay in this state */ - break; - default: - *sof_read = 0; - } - break; - case 3: - if (m[i] == 0xff) - *sof_read = 4; - else - *sof_read = 0; - break; - case 4: - switch (m[i]) { - case 0x96: - /* Pattern found */ - PDEBUG(D_FRAM, - "SOF found, bytes to analyze: %u." - " Frame starts at byte #%u", - len, i + 1); - *sof_read = 0; - return m + i + 1; - break; - case 0xff: - *sof_read = 2; - break; - default: - *sof_read = 0; - } - break; - default: - *sof_read = 0; - } - } - - return NULL; -} diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c deleted file mode 100644 index a33cb78a839c..000000000000 --- a/drivers/media/video/gspca/se401.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * GSPCA Endpoints (formerly known as AOX) se401 USB Camera sub Driver - * - * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com> - * - * Based on the v4l1 se401 driver which is: - * - * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "se401" - -#define BULK_SIZE 4096 -#define PACKET_SIZE 1024 -#define READ_REQ_SIZE 64 -#define MAX_MODES ((READ_REQ_SIZE - 6) / 4) -/* The se401 compression algorithm uses a fixed quant factor, which - can be configured by setting the high nibble of the SE401_OPERATINGMODE - feature. This needs to exactly match what is in libv4l! */ -#define SE401_QUANT_FACT 8 - -#include <linux/input.h> -#include <linux/slab.h> -#include "gspca.h" -#include "se401.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Endpoints se401"); -MODULE_LICENSE("GPL"); - -/* exposure change state machine states */ -enum { - EXPO_CHANGED, - EXPO_DROP_FRAME, - EXPO_NO_CHANGE, -}; - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct { /* exposure/freq control cluster */ - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *freq; - }; - bool has_brightness; - struct v4l2_pix_format fmts[MAX_MODES]; - int pixels_read; - int packet_read; - u8 packet[PACKET_SIZE]; - u8 restart_stream; - u8 button_state; - u8 resetlevel; - u8 resetlevel_frame_count; - int resetlevel_adjust_dir; - int expo_change_state; -}; - - -static void se401_write_req(struct gspca_dev *gspca_dev, u16 req, u16 value, - int silent) -{ - int err; - - if (gspca_dev->usb_err < 0) - return; - - err = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0, NULL, 0, 1000); - if (err < 0) { - if (!silent) - pr_err("write req failed req %#04x val %#04x error %d\n", - req, value, err); - gspca_dev->usb_err = err; - } -} - -static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent) -{ - int err; - - if (gspca_dev->usb_err < 0) - return; - - if (USB_BUF_SZ < READ_REQ_SIZE) { - pr_err("USB_BUF_SZ too small!!\n"); - gspca_dev->usb_err = -ENOBUFS; - return; - } - - err = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0, gspca_dev->usb_buf, READ_REQ_SIZE, 1000); - if (err < 0) { - if (!silent) - pr_err("read req failed req %#04x error %d\n", - req, err); - gspca_dev->usb_err = err; - } -} - -static void se401_set_feature(struct gspca_dev *gspca_dev, - u16 selector, u16 param) -{ - int err; - - if (gspca_dev->usb_err < 0) - return; - - err = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - SE401_REQ_SET_EXT_FEATURE, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - param, selector, NULL, 0, 1000); - if (err < 0) { - pr_err("set feature failed sel %#04x param %#04x error %d\n", - selector, param, err); - gspca_dev->usb_err = err; - } -} - -static int se401_get_feature(struct gspca_dev *gspca_dev, u16 selector) -{ - int err; - - if (gspca_dev->usb_err < 0) - return gspca_dev->usb_err; - - if (USB_BUF_SZ < 2) { - pr_err("USB_BUF_SZ too small!!\n"); - gspca_dev->usb_err = -ENOBUFS; - return gspca_dev->usb_err; - } - - err = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - SE401_REQ_GET_EXT_FEATURE, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, selector, gspca_dev->usb_buf, 2, 1000); - if (err < 0) { - pr_err("get feature failed sel %#04x error %d\n", - selector, err); - gspca_dev->usb_err = err; - return err; - } - return gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - /* HDG: this does not seem to do anything on my cam */ - se401_write_req(gspca_dev, SE401_REQ_SET_BRT, val, 0); -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - u16 gain = 63 - val; - - /* red color gain */ - se401_set_feature(gspca_dev, HV7131_REG_ARCG, gain); - /* green color gain */ - se401_set_feature(gspca_dev, HV7131_REG_AGCG, gain); - /* blue color gain */ - se401_set_feature(gspca_dev, HV7131_REG_ABCG, gain); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val, s32 freq) -{ - struct sd *sd = (struct sd *) gspca_dev; - int integration = val << 6; - u8 expose_h, expose_m, expose_l; - - /* Do this before the set_feature calls, for proper timing wrt - the interrupt driven pkt_scan. Note we may still race but that - is not a big issue, the expo change state machine is merely for - avoiding underexposed frames getting send out, if one sneaks - through so be it */ - sd->expo_change_state = EXPO_CHANGED; - - if (freq == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) - integration = integration - integration % 106667; - if (freq == V4L2_CID_POWER_LINE_FREQUENCY_60HZ) - integration = integration - integration % 88889; - - expose_h = (integration >> 16); - expose_m = (integration >> 8); - expose_l = integration; - - /* integration time low */ - se401_set_feature(gspca_dev, HV7131_REG_TITL, expose_l); - /* integration time mid */ - se401_set_feature(gspca_dev, HV7131_REG_TITM, expose_m); - /* integration time high */ - se401_set_feature(gspca_dev, HV7131_REG_TITU, expose_h); -} - -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct cam *cam = &gspca_dev->cam; - u8 *cd = gspca_dev->usb_buf; - int i, j, n; - int widths[MAX_MODES], heights[MAX_MODES]; - - /* Read the camera descriptor */ - se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 1); - if (gspca_dev->usb_err) { - /* Sometimes after being idle for a while the se401 won't - respond and needs a good kicking */ - usb_reset_device(gspca_dev->dev); - gspca_dev->usb_err = 0; - se401_read_req(gspca_dev, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0); - } - - /* Some cameras start with their LED on */ - se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0); - if (gspca_dev->usb_err) - return gspca_dev->usb_err; - - if (cd[1] != 0x41) { - pr_err("Wrong descriptor type\n"); - return -ENODEV; - } - - if (!(cd[2] & SE401_FORMAT_BAYER)) { - pr_err("Bayer format not supported!\n"); - return -ENODEV; - } - - if (cd[3]) - pr_info("ExtraFeatures: %d\n", cd[3]); - - n = cd[4] | (cd[5] << 8); - if (n > MAX_MODES) { - pr_err("Too many frame sizes\n"); - return -ENODEV; - } - - for (i = 0; i < n ; i++) { - widths[i] = cd[6 + i * 4 + 0] | (cd[6 + i * 4 + 1] << 8); - heights[i] = cd[6 + i * 4 + 2] | (cd[6 + i * 4 + 3] << 8); - } - - for (i = 0; i < n ; i++) { - sd->fmts[i].width = widths[i]; - sd->fmts[i].height = heights[i]; - sd->fmts[i].field = V4L2_FIELD_NONE; - sd->fmts[i].colorspace = V4L2_COLORSPACE_SRGB; - sd->fmts[i].priv = 1; - - /* janggu compression only works for 1/4th or 1/16th res */ - for (j = 0; j < n; j++) { - if (widths[j] / 2 == widths[i] && - heights[j] / 2 == heights[i]) { - sd->fmts[i].priv = 2; - break; - } - } - /* 1/16th if available too is better then 1/4th, because - we then use a larger area of the sensor */ - for (j = 0; j < n; j++) { - if (widths[j] / 4 == widths[i] && - heights[j] / 4 == heights[i]) { - sd->fmts[i].priv = 4; - break; - } - } - - if (sd->fmts[i].priv == 1) { - /* Not a 1/4th or 1/16th res, use bayer */ - sd->fmts[i].pixelformat = V4L2_PIX_FMT_SBGGR8; - sd->fmts[i].bytesperline = widths[i]; - sd->fmts[i].sizeimage = widths[i] * heights[i]; - pr_info("Frame size: %dx%d bayer\n", - widths[i], heights[i]); - } else { - /* Found a match use janggu compression */ - sd->fmts[i].pixelformat = V4L2_PIX_FMT_SE401; - sd->fmts[i].bytesperline = 0; - sd->fmts[i].sizeimage = widths[i] * heights[i] * 3; - pr_info("Frame size: %dx%d 1/%dth janggu\n", - widths[i], heights[i], - sd->fmts[i].priv * sd->fmts[i].priv); - } - } - - cam->cam_mode = sd->fmts; - cam->nmodes = n; - cam->bulk = 1; - cam->bulk_size = BULK_SIZE; - cam->bulk_nurbs = 4; - sd->resetlevel = 0x2d; /* Set initial resetlevel */ - - /* See if the camera supports brightness */ - se401_read_req(gspca_dev, SE401_REQ_GET_BRT, 1); - sd->has_brightness = !!gspca_dev->usb_err; - gspca_dev->usb_err = 0; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -/* function called at start time before URB creation */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - gspca_dev->alt = 1; /* Ignore the bogus isoc alt settings */ - - return gspca_dev->usb_err; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - int mode = 0; - - se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 1); - if (gspca_dev->usb_err) { - /* Sometimes after being idle for a while the se401 won't - respond and needs a good kicking */ - usb_reset_device(gspca_dev->dev); - gspca_dev->usb_err = 0; - se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 1, 0); - } - se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 1, 0); - - se401_set_feature(gspca_dev, HV7131_REG_MODE_B, 0x05); - - /* set size + mode */ - se401_write_req(gspca_dev, SE401_REQ_SET_WIDTH, - gspca_dev->width * mult, 0); - se401_write_req(gspca_dev, SE401_REQ_SET_HEIGHT, - gspca_dev->height * mult, 0); - /* - * HDG: disabled this as it does not seem to do anything - * se401_write_req(gspca_dev, SE401_REQ_SET_OUTPUT_MODE, - * SE401_FORMAT_BAYER, 0); - */ - - switch (mult) { - case 1: /* Raw bayer */ - mode = 0x03; break; - case 2: /* 1/4th janggu */ - mode = SE401_QUANT_FACT << 4; break; - case 4: /* 1/16th janggu */ - mode = (SE401_QUANT_FACT << 4) | 0x02; break; - } - se401_set_feature(gspca_dev, SE401_OPERATINGMODE, mode); - - se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel); - - sd->packet_read = 0; - sd->pixels_read = 0; - sd->restart_stream = 0; - sd->resetlevel_frame_count = 0; - sd->resetlevel_adjust_dir = 0; - sd->expo_change_state = EXPO_NO_CHANGE; - - se401_write_req(gspca_dev, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, 0); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - se401_write_req(gspca_dev, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, 0); - se401_write_req(gspca_dev, SE401_REQ_LED_CONTROL, 0, 0); - se401_write_req(gspca_dev, SE401_REQ_CAMERA_POWER, 0, 0); -} - -static void sd_dq_callback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - unsigned int ahrc, alrc; - int oldreset, adjust_dir; - - /* Restart the stream if requested do so by pkt_scan */ - if (sd->restart_stream) { - sd_stopN(gspca_dev); - sd_start(gspca_dev); - sd->restart_stream = 0; - } - - /* Automatically adjust sensor reset level - Hyundai have some really nice docs about this and other sensor - related stuff on their homepage: www.hei.co.kr */ - sd->resetlevel_frame_count++; - if (sd->resetlevel_frame_count < 20) - return; - - /* For some reason this normally read-only register doesn't get reset - to zero after reading them just once... */ - se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH); - se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL); - se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH); - se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL); - ahrc = 256*se401_get_feature(gspca_dev, HV7131_REG_HIREFNOH) + - se401_get_feature(gspca_dev, HV7131_REG_HIREFNOL); - alrc = 256*se401_get_feature(gspca_dev, HV7131_REG_LOREFNOH) + - se401_get_feature(gspca_dev, HV7131_REG_LOREFNOL); - - /* Not an exact science, but it seems to work pretty well... */ - oldreset = sd->resetlevel; - if (alrc > 10) { - while (alrc >= 10 && sd->resetlevel < 63) { - sd->resetlevel++; - alrc /= 2; - } - } else if (ahrc > 20) { - while (ahrc >= 20 && sd->resetlevel > 0) { - sd->resetlevel--; - ahrc /= 2; - } - } - /* Detect ping-pong-ing and halve adjustment to avoid overshoot */ - if (sd->resetlevel > oldreset) - adjust_dir = 1; - else - adjust_dir = -1; - if (sd->resetlevel_adjust_dir && - sd->resetlevel_adjust_dir != adjust_dir) - sd->resetlevel = oldreset + (sd->resetlevel - oldreset) / 2; - - if (sd->resetlevel != oldreset) { - sd->resetlevel_adjust_dir = adjust_dir; - se401_set_feature(gspca_dev, HV7131_REG_ARLV, sd->resetlevel); - } - - sd->resetlevel_frame_count = 0; -} - -static void sd_complete_frame(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct sd *sd = (struct sd *)gspca_dev; - - switch (sd->expo_change_state) { - case EXPO_CHANGED: - /* The exposure was changed while this frame - was being send, so this frame is ok */ - sd->expo_change_state = EXPO_DROP_FRAME; - break; - case EXPO_DROP_FRAME: - /* The exposure was changed while this frame - was being captured, drop it! */ - gspca_dev->last_packet_type = DISCARD_PACKET; - sd->expo_change_state = EXPO_NO_CHANGE; - break; - case EXPO_NO_CHANGE: - break; - } - gspca_frame_add(gspca_dev, LAST_PACKET, data, len); -} - -static void sd_pkt_scan_janggu(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct sd *sd = (struct sd *)gspca_dev; - int imagesize = gspca_dev->width * gspca_dev->height; - int i, plen, bits, pixels, info, count; - - if (sd->restart_stream) - return; - - /* Sometimes a 1024 bytes garbage bulk packet is send between frames */ - if (gspca_dev->last_packet_type == LAST_PACKET && len == 1024) { - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - - i = 0; - while (i < len) { - /* Read header if not already be present from prev bulk pkt */ - if (sd->packet_read < 4) { - count = 4 - sd->packet_read; - if (count > len - i) - count = len - i; - memcpy(&sd->packet[sd->packet_read], &data[i], count); - sd->packet_read += count; - i += count; - if (sd->packet_read < 4) - break; - } - bits = sd->packet[3] + (sd->packet[2] << 8); - pixels = sd->packet[1] + ((sd->packet[0] & 0x3f) << 8); - info = (sd->packet[0] & 0xc0) >> 6; - plen = ((bits + 47) >> 4) << 1; - /* Sanity checks */ - if (plen > 1024) { - pr_err("invalid packet len %d restarting stream\n", - plen); - goto error; - } - if (info == 3) { - pr_err("unknown frame info value restarting stream\n"); - goto error; - } - - /* Read (remainder of) packet contents */ - count = plen - sd->packet_read; - if (count > len - i) - count = len - i; - memcpy(&sd->packet[sd->packet_read], &data[i], count); - sd->packet_read += count; - i += count; - if (sd->packet_read < plen) - break; - - sd->pixels_read += pixels; - sd->packet_read = 0; - - switch (info) { - case 0: /* Frame data */ - gspca_frame_add(gspca_dev, INTER_PACKET, sd->packet, - plen); - break; - case 1: /* EOF */ - if (sd->pixels_read != imagesize) { - pr_err("frame size %d expected %d\n", - sd->pixels_read, imagesize); - goto error; - } - sd_complete_frame(gspca_dev, sd->packet, plen); - return; /* Discard the rest of the bulk packet !! */ - case 2: /* SOF */ - gspca_frame_add(gspca_dev, FIRST_PACKET, sd->packet, - plen); - sd->pixels_read = pixels; - break; - } - } - return; - -error: - sd->restart_stream = 1; - /* Give userspace a 0 bytes frame, so our dq callback gets - called and it can restart the stream */ - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); -} - -static void sd_pkt_scan_bayer(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct cam *cam = &gspca_dev->cam; - int imagesize = cam->cam_mode[gspca_dev->curr_mode].sizeimage; - - if (gspca_dev->image_len == 0) { - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - return; - } - - if (gspca_dev->image_len + len >= imagesize) { - sd_complete_frame(gspca_dev, data, len); - return; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - int mult = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - - if (len == 0) - return; - - if (mult == 1) /* mult == 1 means raw bayer */ - sd_pkt_scan_bayer(gspca_dev, data, len); - else - sd_pkt_scan_janggu(gspca_dev, data, len); -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct sd *sd = (struct sd *)gspca_dev; - u8 state; - - if (len != 2) - return -EINVAL; - - switch (data[0]) { - case 0: - case 1: - state = data[0]; - break; - default: - return -EINVAL; - } - if (sd->button_state != state) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, state); - input_sync(gspca_dev->input_dev); - sd->button_state = state; - } - - return 0; -} -#endif - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, ctrl->val, sd->freq->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - if (sd->has_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 15); - /* max is really 63 but > 50 is not pretty */ - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 50, 1, 25); - sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 32767, 1, 15000); - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_cluster(2, &sd->exposure); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .dq_callback = sd_dq_callback, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x03e8, 0x0004)}, /* Endpoints/Aox SE401 */ - {USB_DEVICE(0x0471, 0x030b)}, /* Philips PCVC665K */ - {USB_DEVICE(0x047d, 0x5001)}, /* Kensington 67014 */ - {USB_DEVICE(0x047d, 0x5002)}, /* Kensington 6701(5/7) */ - {USB_DEVICE(0x047d, 0x5003)}, /* Kensington 67016 */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static int sd_pre_reset(struct usb_interface *intf) -{ - return 0; -} - -static int sd_post_reset(struct usb_interface *intf) -{ - return 0; -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif - .pre_reset = sd_pre_reset, - .post_reset = sd_post_reset, -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/se401.h b/drivers/media/video/gspca/se401.h deleted file mode 100644 index 96d8ebf3cf59..000000000000 --- a/drivers/media/video/gspca/se401.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * GSPCA Endpoints (formerly known as AOX) se401 USB Camera sub Driver - * - * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com> - * - * Based on the v4l1 se401 driver which is: - * - * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06 -#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41 -#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42 -#define SE401_REQ_CAPTURE_FRAME 0x43 -#define SE401_REQ_GET_BRT 0x44 -#define SE401_REQ_SET_BRT 0x45 -#define SE401_REQ_GET_WIDTH 0x4c -#define SE401_REQ_SET_WIDTH 0x4d -#define SE401_REQ_GET_HEIGHT 0x4e -#define SE401_REQ_SET_HEIGHT 0x4f -#define SE401_REQ_GET_OUTPUT_MODE 0x50 -#define SE401_REQ_SET_OUTPUT_MODE 0x51 -#define SE401_REQ_GET_EXT_FEATURE 0x52 -#define SE401_REQ_SET_EXT_FEATURE 0x53 -#define SE401_REQ_CAMERA_POWER 0x56 -#define SE401_REQ_LED_CONTROL 0x57 -#define SE401_REQ_BIOS 0xff - -#define SE401_BIOS_READ 0x07 - -#define SE401_FORMAT_BAYER 0x40 - -/* Hyundai hv7131b registers - 7121 and 7141 should be the same (haven't really checked...) */ -/* Mode registers: */ -#define HV7131_REG_MODE_A 0x00 -#define HV7131_REG_MODE_B 0x01 -#define HV7131_REG_MODE_C 0x02 -/* Frame registers: */ -#define HV7131_REG_FRSU 0x10 -#define HV7131_REG_FRSL 0x11 -#define HV7131_REG_FCSU 0x12 -#define HV7131_REG_FCSL 0x13 -#define HV7131_REG_FWHU 0x14 -#define HV7131_REG_FWHL 0x15 -#define HV7131_REG_FWWU 0x16 -#define HV7131_REG_FWWL 0x17 -/* Timing registers: */ -#define HV7131_REG_THBU 0x20 -#define HV7131_REG_THBL 0x21 -#define HV7131_REG_TVBU 0x22 -#define HV7131_REG_TVBL 0x23 -#define HV7131_REG_TITU 0x25 -#define HV7131_REG_TITM 0x26 -#define HV7131_REG_TITL 0x27 -#define HV7131_REG_TMCD 0x28 -/* Adjust Registers: */ -#define HV7131_REG_ARLV 0x30 -#define HV7131_REG_ARCG 0x31 -#define HV7131_REG_AGCG 0x32 -#define HV7131_REG_ABCG 0x33 -#define HV7131_REG_APBV 0x34 -#define HV7131_REG_ASLP 0x54 -/* Offset Registers: */ -#define HV7131_REG_OFSR 0x50 -#define HV7131_REG_OFSG 0x51 -#define HV7131_REG_OFSB 0x52 -/* REset level statistics registers: */ -#define HV7131_REG_LOREFNOH 0x57 -#define HV7131_REG_LOREFNOL 0x58 -#define HV7131_REG_HIREFNOH 0x59 -#define HV7131_REG_HIREFNOL 0x5a - -/* se401 registers */ -#define SE401_OPERATINGMODE 0x2000 diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c deleted file mode 100644 index 03fa3fd940b4..000000000000 --- a/drivers/media/video/gspca/sn9c2028.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * SN9C2028 library - * - * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sn9c2028" - -#include "gspca.h" - -MODULE_AUTHOR("Theodore Kilgore"); -MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 sof_read; - u16 model; -}; - -struct init_command { - unsigned char instruction[6]; - unsigned char to_read; /* length to read. 0 means no reply requested */ -}; - -/* How to change the resolution of any of the VGA cams is unknown */ -static const struct v4l2_pix_format vga_mode[] = { - {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* No way to change the resolution of the CIF cams is known */ -static const struct v4l2_pix_format cif_mode[] = { - {352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* the bytes to write are in gspca_dev->usb_buf */ -static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command) -{ - int rc; - - PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0], - command[1], command[2], command[3], command[4], command[5]); - - memcpy(gspca_dev->usb_buf, command, 6); - rc = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_CONFIGURATION, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 2, 0, gspca_dev->usb_buf, 6, 500); - if (rc < 0) { - pr_err("command write [%02x] error %d\n", - gspca_dev->usb_buf[0], rc); - return rc; - } - - return 0; -} - -static int sn9c2028_read1(struct gspca_dev *gspca_dev) -{ - int rc; - - rc = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 1, 0, gspca_dev->usb_buf, 1, 500); - if (rc != 1) { - pr_err("read1 error %d\n", rc); - return (rc < 0) ? rc : -EIO; - } - PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]); - return gspca_dev->usb_buf[0]; -} - -static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading) -{ - int rc; - rc = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 4, 0, gspca_dev->usb_buf, 4, 500); - if (rc != 4) { - pr_err("read4 error %d\n", rc); - return (rc < 0) ? rc : -EIO; - } - memcpy(reading, gspca_dev->usb_buf, 4); - PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0], - reading[1], reading[2], reading[3]); - return rc; -} - -static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command) -{ - int i, status; - __u8 reading[4]; - - status = sn9c2028_command(gspca_dev, command); - if (status < 0) - return status; - - status = -1; - for (i = 0; i < 256 && status < 2; i++) - status = sn9c2028_read1(gspca_dev); - if (status != 2) { - pr_err("long command status read error %d\n", status); - return (status < 0) ? status : -EIO; - } - - memset(reading, 0, 4); - status = sn9c2028_read4(gspca_dev, reading); - if (status < 0) - return status; - - /* in general, the first byte of the response is the first byte of - * the command, or'ed with 8 */ - status = sn9c2028_read1(gspca_dev); - if (status < 0) - return status; - - return 0; -} - -static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command) -{ - int err_code; - - err_code = sn9c2028_command(gspca_dev, command); - if (err_code < 0) - return err_code; - - err_code = sn9c2028_read1(gspca_dev); - if (err_code < 0) - return err_code; - - return 0; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)", - id->idVendor, id->idProduct); - - sd->model = id->idProduct; - - switch (sd->model) { - case 0x7005: - PDEBUG(D_PROBE, "Genius Smart 300 camera"); - break; - case 0x8000: - PDEBUG(D_PROBE, "DC31VC"); - break; - case 0x8001: - PDEBUG(D_PROBE, "Spy camera"); - break; - case 0x8003: - PDEBUG(D_PROBE, "CIF camera"); - break; - case 0x8008: - PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera"); - break; - case 0x800a: - PDEBUG(D_PROBE, "Vivitar 3350b type camera"); - cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP; - break; - } - - switch (sd->model) { - case 0x8000: - case 0x8001: - case 0x8003: - cam->cam_mode = cif_mode; - cam->nmodes = ARRAY_SIZE(cif_mode); - break; - default: - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - } - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - int status = -1; - - sn9c2028_read1(gspca_dev); - sn9c2028_read1(gspca_dev); - status = sn9c2028_read1(gspca_dev); - - return (status < 0) ? status : 0; -} - -static int run_start_commands(struct gspca_dev *gspca_dev, - struct init_command *cam_commands, int n) -{ - int i, err_code = -1; - - for (i = 0; i < n; i++) { - switch (cam_commands[i].to_read) { - case 4: - err_code = sn9c2028_long_command(gspca_dev, - cam_commands[i].instruction); - break; - case 1: - err_code = sn9c2028_short_command(gspca_dev, - cam_commands[i].instruction); - break; - case 0: - err_code = sn9c2028_command(gspca_dev, - cam_commands[i].instruction); - break; - } - if (err_code < 0) - return err_code; - } - return 0; -} - -static int start_spy_cam(struct gspca_dev *gspca_dev) -{ - struct init_command spy_start_commands[] = { - {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4}, - {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, /* width 352 */ - {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, /* height 288 */ - /* {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, */ - {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, - {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* red gain ?*/ - /* {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, */ - {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4}, - /* {{0x13, 0x29, 0x01, 0x0c, 0x00, 0x00}, 4}, */ - {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4}, - /* {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, */ - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4}, - /* {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, */ - {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4}, - {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4}, - {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4}, /*don't mess with*/ - /*{{0x11, 0x04, 0x06, 0x00, 0x00, 0x00}, 4}, observed */ - {{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */ - /*{{0x11, 0x05, 0x65, 0x00, 0x00, 0x00}, 4}, observed */ - {{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */ - {{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4}, /* observed */ - {{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4}, - /*{{0x11, 0x08, 0x06, 0x00, 0x00, 0x00}, 4}, observed */ - {{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4}, - /* {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, */ - /* brightness or gain. 0 is default. 4 is good - * indoors at night with incandescent lighting */ - {{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4}, /*hstart or hoffs*/ - {{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4}, - /* {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, observed */ - {{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1}, /* brighter */ - /* {{0x1b, 0x13, 0x01, 0x00, 0x00, 0x00}, 1}, observed */ - {{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}, /* compresses */ - /* Camera should start to capture now. */ - }; - - return run_start_commands(gspca_dev, spy_start_commands, - ARRAY_SIZE(spy_start_commands)); -} - -static int start_cif_cam(struct gspca_dev *gspca_dev) -{ - struct init_command cif_start_commands[] = { - {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - /* The entire sequence below seems redundant */ - /* {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x22, 0x01, 0x06, 0x00, 0x00}, 4}, - {{0x13, 0x23, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, width? - {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, height? - {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample? - {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4}, - {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, - {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4}, - {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},*/ - {{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1}, - {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1}, /* width/8 */ - {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1}, /* height/8 */ - /* {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample? - * {{0x13, 0x28, 0x01, 0x1e, 0x00, 0x00}, 4}, does nothing - * {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, */ - /* {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4}, - * causes subsampling - * but not a change in the resolution setting! */ - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4}, - {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1}, - {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},/* use compression */ - /* Camera should start to capture now. */ - }; - - return run_start_commands(gspca_dev, cif_start_commands, - ARRAY_SIZE(cif_start_commands)); -} - -static int start_ms350_cam(struct gspca_dev *gspca_dev) -{ - struct init_command ms350_start_commands[] = { - {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4}, - {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, - {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, - {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, - {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, - {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, - {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4}, - {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* width */ - {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* height */ - {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* vstart? */ - {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, - {{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4}, /* hstart? */ - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, - {{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0}, - /* Camera should start to capture now. */ - }; - - return run_start_commands(gspca_dev, ms350_start_commands, - ARRAY_SIZE(ms350_start_commands)); -} - -static int start_genius_cam(struct gspca_dev *gspca_dev) -{ - struct init_command genius_start_commands[] = { - {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, - {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, - /* "preliminary" width and height settings */ - {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4}, - {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, - {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4}, - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4}, - {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* real width */ - {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* real height */ - {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4}, - {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, - {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4}, - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, - {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4}, - {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4}, - {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1}, - {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1}, - {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0} - /* Camera should start to capture now. */ - }; - - return run_start_commands(gspca_dev, genius_start_commands, - ARRAY_SIZE(genius_start_commands)); -} - -static int start_vivitar_cam(struct gspca_dev *gspca_dev) -{ - struct init_command vivitar_start_commands[] = { - {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4}, - {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4}, - {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, - {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, - {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, - {{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4}, - /* - * Above is changed from OEM 0x0b. Fixes Bayer tiling. - * Presumably gives a vertical shift of one row. - */ - {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4}, - /* Above seems to do horizontal shift. */ - {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, - {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, - {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, - {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, - /* Above three commands seem to relate to brightness. */ - {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4}, - {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1}, - /* {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, - {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, - {{0x13, 0x28, 0x01, 0x0b, 0x00, 0x00}, 4}, */ - {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1}, - {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1}, - {{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1}, - /* Above is brightness; OEM driver setting is 0x10 */ - {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4}, - {{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1}, - {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1} - }; - - return run_start_commands(gspca_dev, vivitar_start_commands, - ARRAY_SIZE(vivitar_start_commands)); -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err_code; - - sd->sof_read = 0; - - switch (sd->model) { - case 0x7005: - err_code = start_genius_cam(gspca_dev); - break; - case 0x8001: - err_code = start_spy_cam(gspca_dev); - break; - case 0x8003: - err_code = start_cif_cam(gspca_dev); - break; - case 0x8008: - err_code = start_ms350_cam(gspca_dev); - break; - case 0x800a: - err_code = start_vivitar_cam(gspca_dev); - break; - default: - pr_err("Starting unknown camera, please report this\n"); - return -ENXIO; - } - - return err_code; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - int result; - __u8 data[6]; - - result = sn9c2028_read1(gspca_dev); - if (result < 0) - PDEBUG(D_ERR, "Camera Stop read failed"); - - memset(data, 0, 6); - data[0] = 0x14; - result = sn9c2028_command(gspca_dev, data); - if (result < 0) - PDEBUG(D_ERR, "Camera Stop command failed"); -} - -/* Include sn9c2028 sof detection functions */ -#include "sn9c2028.h" - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - __u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - unsigned char *sof; - - sof = sn9c2028_find_sof(gspca_dev, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sizeof sn9c2028_sof_marker) - n -= sizeof sn9c2028_sof_marker; - else - n = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, data, n); - /* Start next frame. */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sn9c2028_sof_marker, sizeof sn9c2028_sof_marker); - len -= sof - data; - data = sof; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */ - /* The Genius Smart is untested. I can't find an owner ! */ - /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */ - {USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */ - {USB_DEVICE(0x0c45, 0x8003)}, /* Several small CIF cameras */ - /* {USB_DEVICE(0x0c45, 0x8006)}, Unknown VGA camera */ - {USB_DEVICE(0x0c45, 0x8008)}, /* Mini-Shotz ms-350 */ - {USB_DEVICE(0x0c45, 0x800a)}, /* Vivicam 3350B */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sn9c2028.h b/drivers/media/video/gspca/sn9c2028.h deleted file mode 100644 index 8fd1d3e05665..000000000000 --- a/drivers/media/video/gspca/sn9c2028.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SN9C2028 common functions - * - * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn,edu> - * - * Based closely upon the file gspca/pac_common.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -static const unsigned char sn9c2028_sof_marker[5] = - { 0xff, 0xff, 0x00, 0xc4, 0xc4 }; - -static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev, - unsigned char *m, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - - /* Search for the SOF marker (fixed part) in the header */ - for (i = 0; i < len; i++) { - if (m[i] == sn9c2028_sof_marker[sd->sof_read]) { - sd->sof_read++; - if (sd->sof_read == sizeof(sn9c2028_sof_marker)) { - PDEBUG(D_FRAM, - "SOF found, bytes to analyze: %u." - " Frame starts at byte #%u", - len, i + 1); - sd->sof_read = 0; - return m + i + 1; - } - } else { - sd->sof_read = 0; - } - } - - return NULL; -} diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c deleted file mode 100644 index b9c6f17eabb2..000000000000 --- a/drivers/media/video/gspca/sn9c20x.c +++ /dev/null @@ -1,2428 +0,0 @@ -/* - * Sonix sn9c201 sn9c202 library - * - * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr> - * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> - * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/input.h> - -#include "gspca.h" -#include "jpeg.h" - -#include <media/v4l2-chip-ident.h> -#include <linux/dmi.h> - -MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " - "microdia project <microdia@googlegroups.com>"); -MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* - * Pixel format private data - */ -#define SCALE_MASK 0x0f -#define SCALE_160x120 0 -#define SCALE_320x240 1 -#define SCALE_640x480 2 -#define SCALE_1280x1024 3 -#define MODE_RAW 0x10 -#define MODE_JPEG 0x20 -#define MODE_SXGA 0x80 - -#define SENSOR_OV9650 0 -#define SENSOR_OV9655 1 -#define SENSOR_SOI968 2 -#define SENSOR_OV7660 3 -#define SENSOR_OV7670 4 -#define SENSOR_MT9V011 5 -#define SENSOR_MT9V111 6 -#define SENSOR_MT9V112 7 -#define SENSOR_MT9M001 8 -#define SENSOR_MT9M111 9 -#define SENSOR_MT9M112 10 -#define SENSOR_HV7131R 11 -#define SENSOR_MT9VPRB 12 - -/* camera flags */ -#define HAS_NO_BUTTON 0x1 -#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ -#define FLIP_DETECT 0x4 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; - - struct { /* color control cluster */ - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *contrast; - struct v4l2_ctrl *saturation; - struct v4l2_ctrl *hue; - }; - struct { /* blue/red balance control cluster */ - struct v4l2_ctrl *blue; - struct v4l2_ctrl *red; - }; - struct { /* h/vflip control cluster */ - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - }; - struct v4l2_ctrl *gamma; - struct { /* autogain and exposure or gain control cluster */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; - }; - struct v4l2_ctrl *jpegqual; - - struct work_struct work; - struct workqueue_struct *work_thread; - - u32 pktsz; /* (used by pkt_scan) */ - u16 npkt; - s8 nchg; - u8 fmt; /* (used for JPEG QTAB update */ - -#define MIN_AVG_LUM 80 -#define MAX_AVG_LUM 130 - atomic_t avg_lum; - u8 old_step; - u8 older_step; - u8 exposure_step; - - u8 i2c_addr; - u8 i2c_intf; - u8 sensor; - u8 hstart; - u8 vstart; - - u8 jpeg_hdr[JPEG_HDR_SZ]; - - u8 flags; -}; - -static void qual_upd(struct work_struct *work); - -struct i2c_reg_u8 { - u8 reg; - u8 val; -}; - -struct i2c_reg_u16 { - u8 reg; - u16 val; -}; - -static const struct dmi_system_id flip_dmi_table[] = { - { - .ident = "MSI MS-1034", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"), - DMI_MATCH(DMI_PRODUCT_VERSION, "0341") - } - }, - { - .ident = "MSI MS-1632", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), - DMI_MATCH(DMI_BOARD_NAME, "MS-1632") - } - }, - { - .ident = "MSI MS-1633X", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), - DMI_MATCH(DMI_BOARD_NAME, "MS-1633X") - } - }, - { - .ident = "MSI MS-1635X", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), - DMI_MATCH(DMI_BOARD_NAME, "MS-1635X") - } - }, - { - .ident = "ASUSTeK W7J", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_BOARD_NAME, "W7J ") - } - }, - {} -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_160x120 | MODE_JPEG}, - {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_160x120 | MODE_RAW}, - {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 240 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_160x120}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_320x240 | MODE_JPEG}, - {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 , - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_320x240 | MODE_RAW}, - {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 480 * 240 , - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_320x240}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_640x480 | MODE_JPEG}, - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_640x480 | MODE_RAW}, - {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 960 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_640x480}, -}; - -static const struct v4l2_pix_format sxga_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_160x120 | MODE_JPEG}, - {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_160x120 | MODE_RAW}, - {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 240 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_160x120}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_320x240 | MODE_JPEG}, - {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 , - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_320x240 | MODE_RAW}, - {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 480 * 240 , - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_320x240}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = SCALE_640x480 | MODE_JPEG}, - {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_640x480 | MODE_RAW}, - {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 960 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_640x480}, - {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, -}; - -static const struct v4l2_pix_format mono_mode[] = { - {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_160x120 | MODE_RAW}, - {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 , - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_320x240 | MODE_RAW}, - {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_640x480 | MODE_RAW}, - {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, -}; - -static const s16 hsv_red_x[] = { - 41, 44, 46, 48, 50, 52, 54, 56, - 58, 60, 62, 64, 66, 68, 70, 72, - 74, 76, 78, 80, 81, 83, 85, 87, - 88, 90, 92, 93, 95, 97, 98, 100, - 101, 102, 104, 105, 107, 108, 109, 110, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 123, 124, 125, 125, - 126, 127, 127, 128, 128, 129, 129, 129, - 130, 130, 130, 130, 131, 131, 131, 131, - 131, 131, 131, 131, 130, 130, 130, 130, - 129, 129, 129, 128, 128, 127, 127, 126, - 125, 125, 124, 123, 122, 122, 121, 120, - 119, 118, 117, 116, 115, 114, 112, 111, - 110, 109, 107, 106, 105, 103, 102, 101, - 99, 98, 96, 94, 93, 91, 90, 88, - 86, 84, 83, 81, 79, 77, 75, 74, - 72, 70, 68, 66, 64, 62, 60, 58, - 56, 54, 52, 49, 47, 45, 43, 41, - 39, 36, 34, 32, 30, 28, 25, 23, - 21, 19, 16, 14, 12, 9, 7, 5, - 3, 0, -1, -3, -6, -8, -10, -12, - -15, -17, -19, -22, -24, -26, -28, -30, - -33, -35, -37, -39, -41, -44, -46, -48, - -50, -52, -54, -56, -58, -60, -62, -64, - -66, -68, -70, -72, -74, -76, -78, -80, - -81, -83, -85, -87, -88, -90, -92, -93, - -95, -97, -98, -100, -101, -102, -104, -105, - -107, -108, -109, -110, -112, -113, -114, -115, - -116, -117, -118, -119, -120, -121, -122, -123, - -123, -124, -125, -125, -126, -127, -127, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -128, -127, -127, -126, -125, -125, -124, -123, - -122, -122, -121, -120, -119, -118, -117, -116, - -115, -114, -112, -111, -110, -109, -107, -106, - -105, -103, -102, -101, -99, -98, -96, -94, - -93, -91, -90, -88, -86, -84, -83, -81, - -79, -77, -75, -74, -72, -70, -68, -66, - -64, -62, -60, -58, -56, -54, -52, -49, - -47, -45, -43, -41, -39, -36, -34, -32, - -30, -28, -25, -23, -21, -19, -16, -14, - -12, -9, -7, -5, -3, 0, 1, 3, - 6, 8, 10, 12, 15, 17, 19, 22, - 24, 26, 28, 30, 33, 35, 37, 39, 41 -}; - -static const s16 hsv_red_y[] = { - 82, 80, 78, 76, 74, 73, 71, 69, - 67, 65, 63, 61, 58, 56, 54, 52, - 50, 48, 46, 44, 41, 39, 37, 35, - 32, 30, 28, 26, 23, 21, 19, 16, - 14, 12, 10, 7, 5, 3, 0, -1, - -3, -6, -8, -10, -13, -15, -17, -19, - -22, -24, -26, -29, -31, -33, -35, -38, - -40, -42, -44, -46, -48, -51, -53, -55, - -57, -59, -61, -63, -65, -67, -69, -71, - -73, -75, -77, -79, -81, -82, -84, -86, - -88, -89, -91, -93, -94, -96, -98, -99, - -101, -102, -104, -105, -106, -108, -109, -110, - -112, -113, -114, -115, -116, -117, -119, -120, - -120, -121, -122, -123, -124, -125, -126, -126, - -127, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, -128, -128, -128, -128, -128, - -127, -127, -126, -125, -125, -124, -123, -122, - -121, -120, -119, -118, -117, -116, -115, -114, - -113, -111, -110, -109, -107, -106, -105, -103, - -102, -100, -99, -97, -96, -94, -92, -91, - -89, -87, -85, -84, -82, -80, -78, -76, - -74, -73, -71, -69, -67, -65, -63, -61, - -58, -56, -54, -52, -50, -48, -46, -44, - -41, -39, -37, -35, -32, -30, -28, -26, - -23, -21, -19, -16, -14, -12, -10, -7, - -5, -3, 0, 1, 3, 6, 8, 10, - 13, 15, 17, 19, 22, 24, 26, 29, - 31, 33, 35, 38, 40, 42, 44, 46, - 48, 51, 53, 55, 57, 59, 61, 63, - 65, 67, 69, 71, 73, 75, 77, 79, - 81, 82, 84, 86, 88, 89, 91, 93, - 94, 96, 98, 99, 101, 102, 104, 105, - 106, 108, 109, 110, 112, 113, 114, 115, - 116, 117, 119, 120, 120, 121, 122, 123, - 124, 125, 126, 126, 127, 128, 128, 129, - 129, 130, 130, 131, 131, 131, 131, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 131, 131, 131, 130, 130, - 130, 129, 129, 128, 127, 127, 126, 125, - 125, 124, 123, 122, 121, 120, 119, 118, - 117, 116, 115, 114, 113, 111, 110, 109, - 107, 106, 105, 103, 102, 100, 99, 97, - 96, 94, 92, 91, 89, 87, 85, 84, 82 -}; - -static const s16 hsv_green_x[] = { - -124, -124, -125, -125, -125, -125, -125, -125, - -125, -126, -126, -125, -125, -125, -125, -125, - -125, -124, -124, -124, -123, -123, -122, -122, - -121, -121, -120, -120, -119, -118, -117, -117, - -116, -115, -114, -113, -112, -111, -110, -109, - -108, -107, -105, -104, -103, -102, -100, -99, - -98, -96, -95, -93, -92, -91, -89, -87, - -86, -84, -83, -81, -79, -77, -76, -74, - -72, -70, -69, -67, -65, -63, -61, -59, - -57, -55, -53, -51, -49, -47, -45, -43, - -41, -39, -37, -35, -33, -30, -28, -26, - -24, -22, -20, -18, -15, -13, -11, -9, - -7, -4, -2, 0, 1, 3, 6, 8, - 10, 12, 14, 17, 19, 21, 23, 25, - 27, 29, 32, 34, 36, 38, 40, 42, - 44, 46, 48, 50, 52, 54, 56, 58, - 60, 62, 64, 66, 68, 70, 71, 73, - 75, 77, 78, 80, 82, 83, 85, 87, - 88, 90, 91, 93, 94, 96, 97, 98, - 100, 101, 102, 104, 105, 106, 107, 108, - 109, 111, 112, 113, 113, 114, 115, 116, - 117, 118, 118, 119, 120, 120, 121, 122, - 122, 123, 123, 124, 124, 124, 125, 125, - 125, 125, 125, 125, 125, 126, 126, 125, - 125, 125, 125, 125, 125, 124, 124, 124, - 123, 123, 122, 122, 121, 121, 120, 120, - 119, 118, 117, 117, 116, 115, 114, 113, - 112, 111, 110, 109, 108, 107, 105, 104, - 103, 102, 100, 99, 98, 96, 95, 93, - 92, 91, 89, 87, 86, 84, 83, 81, - 79, 77, 76, 74, 72, 70, 69, 67, - 65, 63, 61, 59, 57, 55, 53, 51, - 49, 47, 45, 43, 41, 39, 37, 35, - 33, 30, 28, 26, 24, 22, 20, 18, - 15, 13, 11, 9, 7, 4, 2, 0, - -1, -3, -6, -8, -10, -12, -14, -17, - -19, -21, -23, -25, -27, -29, -32, -34, - -36, -38, -40, -42, -44, -46, -48, -50, - -52, -54, -56, -58, -60, -62, -64, -66, - -68, -70, -71, -73, -75, -77, -78, -80, - -82, -83, -85, -87, -88, -90, -91, -93, - -94, -96, -97, -98, -100, -101, -102, -104, - -105, -106, -107, -108, -109, -111, -112, -113, - -113, -114, -115, -116, -117, -118, -118, -119, - -120, -120, -121, -122, -122, -123, -123, -124, -124 -}; - -static const s16 hsv_green_y[] = { - -100, -99, -98, -97, -95, -94, -93, -91, - -90, -89, -87, -86, -84, -83, -81, -80, - -78, -76, -75, -73, -71, -70, -68, -66, - -64, -63, -61, -59, -57, -55, -53, -51, - -49, -48, -46, -44, -42, -40, -38, -36, - -34, -32, -30, -27, -25, -23, -21, -19, - -17, -15, -13, -11, -9, -7, -4, -2, - 0, 1, 3, 5, 7, 9, 11, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 59, 61, - 63, 65, 67, 68, 70, 72, 74, 75, - 77, 78, 80, 82, 83, 85, 86, 88, - 89, 90, 92, 93, 95, 96, 97, 98, - 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 112, 113, 114, - 115, 115, 116, 116, 117, 117, 118, 118, - 119, 119, 119, 120, 120, 120, 120, 120, - 121, 121, 121, 121, 121, 121, 120, 120, - 120, 120, 120, 119, 119, 119, 118, 118, - 117, 117, 116, 116, 115, 114, 114, 113, - 112, 111, 111, 110, 109, 108, 107, 106, - 105, 104, 103, 102, 100, 99, 98, 97, - 95, 94, 93, 91, 90, 89, 87, 86, - 84, 83, 81, 80, 78, 76, 75, 73, - 71, 70, 68, 66, 64, 63, 61, 59, - 57, 55, 53, 51, 49, 48, 46, 44, - 42, 40, 38, 36, 34, 32, 30, 27, - 25, 23, 21, 19, 17, 15, 13, 11, - 9, 7, 4, 2, 0, -1, -3, -5, - -7, -9, -11, -14, -16, -18, -20, -22, - -24, -26, -28, -30, -32, -34, -36, -38, - -40, -42, -44, -46, -48, -50, -52, -54, - -56, -58, -59, -61, -63, -65, -67, -68, - -70, -72, -74, -75, -77, -78, -80, -82, - -83, -85, -86, -88, -89, -90, -92, -93, - -95, -96, -97, -98, -100, -101, -102, -103, - -104, -105, -106, -107, -108, -109, -110, -111, - -112, -112, -113, -114, -115, -115, -116, -116, - -117, -117, -118, -118, -119, -119, -119, -120, - -120, -120, -120, -120, -121, -121, -121, -121, - -121, -121, -120, -120, -120, -120, -120, -119, - -119, -119, -118, -118, -117, -117, -116, -116, - -115, -114, -114, -113, -112, -111, -111, -110, - -109, -108, -107, -106, -105, -104, -103, -102, -100 -}; - -static const s16 hsv_blue_x[] = { - 112, 113, 114, 114, 115, 116, 117, 117, - 118, 118, 119, 119, 120, 120, 120, 121, - 121, 121, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 121, 121, - 121, 120, 120, 120, 119, 119, 118, 118, - 117, 116, 116, 115, 114, 113, 113, 112, - 111, 110, 109, 108, 107, 106, 105, 104, - 103, 102, 100, 99, 98, 97, 95, 94, - 93, 91, 90, 88, 87, 85, 84, 82, - 80, 79, 77, 76, 74, 72, 70, 69, - 67, 65, 63, 61, 60, 58, 56, 54, - 52, 50, 48, 46, 44, 42, 40, 38, - 36, 34, 32, 30, 28, 26, 24, 22, - 19, 17, 15, 13, 11, 9, 7, 5, - 2, 0, -1, -3, -5, -7, -9, -12, - -14, -16, -18, -20, -22, -24, -26, -28, - -31, -33, -35, -37, -39, -41, -43, -45, - -47, -49, -51, -53, -54, -56, -58, -60, - -62, -64, -66, -67, -69, -71, -73, -74, - -76, -78, -79, -81, -83, -84, -86, -87, - -89, -90, -92, -93, -94, -96, -97, -98, - -99, -101, -102, -103, -104, -105, -106, -107, - -108, -109, -110, -111, -112, -113, -114, -114, - -115, -116, -117, -117, -118, -118, -119, -119, - -120, -120, -120, -121, -121, -121, -122, -122, - -122, -122, -122, -122, -122, -122, -122, -122, - -122, -122, -121, -121, -121, -120, -120, -120, - -119, -119, -118, -118, -117, -116, -116, -115, - -114, -113, -113, -112, -111, -110, -109, -108, - -107, -106, -105, -104, -103, -102, -100, -99, - -98, -97, -95, -94, -93, -91, -90, -88, - -87, -85, -84, -82, -80, -79, -77, -76, - -74, -72, -70, -69, -67, -65, -63, -61, - -60, -58, -56, -54, -52, -50, -48, -46, - -44, -42, -40, -38, -36, -34, -32, -30, - -28, -26, -24, -22, -19, -17, -15, -13, - -11, -9, -7, -5, -2, 0, 1, 3, - 5, 7, 9, 12, 14, 16, 18, 20, - 22, 24, 26, 28, 31, 33, 35, 37, - 39, 41, 43, 45, 47, 49, 51, 53, - 54, 56, 58, 60, 62, 64, 66, 67, - 69, 71, 73, 74, 76, 78, 79, 81, - 83, 84, 86, 87, 89, 90, 92, 93, - 94, 96, 97, 98, 99, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112 -}; - -static const s16 hsv_blue_y[] = { - -11, -13, -15, -17, -19, -21, -23, -25, - -27, -29, -31, -33, -35, -37, -39, -41, - -43, -45, -46, -48, -50, -52, -54, -55, - -57, -59, -61, -62, -64, -66, -67, -69, - -71, -72, -74, -75, -77, -78, -80, -81, - -83, -84, -86, -87, -88, -90, -91, -92, - -93, -95, -96, -97, -98, -99, -100, -101, - -102, -103, -104, -105, -106, -106, -107, -108, - -109, -109, -110, -111, -111, -112, -112, -113, - -113, -114, -114, -114, -115, -115, -115, -115, - -116, -116, -116, -116, -116, -116, -116, -116, - -116, -115, -115, -115, -115, -114, -114, -114, - -113, -113, -112, -112, -111, -111, -110, -110, - -109, -108, -108, -107, -106, -105, -104, -103, - -102, -101, -100, -99, -98, -97, -96, -95, - -94, -93, -91, -90, -89, -88, -86, -85, - -84, -82, -81, -79, -78, -76, -75, -73, - -71, -70, -68, -67, -65, -63, -62, -60, - -58, -56, -55, -53, -51, -49, -47, -45, - -44, -42, -40, -38, -36, -34, -32, -30, - -28, -26, -24, -22, -20, -18, -16, -14, - -12, -10, -8, -6, -4, -2, 0, 1, - 3, 5, 7, 9, 11, 13, 15, 17, - 19, 21, 23, 25, 27, 29, 31, 33, - 35, 37, 39, 41, 43, 45, 46, 48, - 50, 52, 54, 55, 57, 59, 61, 62, - 64, 66, 67, 69, 71, 72, 74, 75, - 77, 78, 80, 81, 83, 84, 86, 87, - 88, 90, 91, 92, 93, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, - 106, 106, 107, 108, 109, 109, 110, 111, - 111, 112, 112, 113, 113, 114, 114, 114, - 115, 115, 115, 115, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 115, 115, 115, - 115, 114, 114, 114, 113, 113, 112, 112, - 111, 111, 110, 110, 109, 108, 108, 107, - 106, 105, 104, 103, 102, 101, 100, 99, - 98, 97, 96, 95, 94, 93, 91, 90, - 89, 88, 86, 85, 84, 82, 81, 79, - 78, 76, 75, 73, 71, 70, 68, 67, - 65, 63, 62, 60, 58, 56, 55, 53, - 51, 49, 47, 45, 44, 42, 40, 38, - 36, 34, 32, 30, 28, 26, 24, 22, - 20, 18, 16, 14, 12, 10, 8, 6, - 4, 2, 0, -1, -3, -5, -7, -9, -11 -}; - -static const u16 i2c_ident[] = { - V4L2_IDENT_OV9650, - V4L2_IDENT_OV9655, - V4L2_IDENT_SOI968, - V4L2_IDENT_OV7660, - V4L2_IDENT_OV7670, - V4L2_IDENT_MT9V011, - V4L2_IDENT_MT9V111, - V4L2_IDENT_MT9V112, - V4L2_IDENT_MT9M001C12ST, - V4L2_IDENT_MT9M111, - V4L2_IDENT_MT9M112, - V4L2_IDENT_HV7131R, -[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN, -}; - -static const u16 bridge_init[][2] = { - {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, - {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, - {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, - {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00}, - {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50}, - {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50}, - {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04}, - {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05}, - {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00}, - {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d}, - {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04}, - {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8}, - {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32}, - {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd}, - {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01}, - {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, - {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, - {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, - {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}, - {0x1007, 0x00} -}; - -/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ -static const u8 ov_gain[] = { - 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, - 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, - 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, - 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */, - 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */, - 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */, - 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */, - 0x70 /* 8x */ -}; - -/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ -static const u16 micron1_gain[] = { - /* 1x 1.25x 1.5x 1.75x */ - 0x0020, 0x0028, 0x0030, 0x0038, - /* 2x 2.25x 2.5x 2.75x */ - 0x00a0, 0x00a4, 0x00a8, 0x00ac, - /* 3x 3.25x 3.5x 3.75x */ - 0x00b0, 0x00b4, 0x00b8, 0x00bc, - /* 4x 4.25x 4.5x 4.75x */ - 0x00c0, 0x00c4, 0x00c8, 0x00cc, - /* 5x 5.25x 5.5x 5.75x */ - 0x00d0, 0x00d4, 0x00d8, 0x00dc, - /* 6x 6.25x 6.5x 6.75x */ - 0x00e0, 0x00e4, 0x00e8, 0x00ec, - /* 7x 7.25x 7.5x 7.75x */ - 0x00f0, 0x00f4, 0x00f8, 0x00fc, - /* 8x */ - 0x01c0 -}; - -/* mt9m001 sensor uses a different gain formula then other micron sensors */ -/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ -static const u16 micron2_gain[] = { - /* 1x 1.25x 1.5x 1.75x */ - 0x0008, 0x000a, 0x000c, 0x000e, - /* 2x 2.25x 2.5x 2.75x */ - 0x0010, 0x0012, 0x0014, 0x0016, - /* 3x 3.25x 3.5x 3.75x */ - 0x0018, 0x001a, 0x001c, 0x001e, - /* 4x 4.25x 4.5x 4.75x */ - 0x0020, 0x0051, 0x0052, 0x0053, - /* 5x 5.25x 5.5x 5.75x */ - 0x0054, 0x0055, 0x0056, 0x0057, - /* 6x 6.25x 6.5x 6.75x */ - 0x0058, 0x0059, 0x005a, 0x005b, - /* 7x 7.25x 7.5x 7.75x */ - 0x005c, 0x005d, 0x005e, 0x005f, - /* 8x */ - 0x0060 -}; - -/* Gain = .5 + bit[7:0] / 16 */ -static const u8 hv7131r_gain[] = { - 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, - 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, - 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, - 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */, - 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */, - 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */, - 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */, - 0x78 /* 8x */ -}; - -static const struct i2c_reg_u8 soi968_init[] = { - {0x0c, 0x00}, {0x0f, 0x1f}, - {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, - {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, - {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, - {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, - {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, - {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13}, - {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, - {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, - {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, - {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, -}; - -static const struct i2c_reg_u8 ov7660_init[] = { - {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, - {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, - {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, - /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using - 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */ - {0x17, 0x10}, {0x18, 0x61}, - {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, - {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00}, - {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50}, -}; - -static const struct i2c_reg_u8 ov7670_init[] = { - {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, - {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, - {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, - {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, - {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07}, - {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75}, - {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8}, - {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, - {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27}, - {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, - {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a}, - {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00}, - {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, - {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80}, - {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, - {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20}, - {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c}, - {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66}, - {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, - {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40}, - {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02}, - {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a}, - {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, - {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04}, - {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30}, - {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88}, - {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, - {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99}, - {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, - {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, - {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, - {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, - {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, - {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, - {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06}, - {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a}, - {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a}, - {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84}, - {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d}, - {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d}, - {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00}, - {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, - {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60}, - {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, - {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e}, - {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56}, - {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03}, - {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47}, - {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74}, - {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2}, - {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00}, - {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a}, - {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00}, - {0x93, 0x00}, -}; - -static const struct i2c_reg_u8 ov9650_init[] = { - {0x00, 0x00}, {0x01, 0x78}, - {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, - {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, - {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, - {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c}, - {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2}, - {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07}, - {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00}, - {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04}, - {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68}, - {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80}, - {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00}, - {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00}, - {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30}, - {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf}, - {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00}, - {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01}, - {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19}, - {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1}, - {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80}, - {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00}, - {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20}, - {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf}, - {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88}, - {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00}, - {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8}, - {0xaa, 0x92}, {0xab, 0x0a}, -}; - -static const struct i2c_reg_u8 ov9655_init[] = { - {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, - {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, - {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, - {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, - {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19}, - {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80}, - {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c}, - {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc}, - {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05}, - {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e}, - {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, - {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, - {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, - {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, - {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, - {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01}, - {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, - {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00}, - {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61}, - {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, - {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01}, - {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a}, - {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c}, - {0x04, 0x03}, {0x00, 0x13}, -}; - -static const struct i2c_reg_u16 mt9v112_init[] = { - {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, - {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, - {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, - {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a}, - {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58}, - {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001}, - {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020}, - {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020}, - {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020}, - {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, - {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2}, - {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, - {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020}, - {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, - {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae}, - {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, -}; - -static const struct i2c_reg_u16 mt9v111_init[] = { - {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, - {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0}, - {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e}, - {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016}, - {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004}, - {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008}, - {0x0e, 0x0008}, {0x20, 0x0000} -}; - -static const struct i2c_reg_u16 mt9v011_init[] = { - {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, - {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, - {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, - {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000}, - {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000}, - {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000}, - {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000}, - {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000}, - {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000}, - {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000}, - {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000}, - {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000}, - {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024}, - {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000}, - {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100}, - {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1}, - {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000}, - {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000}, - {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000}, - {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101}, - {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003}, - {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, - {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000}, - {0x06, 0x0029}, {0x05, 0x0009}, -}; - -static const struct i2c_reg_u16 mt9m001_init[] = { - {0x0d, 0x0001}, - {0x0d, 0x0000}, - {0x04, 0x0500}, /* hres = 1280 */ - {0x03, 0x0400}, /* vres = 1024 */ - {0x20, 0x1100}, - {0x06, 0x0010}, - {0x2b, 0x0024}, - {0x2e, 0x0024}, - {0x35, 0x0024}, - {0x2d, 0x0020}, - {0x2c, 0x0020}, - {0x09, 0x0ad4}, - {0x35, 0x0057}, -}; - -static const struct i2c_reg_u16 mt9m111_init[] = { - {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, - {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, - {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, - {0xf0, 0x0000}, -}; - -static const struct i2c_reg_u16 mt9m112_init[] = { - {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, - {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, - {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, - {0xf0, 0x0000}, -}; - -static const struct i2c_reg_u8 hv7131r_init[] = { - {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, - {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, - {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, - {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07}, - {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62}, - {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10}, - {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00}, - {0x23, 0x09}, {0x01, 0x08}, -}; - -static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) -{ - struct usb_device *dev = gspca_dev->dev; - int result; - - if (gspca_dev->usb_err < 0) - return; - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x00, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - reg, - 0x00, - gspca_dev->usb_buf, - length, - 500); - if (unlikely(result < 0 || result != length)) { - pr_err("Read register %02x failed %d\n", reg, result); - gspca_dev->usb_err = result; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, u16 reg, - const u8 *buffer, int length) -{ - struct usb_device *dev = gspca_dev->dev; - int result; - - if (gspca_dev->usb_err < 0) - return; - memcpy(gspca_dev->usb_buf, buffer, length); - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - reg, - 0x00, - gspca_dev->usb_buf, - length, - 500); - if (unlikely(result < 0 || result != length)) { - pr_err("Write register %02x failed %d\n", reg, result); - gspca_dev->usb_err = result; - } -} - -static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) -{ - reg_w(gspca_dev, reg, &value, 1); -} - -static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) -{ - int i; - - reg_w(gspca_dev, 0x10c0, buffer, 8); - for (i = 0; i < 5; i++) { - reg_r(gspca_dev, 0x10c0, 1); - if (gspca_dev->usb_err < 0) - return; - if (gspca_dev->usb_buf[0] & 0x04) { - if (gspca_dev->usb_buf[0] & 0x08) { - pr_err("i2c_w error\n"); - gspca_dev->usb_err = -EIO; - } - return; - } - msleep(10); - } - pr_err("i2c_w reg %02x no response\n", buffer[2]); -/* gspca_dev->usb_err = -EIO; fixme: may occur */ -} - -static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 row[8]; - - /* - * from the point of view of the bridge, the length - * includes the address - */ - row[0] = sd->i2c_intf | (2 << 4); - row[1] = sd->i2c_addr; - row[2] = reg; - row[3] = val; - row[4] = 0x00; - row[5] = 0x00; - row[6] = 0x00; - row[7] = 0x10; - - i2c_w(gspca_dev, row); -} - -static void i2c_w1_buf(struct gspca_dev *gspca_dev, - const struct i2c_reg_u8 *buf, int sz) -{ - while (--sz >= 0) { - i2c_w1(gspca_dev, buf->reg, buf->val); - buf++; - } -} - -static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 row[8]; - - /* - * from the point of view of the bridge, the length - * includes the address - */ - row[0] = sd->i2c_intf | (3 << 4); - row[1] = sd->i2c_addr; - row[2] = reg; - row[3] = val >> 8; - row[4] = val; - row[5] = 0x00; - row[6] = 0x00; - row[7] = 0x10; - - i2c_w(gspca_dev, row); -} - -static void i2c_w2_buf(struct gspca_dev *gspca_dev, - const struct i2c_reg_u16 *buf, int sz) -{ - while (--sz >= 0) { - i2c_w2(gspca_dev, buf->reg, buf->val); - buf++; - } -} - -static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 row[8]; - - row[0] = sd->i2c_intf | (1 << 4); - row[1] = sd->i2c_addr; - row[2] = reg; - row[3] = 0; - row[4] = 0; - row[5] = 0; - row[6] = 0; - row[7] = 0x10; - i2c_w(gspca_dev, row); - row[0] = sd->i2c_intf | (1 << 4) | 0x02; - row[2] = 0; - i2c_w(gspca_dev, row); - reg_r(gspca_dev, 0x10c2, 5); - *val = gspca_dev->usb_buf[4]; -} - -static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 row[8]; - - row[0] = sd->i2c_intf | (1 << 4); - row[1] = sd->i2c_addr; - row[2] = reg; - row[3] = 0; - row[4] = 0; - row[5] = 0; - row[6] = 0; - row[7] = 0x10; - i2c_w(gspca_dev, row); - row[0] = sd->i2c_intf | (2 << 4) | 0x02; - row[2] = 0; - i2c_w(gspca_dev, row); - reg_r(gspca_dev, 0x10c2, 5); - *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; -} - -static void ov9650_init_sensor(struct gspca_dev *gspca_dev) -{ - u16 id; - struct sd *sd = (struct sd *) gspca_dev; - - i2c_r2(gspca_dev, 0x1c, &id); - if (gspca_dev->usb_err < 0) - return; - - if (id != 0x7fa2) { - pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); - gspca_dev->usb_err = -ENODEV; - return; - } - - i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(200); - i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init)); - if (gspca_dev->usb_err < 0) - pr_err("OV9650 sensor initialization failed\n"); - sd->hstart = 1; - sd->vstart = 7; -} - -static void ov9655_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(200); - i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init)); - if (gspca_dev->usb_err < 0) - pr_err("OV9655 sensor initialization failed\n"); - - sd->hstart = 1; - sd->vstart = 2; -} - -static void soi968_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(200); - i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init)); - if (gspca_dev->usb_err < 0) - pr_err("SOI968 sensor initialization failed\n"); - - sd->hstart = 60; - sd->vstart = 11; -} - -static void ov7660_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(200); - i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init)); - if (gspca_dev->usb_err < 0) - pr_err("OV7660 sensor initialization failed\n"); - sd->hstart = 3; - sd->vstart = 3; -} - -static void ov7670_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(200); - i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init)); - if (gspca_dev->usb_err < 0) - pr_err("OV7670 sensor initialization failed\n"); - - sd->hstart = 0; - sd->vstart = 1; -} - -static void mt9v_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 value; - - sd->i2c_addr = 0x5d; - i2c_r2(gspca_dev, 0xff, &value); - if (gspca_dev->usb_err >= 0 - && value == 0x8243) { - i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init)); - if (gspca_dev->usb_err < 0) { - pr_err("MT9V011 sensor initialization failed\n"); - return; - } - sd->hstart = 2; - sd->vstart = 2; - sd->sensor = SENSOR_MT9V011; - pr_info("MT9V011 sensor detected\n"); - return; - } - - gspca_dev->usb_err = 0; - sd->i2c_addr = 0x5c; - i2c_w2(gspca_dev, 0x01, 0x0004); - i2c_r2(gspca_dev, 0xff, &value); - if (gspca_dev->usb_err >= 0 - && value == 0x823a) { - i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init)); - if (gspca_dev->usb_err < 0) { - pr_err("MT9V111 sensor initialization failed\n"); - return; - } - sd->hstart = 2; - sd->vstart = 2; - sd->sensor = SENSOR_MT9V111; - pr_info("MT9V111 sensor detected\n"); - return; - } - - gspca_dev->usb_err = 0; - sd->i2c_addr = 0x5d; - i2c_w2(gspca_dev, 0xf0, 0x0000); - if (gspca_dev->usb_err < 0) { - gspca_dev->usb_err = 0; - sd->i2c_addr = 0x48; - i2c_w2(gspca_dev, 0xf0, 0x0000); - } - i2c_r2(gspca_dev, 0x00, &value); - if (gspca_dev->usb_err >= 0 - && value == 0x1229) { - i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init)); - if (gspca_dev->usb_err < 0) { - pr_err("MT9V112 sensor initialization failed\n"); - return; - } - sd->hstart = 6; - sd->vstart = 2; - sd->sensor = SENSOR_MT9V112; - pr_info("MT9V112 sensor detected\n"); - return; - } - - gspca_dev->usb_err = -ENODEV; -} - -static void mt9m112_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init)); - if (gspca_dev->usb_err < 0) - pr_err("MT9M112 sensor initialization failed\n"); - - sd->hstart = 0; - sd->vstart = 2; -} - -static void mt9m111_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init)); - if (gspca_dev->usb_err < 0) - pr_err("MT9M111 sensor initialization failed\n"); - - sd->hstart = 0; - sd->vstart = 2; -} - -static void mt9m001_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 id; - - i2c_r2(gspca_dev, 0x00, &id); - if (gspca_dev->usb_err < 0) - return; - - /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ - switch (id) { - case 0x8411: - case 0x8421: - pr_info("MT9M001 color sensor detected\n"); - break; - case 0x8431: - pr_info("MT9M001 mono sensor detected\n"); - break; - default: - pr_err("No MT9M001 chip detected, ID = %x\n\n", id); - gspca_dev->usb_err = -ENODEV; - return; - } - - i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init)); - if (gspca_dev->usb_err < 0) - pr_err("MT9M001 sensor initialization failed\n"); - - sd->hstart = 1; - sd->vstart = 1; -} - -static void hv7131r_init_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init)); - if (gspca_dev->usb_err < 0) - pr_err("HV7131R Sensor initialization failed\n"); - - sd->hstart = 0; - sd->vstart = 1; -} - -static void set_cmatrix(struct gspca_dev *gspca_dev, - s32 brightness, s32 contrast, s32 satur, s32 hue) -{ - s32 hue_coord, hue_index = 180 + hue; - u8 cmatrix[21]; - - memset(cmatrix, 0, sizeof cmatrix); - cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26; - cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; - cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; - cmatrix[18] = brightness - 0x80; - - hue_coord = (hsv_red_x[hue_index] * satur) >> 8; - cmatrix[6] = hue_coord; - cmatrix[7] = (hue_coord >> 8) & 0x0f; - - hue_coord = (hsv_red_y[hue_index] * satur) >> 8; - cmatrix[8] = hue_coord; - cmatrix[9] = (hue_coord >> 8) & 0x0f; - - hue_coord = (hsv_green_x[hue_index] * satur) >> 8; - cmatrix[10] = hue_coord; - cmatrix[11] = (hue_coord >> 8) & 0x0f; - - hue_coord = (hsv_green_y[hue_index] * satur) >> 8; - cmatrix[12] = hue_coord; - cmatrix[13] = (hue_coord >> 8) & 0x0f; - - hue_coord = (hsv_blue_x[hue_index] * satur) >> 8; - cmatrix[14] = hue_coord; - cmatrix[15] = (hue_coord >> 8) & 0x0f; - - hue_coord = (hsv_blue_y[hue_index] * satur) >> 8; - cmatrix[16] = hue_coord; - cmatrix[17] = (hue_coord >> 8) & 0x0f; - - reg_w(gspca_dev, 0x10e1, cmatrix, 21); -} - -static void set_gamma(struct gspca_dev *gspca_dev, s32 val) -{ - u8 gamma[17]; - u8 gval = val * 0xb8 / 0x100; - - gamma[0] = 0x0a; - gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); - gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8); - gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8); - gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8); - gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8); - gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8); - gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8); - gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8); - gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8); - gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8); - gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8); - gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8); - gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8); - gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8); - gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); - gamma[16] = 0xf5; - - reg_w(gspca_dev, 0x1190, gamma, 17); -} - -static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red) -{ - reg_w1(gspca_dev, 0x118c, red); - reg_w1(gspca_dev, 0x118f, blue); -} - -static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) -{ - u8 value, tslb; - u16 value2; - struct sd *sd = (struct sd *) gspca_dev; - - if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { - hflip = !hflip; - vflip = !vflip; - } - - switch (sd->sensor) { - case SENSOR_OV7660: - value = 0x01; - if (hflip) - value |= 0x20; - if (vflip) { - value |= 0x10; - sd->vstart = 2; - } else { - sd->vstart = 3; - } - reg_w1(gspca_dev, 0x1182, sd->vstart); - i2c_w1(gspca_dev, 0x1e, value); - break; - case SENSOR_OV9650: - i2c_r1(gspca_dev, 0x1e, &value); - value &= ~0x30; - tslb = 0x01; - if (hflip) - value |= 0x20; - if (vflip) { - value |= 0x10; - tslb = 0x49; - } - i2c_w1(gspca_dev, 0x1e, value); - i2c_w1(gspca_dev, 0x3a, tslb); - break; - case SENSOR_MT9V111: - case SENSOR_MT9V011: - i2c_r2(gspca_dev, 0x20, &value2); - value2 &= ~0xc0a0; - if (hflip) - value2 |= 0x8080; - if (vflip) - value2 |= 0x4020; - i2c_w2(gspca_dev, 0x20, value2); - break; - case SENSOR_MT9M112: - case SENSOR_MT9M111: - case SENSOR_MT9V112: - i2c_r2(gspca_dev, 0x20, &value2); - value2 &= ~0x0003; - if (hflip) - value2 |= 0x0002; - if (vflip) - value2 |= 0x0001; - i2c_w2(gspca_dev, 0x20, value2); - break; - case SENSOR_HV7131R: - i2c_r1(gspca_dev, 0x01, &value); - value &= ~0x03; - if (vflip) - value |= 0x01; - if (hflip) - value |= 0x02; - i2c_w1(gspca_dev, 0x01, value); - break; - } -} - -static void set_exposure(struct gspca_dev *gspca_dev, s32 expo) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 exp[8] = {sd->i2c_intf, sd->i2c_addr, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - int expo2; - - if (gspca_dev->streaming) - exp[7] = 0x1e; - - switch (sd->sensor) { - case SENSOR_OV7660: - case SENSOR_OV7670: - case SENSOR_OV9655: - case SENSOR_OV9650: - if (expo > 547) - expo2 = 547; - else - expo2 = expo; - exp[0] |= (2 << 4); - exp[2] = 0x10; /* AECH */ - exp[3] = expo2 >> 2; - exp[7] = 0x10; - i2c_w(gspca_dev, exp); - exp[2] = 0x04; /* COM1 */ - exp[3] = expo2 & 0x0003; - exp[7] = 0x10; - i2c_w(gspca_dev, exp); - expo -= expo2; - exp[7] = 0x1e; - exp[0] |= (3 << 4); - exp[2] = 0x2d; /* ADVFL & ADVFH */ - exp[3] = expo; - exp[4] = expo >> 8; - break; - case SENSOR_MT9M001: - case SENSOR_MT9V112: - case SENSOR_MT9V011: - exp[0] |= (3 << 4); - exp[2] = 0x09; - exp[3] = expo >> 8; - exp[4] = expo; - break; - case SENSOR_HV7131R: - exp[0] |= (4 << 4); - exp[2] = 0x25; - exp[3] = expo >> 5; - exp[4] = expo << 3; - exp[5] = 0; - break; - default: - return; - } - i2c_w(gspca_dev, exp); -} - -static void set_gain(struct gspca_dev *gspca_dev, s32 g) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 gain[8] = {sd->i2c_intf, sd->i2c_addr, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - - if (gspca_dev->streaming) - gain[7] = 0x15; /* or 1d ? */ - - switch (sd->sensor) { - case SENSOR_OV7660: - case SENSOR_OV7670: - case SENSOR_SOI968: - case SENSOR_OV9655: - case SENSOR_OV9650: - gain[0] |= (2 << 4); - gain[3] = ov_gain[g]; - break; - case SENSOR_MT9V011: - gain[0] |= (3 << 4); - gain[2] = 0x35; - gain[3] = micron1_gain[g] >> 8; - gain[4] = micron1_gain[g]; - break; - case SENSOR_MT9V112: - gain[0] |= (3 << 4); - gain[2] = 0x2f; - gain[3] = micron1_gain[g] >> 8; - gain[4] = micron1_gain[g]; - break; - case SENSOR_MT9M001: - gain[0] |= (3 << 4); - gain[2] = 0x2f; - gain[3] = micron2_gain[g] >> 8; - gain[4] = micron2_gain[g]; - break; - case SENSOR_HV7131R: - gain[0] |= (2 << 4); - gain[2] = 0x30; - gain[3] = hv7131r_gain[g]; - break; - default: - return; - } - i2c_w(gspca_dev, gain); -} - -static void set_quality(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - jpeg_set_qual(sd->jpeg_hdr, val); - reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ - reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ - reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); - reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); - reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */ - reg_w1(gspca_dev, 0x10e0, sd->fmt); - sd->fmt ^= 0x0c; /* invert QTAB use + write */ - reg_w1(gspca_dev, 0x10e0, sd->fmt); -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int sd_dbg_g_register(struct gspca_dev *gspca_dev, - struct v4l2_dbg_register *reg) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (reg->match.type) { - case V4L2_CHIP_MATCH_HOST: - if (reg->match.addr != 0) - return -EINVAL; - if (reg->reg < 0x1000 || reg->reg > 0x11ff) - return -EINVAL; - reg_r(gspca_dev, reg->reg, 1); - reg->val = gspca_dev->usb_buf[0]; - return gspca_dev->usb_err; - case V4L2_CHIP_MATCH_I2C_ADDR: - if (reg->match.addr != sd->i2c_addr) - return -EINVAL; - if (sd->sensor >= SENSOR_MT9V011 && - sd->sensor <= SENSOR_MT9M112) { - i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val); - } else { - i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val); - } - return gspca_dev->usb_err; - } - return -EINVAL; -} - -static int sd_dbg_s_register(struct gspca_dev *gspca_dev, - struct v4l2_dbg_register *reg) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (reg->match.type) { - case V4L2_CHIP_MATCH_HOST: - if (reg->match.addr != 0) - return -EINVAL; - if (reg->reg < 0x1000 || reg->reg > 0x11ff) - return -EINVAL; - reg_w1(gspca_dev, reg->reg, reg->val); - return gspca_dev->usb_err; - case V4L2_CHIP_MATCH_I2C_ADDR: - if (reg->match.addr != sd->i2c_addr) - return -EINVAL; - if (sd->sensor >= SENSOR_MT9V011 && - sd->sensor <= SENSOR_MT9M112) { - i2c_w2(gspca_dev, reg->reg, reg->val); - } else { - i2c_w1(gspca_dev, reg->reg, reg->val); - } - return gspca_dev->usb_err; - } - return -EINVAL; -} -#endif - -static int sd_chip_ident(struct gspca_dev *gspca_dev, - struct v4l2_dbg_chip_ident *chip) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (chip->match.type) { - case V4L2_CHIP_MATCH_HOST: - if (chip->match.addr != 0) - return -EINVAL; - chip->revision = 0; - chip->ident = V4L2_IDENT_SN9C20X; - return 0; - case V4L2_CHIP_MATCH_I2C_ADDR: - if (chip->match.addr != sd->i2c_addr) - return -EINVAL; - chip->revision = 0; - chip->ident = i2c_ident[sd->sensor]; - return 0; - } - return -EINVAL; -} - -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - cam->needs_full_bandwidth = 1; - - sd->sensor = id->driver_info >> 8; - sd->i2c_addr = id->driver_info; - sd->flags = id->driver_info >> 16; - sd->i2c_intf = 0x80; /* i2c 100 Kb/s */ - - switch (sd->sensor) { - case SENSOR_MT9M112: - case SENSOR_MT9M111: - case SENSOR_OV9650: - case SENSOR_SOI968: - cam->cam_mode = sxga_mode; - cam->nmodes = ARRAY_SIZE(sxga_mode); - break; - case SENSOR_MT9M001: - cam->cam_mode = mono_mode; - cam->nmodes = ARRAY_SIZE(mono_mode); - break; - case SENSOR_HV7131R: - sd->i2c_intf = 0x81; /* i2c 400 Kb/s */ - /* fall thru */ - default: - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - break; - } - - sd->old_step = 0; - sd->older_step = 0; - sd->exposure_step = 16; - - INIT_WORK(&sd->work, qual_upd); - - return 0; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - /* color control cluster */ - case V4L2_CID_BRIGHTNESS: - set_cmatrix(gspca_dev, sd->brightness->val, - sd->contrast->val, sd->saturation->val, sd->hue->val); - break; - case V4L2_CID_GAMMA: - set_gamma(gspca_dev, ctrl->val); - break; - /* blue/red balance cluster */ - case V4L2_CID_BLUE_BALANCE: - set_redblue(gspca_dev, sd->blue->val, sd->red->val); - break; - /* h/vflip cluster */ - case V4L2_CID_HFLIP: - set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val); - break; - /* standalone exposure control */ - case V4L2_CID_EXPOSURE: - set_exposure(gspca_dev, ctrl->val); - break; - /* standalone gain control */ - case V4L2_CID_GAIN: - set_gain(gspca_dev, ctrl->val); - break; - /* autogain + exposure or gain control cluster */ - case V4L2_CID_AUTOGAIN: - if (sd->sensor == SENSOR_SOI968) - set_gain(gspca_dev, sd->gain->val); - else - set_exposure(gspca_dev, sd->exposure->val); - break; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - set_quality(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 13); - - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); - sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 127); - sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 127); - sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, -180, 180, 1, 0); - - sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAMMA, 0, 255, 1, 0x10); - - sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); - sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); - - if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && - sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && - sd->sensor != SENSOR_MT9VPRB) { - sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - } - - if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && - sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 && - sd->sensor != SENSOR_MT9V111) - sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33); - - if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 && - sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) { - sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 28, 1, 0); - sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - } - - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - v4l2_ctrl_cluster(4, &sd->brightness); - v4l2_ctrl_cluster(2, &sd->blue); - if (sd->hflip) - v4l2_ctrl_cluster(2, &sd->hflip); - if (sd->autogain) { - if (sd->sensor == SENSOR_SOI968) - /* this sensor doesn't have the exposure control and - autogain is clustered with gain instead. This works - because sd->exposure == NULL. */ - v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false); - else - /* Otherwise autogain is clustered with exposure. */ - v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); - } - return 0; -} - -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - u8 value; - u8 i2c_init[9] = - {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; - - for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { - value = bridge_init[i][1]; - reg_w(gspca_dev, bridge_init[i][0], &value, 1); - if (gspca_dev->usb_err < 0) { - pr_err("Device initialization failed\n"); - return gspca_dev->usb_err; - } - } - - if (sd->flags & LED_REVERSE) - reg_w1(gspca_dev, 0x1006, 0x00); - else - reg_w1(gspca_dev, 0x1006, 0x20); - - reg_w(gspca_dev, 0x10c0, i2c_init, 9); - if (gspca_dev->usb_err < 0) { - pr_err("Device initialization failed\n"); - return gspca_dev->usb_err; - } - - switch (sd->sensor) { - case SENSOR_OV9650: - ov9650_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("OV9650 sensor detected\n"); - break; - case SENSOR_OV9655: - ov9655_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("OV9655 sensor detected\n"); - break; - case SENSOR_SOI968: - soi968_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("SOI968 sensor detected\n"); - break; - case SENSOR_OV7660: - ov7660_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("OV7660 sensor detected\n"); - break; - case SENSOR_OV7670: - ov7670_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("OV7670 sensor detected\n"); - break; - case SENSOR_MT9VPRB: - mt9v_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("MT9VPRB sensor detected\n"); - break; - case SENSOR_MT9M111: - mt9m111_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("MT9M111 sensor detected\n"); - break; - case SENSOR_MT9M112: - mt9m112_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("MT9M112 sensor detected\n"); - break; - case SENSOR_MT9M001: - mt9m001_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - break; - case SENSOR_HV7131R: - hv7131r_init_sensor(gspca_dev); - if (gspca_dev->usb_err < 0) - break; - pr_info("HV7131R sensor detected\n"); - break; - default: - pr_err("Unsupported sensor\n"); - gspca_dev->usb_err = -ENODEV; - } - return gspca_dev->usb_err; -} - -static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 value; - - switch (sd->sensor) { - case SENSOR_SOI968: - if (mode & MODE_SXGA) { - i2c_w1(gspca_dev, 0x17, 0x1d); - i2c_w1(gspca_dev, 0x18, 0xbd); - i2c_w1(gspca_dev, 0x19, 0x01); - i2c_w1(gspca_dev, 0x1a, 0x81); - i2c_w1(gspca_dev, 0x12, 0x00); - sd->hstart = 140; - sd->vstart = 19; - } else { - i2c_w1(gspca_dev, 0x17, 0x13); - i2c_w1(gspca_dev, 0x18, 0x63); - i2c_w1(gspca_dev, 0x19, 0x01); - i2c_w1(gspca_dev, 0x1a, 0x79); - i2c_w1(gspca_dev, 0x12, 0x40); - sd->hstart = 60; - sd->vstart = 11; - } - break; - case SENSOR_OV9650: - if (mode & MODE_SXGA) { - i2c_w1(gspca_dev, 0x17, 0x1b); - i2c_w1(gspca_dev, 0x18, 0xbc); - i2c_w1(gspca_dev, 0x19, 0x01); - i2c_w1(gspca_dev, 0x1a, 0x82); - i2c_r1(gspca_dev, 0x12, &value); - i2c_w1(gspca_dev, 0x12, value & 0x07); - } else { - i2c_w1(gspca_dev, 0x17, 0x24); - i2c_w1(gspca_dev, 0x18, 0xc5); - i2c_w1(gspca_dev, 0x19, 0x00); - i2c_w1(gspca_dev, 0x1a, 0x3c); - i2c_r1(gspca_dev, 0x12, &value); - i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); - } - break; - case SENSOR_MT9M112: - case SENSOR_MT9M111: - if (mode & MODE_SXGA) { - i2c_w2(gspca_dev, 0xf0, 0x0002); - i2c_w2(gspca_dev, 0xc8, 0x970b); - i2c_w2(gspca_dev, 0xf0, 0x0000); - } else { - i2c_w2(gspca_dev, 0xf0, 0x0002); - i2c_w2(gspca_dev, 0xc8, 0x8000); - i2c_w2(gspca_dev, 0xf0, 0x0000); - } - break; - } -} - -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct usb_interface *intf; - u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv; - - /* - * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth - * than our regular bandwidth calculations reserve, so we force the - * use of a specific altsetting when using the SN9C20X_I420 fmt. - */ - if (!(flags & (MODE_RAW | MODE_JPEG))) { - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - - if (intf->num_altsetting != 9) { - pr_warn("sn9c20x camera with unknown number of alt " - "settings (%d), please report!\n", - intf->num_altsetting); - gspca_dev->alt = intf->num_altsetting; - return 0; - } - - switch (gspca_dev->width) { - case 160: /* 160x120 */ - gspca_dev->alt = 2; - break; - case 320: /* 320x240 */ - gspca_dev->alt = 6; - break; - default: /* >= 640x480 */ - gspca_dev->alt = 9; - break; - } - } - - return 0; -} - -#define HW_WIN(mode, hstart, vstart) \ -((const u8 []){hstart, 0, vstart, 0, \ -(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ -(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) - -#define CLR_WIN(width, height) \ -((const u8 [])\ -{0, width >> 2, 0, height >> 1,\ -((width >> 10) & 0x01) | ((height >> 8) & 0x6)}) - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - int width = gspca_dev->width; - int height = gspca_dev->height; - u8 fmt, scale = 0; - - jpeg_define(sd->jpeg_hdr, height, width, - 0x21); - jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); - - if (mode & MODE_RAW) - fmt = 0x2d; - else if (mode & MODE_JPEG) - fmt = 0x24; - else - fmt = 0x2f; /* YUV 420 */ - sd->fmt = fmt; - - switch (mode & SCALE_MASK) { - case SCALE_1280x1024: - scale = 0xc0; - pr_info("Set 1280x1024\n"); - break; - case SCALE_640x480: - scale = 0x80; - pr_info("Set 640x480\n"); - break; - case SCALE_320x240: - scale = 0x90; - pr_info("Set 320x240\n"); - break; - case SCALE_160x120: - scale = 0xa0; - pr_info("Set 160x120\n"); - break; - } - - configure_sensor_output(gspca_dev, mode); - reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); - reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); - reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5); - reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6); - reg_w1(gspca_dev, 0x1189, scale); - reg_w1(gspca_dev, 0x10e0, fmt); - - set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness), - v4l2_ctrl_g_ctrl(sd->contrast), - v4l2_ctrl_g_ctrl(sd->saturation), - v4l2_ctrl_g_ctrl(sd->hue)); - set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); - set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - if (sd->gain) - set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); - if (sd->exposure) - set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); - if (sd->hflip) - set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), - v4l2_ctrl_g_ctrl(sd->vflip)); - - reg_w1(gspca_dev, 0x1007, 0x20); - reg_w1(gspca_dev, 0x1061, 0x03); - - /* if JPEG, prepare the compression quality update */ - if (mode & MODE_JPEG) { - sd->pktsz = sd->npkt = 0; - sd->nchg = 0; - sd->work_thread = - create_singlethread_workqueue(KBUILD_MODNAME); - } - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - reg_w1(gspca_dev, 0x1007, 0x00); - reg_w1(gspca_dev, 0x1061, 0x01); -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->work_thread != NULL) { - mutex_unlock(&gspca_dev->usb_lock); - destroy_workqueue(sd->work_thread); - mutex_lock(&gspca_dev->usb_lock); - sd->work_thread = NULL; - } -} - -static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure); - s32 max = sd->exposure->maximum - sd->exposure_step; - s32 min = sd->exposure->minimum + sd->exposure_step; - s16 new_exp; - - /* - * some hardcoded values are present - * like those for maximal/minimal exposure - * and exposure steps - */ - if (avg_lum < MIN_AVG_LUM) { - if (cur_exp > max) - return; - - new_exp = cur_exp + sd->exposure_step; - if (new_exp > max) - new_exp = max; - if (new_exp < min) - new_exp = min; - v4l2_ctrl_s_ctrl(sd->exposure, new_exp); - - sd->older_step = sd->old_step; - sd->old_step = 1; - - if (sd->old_step ^ sd->older_step) - sd->exposure_step /= 2; - else - sd->exposure_step += 2; - } - if (avg_lum > MAX_AVG_LUM) { - if (cur_exp < min) - return; - new_exp = cur_exp - sd->exposure_step; - if (new_exp > max) - new_exp = max; - if (new_exp < min) - new_exp = min; - v4l2_ctrl_s_ctrl(sd->exposure, new_exp); - sd->older_step = sd->old_step; - sd->old_step = 0; - - if (sd->old_step ^ sd->older_step) - sd->exposure_step /= 2; - else - sd->exposure_step += 2; - } -} - -static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain); - - if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum) - v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1); - if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum) - v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1); -} - -static void sd_dqcallback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int avg_lum; - - if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) - return; - - avg_lum = atomic_read(&sd->avg_lum); - if (sd->sensor == SENSOR_SOI968) - do_autogain(gspca_dev, avg_lum); - else - do_autoexposure(gspca_dev, avg_lum); -} - -/* JPEG quality update */ -/* This function is executed from a work queue. */ -static void qual_upd(struct work_struct *work) -{ - struct sd *sd = container_of(work, struct sd, work); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual); - - mutex_lock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, "qual_upd %d%%", qual); - set_quality(gspca_dev, qual); - mutex_unlock(&gspca_dev->usb_lock); -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet */ - int len) /* interrupt packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - return 0; - } - return -EINVAL; -} -#endif - -/* check the JPEG compression */ -static void transfer_check(struct gspca_dev *gspca_dev, - u8 *data) -{ - struct sd *sd = (struct sd *) gspca_dev; - int new_qual, r; - - new_qual = 0; - - /* if USB error, discard the frame and decrease the quality */ - if (data[6] & 0x08) { /* USB FIFO full */ - gspca_dev->last_packet_type = DISCARD_PACKET; - new_qual = -5; - } else { - - /* else, compute the filling rate and a new JPEG quality */ - r = (sd->pktsz * 100) / - (sd->npkt * - gspca_dev->urb[0]->iso_frame_desc[0].length); - if (r >= 85) - new_qual = -3; - else if (r < 75) - new_qual = 2; - } - if (new_qual != 0) { - sd->nchg += new_qual; - if (sd->nchg < -6 || sd->nchg >= 12) { - /* Note: we are in interrupt context, so we can't - use v4l2_ctrl_g/s_ctrl here. Access the value - directly instead. */ - s32 curqual = sd->jpegqual->cur.val; - sd->nchg = 0; - new_qual += curqual; - if (new_qual < sd->jpegqual->minimum) - new_qual = sd->jpegqual->minimum; - else if (new_qual > sd->jpegqual->maximum) - new_qual = sd->jpegqual->maximum; - if (new_qual != curqual) { - sd->jpegqual->cur.val = new_qual; - queue_work(sd->work_thread, &sd->work); - } - } - } else { - sd->nchg = 0; - } - sd->pktsz = sd->npkt = 0; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int avg_lum, is_jpeg; - static const u8 frame_header[] = - {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; - - is_jpeg = (sd->fmt & 0x03) == 0; - if (len >= 64 && memcmp(data, frame_header, 6) == 0) { - avg_lum = ((data[35] >> 2) & 3) | - (data[20] << 2) | - (data[19] << 10); - avg_lum += ((data[35] >> 4) & 3) | - (data[22] << 2) | - (data[21] << 10); - avg_lum += ((data[35] >> 6) & 3) | - (data[24] << 2) | - (data[23] << 10); - avg_lum += (data[36] & 3) | - (data[26] << 2) | - (data[25] << 10); - avg_lum += ((data[36] >> 2) & 3) | - (data[28] << 2) | - (data[27] << 10); - avg_lum += ((data[36] >> 4) & 3) | - (data[30] << 2) | - (data[29] << 10); - avg_lum += ((data[36] >> 6) & 3) | - (data[32] << 2) | - (data[31] << 10); - avg_lum += ((data[44] >> 4) & 3) | - (data[34] << 2) | - (data[33] << 10); - avg_lum >>= 9; - atomic_set(&sd->avg_lum, avg_lum); - - if (is_jpeg) - transfer_check(gspca_dev, data); - - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - len -= 64; - if (len == 0) - return; - data += 64; - } - if (gspca_dev->last_packet_type == LAST_PACKET) { - if (is_jpeg) { - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, - data, len); - } else { - gspca_frame_add(gspca_dev, FIRST_PACKET, - data, len); - } - } else { - /* if JPEG, count the packets and their size */ - if (is_jpeg) { - sd->npkt++; - sd->pktsz += len; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - } -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = KBUILD_MODNAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif - .dq_callback = sd_dqcallback, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .set_register = sd_dbg_s_register, - .get_register = sd_dbg_g_register, -#endif - .get_chip_ident = sd_chip_ident, -}; - -#define SN9C20X(sensor, i2c_addr, flags) \ - .driver_info = ((flags & 0xff) << 16) \ - | (SENSOR_ ## sensor << 8) \ - | (i2c_addr) - -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)}, - {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, - (FLIP_DETECT | HAS_NO_BUTTON))}, - {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, - {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, - {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)}, - {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)}, - {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, - {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, - {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, - {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)}, - {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)}, - {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, - {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, - {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)}, - {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)}, - {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, - {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, - {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, - {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = KBUILD_MODNAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c deleted file mode 100644 index fd1f8d2d3b0b..000000000000 --- a/drivers/media/video/gspca/sonixb.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* - * sonix sn9c102 (bayer) library - * - * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr> - * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr - * Add Pas106 Stefano Mozzi (C) 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Some documentation on known sonixb registers: - -Reg Use -sn9c101 / sn9c102: -0x10 high nibble red gain low nibble blue gain -0x11 low nibble green gain -sn9c103: -0x05 red gain 0-127 -0x06 blue gain 0-127 -0x07 green gain 0-127 -all: -0x08-0x0f i2c / 3wire registers -0x12 hstart -0x13 vstart -0x15 hsize (hsize = register-value * 16) -0x16 vsize (vsize = register-value * 16) -0x17 bit 0 toggle compression quality (according to sn9c102 driver) -0x18 bit 7 enables compression, bit 4-5 set image down scaling: - 00 scale 1, 01 scale 1/2, 10, scale 1/4 -0x19 high-nibble is sensor clock divider, changes exposure on sensors which - use a clock generated by the bridge. Some sensors have their own clock. -0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32) -0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32) -0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32) -0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32) -*/ - -#define MODULE_NAME "sonixb" - -#include <linux/input.h> -#include "gspca.h" - -MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *plfreq; - - atomic_t avg_lum; - int prev_avg_lum; - int exposure_knee; - int header_read; - u8 header[12]; /* Header without sof marker */ - - unsigned char autogain_ignore_frames; - unsigned char frames_to_drop; - - __u8 bridge; /* Type of bridge */ -#define BRIDGE_101 0 -#define BRIDGE_102 0 /* We make no difference between 101 and 102 */ -#define BRIDGE_103 1 - - __u8 sensor; /* Type of image sensor chip */ -#define SENSOR_HV7131D 0 -#define SENSOR_HV7131R 1 -#define SENSOR_OV6650 2 -#define SENSOR_OV7630 3 -#define SENSOR_PAS106 4 -#define SENSOR_PAS202 5 -#define SENSOR_TAS5110C 6 -#define SENSOR_TAS5110D 7 -#define SENSOR_TAS5130CXX 8 - __u8 reg11; -}; - -typedef const __u8 sensor_init_t[8]; - -struct sensor_data { - const __u8 *bridge_init; - sensor_init_t *sensor_init; - int sensor_init_size; - int flags; - __u8 sensor_addr; -}; - -/* sensor_data flags */ -#define F_SIF 0x01 /* sif or vga */ - -/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ -#define MODE_RAW 0x10 /* raw bayer mode */ -#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ - -#define COMP 0xc7 /* 0x87 //0x07 */ -#define COMP1 0xc9 /* 0x89 //0x09 */ - -#define MCK_INIT 0x63 -#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/ - -#define SYS_CLK 0x04 - -#define SENS(bridge, sensor, _flags, _sensor_addr) \ -{ \ - .bridge_init = bridge, \ - .sensor_init = sensor, \ - .sensor_init_size = sizeof(sensor), \ - .flags = _flags, .sensor_addr = _sensor_addr \ -} - -/* We calculate the autogain at the end of the transfer of a frame, at this - moment a frame with the old settings is being captured and transmitted. So - if we adjust the gain or exposure we must ignore atleast the next frame for - the new settings to come into effect before doing any other adjustments. */ -#define AUTOGAIN_IGNORE_FRAMES 1 - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2 | MODE_RAW}, - {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format sif_mode[] = { - {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 | MODE_RAW | MODE_REDUCED_SIF}, - {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 | MODE_REDUCED_SIF}, - {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 | MODE_RAW}, - {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 | MODE_REDUCED_SIF}, - {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 5 / 4, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -static const __u8 initHv7131d[] = { - 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, - 0x28, 0x1e, 0x60, 0x8e, 0x42, -}; -static const __u8 hv7131d_sensor_init[][8] = { - {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, - {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17}, - {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17}, - {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */ - {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */ -}; - -static const __u8 initHv7131r[] = { - 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, - 0x28, 0x1e, 0x60, 0x8a, 0x20, -}; -static const __u8 hv7131r_sensor_init[][8] = { - {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, - {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, - {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, - {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16}, - {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15}, -}; -static const __u8 initOv6650[] = { - 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, - 0x10, -}; -static const __u8 ov6650_sensor_init[][8] = { - /* Bright, contrast, etc are set through SCBB interface. - * AVCAP on win2 do not send any data on this controls. */ - /* Anyway, some registers appears to alter bright and constrat */ - - /* Reset sensor */ - {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, - /* Set clock register 0x11 low nibble is clock divider */ - {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10}, - /* Next some unknown stuff */ - {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10}, -/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10}, - * THIS SET GREEN SCREEN - * (pixels could be innverted in decode kind of "brg", - * but blue wont be there. Avoid this data ... */ - {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ - {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, - {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10}, - /* Enable rgb brightness control */ - {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10}, - /* HDG: Note windows uses the line below, which sets both register 0x60 - and 0x61 I believe these registers of the ov6650 are identical as - those of the ov7630, because if this is true the windows settings - add a bit additional red gain and a lot additional blue gain, which - matches my findings that the windows settings make blue much too - blue and red a little too red. - {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */ - /* Some more unknown stuff */ - {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, - {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ -}; - -static const __u8 initOv7630[] = { - 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ - 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ - 0x28, 0x1e, /* H & V sizes r15 .. r16 */ - 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ -}; -static const __u8 ov7630_sensor_init[][8] = { - {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, -/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ - {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ - {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, - {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, - {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, - {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10}, - {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, - {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, - {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, - {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, -/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */ - {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, - {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, - {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, - {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10}, - {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, - {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, -}; - -static const __u8 initPas106[] = { - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, - 0x16, 0x12, 0x24, COMP1, MCK_INIT1, -}; -/* compression 0x86 mckinit1 0x2b */ - -/* "Known" PAS106B registers: - 0x02 clock divider - 0x03 Variable framerate bits 4-11 - 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !! - The variable framerate control must never be set lower then 300, - which sets the framerate at 90 / reg02, otherwise vsync is lost. - 0x05 Shutter Time Line Offset, this can be used as an exposure control: - 0 = use full frame time, 255 = no exposure at all - Note this may never be larger then "var-framerate control" / 2 - 2. - When var-framerate control is < 514, no exposure is reached at the max - allowed value for the framerate control value, rather then at 255. - 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but - only a very little bit, leave at 0xcd - 0x07 offset sign bit (bit0 1 > negative offset) - 0x08 offset - 0x09 Blue Gain - 0x0a Green1 Gain - 0x0b Green2 Gain - 0x0c Red Gain - 0x0e Global gain - 0x13 Write 1 to commit settings to sensor -*/ - -static const __u8 pas106_sensor_init[][8] = { - /* Pixel Clock Divider 6 */ - { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, - /* Frame Time MSB (also seen as 0x12) */ - { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 }, - /* Frame Time LSB (also seen as 0x05) */ - { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 }, - /* Shutter Time Line Offset (also seen as 0x6d) */ - { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 }, - /* Shutter Time Pixel Offset (also seen as 0xb1) */ - { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 }, - /* Black Level Subtract Sign (also seen 0x00) */ - { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 }, - /* Black Level Subtract Level (also seen 0x01) */ - { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, - { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 }, - /* Color Gain B Pixel 5 a */ - { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 }, - /* Color Gain G1 Pixel 1 5 */ - { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 }, - /* Color Gain G2 Pixel 1 0 5 */ - { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 }, - /* Color Gain R Pixel 3 1 */ - { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 }, - /* Color GainH Pixel */ - { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 }, - /* Global Gain */ - { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 }, - /* Contrast */ - { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 }, - /* H&V synchro polarity */ - { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 }, - /* ?default */ - { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 }, - /* DAC scale */ - { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 }, - /* ?default */ - { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 }, - /* Validate Settings */ - { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 }, -}; - -static const __u8 initPas202[] = { - 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, - 0x28, 0x1e, 0x20, 0x89, 0x20, -}; - -/* "Known" PAS202BCB registers: - 0x02 clock divider - 0x04 Variable framerate bits 6-11 (*) - 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !! - 0x07 Blue Gain - 0x08 Green Gain - 0x09 Red Gain - 0x0b offset sign bit (bit0 1 > negative offset) - 0x0c offset - 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too, - leave at 1 otherwise we get a jump in our exposure control - 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all - 0x10 Master gain 0 - 31 - 0x11 write 1 to apply changes - (*) The variable framerate control must never be set lower then 500 - which sets the framerate at 30 / reg02, otherwise vsync is lost. -*/ -static const __u8 pas202_sensor_init[][8] = { - /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like - to set it lower, but for some reason the bridge starts missing - vsync's then */ - {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, - {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, - {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10}, - {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, - {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, - {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, - {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, - {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, - {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, -}; - -static const __u8 initTas5110c[] = { - 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a, - 0x16, 0x12, 0x60, 0x86, 0x2b, -}; -/* Same as above, except a different hstart */ -static const __u8 initTas5110d[] = { - 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a, - 0x16, 0x12, 0x60, 0x86, 0x2b, -}; -/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */ -static const __u8 tas5110c_sensor_init[][8] = { - {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, - {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, -}; -/* Known TAS5110D registers - * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain - * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted) - * Note: writing reg03 seems to only work when written together with 02 - */ -static const __u8 tas5110d_sensor_init[][8] = { - {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */ -}; - -static const __u8 initTas5130[] = { - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a, - 0x28, 0x1e, 0x60, COMP, MCK_INIT, -}; -static const __u8 tas5130_sensor_init[][8] = { -/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, - * shutter 0x47 short exposure? */ - {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, - /* shutter 0x01 long exposure */ - {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, -}; - -static const struct sensor_data sensor_data[] = { - SENS(initHv7131d, hv7131d_sensor_init, 0, 0), - SENS(initHv7131r, hv7131r_sensor_init, 0, 0), - SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60), - SENS(initOv7630, ov7630_sensor_init, 0, 0x21), - SENS(initPas106, pas106_sensor_init, F_SIF, 0), - SENS(initPas202, pas202_sensor_init, 0, 0), - SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0), - SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0), - SENS(initTas5130, tas5130_sensor_init, 0, 0), -}; - -/* get one byte in gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 value) -{ - int res; - - if (gspca_dev->usb_err < 0) - return; - - res = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, - 0, /* index */ - gspca_dev->usb_buf, 1, - 500); - - if (res < 0) { - dev_err(gspca_dev->v4l2_dev.dev, - "Error reading register %02x: %d\n", value, res); - gspca_dev->usb_err = res; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, - __u16 value, - const __u8 *buffer, - int len) -{ - int res; - - if (gspca_dev->usb_err < 0) - return; - - memcpy(gspca_dev->usb_buf, buffer, len); - res = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, - 0, /* index */ - gspca_dev->usb_buf, len, - 500); - - if (res < 0) { - dev_err(gspca_dev->v4l2_dev.dev, - "Error writing register %02x: %d\n", value, res); - gspca_dev->usb_err = res; - } -} - -static void i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) -{ - int retry = 60; - - if (gspca_dev->usb_err < 0) - return; - - /* is i2c ready */ - reg_w(gspca_dev, 0x08, buffer, 8); - while (retry--) { - if (gspca_dev->usb_err < 0) - return; - msleep(10); - reg_r(gspca_dev, 0x08); - if (gspca_dev->usb_buf[0] & 0x04) { - if (gspca_dev->usb_buf[0] & 0x08) { - dev_err(gspca_dev->v4l2_dev.dev, - "i2c write error\n"); - gspca_dev->usb_err = -EIO; - } - return; - } - } - - dev_err(gspca_dev->v4l2_dev.dev, "i2c write timeout\n"); - gspca_dev->usb_err = -EIO; -} - -static void i2c_w_vector(struct gspca_dev *gspca_dev, - const __u8 buffer[][8], int len) -{ - for (;;) { - if (gspca_dev->usb_err < 0) - return; - reg_w(gspca_dev, 0x08, *buffer, 8); - len -= 8; - if (len <= 0) - break; - buffer++; - } -} - -static void setbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { - case SENSOR_OV6650: - case SENSOR_OV7630: { - __u8 i2cOV[] = - {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; - - /* change reg 0x06 */ - i2cOV[1] = sensor_data[sd->sensor].sensor_addr; - i2cOV[3] = sd->brightness->val; - i2c_w(gspca_dev, i2cOV); - break; - } - case SENSOR_PAS106: - case SENSOR_PAS202: { - __u8 i2cpbright[] = - {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16}; - __u8 i2cpdoit[] = - {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16}; - - /* PAS106 uses reg 7 and 8 instead of b and c */ - if (sd->sensor == SENSOR_PAS106) { - i2cpbright[2] = 7; - i2cpdoit[2] = 0x13; - } - - if (sd->brightness->val < 127) { - /* change reg 0x0b, signreg */ - i2cpbright[3] = 0x01; - /* set reg 0x0c, offset */ - i2cpbright[4] = 127 - sd->brightness->val; - } else - i2cpbright[4] = sd->brightness->val - 127; - - i2c_w(gspca_dev, i2cpbright); - i2c_w(gspca_dev, i2cpdoit); - break; - } - default: - break; - } -} - -static void setgain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 gain = gspca_dev->gain->val; - - switch (sd->sensor) { - case SENSOR_HV7131D: { - __u8 i2c[] = - {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; - - i2c[3] = 0x3f - gain; - i2c[4] = 0x3f - gain; - i2c[5] = 0x3f - gain; - - i2c_w(gspca_dev, i2c); - break; - } - case SENSOR_TAS5110C: - case SENSOR_TAS5130CXX: { - __u8 i2c[] = - {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; - - i2c[4] = 255 - gain; - i2c_w(gspca_dev, i2c); - break; - } - case SENSOR_TAS5110D: { - __u8 i2c[] = { - 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 }; - gain = 255 - gain; - /* The bits in the register are the wrong way around!! */ - i2c[3] |= (gain & 0x80) >> 7; - i2c[3] |= (gain & 0x40) >> 5; - i2c[3] |= (gain & 0x20) >> 3; - i2c[3] |= (gain & 0x10) >> 1; - i2c[3] |= (gain & 0x08) << 1; - i2c[3] |= (gain & 0x04) << 3; - i2c[3] |= (gain & 0x02) << 5; - i2c[3] |= (gain & 0x01) << 7; - i2c_w(gspca_dev, i2c); - break; - } - case SENSOR_OV6650: - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - - /* - * The ov7630's gain is weird, at 32 the gain drops to the - * same level as at 16, so skip 32-47 (of the 0-63 scale). - */ - if (sd->sensor == SENSOR_OV7630 && gain >= 32) - gain += 16; - - i2c[1] = sensor_data[sd->sensor].sensor_addr; - i2c[3] = gain; - i2c_w(gspca_dev, i2c); - break; - } - case SENSOR_PAS106: - case SENSOR_PAS202: { - __u8 i2cpgain[] = - {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15}; - __u8 i2cpcolorgain[] = - {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15}; - __u8 i2cpdoit[] = - {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16}; - - /* PAS106 uses different regs (and has split green gains) */ - if (sd->sensor == SENSOR_PAS106) { - i2cpgain[2] = 0x0e; - i2cpcolorgain[0] = 0xd0; - i2cpcolorgain[2] = 0x09; - i2cpdoit[2] = 0x13; - } - - i2cpgain[3] = gain; - i2cpcolorgain[3] = gain >> 1; - i2cpcolorgain[4] = gain >> 1; - i2cpcolorgain[5] = gain >> 1; - i2cpcolorgain[6] = gain >> 1; - - i2c_w(gspca_dev, i2cpgain); - i2c_w(gspca_dev, i2cpcolorgain); - i2c_w(gspca_dev, i2cpdoit); - break; - } - default: - if (sd->bridge == BRIDGE_103) { - u8 buf[3] = { gain, gain, gain }; /* R, G, B */ - reg_w(gspca_dev, 0x05, buf, 3); - } else { - u8 buf[2]; - buf[0] = gain << 4 | gain; /* Red and blue */ - buf[1] = gain; /* Green */ - reg_w(gspca_dev, 0x10, buf, 2); - } - } -} - -static void setexposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { - case SENSOR_HV7131D: { - /* Note the datasheet wrongly says line mode exposure uses reg - 0x26 and 0x27, testing has shown 0x25 + 0x26 */ - __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17}; - u16 reg = gspca_dev->exposure->val; - - i2c[3] = reg >> 8; - i2c[4] = reg & 0xff; - i2c_w(gspca_dev, i2c); - break; - } - case SENSOR_TAS5110C: - case SENSOR_TAS5110D: { - /* register 19's high nibble contains the sn9c10x clock divider - The high nibble configures the no fps according to the - formula: 60 / high_nibble. With a maximum of 30 fps */ - u8 reg = gspca_dev->exposure->val; - - reg = (reg << 4) | 0x0b; - reg_w(gspca_dev, 0x19, ®, 1); - break; - } - case SENSOR_OV6650: - case SENSOR_OV7630: { - /* The ov6650 / ov7630 have 2 registers which both influence - exposure, register 11, whose low nibble sets the nr off fps - according to: fps = 30 / (low_nibble + 1) - - The fps configures the maximum exposure setting, but it is - possible to use less exposure then what the fps maximum - allows by setting register 10. register 10 configures the - actual exposure as quotient of the full exposure, with 0 - being no exposure at all (not very useful) and reg10_max - being max exposure possible at that framerate. - - The code maps our 0 - 510 ms exposure ctrl to these 2 - registers, trying to keep fps as high as possible. - */ - __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}; - int reg10, reg11, reg10_max; - - /* ov6645 datasheet says reg10_max is 9a, but that uses - tline * 2 * reg10 as formula for calculating texpo, the - ov6650 probably uses the same formula as the 7730 which uses - tline * 4 * reg10, which explains why the reg10max we've - found experimentally for the ov6650 is exactly half that of - the ov6645. The ov7630 datasheet says the max is 0x41. */ - if (sd->sensor == SENSOR_OV6650) { - reg10_max = 0x4d; - i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */ - } else - reg10_max = 0x41; - - reg11 = (15 * gspca_dev->exposure->val + 999) / 1000; - if (reg11 < 1) - reg11 = 1; - else if (reg11 > 16) - reg11 = 16; - - /* In 640x480, if the reg11 has less than 4, the image is - unstable (the bridge goes into a higher compression mode - which we have not reverse engineered yet). */ - if (gspca_dev->width == 640 && reg11 < 4) - reg11 = 4; - - /* frame exposure time in ms = 1000 * reg11 / 30 -> - reg10 = (gspca_dev->exposure->val / 2) * reg10_max - / (1000 * reg11 / 30) */ - reg10 = (gspca_dev->exposure->val * 15 * reg10_max) - / (1000 * reg11); - - /* Don't allow this to get below 10 when using autogain, the - steps become very large (relatively) when below 10 causing - the image to oscilate from much too dark, to much too bright - and back again. */ - if (gspca_dev->autogain->val && reg10 < 10) - reg10 = 10; - else if (reg10 > reg10_max) - reg10 = reg10_max; - - /* Write reg 10 and reg11 low nibble */ - i2c[1] = sensor_data[sd->sensor].sensor_addr; - i2c[3] = reg10; - i2c[4] |= reg11 - 1; - - /* If register 11 didn't change, don't change it */ - if (sd->reg11 == reg11) - i2c[0] = 0xa0; - - i2c_w(gspca_dev, i2c); - if (gspca_dev->usb_err == 0) - sd->reg11 = reg11; - break; - } - case SENSOR_PAS202: { - __u8 i2cpframerate[] = - {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16}; - __u8 i2cpexpo[] = - {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16}; - const __u8 i2cpdoit[] = - {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16}; - int framerate_ctrl; - - /* The exposure knee for the autogain algorithm is 200 - (100 ms / 10 fps on other sensors), for values below this - use the control for setting the partial frame expose time, - above that use variable framerate. This way we run at max - framerate (640x480@7.5 fps, 320x240@10fps) until the knee - is reached. Using the variable framerate control above 200 - is better then playing around with both clockdiv + partial - frame exposure times (like we are doing with the ov chips), - as that sometimes leads to jumps in the exposure control, - which are bad for auto exposure. */ - if (gspca_dev->exposure->val < 200) { - i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255) - / 200; - framerate_ctrl = 500; - } else { - /* The PAS202's exposure control goes from 0 - 4095, - but anything below 500 causes vsync issues, so scale - our 200-1023 to 500-4095 */ - framerate_ctrl = (gspca_dev->exposure->val - 200) - * 1000 / 229 + 500; - } - - i2cpframerate[3] = framerate_ctrl >> 6; - i2cpframerate[4] = framerate_ctrl & 0x3f; - i2c_w(gspca_dev, i2cpframerate); - i2c_w(gspca_dev, i2cpexpo); - i2c_w(gspca_dev, i2cpdoit); - break; - } - case SENSOR_PAS106: { - __u8 i2cpframerate[] = - {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14}; - __u8 i2cpexpo[] = - {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14}; - const __u8 i2cpdoit[] = - {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14}; - int framerate_ctrl; - - /* For values below 150 use partial frame exposure, above - that use framerate ctrl */ - if (gspca_dev->exposure->val < 150) { - i2cpexpo[3] = 150 - gspca_dev->exposure->val; - framerate_ctrl = 300; - } else { - /* The PAS106's exposure control goes from 0 - 4095, - but anything below 300 causes vsync issues, so scale - our 150-1023 to 300-4095 */ - framerate_ctrl = (gspca_dev->exposure->val - 150) - * 1000 / 230 + 300; - } - - i2cpframerate[3] = framerate_ctrl >> 4; - i2cpframerate[4] = framerate_ctrl & 0x0f; - i2c_w(gspca_dev, i2cpframerate); - i2c_w(gspca_dev, i2cpexpo); - i2c_w(gspca_dev, i2cpdoit); - break; - } - default: - break; - } -} - -static void setfreq(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) { - /* Framerate adjust register for artificial light 50 hz flicker - compensation, for the ov6650 this is identical to ov6630 - 0x2b register, see ov6630 datasheet. - 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ - __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; - switch (sd->plfreq->val) { - default: -/* case 0: * no filter*/ -/* case 2: * 60 hz */ - i2c[3] = 0; - break; - case 1: /* 50 hz */ - i2c[3] = (sd->sensor == SENSOR_OV6650) - ? 0x4f : 0x8a; - break; - } - i2c[1] = sensor_data[sd->sensor].sensor_addr; - i2c_w(gspca_dev, i2c); - } -} - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int deadzone, desired_avg_lum, avg_lum; - - avg_lum = atomic_read(&sd->avg_lum); - if (avg_lum == -1) - return; - - if (sd->autogain_ignore_frames > 0) { - sd->autogain_ignore_frames--; - return; - } - - /* SIF / VGA sensors have a different autoexposure area and thus - different avg_lum values for the same picture brightness */ - if (sensor_data[sd->sensor].flags & F_SIF) { - deadzone = 500; - /* SIF sensors tend to overexpose, so keep this small */ - desired_avg_lum = 5000; - } else { - deadzone = 1500; - desired_avg_lum = 13000; - } - - if (sd->brightness) - desired_avg_lum = sd->brightness->val * desired_avg_lum / 127; - - if (gspca_dev->exposure->maximum < 500) { - if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, - desired_avg_lum, deadzone)) - sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; - } else { - int gain_knee = gspca_dev->gain->maximum * 9 / 10; - if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum, - deadzone, gain_knee, sd->exposure_knee)) - sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - reg_r(gspca_dev, 0x00); - if (gspca_dev->usb_buf[0] != 0x10) - return -ENODEV; - - /* copy the webcam info from the device id */ - sd->sensor = id->driver_info >> 8; - sd->bridge = id->driver_info & 0xff; - - cam = &gspca_dev->cam; - if (!(sensor_data[sd->sensor].flags & F_SIF)) { - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - } else { - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - } - cam->npkt = 36; /* 36 packets per ISOC message */ - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - const __u8 stop = 0x09; /* Disable stream turn of LED */ - - reg_w(gspca_dev, 0x01, &stop, 1); - - return gspca_dev->usb_err; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) { - /* when switching to autogain set defaults to make sure - we are on a valid point of the autogain gain / - exposure knee graph, and give this change time to - take effect before doing autogain. */ - gspca_dev->gain->val = gspca_dev->gain->default_value; - gspca_dev->exposure->val = gspca_dev->exposure->default_value; - sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev); - break; - case V4L2_CID_AUTOGAIN: - if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val)) - setexposure(gspca_dev); - if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val)) - setgain(gspca_dev); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setfreq(gspca_dev); - break; - default: - return -EINVAL; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -/* this function is called at probe time */ -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - - if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 || - sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202) - sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); - - /* Gain range is sensor dependent */ - switch (sd->sensor) { - case SENSOR_OV6650: - case SENSOR_PAS106: - case SENSOR_PAS202: - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 31, 1, 15); - break; - case SENSOR_OV7630: - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 47, 1, 31); - break; - case SENSOR_HV7131D: - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 63, 1, 31); - break; - case SENSOR_TAS5110C: - case SENSOR_TAS5110D: - case SENSOR_TAS5130CXX: - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 127); - break; - default: - if (sd->bridge == BRIDGE_103) { - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 127, 1, 63); - } else { - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 15, 1, 7); - } - } - - /* Exposure range is sensor dependent, and not all have exposure */ - switch (sd->sensor) { - case SENSOR_HV7131D: - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 8191, 1, 482); - sd->exposure_knee = 964; - break; - case SENSOR_OV6650: - case SENSOR_OV7630: - case SENSOR_PAS106: - case SENSOR_PAS202: - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 1023, 1, 66); - sd->exposure_knee = 200; - break; - case SENSOR_TAS5110C: - case SENSOR_TAS5110D: - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 2, 15, 1, 2); - break; - } - - if (gspca_dev->exposure) { - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - } - - if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630) - sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, - V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - if (gspca_dev->autogain) - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - int i, mode; - __u8 regs[0x31]; - - mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; - /* Copy registers 0x01 - 0x19 from the template */ - memcpy(®s[0x01], sensor_data[sd->sensor].bridge_init, 0x19); - /* Set the mode */ - regs[0x18] |= mode << 4; - - /* Set bridge gain to 1.0 */ - if (sd->bridge == BRIDGE_103) { - regs[0x05] = 0x20; /* Red */ - regs[0x06] = 0x20; /* Green */ - regs[0x07] = 0x20; /* Blue */ - } else { - regs[0x10] = 0x00; /* Red and blue */ - regs[0x11] = 0x00; /* Green */ - } - - /* Setup pixel numbers and auto exposure window */ - if (sensor_data[sd->sensor].flags & F_SIF) { - regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */ - regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */ - regs[0x1c] = 0x02; /* AE H-start 64 */ - regs[0x1d] = 0x02; /* AE V-start 64 */ - regs[0x1e] = 0x09; /* AE H-end 288 */ - regs[0x1f] = 0x07; /* AE V-end 224 */ - } else { - regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */ - regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */ - regs[0x1c] = 0x05; /* AE H-start 160 */ - regs[0x1d] = 0x03; /* AE V-start 96 */ - regs[0x1e] = 0x0f; /* AE H-end 480 */ - regs[0x1f] = 0x0c; /* AE V-end 384 */ - } - - /* Setup the gamma table (only used with the sn9c103 bridge) */ - for (i = 0; i < 16; i++) - regs[0x20 + i] = i * 16; - regs[0x20 + i] = 255; - - /* Special cases where some regs depend on mode or bridge */ - switch (sd->sensor) { - case SENSOR_TAS5130CXX: - /* FIXME / TESTME - probably not mode specific at all most likely the upper - nibble of 0x19 is exposure (clock divider) just as with - the tas5110, we need someone to test this. */ - regs[0x19] = mode ? 0x23 : 0x43; - break; - case SENSOR_OV7630: - /* FIXME / TESTME for some reason with the 101/102 bridge the - clock is set to 12 Mhz (reg1 == 0x04), rather then 24. - Also the hstart needs to go from 1 to 2 when using a 103, - which is likely related. This does not seem right. */ - if (sd->bridge == BRIDGE_103) { - regs[0x01] = 0x44; /* Select 24 Mhz clock */ - regs[0x12] = 0x02; /* Set hstart to 2 */ - } - } - /* Disable compression when the raw bayer format has been selected */ - if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) - regs[0x18] &= ~0x80; - - /* Vga mode emulation on SIF sensor? */ - if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { - regs[0x12] += 16; /* hstart adjust */ - regs[0x13] += 24; /* vstart adjust */ - regs[0x15] = 320 / 16; /* hsize */ - regs[0x16] = 240 / 16; /* vsize */ - } - - /* reg 0x01 bit 2 video transfert on */ - reg_w(gspca_dev, 0x01, ®s[0x01], 1); - /* reg 0x17 SensorClk enable inv Clk 0x60 */ - reg_w(gspca_dev, 0x17, ®s[0x17], 1); - /* Set the registers from the template */ - reg_w(gspca_dev, 0x01, ®s[0x01], - (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f); - - /* Init the sensor */ - i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, - sensor_data[sd->sensor].sensor_init_size); - - /* Mode / bridge specific sensor setup */ - switch (sd->sensor) { - case SENSOR_PAS202: { - const __u8 i2cpclockdiv[] = - {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}; - /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */ - if (mode) - i2c_w(gspca_dev, i2cpclockdiv); - break; - } - case SENSOR_OV7630: - /* FIXME / TESTME We should be able to handle this identical - for the 101/102 and the 103 case */ - if (sd->bridge == BRIDGE_103) { - const __u8 i2c[] = { 0xa0, 0x21, 0x13, - 0x80, 0x00, 0x00, 0x00, 0x10 }; - i2c_w(gspca_dev, i2c); - } - break; - } - /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ - reg_w(gspca_dev, 0x15, ®s[0x15], 2); - /* compression register */ - reg_w(gspca_dev, 0x18, ®s[0x18], 1); - /* H_start */ - reg_w(gspca_dev, 0x12, ®s[0x12], 1); - /* V_START */ - reg_w(gspca_dev, 0x13, ®s[0x13], 1); - /* reset 0x17 SensorClk enable inv Clk 0x60 */ - /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ - reg_w(gspca_dev, 0x17, ®s[0x17], 1); - /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - reg_w(gspca_dev, 0x19, ®s[0x19], 1); - /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ - reg_w(gspca_dev, 0x1c, ®s[0x1c], 4); - /* Enable video transfert */ - reg_w(gspca_dev, 0x01, ®s[0x01], 1); - /* Compression */ - reg_w(gspca_dev, 0x18, ®s[0x18], 2); - msleep(20); - - sd->reg11 = -1; - - setgain(gspca_dev); - setbrightness(gspca_dev); - setexposure(gspca_dev); - setfreq(gspca_dev); - - sd->frames_to_drop = 0; - sd->autogain_ignore_frames = 0; - gspca_dev->exp_too_high_cnt = 0; - gspca_dev->exp_too_low_cnt = 0; - atomic_set(&sd->avg_lum, -1); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - sd_init(gspca_dev); -} - -static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12; - - /* frames start with: - * ff ff 00 c4 c4 96 synchro - * 00 (unknown) - * xx (frame sequence / size / compression) - * (xx) (idem - extra byte for sn9c103) - * ll mm brightness sum inside auto exposure - * ll mm brightness sum outside auto exposure - * (xx xx xx xx xx) audio values for snc103 - */ - for (i = 0; i < len; i++) { - switch (sd->header_read) { - case 0: - if (data[i] == 0xff) - sd->header_read++; - break; - case 1: - if (data[i] == 0xff) - sd->header_read++; - else - sd->header_read = 0; - break; - case 2: - if (data[i] == 0x00) - sd->header_read++; - else if (data[i] != 0xff) - sd->header_read = 0; - break; - case 3: - if (data[i] == 0xc4) - sd->header_read++; - else if (data[i] == 0xff) - sd->header_read = 1; - else - sd->header_read = 0; - break; - case 4: - if (data[i] == 0xc4) - sd->header_read++; - else if (data[i] == 0xff) - sd->header_read = 1; - else - sd->header_read = 0; - break; - case 5: - if (data[i] == 0x96) - sd->header_read++; - else if (data[i] == 0xff) - sd->header_read = 1; - else - sd->header_read = 0; - break; - default: - sd->header[sd->header_read - 6] = data[i]; - sd->header_read++; - if (sd->header_read == header_size) { - sd->header_read = 0; - return data + i + 1; - } - } - } - return NULL; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0; - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - u8 *sof; - - sof = find_sof(gspca_dev, data, len); - if (sof) { - if (sd->bridge == BRIDGE_103) { - fr_h_sz = 18; - lum_offset = 3; - } else { - fr_h_sz = 12; - lum_offset = 2; - } - - len_after_sof = len - (sof - data); - len = (sof - data) - fr_h_sz; - if (len < 0) - len = 0; - } - - if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { - /* In raw mode we sometimes get some garbage after the frame - ignore this */ - int used; - int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; - - used = gspca_dev->image_len; - if (used + len > size) - len = size - used; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - - if (sof) { - int lum = sd->header[lum_offset] + - (sd->header[lum_offset + 1] << 8); - - /* When exposure changes midway a frame we - get a lum of 0 in this case drop 2 frames - as the frames directly after an exposure - change have an unstable image. Sometimes lum - *really* is 0 (cam used in low light with - low exposure setting), so do not drop frames - if the previous lum was 0 too. */ - if (lum == 0 && sd->prev_avg_lum != 0) { - lum = -1; - sd->frames_to_drop = 2; - sd->prev_avg_lum = 0; - } else - sd->prev_avg_lum = lum; - atomic_set(&sd->avg_lum, lum); - - if (sd->frames_to_drop) - sd->frames_to_drop--; - else - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof); - } -} - -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - switch (menu->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - } - break; - } - return -EINVAL; -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrupt packet length */ -{ - int ret = -EINVAL; - - if (len == 1 && data[0] == 1) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - return ret; -} -#endif - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .querymenu = sd_querymenu, - .dq_callback = do_autogain, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -#define SB(sensor, bridge) \ - .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge - - -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ - {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ - {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ - {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, - {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, - {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, - {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, - {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, -#endif - {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, - {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, - {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)}, - /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */ - {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, - {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, - {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, - /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ - /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */ - {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)}, - {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)}, - /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */ - {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, - {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)}, - {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)}, - {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, - {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c deleted file mode 100644 index 150b2df40f7f..000000000000 --- a/drivers/media/video/gspca/sonixj.c +++ /dev/null @@ -1,3206 +0,0 @@ -/* - * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver - * - * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr> - * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sonixj" - -#include <linux/input.h> -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* controls */ -enum e_ctrl { - BRIGHTNESS, - CONTRAST, - COLORS, - BLUE, - RED, - GAMMA, - EXPOSURE, - AUTOGAIN, - GAIN, - HFLIP, - VFLIP, - SHARPNESS, - ILLUM, - FREQ, - NCTRLS /* number of controls */ -}; - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct gspca_ctrl ctrls[NCTRLS]; - - atomic_t avg_lum; - u32 exposure; - - struct work_struct work; - struct workqueue_struct *work_thread; - - u32 pktsz; /* (used by pkt_scan) */ - u16 npkt; - s8 nchg; - s8 short_mark; - - u8 quality; /* image quality */ -#define QUALITY_MIN 25 -#define QUALITY_MAX 90 -#define QUALITY_DEF 70 - - u8 reg01; - u8 reg17; - u8 reg18; - u8 flags; - - s8 ag_cnt; -#define AG_CNT_START 13 - - u8 bridge; -#define BRIDGE_SN9C102P 0 -#define BRIDGE_SN9C105 1 -#define BRIDGE_SN9C110 2 -#define BRIDGE_SN9C120 3 - u8 sensor; /* Type of image sensor chip */ - u8 i2c_addr; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; -enum sensors { - SENSOR_ADCM1700, - SENSOR_GC0307, - SENSOR_HV7131R, - SENSOR_MI0360, - SENSOR_MI0360B, - SENSOR_MO4000, - SENSOR_MT9V111, - SENSOR_OM6802, - SENSOR_OV7630, - SENSOR_OV7648, - SENSOR_OV7660, - SENSOR_PO1030, - SENSOR_PO2030N, - SENSOR_SOI768, - SENSOR_SP80708, -}; - -static void qual_upd(struct work_struct *work); - -/* device flags */ -#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */ -#define F_ILLUM 0x02 /* presence of illuminator */ - -/* sn9c1xx definitions */ -/* register 0x01 */ -#define S_PWR_DN 0x01 /* sensor power down */ -#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */ -#define V_TX_EN 0x04 /* video transfer enable */ -#define LED 0x08 /* output to pin LED */ -#define SCL_SEL_OD 0x20 /* open-drain mode */ -#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */ -/* register 0x17 */ -#define MCK_SIZE_MASK 0x1f /* sensor master clock */ -#define SEN_CLK_EN 0x20 /* enable sensor clock */ -#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ - -/* V4L2 controls supported by the driver */ -static void setbrightness(struct gspca_dev *gspca_dev); -static void setcontrast(struct gspca_dev *gspca_dev); -static void setcolors(struct gspca_dev *gspca_dev); -static void setredblue(struct gspca_dev *gspca_dev); -static void setgamma(struct gspca_dev *gspca_dev); -static void setexposure(struct gspca_dev *gspca_dev); -static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); -static void setgain(struct gspca_dev *gspca_dev); -static void sethvflip(struct gspca_dev *gspca_dev); -static void setsharpness(struct gspca_dev *gspca_dev); -static void setillum(struct gspca_dev *gspca_dev); -static void setfreq(struct gspca_dev *gspca_dev); - -static const struct ctrl sd_ctrls[NCTRLS] = { -[BRIGHTNESS] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x80, - }, - .set_control = setbrightness - }, -[CONTRAST] = { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, -#define CONTRAST_MAX 127 - .maximum = CONTRAST_MAX, - .step = 1, - .default_value = 20, - }, - .set_control = setcontrast - }, -[COLORS] = { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 40, - .step = 1, -#define COLORS_DEF 25 - .default_value = COLORS_DEF, - }, - .set_control = setcolors - }, -[BLUE] = { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Balance", - .minimum = 24, - .maximum = 40, - .step = 1, - .default_value = 32, - }, - .set_control = setredblue - }, -[RED] = { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Balance", - .minimum = 24, - .maximum = 40, - .step = 1, - .default_value = 32, - }, - .set_control = setredblue - }, -[GAMMA] = { - { - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0, - .maximum = 40, - .step = 1, -#define GAMMA_DEF 20 - .default_value = GAMMA_DEF, - }, - .set_control = setgamma - }, -[EXPOSURE] = { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 500, - .maximum = 1500, - .step = 1, - .default_value = 1024 - }, - .set_control = setexposure - }, -[AUTOGAIN] = { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Gain", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = sd_setautogain, - }, -[GAIN] = { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 4, - .maximum = 49, - .step = 1, - .default_value = 15 - }, - .set_control = setgain - }, -[HFLIP] = { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = sethvflip - }, -[VFLIP] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vflip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = sethvflip - }, -[SHARPNESS] = { - { - .id = V4L2_CID_SHARPNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Sharpness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 90, - }, - .set_control = setsharpness - }, -[ILLUM] = { - { - .id = V4L2_CID_ILLUMINATORS_1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Illuminator / infrared", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = setillum - }, -/* ov7630/ov7648/ov7660 only */ -[FREQ] = { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light frequency filter", - .minimum = 0, - .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ - .step = 1, - .default_value = 1, - }, - .set_control = setfreq - }, -}; - -/* table of the disabled controls */ -static const __u32 ctrl_dis[] = { -[SENSOR_ADCM1700] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_GC0307] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_HV7131R] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << FREQ), - -[SENSOR_MI0360] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MI0360B] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MO4000] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_MT9V111] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_OM6802] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_OV7630] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP), - -[SENSOR_OV7648] = (1 << EXPOSURE) | - (1 << GAIN) | - (1 << HFLIP), - -[SENSOR_OV7660] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP), - -[SENSOR_PO1030] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_PO2030N] = (1 << FREQ), - -[SENSOR_SOI768] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), - -[SENSOR_SP80708] = (1 << EXPOSURE) | - (1 << AUTOGAIN) | - (1 << GAIN) | - (1 << HFLIP) | - (1 << VFLIP) | - (1 << FREQ), -}; - -static const struct v4l2_pix_format cif_mode[] = { - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */ - .sizeimage = 640 * 480 * 3 / 4 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const u8 sn_adcm1700[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_gc0307[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_hv7131[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, -/* reg18 reg19 reg1a reg1b */ - 0x0a, 0x00, 0x00, 0x00 -}; - -static const u8 sn_mi0360[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_mi0360b[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_mo4000[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x08, 0x00, 0x00, 0x00 -}; - -static const u8 sn_mt9v111[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_om6802[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x05, 0x00, 0x00, 0x00 -}; - -static const u8 sn_ov7630[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, -/* reg18 reg19 reg1a reg1b */ - 0x0b, 0x00, 0x00, 0x00 -}; - -static const u8 sn_ov7648[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x0b, 0x00, 0x00, 0x00 -}; - -static const u8 sn_ov7660[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -static const u8 sn_po1030[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -static const u8 sn_po2030n[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -static const u8 sn_soi768[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -static const u8 sn_sp80708[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -/* sequence specific to the sensors - !! index = SENSOR_xxx */ -static const u8 *sn_tb[] = { -[SENSOR_ADCM1700] = sn_adcm1700, -[SENSOR_GC0307] = sn_gc0307, -[SENSOR_HV7131R] = sn_hv7131, -[SENSOR_MI0360] = sn_mi0360, -[SENSOR_MI0360B] = sn_mi0360b, -[SENSOR_MO4000] = sn_mo4000, -[SENSOR_MT9V111] = sn_mt9v111, -[SENSOR_OM6802] = sn_om6802, -[SENSOR_OV7630] = sn_ov7630, -[SENSOR_OV7648] = sn_ov7648, -[SENSOR_OV7660] = sn_ov7660, -[SENSOR_PO1030] = sn_po1030, -[SENSOR_PO2030N] = sn_po2030n, -[SENSOR_SOI768] = sn_soi768, -[SENSOR_SP80708] = sn_sp80708, -}; - -/* default gamma table */ -static const u8 gamma_def[17] = { - 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, - 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff -}; -/* gamma for sensor ADCM1700 */ -static const u8 gamma_spec_0[17] = { - 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4, - 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5 -}; -/* gamma for sensors HV7131R and MT9V111 */ -static const u8 gamma_spec_1[17] = { - 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, - 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 -}; -/* gamma for sensor GC0307 */ -static const u8 gamma_spec_2[17] = { - 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab, - 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb -}; -/* gamma for sensor SP80708 */ -static const u8 gamma_spec_3[17] = { - 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, - 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 -}; - -/* color matrix and offsets */ -static const u8 reg84[] = { - 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */ - 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */ - 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ - 0x00, 0x00, 0x00 /* YUV offsets */ -}; - -#define DELAY 0xdd - -static const u8 adcm1700_sensor_init[][8] = { - {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */ - {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 adcm1700_sensor_param1[][8] = { - {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */ - {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10}, - - {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10}, - {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */ - - {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10}, - {} -}; -static const u8 gc0307_sensor_init[][8] = { - {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/ - {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 gc0307_sensor_param1[][8] = { - {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10}, - {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10}, - {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10}, - {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10}, -/*param3*/ - {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10}, - {} -}; - -static const u8 hv7131r_sensor_init[][8] = { - {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, - {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10}, -/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */ - {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10}, -/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */ - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10}, - {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10}, - {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10}, - {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ - {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10}, - /* set sensor clock */ - {} -}; -static const u8 mi0360_sensor_init[][8] = { - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, - {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, - {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, - {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10}, - {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, - {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10}, - {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, - {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10}, - {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, - - {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10}, - - {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ - {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ - - {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */ -/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ -/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ - {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ - {} -}; -static const u8 mi0360b_sensor_init[][8] = { - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/ - {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/ - {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, - {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, - {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, - {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10}, - {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, - {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10}, - {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, - {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10}, - {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, - - {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, - {} -}; -static const u8 mi0360b_sensor_param1[][8] = { - {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ - - {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10}, - {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ - {} -}; -static const u8 mo4000_sensor_init[][8] = { - {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 mt9v111_sensor_init[][8] = { - {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ - {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ - {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ - {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ - {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ - {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ - {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ - {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */ - {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */ - {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */ - {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */ - {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 mt9v111_sensor_param1[][8] = { - {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */ - {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */ - {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */ - {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */ - {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ - {} -}; -static const u8 om6802_init0[2][8] = { -/*fixme: variable*/ - {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10}, -}; -static const u8 om6802_sensor_init[][8] = { - {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10}, - /* factory mode */ - {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10}, - /* output raw RGB */ - {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, -/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */ - {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10}, - /* auto-exposure speed (0) / white balance mode (auto RGB) */ -/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10}, - * set color mode */ -/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10}, - * max AGC value in AE */ -/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10}, - * preset AGC */ -/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10}, - * preset brightness */ -/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10}, - * preset contrast */ -/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10}, - * preset gamma */ - {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10}, - /* luminance mode (0x4f -> AutoExpo on) */ - {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10}, - /* preset shutter */ -/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10}, - * auto frame rate */ -/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */ - {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 om6802_sensor_param1[][8] = { - {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 ov7630_sensor_init[][8] = { - {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, -/* win: i2c_r from 00 to 80 */ - {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, - {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10}, -/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30) - 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */ - {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10}, - {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, - {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10}, - {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10}, - {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10}, - {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10}, - {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10}, - {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10}, - {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10}, - {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10}, - {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10}, - {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10}, - {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10}, - {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, - {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 ov7630_sensor_param1[][8] = { - {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, -/*fixme: + 0x12, 0x04*/ -/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN - * set by setvflip */ - {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, -/* */ -/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */ -/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */ -/* */ - {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, -/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ - {} -}; - -static const u8 ov7648_sensor_init[][8] = { - {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10}, - {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10}, - {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10}, - {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10}, - {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10}, - {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10}, - {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10}, - {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10}, - {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10}, - {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10}, - {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10}, - {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10}, - {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10}, - {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10}, - {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10}, - {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10}, - - {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10}, -/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ -/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ -/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */ - {} -}; -static const u8 ov7648_sensor_param1[][8] = { -/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN - * set by setvflip */ - {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, -/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */ -/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */ -/*...*/ - {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */ -/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */ - - {} -}; - -static const u8 ov7660_sensor_init[][8] = { - {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, - /* Outformat = rawRGB */ - {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ - {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, - /* GAIN BLUE RED VREF */ - {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, - /* COM 1 BAVE GEAVE AECHH */ - {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ - {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ - {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, - /* AECH CLKRC COM7 COM8 */ - {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ - {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, - /* HSTART HSTOP VSTRT VSTOP */ - {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */ - {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ - {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, - /* BOS GBOS GROS ROS (BGGR offset) */ -/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */ - {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, - /* AEW AEB VPT BBIAS */ - {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, - /* GbBIAS RSVD EXHCH EXHCL */ - {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10}, - /* RBIAS ADVFL ASDVFH YAVE */ - {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10}, - /* HSYST HSYEN HREF */ - {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */ - {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10}, - /* ADC ACOM OFON TSLB */ - {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10}, - /* COM11 COM12 COM13 COM14 */ - {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10}, - /* EDGE COM15 COM16 COM17 */ - {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */ - {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */ - {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */ - {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */ - {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */ - {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */ - {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */ - {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */ - {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */ - {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, - /* LCC1 LCC2 LCC3 LCC4 */ - {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ - {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */ - {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, - /* band gap reference [0:3] DBLV */ - {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */ - {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ - {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ - {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ - {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ -/* not in all ms-win traces*/ - {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 ov7660_sensor_param1[][8] = { - {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ - /* bits[3..0]reserved */ - {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, - /* VREF vertical frame ctrl */ - {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */ - {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */ - {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */ - {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ -/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ -/****** (some exchanges in the win trace) ******/ -/*fixme:param2*/ - {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ - {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ - {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ - {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */ -/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ -/****** (some exchanges in the win trace) ******/ -/******!! startsensor KO if changed !!****/ -/*fixme: param3*/ - {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, - {} -}; - -static const u8 po1030_sensor_init[][8] = { -/* the sensor registers are described in m5602/m5602_po1030.h */ - {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */ - {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */ - {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10}, - {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10}, - {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10}, - {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */ - {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10}, - {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */ - {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10}, - {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */ - {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10}, - {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10}, - {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10}, - {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10}, - {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10}, - {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10}, - {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */ - {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10}, - - {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10}, - {} -}; -static const u8 po1030_sensor_param1[][8] = { -/* from ms-win traces - these values change with auto gain/expo/wb.. */ - {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10}, -/* mean values */ - {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */ - {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */ - {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */ - - {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */ - {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */ - {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10}, -/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */ - {} -}; - -static const u8 po2030n_sensor_init[][8] = { - {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ - {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ - {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10}, - {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10}, - {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10}, - {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10}, - {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10}, - {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10}, - {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10}, - {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10}, - {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10}, - {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10}, - {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10}, - {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10}, - {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10}, - {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10}, - {} -}; -static const u8 po2030n_sensor_param1[][8] = { - {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10}, - {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ - {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */ -/*param2*/ - {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, - {} -}; - -static const u8 soi768_sensor_init[][8] = { - {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ - {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */ - {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 soi768_sensor_param1[][8] = { - {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10}, -/* */ -/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */ -/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */ - {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, -/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */ - {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10}, -/* the next sequence should be used for auto gain */ - {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10}, - /* global gain ? : 07 - change with 0x15 at the end */ - {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */ - {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x21, 0x2d, 0x63, 0x03, 0x00, 0x00, 0x10}, - /* exposure ? : 0200 - change with 0x1e at the end */ - {} -}; - -static const u8 sp80708_sensor_init[][8] = { - {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, - {} -}; -static const u8 sp80708_sensor_param1[][8] = { - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10}, - {} -}; - -static const u8 (*sensor_init[])[8] = { -[SENSOR_ADCM1700] = adcm1700_sensor_init, -[SENSOR_GC0307] = gc0307_sensor_init, -[SENSOR_HV7131R] = hv7131r_sensor_init, -[SENSOR_MI0360] = mi0360_sensor_init, -[SENSOR_MI0360B] = mi0360b_sensor_init, -[SENSOR_MO4000] = mo4000_sensor_init, -[SENSOR_MT9V111] = mt9v111_sensor_init, -[SENSOR_OM6802] = om6802_sensor_init, -[SENSOR_OV7630] = ov7630_sensor_init, -[SENSOR_OV7648] = ov7648_sensor_init, -[SENSOR_OV7660] = ov7660_sensor_init, -[SENSOR_PO1030] = po1030_sensor_init, -[SENSOR_PO2030N] = po2030n_sensor_init, -[SENSOR_SOI768] = soi768_sensor_init, -[SENSOR_SP80708] = sp80708_sensor_init, -}; - -/* read <len> bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - u16 value, int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); - return; - } -#endif - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, 0, - gspca_dev->usb_buf, len, - 500); - PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w1(struct gspca_dev *gspca_dev, - u16 value, - u8 data) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); - gspca_dev->usb_buf[0] = data; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, - 0, - gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w1 err %d\n", ret); - gspca_dev->usb_err = ret; - } -} -static void reg_w(struct gspca_dev *gspca_dev, - u16 value, - const u8 *buffer, - int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", - value, buffer[0], buffer[1]); -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_w: buffer overflow\n"); - return; - } -#endif - memcpy(gspca_dev->usb_buf, buffer, len); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, 0, - gspca_dev->usb_buf, len, - 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* I2C write 1 byte */ -static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val); - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_OM6802: - case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */ - gspca_dev->usb_buf[0] = 0x80 | (2 << 4); - break; - default: /* i2c command = a1 (400 kHz) */ - gspca_dev->usb_buf[0] = 0x81 | (2 << 4); - break; - } - gspca_dev->usb_buf[1] = sd->i2c_addr; - gspca_dev->usb_buf[2] = reg; - gspca_dev->usb_buf[3] = val; - gspca_dev->usb_buf[4] = 0; - gspca_dev->usb_buf[5] = 0; - gspca_dev->usb_buf[6] = 0; - gspca_dev->usb_buf[7] = 0x10; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x08, /* value = i2c */ - 0, - gspca_dev->usb_buf, 8, - 500); - if (ret < 0) { - pr_err("i2c_w1 err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* I2C write 8 bytes */ -static void i2c_w8(struct gspca_dev *gspca_dev, - const u8 *buffer) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..", - buffer[2], buffer[3]); - memcpy(gspca_dev->usb_buf, buffer, 8); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x08, 0, /* value, index */ - gspca_dev->usb_buf, 8, - 500); - msleep(2); - if (ret < 0) { - pr_err("i2c_w8 err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */ -static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 mode[8]; - - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_OM6802: - case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */ - mode[0] = 0x80 | 0x10; - break; - default: /* i2c command = 91 (400 kHz) */ - mode[0] = 0x81 | 0x10; - break; - } - mode[1] = sd->i2c_addr; - mode[2] = reg; - mode[3] = 0; - mode[4] = 0; - mode[5] = 0; - mode[6] = 0; - mode[7] = 0x10; - i2c_w8(gspca_dev, mode); - msleep(2); - mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02; - mode[2] = 0; - i2c_w8(gspca_dev, mode); - msleep(2); - reg_r(gspca_dev, 0x0a, 5); -} - -static void i2c_w_seq(struct gspca_dev *gspca_dev, - const u8 (*data)[8]) -{ - while ((*data)[0] != 0) { - if ((*data)[0] != DELAY) - i2c_w8(gspca_dev, *data); - else - msleep((*data)[1]); - data++; - } -} - -/* check the ID of the hv7131 sensor */ -/* this sequence is needed because it activates the sensor */ -static void hv7131r_probe(struct gspca_dev *gspca_dev) -{ - i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ - msleep(10); - reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ - msleep(10); - i2c_r(gspca_dev, 0, 5); /* read sensor id */ - if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */ - && gspca_dev->usb_buf[1] == 0x09 - && gspca_dev->usb_buf[2] == 0x01) { - PDEBUG(D_PROBE, "Sensor HV7131R found"); - return; - } - pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], - gspca_dev->usb_buf[2]); -} - -static void mi0360_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, j; - u16 val = 0; - static const u8 probe_tb[][4][8] = { - { /* mi0360 */ - {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10} - }, - { /* mt9v111 */ - {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, - {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} - }, - }; - - for (i = 0; i < ARRAY_SIZE(probe_tb); i++) { - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - for (j = 0; j < 3; j++) - i2c_w8(gspca_dev, probe_tb[i][j]); - msleep(2); - reg_r(gspca_dev, 0x0a, 5); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - if (probe_tb[i][3][0] != 0) - i2c_w8(gspca_dev, probe_tb[i][3]); - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if (val != 0xffff) - break; - } - if (gspca_dev->usb_err < 0) - return; - switch (val) { - case 0x8221: - PDEBUG(D_PROBE, "Sensor mi0360b"); - sd->sensor = SENSOR_MI0360B; - break; - case 0x823a: - PDEBUG(D_PROBE, "Sensor mt9v111"); - sd->sensor = SENSOR_MT9V111; - break; - case 0x8243: - PDEBUG(D_PROBE, "Sensor mi0360"); - break; - default: - PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); - break; - } -} - -static void ov7630_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 val; - - /* check ov76xx */ - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - sd->i2c_addr = 0x21; - i2c_r(gspca_dev, 0x0a, 2); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if (gspca_dev->usb_err < 0) - return; - if (val == 0x7628) { /* soi768 */ - sd->sensor = SENSOR_SOI768; -/*fixme: only valid for 0c45:613e?*/ - gspca_dev->cam.input_flags = - V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP; - PDEBUG(D_PROBE, "Sensor soi768"); - return; - } - PDEBUG(D_PROBE, "Sensor ov%04x", val); -} - -static void ov7648_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 val; - - /* check ov76xx */ - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - sd->i2c_addr = 0x21; - i2c_r(gspca_dev, 0x0a, 2); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if ((val & 0xff00) == 0x7600) { /* ov76xx */ - PDEBUG(D_PROBE, "Sensor ov%04x", val); - return; - } - - /* check po1030 */ - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - sd->i2c_addr = 0x6e; - i2c_r(gspca_dev, 0x00, 2); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if (gspca_dev->usb_err < 0) - return; - if (val == 0x1030) { /* po1030 */ - PDEBUG(D_PROBE, "Sensor po1030"); - sd->sensor = SENSOR_PO1030; - return; - } - pr_err("Unknown sensor %04x\n", val); -} - -/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */ -static void po2030n_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 val; - - /* check gc0307 */ - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - reg_w1(gspca_dev, 0x02, 0x22); - sd->i2c_addr = 0x21; - i2c_r(gspca_dev, 0x00, 1); - val = gspca_dev->usb_buf[4]; - reg_w1(gspca_dev, 0x01, 0x29); /* reset */ - reg_w1(gspca_dev, 0x17, 0x42); - if (val == 0x99) { /* gc0307 (?) */ - PDEBUG(D_PROBE, "Sensor gc0307"); - sd->sensor = SENSOR_GC0307; - return; - } - - /* check po2030n */ - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x0a); - sd->i2c_addr = 0x6e; - i2c_r(gspca_dev, 0x00, 2); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if (gspca_dev->usb_err < 0) - return; - if (val == 0x2030) { - PDEBUG(D_PROBE, "Sensor po2030n"); -/* sd->sensor = SENSOR_PO2030N; */ - } else { - pr_err("Unknown sensor ID %04x\n", val); - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - sd->bridge = id->driver_info >> 16; - sd->sensor = id->driver_info >> 8; - sd->flags = id->driver_info; - - cam = &gspca_dev->cam; - if (sd->sensor == SENSOR_ADCM1700) { - cam->cam_mode = cif_mode; - cam->nmodes = ARRAY_SIZE(cif_mode); - } else { - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - } - cam->npkt = 24; /* 24 packets per ISOC message */ - cam->ctrls = sd->ctrls; - - sd->ag_cnt = -1; - sd->quality = QUALITY_DEF; - - INIT_WORK(&sd->work, qual_upd); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - const u8 *sn9c1xx; - u8 regGpio[] = { 0x29, 0x70 }; /* no audio */ - u8 regF1; - - /* setup a selector by bridge */ - reg_w1(gspca_dev, 0xf1, 0x01); - reg_r(gspca_dev, 0x00, 1); - reg_w1(gspca_dev, 0xf1, 0x00); - reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ - regF1 = gspca_dev->usb_buf[0]; - if (gspca_dev->usb_err < 0) - return gspca_dev->usb_err; - PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); - if (gspca_dev->audio) - regGpio[1] |= 0x04; /* with audio */ - switch (sd->bridge) { - case BRIDGE_SN9C102P: - case BRIDGE_SN9C105: - if (regF1 != 0x11) - return -ENODEV; - break; - default: -/* case BRIDGE_SN9C110: */ -/* case BRIDGE_SN9C120: */ - if (regF1 != 0x12) - return -ENODEV; - } - - switch (sd->sensor) { - case SENSOR_MI0360: - mi0360_probe(gspca_dev); - break; - case SENSOR_OV7630: - ov7630_probe(gspca_dev); - break; - case SENSOR_OV7648: - ov7648_probe(gspca_dev); - break; - case SENSOR_PO2030N: - po2030n_probe(gspca_dev); - break; - } - - switch (sd->bridge) { - case BRIDGE_SN9C102P: - reg_w1(gspca_dev, 0x02, regGpio[1]); - break; - default: - reg_w(gspca_dev, 0x01, regGpio, 2); - break; - } - - if (sd->sensor == SENSOR_OM6802) - sd->ctrls[SHARPNESS].def = 0x10; - - /* Note we do not disable the sensor clock here (power saving mode), - as that also disables the button on the cam. */ - reg_w1(gspca_dev, 0xf1, 0x00); - - /* set the i2c address */ - sn9c1xx = sn_tb[sd->sensor]; - sd->i2c_addr = sn9c1xx[9]; - - gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; - if (!(sd->flags & F_ILLUM)) - gspca_dev->ctrl_dis |= (1 << ILLUM); - - return gspca_dev->usb_err; -} - -static u32 expo_adjust(struct gspca_dev *gspca_dev, - u32 expo) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { - case SENSOR_GC0307: { - int a, b; - - /* expo = 0..255 -> a = 19..43 */ - a = 19 + expo * 25 / 256; - i2c_w1(gspca_dev, 0x68, a); - a -= 12; - b = a * a * 4; /* heuristic */ - i2c_w1(gspca_dev, 0x03, b >> 8); - i2c_w1(gspca_dev, 0x04, b); - break; - } - case SENSOR_HV7131R: { - u8 Expodoit[] = - { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 }; - - Expodoit[3] = expo >> 16; - Expodoit[4] = expo >> 8; - Expodoit[5] = expo; - i2c_w8(gspca_dev, Expodoit); - break; - } - case SENSOR_MI0360: - case SENSOR_MI0360B: { - u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ - { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 }; - static const u8 doit[] = /* update sensor */ - { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; - static const u8 sensorgo[] = /* sensor on */ - { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; - - if (expo > 0x0635) - expo = 0x0635; - else if (expo < 0x0001) - expo = 0x0001; - expoMi[3] = expo >> 8; - expoMi[4] = expo; - i2c_w8(gspca_dev, expoMi); - i2c_w8(gspca_dev, doit); - i2c_w8(gspca_dev, sensorgo); - break; - } - case SENSOR_MO4000: { - u8 expoMof[] = - { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 }; - u8 expoMo10[] = - { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 }; - static const u8 gainMo[] = - { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; - - if (expo > 0x1fff) - expo = 0x1fff; - else if (expo < 0x0001) - expo = 0x0001; - expoMof[3] = (expo & 0x03fc) >> 2; - i2c_w8(gspca_dev, expoMof); - expoMo10[3] = ((expo & 0x1c00) >> 10) - | ((expo & 0x0003) << 4); - i2c_w8(gspca_dev, expoMo10); - i2c_w8(gspca_dev, gainMo); - PDEBUG(D_FRAM, "set exposure %d", - ((expoMo10[3] & 0x07) << 10) - | (expoMof[3] << 2) - | ((expoMo10[3] & 0x30) >> 4)); - break; - } - case SENSOR_MT9V111: { - u8 expo_c1[] = - { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; - - if (expo > 0x0390) - expo = 0x0390; - else if (expo < 0x0060) - expo = 0x0060; - expo_c1[3] = expo >> 8; - expo_c1[4] = expo; - i2c_w8(gspca_dev, expo_c1); - break; - } - case SENSOR_OM6802: { - u8 gainOm[] = - { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; - /* preset AGC - works when AutoExpo = off */ - - if (expo > 0x03ff) - expo = 0x03ff; - if (expo < 0x0001) - expo = 0x0001; - gainOm[3] = expo >> 2; - i2c_w8(gspca_dev, gainOm); - reg_w1(gspca_dev, 0x96, expo >> 5); - PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); - break; - } - } - return expo; -} - -static void setbrightness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned int expo; - int brightness; - u8 k2; - - brightness = sd->ctrls[BRIGHTNESS].val; - k2 = (brightness - 0x80) >> 2; - switch (sd->sensor) { - case SENSOR_ADCM1700: - if (k2 > 0x1f) - k2 = 0; /* only positive Y offset */ - break; - case SENSOR_HV7131R: - expo = brightness << 12; - if (expo > 0x002dc6c0) - expo = 0x002dc6c0; - else if (expo < 0x02a0) - expo = 0x02a0; - sd->exposure = expo_adjust(gspca_dev, expo); - break; - case SENSOR_MI0360: - case SENSOR_MO4000: - expo = brightness << 4; - sd->exposure = expo_adjust(gspca_dev, expo); - break; - case SENSOR_MI0360B: - expo = brightness << 2; - sd->exposure = expo_adjust(gspca_dev, expo); - break; - case SENSOR_GC0307: - expo = brightness; - sd->exposure = expo_adjust(gspca_dev, expo); - return; /* don't set the Y offset */ - case SENSOR_MT9V111: - expo = brightness << 2; - sd->exposure = expo_adjust(gspca_dev, expo); - return; /* don't set the Y offset */ - case SENSOR_OM6802: - expo = brightness << 2; - sd->exposure = expo_adjust(gspca_dev, expo); - return; /* Y offset already set */ - } - - reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ -} - -static void setcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 k2; - u8 contrast[6]; - - k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1) - + 37; /* 37..73 */ - contrast[0] = (k2 + 1) / 2; /* red */ - contrast[1] = 0; - contrast[2] = k2; /* green */ - contrast[3] = 0; - contrast[4] = k2 / 5; /* blue */ - contrast[5] = 0; - reg_w(gspca_dev, 0x84, contrast, sizeof contrast); -} - -static void setcolors(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, v, colors; - const s16 *uv; - u8 reg8a[12]; /* U & V gains */ - static const s16 uv_com[6] = { /* same as reg84 in signed decimal */ - -24, -38, 64, /* UR UG UB */ - 62, -51, -9 /* VR VG VB */ - }; - static const s16 uv_mi0360b[6] = { - -20, -38, 64, /* UR UG UB */ - 60, -51, -9 /* VR VG VB */ - }; - - colors = sd->ctrls[COLORS].val; - if (sd->sensor == SENSOR_MI0360B) - uv = uv_mi0360b; - else - uv = uv_com; - for (i = 0; i < 6; i++) { - v = uv[i] * colors / COLORS_DEF; - reg8a[i * 2] = v; - reg8a[i * 2 + 1] = (v >> 8) & 0x0f; - } - reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a); -} - -static void setredblue(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PO2030N) { - u8 rg1b[] = /* red green1 blue (no g2) */ - {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; - - /* 0x40 = normal value = gain x 1 */ - rg1b[3] = sd->ctrls[RED].val * 2; - rg1b[5] = sd->ctrls[BLUE].val * 2; - i2c_w8(gspca_dev, rg1b); - return; - } - reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); -/* reg_w1(gspca_dev, 0x07, 32); */ - reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); -} - -static void setgamma(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, val; - u8 gamma[17]; - const u8 *gamma_base; - static const u8 delta[17] = { - 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a, - 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00 - }; - - switch (sd->sensor) { - case SENSOR_ADCM1700: - gamma_base = gamma_spec_0; - break; - case SENSOR_HV7131R: - case SENSOR_MI0360B: - case SENSOR_MT9V111: - gamma_base = gamma_spec_1; - break; - case SENSOR_GC0307: - gamma_base = gamma_spec_2; - break; - case SENSOR_SP80708: - gamma_base = gamma_spec_3; - break; - default: - gamma_base = gamma_def; - break; - } - - val = sd->ctrls[GAMMA].val; - for (i = 0; i < sizeof gamma; i++) - gamma[i] = gamma_base[i] - + delta[i] * (val - GAMMA_DEF) / 32; - reg_w(gspca_dev, 0x20, gamma, sizeof gamma); -} - -static void setexposure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PO2030N) { - u8 rexpo[] = /* 1a: expo H, 1b: expo M */ - {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; - - rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; - i2c_w8(gspca_dev, rexpo); - msleep(6); - rexpo[2] = 0x1b; - rexpo[3] = sd->ctrls[EXPOSURE].val; - i2c_w8(gspca_dev, rexpo); - } -} - -static void setautogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) - return; - switch (sd->sensor) { - case SENSOR_OV7630: - case SENSOR_OV7648: { - u8 comb; - - if (sd->sensor == SENSOR_OV7630) - comb = 0xc0; - else - comb = 0xa0; - if (sd->ctrls[AUTOGAIN].val) - comb |= 0x03; - i2c_w1(&sd->gspca_dev, 0x13, comb); - return; - } - } - if (sd->ctrls[AUTOGAIN].val) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; -} - -static void setgain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_PO2030N) { - u8 rgain[] = /* 15: gain */ - {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; - - rgain[3] = sd->ctrls[GAIN].val; - i2c_w8(gspca_dev, rgain); - } -} - -static void sethvflip(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 comn; - - switch (sd->sensor) { - case SENSOR_HV7131R: - comn = 0x18; /* clkdiv = 1, ablcen = 1 */ - if (sd->ctrls[VFLIP].val) - comn |= 0x01; - i2c_w1(gspca_dev, 0x01, comn); /* sctra */ - break; - case SENSOR_OV7630: - comn = 0x02; - if (!sd->ctrls[VFLIP].val) - comn |= 0x80; - i2c_w1(gspca_dev, 0x75, comn); - break; - case SENSOR_OV7648: - comn = 0x06; - if (sd->ctrls[VFLIP].val) - comn |= 0x80; - i2c_w1(gspca_dev, 0x75, comn); - break; - case SENSOR_PO2030N: - /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2) - * (reset value: 0x0A) - * bit7: HM: Horizontal Mirror: 0: disable, 1: enable - * bit6: VM: Vertical Mirror: 0: disable, 1: enable - * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical - * bit4: FT: Single Frame Transfer: 0: disable, 1: enable - * bit3-0: X - */ - comn = 0x0a; - if (sd->ctrls[HFLIP].val) - comn |= 0x80; - if (sd->ctrls[VFLIP].val) - comn |= 0x40; - i2c_w1(&sd->gspca_dev, 0x1e, comn); - break; - } -} - -static void setsharpness(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); -} - -static void setillum(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (gspca_dev->ctrl_dis & (1 << ILLUM)) - return; - switch (sd->sensor) { - case SENSOR_ADCM1700: - reg_w1(gspca_dev, 0x02, /* gpio */ - sd->ctrls[ILLUM].val ? 0x64 : 0x60); - break; - case SENSOR_MT9V111: - reg_w1(gspca_dev, 0x02, - sd->ctrls[ILLUM].val ? 0x77 : 0x74); -/* should have been: */ -/* 0x55 : 0x54); * 370i */ -/* 0x66 : 0x64); * Clip */ - break; - } -} - -static void setfreq(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (gspca_dev->ctrl_dis & (1 << FREQ)) - return; - if (sd->sensor == SENSOR_OV7660) { - u8 com8; - - com8 = 0xdf; /* auto gain/wb/expo */ - switch (sd->ctrls[FREQ].val) { - case 0: /* Banding filter disabled */ - i2c_w1(gspca_dev, 0x13, com8 | 0x20); - break; - case 1: /* 50 hz */ - i2c_w1(gspca_dev, 0x13, com8); - i2c_w1(gspca_dev, 0x3b, 0x0a); - break; - case 2: /* 60 hz */ - i2c_w1(gspca_dev, 0x13, com8); - i2c_w1(gspca_dev, 0x3b, 0x02); - break; - } - } else { - u8 reg2a = 0, reg2b = 0, reg2d = 0; - - /* Get reg2a / reg2d base values */ - switch (sd->sensor) { - case SENSOR_OV7630: - reg2a = 0x08; - reg2d = 0x01; - break; - case SENSOR_OV7648: - reg2a = 0x11; - reg2d = 0x81; - break; - } - - switch (sd->ctrls[FREQ].val) { - case 0: /* Banding filter disabled */ - break; - case 1: /* 50 hz (filter on and framerate adj) */ - reg2a |= 0x80; - reg2b = 0xac; - reg2d |= 0x04; - break; - case 2: /* 60 hz (filter on, no framerate adj) */ - reg2a |= 0x80; - reg2d |= 0x04; - break; - } - i2c_w1(gspca_dev, 0x2a, reg2a); - i2c_w1(gspca_dev, 0x2b, reg2b); - i2c_w1(gspca_dev, 0x2d, reg2d); - } -} - -static void setjpegqual(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - jpeg_set_qual(sd->jpeg_hdr, sd->quality); -#if USB_BUF_SZ < 64 -#error "No room enough in usb_buf for quantization table" -#endif - memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x0100, 0, - gspca_dev->usb_buf, 64, - 500); - memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x0140, 0, - gspca_dev->usb_buf, 64, - 500); - - sd->reg18 ^= 0x40; - reg_w1(gspca_dev, 0x18, sd->reg18); -} - -/* JPEG quality update */ -/* This function is executed from a work queue. */ -static void qual_upd(struct work_struct *work) -{ - struct sd *sd = container_of(work, struct sd, work); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - - mutex_lock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality); - setjpegqual(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - u8 reg01, reg17; - u8 reg0102[2]; - const u8 *sn9c1xx; - const u8 (*init)[8]; - const u8 *reg9a; - int mode; - static const u8 reg9a_def[] = - {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; - static const u8 reg9a_spec[] = - {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; - static const u8 regd4[] = {0x60, 0x00, 0x00}; - static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; - static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; - static const u8 CA_adcm1700[] = - { 0x14, 0xec, 0x0a, 0xf6 }; - static const u8 CA_po2030n[] = - { 0x1e, 0xe2, 0x14, 0xec }; - static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ - static const u8 CE_gc0307[] = - { 0x32, 0xce, 0x2d, 0xd3 }; - static const u8 CE_ov76xx[] = - { 0x32, 0xdd, 0x32, 0xdd }; - static const u8 CE_po2030n[] = - { 0x14, 0xe7, 0x1e, 0xdd }; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - - /* initialize the bridge */ - sn9c1xx = sn_tb[sd->sensor]; - - /* sensor clock already enabled in sd_init */ - /* reg_w1(gspca_dev, 0xf1, 0x00); */ - reg01 = sn9c1xx[1]; - if (sd->flags & F_PDN_INV) - reg01 ^= S_PDN_INV; /* power down inverted */ - reg_w1(gspca_dev, 0x01, reg01); - - /* configure gpio */ - reg0102[0] = reg01; - reg0102[1] = sn9c1xx[2]; - if (gspca_dev->audio) - reg0102[1] |= 0x04; /* keep the audio connection */ - reg_w(gspca_dev, 0x01, reg0102, 2); - reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); - reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); - switch (sd->sensor) { - case SENSOR_GC0307: - case SENSOR_OV7660: - case SENSOR_PO1030: - case SENSOR_PO2030N: - case SENSOR_SOI768: - case SENSOR_SP80708: - reg9a = reg9a_spec; - break; - default: - reg9a = reg9a_def; - break; - } - reg_w(gspca_dev, 0x9a, reg9a, 6); - - reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); - - reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); - - reg17 = sn9c1xx[0x17]; - switch (sd->sensor) { - case SENSOR_GC0307: - msleep(50); /*fixme: is it useful? */ - break; - case SENSOR_OM6802: - msleep(10); - reg_w1(gspca_dev, 0x02, 0x73); - reg17 |= SEN_CLK_EN; - reg_w1(gspca_dev, 0x17, reg17); - reg_w1(gspca_dev, 0x01, 0x22); - msleep(100); - reg01 = SCL_SEL_OD | S_PDN_INV; - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x04; /* clock / 4 */ - break; - } - reg01 |= SYS_SEL_48M; - reg_w1(gspca_dev, 0x01, reg01); - reg17 |= SEN_CLK_EN; - reg_w1(gspca_dev, 0x17, reg17); - reg01 &= ~S_PWR_DN; /* sensor power on */ - reg_w1(gspca_dev, 0x01, reg01); - reg01 &= ~SCL_SEL_OD; /* remove open-drain mode */ - reg_w1(gspca_dev, 0x01, reg01); - - switch (sd->sensor) { - case SENSOR_HV7131R: - hv7131r_probe(gspca_dev); /*fixme: is it useful? */ - break; - case SENSOR_OM6802: - msleep(10); - reg_w1(gspca_dev, 0x01, reg01); - i2c_w8(gspca_dev, om6802_init0[0]); - i2c_w8(gspca_dev, om6802_init0[1]); - msleep(15); - reg_w1(gspca_dev, 0x02, 0x71); - msleep(150); - break; - case SENSOR_SP80708: - msleep(100); - reg_w1(gspca_dev, 0x02, 0x62); - break; - } - - /* initialize the sensor */ - i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); - - reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); - reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); - reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); - reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]); - reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); - if (sd->sensor == SENSOR_ADCM1700) { - reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */ - reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */ - } else { - reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */ - reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */ - } - reg_w1(gspca_dev, 0xc6, 0x00); - reg_w1(gspca_dev, 0xc7, 0x00); - if (sd->sensor == SENSOR_ADCM1700) { - reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */ - reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */ - } else { - reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */ - reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */ - } - reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); - switch (sd->sensor) { - case SENSOR_OM6802: -/* case SENSOR_OV7648: * fixme: sometimes */ - break; - default: - reg17 |= DEF_EN; - break; - } - reg_w1(gspca_dev, 0x17, reg17); - - reg_w1(gspca_dev, 0x05, 0x00); /* red */ - reg_w1(gspca_dev, 0x07, 0x00); /* green */ - reg_w1(gspca_dev, 0x06, 0x00); /* blue */ - reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); - - setgamma(gspca_dev); - -/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */ - for (i = 0; i < 8; i++) - reg_w(gspca_dev, 0x84, reg84, sizeof reg84); - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_OV7660: - case SENSOR_SP80708: - reg_w1(gspca_dev, 0x9a, 0x05); - break; - case SENSOR_GC0307: - case SENSOR_MT9V111: - case SENSOR_MI0360B: - reg_w1(gspca_dev, 0x9a, 0x07); - break; - case SENSOR_OV7630: - case SENSOR_OV7648: - reg_w1(gspca_dev, 0x9a, 0x0a); - break; - case SENSOR_PO2030N: - case SENSOR_SOI768: - reg_w1(gspca_dev, 0x9a, 0x06); - break; - default: - reg_w1(gspca_dev, 0x9a, 0x08); - break; - } - setsharpness(gspca_dev); - - reg_w(gspca_dev, 0x84, reg84, sizeof reg84); - reg_w1(gspca_dev, 0x05, 0x20); /* red */ - reg_w1(gspca_dev, 0x07, 0x20); /* green */ - reg_w1(gspca_dev, 0x06, 0x20); /* blue */ - - init = NULL; - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - reg01 |= SYS_SEL_48M | V_TX_EN; - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x02; /* clock / 2 */ - switch (sd->sensor) { - case SENSOR_ADCM1700: - init = adcm1700_sensor_param1; - break; - case SENSOR_GC0307: - init = gc0307_sensor_param1; - break; - case SENSOR_HV7131R: - case SENSOR_MI0360: - if (!mode) - reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */ - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x01; /* clock / 1 */ - break; - case SENSOR_MI0360B: - init = mi0360b_sensor_param1; - break; - case SENSOR_MO4000: - if (mode) { /* if 320x240 */ - reg01 &= ~SYS_SEL_48M; /* clk 24Mz */ - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x01; /* clock / 1 */ - } - break; - case SENSOR_MT9V111: - init = mt9v111_sensor_param1; - break; - case SENSOR_OM6802: - init = om6802_sensor_param1; - if (!mode) { /* if 640x480 */ - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x04; /* clock / 4 */ - } else { - reg01 &= ~SYS_SEL_48M; /* clk 24Mz */ - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x02; /* clock / 2 */ - } - break; - case SENSOR_OV7630: - init = ov7630_sensor_param1; - break; - case SENSOR_OV7648: - init = ov7648_sensor_param1; - reg17 &= ~MCK_SIZE_MASK; - reg17 |= 0x01; /* clock / 1 */ - break; - case SENSOR_OV7660: - init = ov7660_sensor_param1; - break; - case SENSOR_PO1030: - init = po1030_sensor_param1; - break; - case SENSOR_PO2030N: - init = po2030n_sensor_param1; - break; - case SENSOR_SOI768: - init = soi768_sensor_param1; - break; - case SENSOR_SP80708: - init = sp80708_sensor_param1; - break; - } - - /* more sensor initialization - param1 */ - if (init != NULL) { - i2c_w_seq(gspca_dev, init); -/* init = NULL; */ - } - - reg_w(gspca_dev, 0xc0, C0, 6); - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_GC0307: - case SENSOR_SOI768: - reg_w(gspca_dev, 0xca, CA_adcm1700, 4); - break; - case SENSOR_PO2030N: - reg_w(gspca_dev, 0xca, CA_po2030n, 4); - break; - default: - reg_w(gspca_dev, 0xca, CA, 4); - break; - } - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_OV7630: - case SENSOR_OV7648: - case SENSOR_OV7660: - case SENSOR_SOI768: - reg_w(gspca_dev, 0xce, CE_ov76xx, 4); - break; - case SENSOR_GC0307: - reg_w(gspca_dev, 0xce, CE_gc0307, 4); - break; - case SENSOR_PO2030N: - reg_w(gspca_dev, 0xce, CE_po2030n, 4); - break; - default: - reg_w(gspca_dev, 0xce, CE, 4); - /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ - break; - } - - /* here change size mode 0 -> VGA; 1 -> CIF */ - sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; - reg_w1(gspca_dev, 0x18, sd->reg18); - setjpegqual(gspca_dev); - - reg_w1(gspca_dev, 0x17, reg17); - reg_w1(gspca_dev, 0x01, reg01); - sd->reg01 = reg01; - sd->reg17 = reg17; - - sethvflip(gspca_dev); - setbrightness(gspca_dev); - setcontrast(gspca_dev); - setcolors(gspca_dev); - setautogain(gspca_dev); - if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { - setexposure(gspca_dev); - setgain(gspca_dev); - } - setfreq(gspca_dev); - - sd->pktsz = sd->npkt = 0; - sd->nchg = sd->short_mark = 0; - sd->work_thread = create_singlethread_workqueue(MODULE_NAME); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const u8 stophv7131[] = - { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; - static const u8 stopmi0360[] = - { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; - static const u8 stopov7648[] = - { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; - static const u8 stopsoi768[] = - { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; - u8 reg01; - u8 reg17; - - reg01 = sd->reg01; - reg17 = sd->reg17 & ~SEN_CLK_EN; - switch (sd->sensor) { - case SENSOR_ADCM1700: - case SENSOR_GC0307: - case SENSOR_PO2030N: - case SENSOR_SP80708: - reg01 |= LED; - reg_w1(gspca_dev, 0x01, reg01); - reg01 &= ~(LED | V_TX_EN); - reg_w1(gspca_dev, 0x01, reg01); -/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */ - break; - case SENSOR_HV7131R: - reg01 &= ~V_TX_EN; - reg_w1(gspca_dev, 0x01, reg01); - i2c_w8(gspca_dev, stophv7131); - break; - case SENSOR_MI0360: - case SENSOR_MI0360B: - reg01 &= ~V_TX_EN; - reg_w1(gspca_dev, 0x01, reg01); -/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */ - i2c_w8(gspca_dev, stopmi0360); - break; - case SENSOR_MT9V111: - case SENSOR_OM6802: - case SENSOR_PO1030: - reg01 &= ~V_TX_EN; - reg_w1(gspca_dev, 0x01, reg01); - break; - case SENSOR_OV7630: - case SENSOR_OV7648: - reg01 &= ~V_TX_EN; - reg_w1(gspca_dev, 0x01, reg01); - i2c_w8(gspca_dev, stopov7648); - break; - case SENSOR_OV7660: - reg01 &= ~V_TX_EN; - reg_w1(gspca_dev, 0x01, reg01); - break; - case SENSOR_SOI768: - i2c_w8(gspca_dev, stopsoi768); - break; - } - - reg01 |= SCL_SEL_OD; - reg_w1(gspca_dev, 0x01, reg01); - reg01 |= S_PWR_DN; /* sensor power down */ - reg_w1(gspca_dev, 0x01, reg01); - reg_w1(gspca_dev, 0x17, reg17); - reg01 &= ~SYS_SEL_48M; /* clock 24MHz */ - reg_w1(gspca_dev, 0x01, reg01); - reg01 |= LED; - reg_w1(gspca_dev, 0x01, reg01); - /* Don't disable sensor clock as that disables the button on the cam */ - /* reg_w1(gspca_dev, 0xf1, 0x01); */ -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->work_thread != NULL) { - mutex_unlock(&gspca_dev->usb_lock); - destroy_workqueue(sd->work_thread); - mutex_lock(&gspca_dev->usb_lock); - sd->work_thread = NULL; - } -} - -#define WANT_REGULAR_AUTOGAIN -#include "autogain_functions.h" - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int delta; - int expotimes; - u8 luma_mean = 130; - u8 luma_delta = 20; - - /* Thanks S., without your advice, autobright should not work :) */ - if (sd->ag_cnt < 0) - return; - if (--sd->ag_cnt >= 0) - return; - sd->ag_cnt = AG_CNT_START; - - delta = atomic_read(&sd->avg_lum); - PDEBUG(D_FRAM, "mean lum %d", delta); - - if (sd->sensor == SENSOR_PO2030N) { - auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, - 15, 1024); - return; - } - - if (delta < luma_mean - luma_delta || - delta > luma_mean + luma_delta) { - switch (sd->sensor) { - case SENSOR_GC0307: - expotimes = sd->exposure; - expotimes += (luma_mean - delta) >> 6; - if (expotimes < 0) - expotimes = 0; - sd->exposure = expo_adjust(gspca_dev, - (unsigned int) expotimes); - break; - case SENSOR_HV7131R: - expotimes = sd->exposure >> 8; - expotimes += (luma_mean - delta) >> 4; - if (expotimes < 0) - expotimes = 0; - sd->exposure = expo_adjust(gspca_dev, - (unsigned int) (expotimes << 8)); - break; - case SENSOR_OM6802: - case SENSOR_MT9V111: - expotimes = sd->exposure; - expotimes += (luma_mean - delta) >> 2; - if (expotimes < 0) - expotimes = 0; - sd->exposure = expo_adjust(gspca_dev, - (unsigned int) expotimes); - setredblue(gspca_dev); - break; - default: -/* case SENSOR_MO4000: */ -/* case SENSOR_MI0360: */ -/* case SENSOR_MI0360B: */ - expotimes = sd->exposure; - expotimes += (luma_mean - delta) >> 6; - if (expotimes < 0) - expotimes = 0; - sd->exposure = expo_adjust(gspca_dev, - (unsigned int) expotimes); - setredblue(gspca_dev); - break; - } - } -} - -/* set the average luminosity from an isoc marker */ -static void set_lum(struct sd *sd, - u8 *data) -{ - int avg_lum; - - /* w0 w1 w2 - * w3 w4 w5 - * w6 w7 w8 - */ - avg_lum = (data[27] << 8) + data[28] /* w3 */ - - + (data[31] << 8) + data[32] /* w5 */ - - + (data[23] << 8) + data[24] /* w1 */ - - + (data[35] << 8) + data[36] /* w7 */ - - + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */ - avg_lum >>= 10; - atomic_set(&sd->avg_lum, avg_lum); -} - -/* scan the URB packets */ -/* This function is run at interrupt level. */ -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, new_qual; - - /* - * A frame ends on the marker - * ff ff 00 c4 c4 96 .. - * which is 62 bytes long and is followed by various information - * including statuses and luminosity. - * - * A marker may be splitted on two packets. - * - * The 6th byte of a marker contains the bits: - * 0x08: USB full - * 0xc0: frame sequence - * When the bit 'USB full' is set, the frame must be discarded; - * this is also the case when the 2 bytes before the marker are - * not the JPEG end of frame ('ff d9'). - */ - - /* count the packets and their size */ - sd->npkt++; - sd->pktsz += len; - -/*fixme: assumption about the following code: - * - there can be only one marker in a packet - */ - - /* skip the remaining bytes of a short marker */ - i = sd->short_mark; - if (i != 0) { - sd->short_mark = 0; - if (i < 0 /* if 'ff' at end of previous packet */ - && data[0] == 0xff - && data[1] == 0x00) - goto marker_found; - if (data[0] == 0xff && data[1] == 0xff) { - i = 0; - goto marker_found; - } - len -= i; - if (len <= 0) - return; - data += i; - } - - /* search backwards if there is a marker in the packet */ - for (i = len - 1; --i >= 0; ) { - if (data[i] != 0xff) { - i--; - continue; - } - if (data[i + 1] == 0xff) { - - /* (there may be 'ff ff' inside a marker) */ - if (i + 2 >= len || data[i + 2] == 0x00) - goto marker_found; - } - } - - /* no marker found */ - /* add the JPEG header if first fragment */ - if (data[len - 1] == 0xff) - sd->short_mark = -1; - if (gspca_dev->last_packet_type == LAST_PACKET) - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - return; - - /* marker found */ - /* if some error, discard the frame and decrease the quality */ -marker_found: - new_qual = 0; - if (i > 2) { - if (data[i - 2] != 0xff || data[i - 1] != 0xd9) { - gspca_dev->last_packet_type = DISCARD_PACKET; - new_qual = -3; - } - } else if (i + 6 < len) { - if (data[i + 6] & 0x08) { - gspca_dev->last_packet_type = DISCARD_PACKET; - new_qual = -5; - } - } - - gspca_frame_add(gspca_dev, LAST_PACKET, data, i); - - /* compute the filling rate and a new JPEG quality */ - if (new_qual == 0) { - int r; - - r = (sd->pktsz * 100) / - (sd->npkt * - gspca_dev->urb[0]->iso_frame_desc[0].length); - if (r >= 85) - new_qual = -3; - else if (r < 75) - new_qual = 2; - } - if (new_qual != 0) { - sd->nchg += new_qual; - if (sd->nchg < -6 || sd->nchg >= 12) { - sd->nchg = 0; - new_qual += sd->quality; - if (new_qual < QUALITY_MIN) - new_qual = QUALITY_MIN; - else if (new_qual > QUALITY_MAX) - new_qual = QUALITY_MAX; - if (new_qual != sd->quality) { - sd->quality = new_qual; - queue_work(sd->work_thread, &sd->work); - } - } - } else { - sd->nchg = 0; - } - sd->pktsz = sd->npkt = 0; - - /* if the marker is smaller than 62 bytes, - * memorize the number of bytes to skip in the next packet */ - if (i + 62 > len) { /* no more usable data */ - sd->short_mark = i + 62 - len; - return; - } - if (sd->ag_cnt >= 0) - set_lum(sd, data + i); - - /* if more data, start a new frame */ - i += 62; - if (i < len) { - data += i; - len -= i; - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - } -} - -static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->ctrls[AUTOGAIN].val = val; - if (val) - gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); - else - gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); - if (gspca_dev->streaming) - setautogain(gspca_dev); - return gspca_dev->usb_err; -} - -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - switch (menu->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - } - break; - } - return -EINVAL; -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrupt packet length */ -{ - int ret = -EINVAL; - - if (len == 1 && data[0] == 1) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - return ret; -} -#endif - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = NCTRLS, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, - .querymenu = sd_querymenu, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* -- module initialisation -- */ -#define BS(bridge, sensor) \ - .driver_info = (BRIDGE_ ## bridge << 16) \ - | (SENSOR_ ## sensor << 8) -#define BSF(bridge, sensor, flags) \ - .driver_info = (BRIDGE_ ## bridge << 16) \ - | (SENSOR_ ## sensor << 8) \ - | (flags) -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)}, - {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, - {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, - {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, - {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, - {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, - {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, - {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)}, - {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)}, -/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */ - {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)}, -/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */ -/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */ - {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)}, -/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */ - {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)}, - /* or MT9V111 */ -/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ -/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ -/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ - {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)}, - {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, -/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ -/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ -/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */ - {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, - {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, - {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, - {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/ -/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ - {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/ - {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/ -/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */ -/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */ -/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */ - {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/ -/*bw600.inf:*/ - {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/ - {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)}, - {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)}, - {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)}, -/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */ - {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)}, - /* or MT9V111 / MI0360B */ -/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */ - {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)}, - {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)}, - {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)}, - {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, - {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, - {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ - /* or GC0305 / GC0307 */ - {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ - {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ - {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)}, -/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c deleted file mode 100644 index 14d635277d71..000000000000 --- a/drivers/media/video/gspca/spca1528.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * spca1528 subdriver - * - * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca1528" - -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("SPCA1528 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - u8 pkt_seq; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -static const struct v4l2_pix_format vga_mode[] = { -/* (does not work correctly) - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 5 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, -*/ - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -}; - -/* read <len> bytes to gspca usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - u8 req, - u16 index, - int len) -{ -#if USB_BUF_SZ < 64 -#error "USB buffer too small" -#endif - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, /* value */ - index, - gspca_dev->usb_buf, len, - 500); - PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index, - gspca_dev->usb_buf[0]); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, - u8 req, - u16 value, - u16 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index); - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, - NULL, 0, 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_wb(struct gspca_dev *gspca_dev, - u8 req, - u16 value, - u16 index, - u8 byte) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte); - gspca_dev->usb_buf[0] = byte; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, - gspca_dev->usb_buf, 1, 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void wait_status_0(struct gspca_dev *gspca_dev) -{ - int i, w; - - i = 16; - w = 0; - do { - reg_r(gspca_dev, 0x21, 0x0000, 1); - if (gspca_dev->usb_buf[0] == 0) - return; - w += 15; - msleep(w); - } while (--i > 0); - PDEBUG(D_ERR, "wait_status_0 timeout"); - gspca_dev->usb_err = -ETIME; -} - -static void wait_status_1(struct gspca_dev *gspca_dev) -{ - int i; - - i = 10; - do { - reg_r(gspca_dev, 0x21, 0x0001, 1); - msleep(10); - if (gspca_dev->usb_buf[0] == 1) { - reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00); - reg_r(gspca_dev, 0x21, 0x0001, 1); - return; - } - } while (--i > 0); - PDEBUG(D_ERR, "wait_status_1 timeout"); - gspca_dev->usb_err = -ETIME; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val); -} - -static void sethue(struct gspca_dev *gspca_dev, s32 val) -{ - reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val); -} - -static void setcolor(struct gspca_dev *gspca_dev, s32 val) -{ - reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val); -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */ - /*fixme: 256 in ms-win traces*/ - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 0x00, 0x0001, 0x2067); - reg_w(gspca_dev, 0x00, 0x00d0, 0x206b); - reg_w(gspca_dev, 0x00, 0x0000, 0x206c); - reg_w(gspca_dev, 0x00, 0x0001, 0x2069); - msleep(8); - reg_w(gspca_dev, 0x00, 0x00c0, 0x206b); - reg_w(gspca_dev, 0x00, 0x0000, 0x206c); - reg_w(gspca_dev, 0x00, 0x0001, 0x2069); - - reg_r(gspca_dev, 0x20, 0x0000, 1); - reg_r(gspca_dev, 0x20, 0x0000, 5); - reg_r(gspca_dev, 0x23, 0x0000, 64); - PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c], - &gspca_dev->usb_buf[0x30]); - reg_r(gspca_dev, 0x23, 0x0001, 64); - return gspca_dev->usb_err; -} - -/* function called at start time before URB creation */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - u8 mode; - - reg_r(gspca_dev, 0x00, 0x2520, 1); - wait_status_0(gspca_dev); - reg_w(gspca_dev, 0xc5, 0x0003, 0x0000); - wait_status_1(gspca_dev); - - wait_status_0(gspca_dev); - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode); - reg_r(gspca_dev, 0x25, 0x0004, 1); - reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06); /* 420 */ - reg_r(gspca_dev, 0x27, 0x0000, 1); - -/* not useful.. - gspca_dev->alt = 4; * use alternate setting 3 */ - - return gspca_dev->usb_err; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* initialize the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - - /* the JPEG quality shall be 85% */ - jpeg_set_qual(sd->jpeg_hdr, 85); - - reg_r(gspca_dev, 0x00, 0x2520, 1); - msleep(8); - - /* start the capture */ - wait_status_0(gspca_dev); - reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */ - wait_status_1(gspca_dev); - wait_status_0(gspca_dev); - msleep(200); - - sd->pkt_seq = 0; - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* stop the capture */ - wait_status_0(gspca_dev); - reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */ - wait_status_1(gspca_dev); - wait_status_0(gspca_dev); -} - -/* move a packet adding 0x00 after 0xff */ -static void add_packet(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - int i; - - i = 0; - do { - if (data[i] == 0xff) { - gspca_frame_add(gspca_dev, INTER_PACKET, - data, i + 1); - len -= i; - data += i; - *data = 0x00; - i = 0; - } - } while (++i < len); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - static const u8 ffd9[] = {0xff, 0xd9}; - - /* image packets start with: - * 02 8n - * with <n> bit: - * 0x01: even (0) / odd (1) image - * 0x02: end of image when set - */ - if (len < 3) - return; /* empty packet */ - if (*data == 0x02) { - if (data[1] & 0x02) { - sd->pkt_seq = !(data[1] & 1); - add_packet(gspca_dev, data + 2, len - 2); - gspca_frame_add(gspca_dev, LAST_PACKET, - ffd9, 2); - return; - } - if ((data[1] & 1) != sd->pkt_seq) - goto err; - if (gspca_dev->last_packet_type == LAST_PACKET) - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - add_packet(gspca_dev, data + 2, len - 2); - return; - } -err: - gspca_dev->last_packet_type = DISCARD_PACKET; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_HUE: - sethue(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolor(gspca_dev, ctrl->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 8, 1, 1); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, 0, 255, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 8, 1, 1); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 255, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x04fc, 0x1528)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - /* the video interface for isochronous transfer is 1 */ - if (intf->cur_altsetting->desc.bInterfaceNumber != 1) - return -ENODEV; - - return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c deleted file mode 100644 index 25cb68d0556d..000000000000 --- a/drivers/media/video/gspca/spca500.c +++ /dev/null @@ -1,990 +0,0 @@ -/* - * SPCA500 chip based cameras initialization data - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca500" - -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define QUALITY 85 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - char subtype; -#define AgfaCl20 0 -#define AiptekPocketDV 1 -#define BenqDC1016 2 -#define CreativePCCam300 3 -#define DLinkDSC350 4 -#define Gsmartmini 5 -#define IntelPocketPCCamera 6 -#define KodakEZ200 7 -#define LogitechClickSmart310 8 -#define LogitechClickSmart510 9 -#define LogitechTraveler 10 -#define MustekGsmart300 11 -#define Optimedia 12 -#define PalmPixDC85 13 -#define ToptroIndus 14 - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const struct v4l2_pix_format sif_mode[] = { - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* Frame packet header offsets for the spca500 */ -#define SPCA500_OFFSET_PADDINGLB 2 -#define SPCA500_OFFSET_PADDINGHB 3 -#define SPCA500_OFFSET_MODE 4 -#define SPCA500_OFFSET_IMGWIDTH 5 -#define SPCA500_OFFSET_IMGHEIGHT 6 -#define SPCA500_OFFSET_IMGMODE 7 -#define SPCA500_OFFSET_QTBLINDEX 8 -#define SPCA500_OFFSET_FRAMSEQ 9 -#define SPCA500_OFFSET_CDSPINFO 10 -#define SPCA500_OFFSET_GPIO 11 -#define SPCA500_OFFSET_AUGPIO 12 -#define SPCA500_OFFSET_DATA 16 - - -static const __u16 spca500_visual_defaults[][3] = { - {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, - * hue (H byte) = 0, - * saturation/hue enable, - * brightness/contrast enable. - */ - {0x00, 0x0000, 0x8167}, /* brightness = 0 */ - {0x00, 0x0020, 0x8168}, /* contrast = 0 */ - {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, - * hue (H byte) = 0, saturation/hue enable, - * brightness/contrast enable. - * was 0x0003, now 0x0000. - */ - {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */ - {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */ - {0x00, 0x0050, 0x8157}, /* edge gain high threshold */ - {0x00, 0x0030, 0x8158}, /* edge gain low threshold */ - {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */ - {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */ - {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ - {0x0c, 0x0004, 0x0000}, - /* set interface */ - {} -}; -static const __u16 Clicksmart510_defaults[][3] = { - {0x00, 0x00, 0x8211}, - {0x00, 0x01, 0x82c0}, - {0x00, 0x10, 0x82cb}, - {0x00, 0x0f, 0x800d}, - {0x00, 0x82, 0x8225}, - {0x00, 0x21, 0x8228}, - {0x00, 0x00, 0x8203}, - {0x00, 0x00, 0x8204}, - {0x00, 0x08, 0x8205}, - {0x00, 0xf8, 0x8206}, - {0x00, 0x28, 0x8207}, - {0x00, 0xa0, 0x8208}, - {0x00, 0x08, 0x824a}, - {0x00, 0x08, 0x8214}, - {0x00, 0x80, 0x82c1}, - {0x00, 0x00, 0x82c2}, - {0x00, 0x00, 0x82ca}, - {0x00, 0x80, 0x82c1}, - {0x00, 0x04, 0x82c2}, - {0x00, 0x00, 0x82ca}, - {0x00, 0xfc, 0x8100}, - {0x00, 0xfc, 0x8105}, - {0x00, 0x30, 0x8101}, - {0x00, 0x00, 0x8102}, - {0x00, 0x00, 0x8103}, - {0x00, 0x66, 0x8107}, - {0x00, 0x00, 0x816b}, - {0x00, 0x00, 0x8155}, - {0x00, 0x01, 0x8156}, - {0x00, 0x60, 0x8157}, - {0x00, 0x40, 0x8158}, - {0x00, 0x0a, 0x8159}, - {0x00, 0x06, 0x815a}, - {0x00, 0x00, 0x813f}, - {0x00, 0x00, 0x8200}, - {0x00, 0x19, 0x8201}, - {0x00, 0x00, 0x82c1}, - {0x00, 0xa0, 0x82c2}, - {0x00, 0x00, 0x82ca}, - {0x00, 0x00, 0x8117}, - {0x00, 0x00, 0x8118}, - {0x00, 0x65, 0x8119}, - {0x00, 0x00, 0x811a}, - {0x00, 0x00, 0x811b}, - {0x00, 0x55, 0x811c}, - {0x00, 0x65, 0x811d}, - {0x00, 0x55, 0x811e}, - {0x00, 0x16, 0x811f}, - {0x00, 0x19, 0x8120}, - {0x00, 0x80, 0x8103}, - {0x00, 0x83, 0x816b}, - {0x00, 0x25, 0x8168}, - {0x00, 0x01, 0x820f}, - {0x00, 0xff, 0x8115}, - {0x00, 0x48, 0x8116}, - {0x00, 0x50, 0x8151}, - {0x00, 0x40, 0x8152}, - {0x00, 0x78, 0x8153}, - {0x00, 0x40, 0x8154}, - {0x00, 0x00, 0x8167}, - {0x00, 0x20, 0x8168}, - {0x00, 0x00, 0x816a}, - {0x00, 0x03, 0x816b}, - {0x00, 0x20, 0x8169}, - {0x00, 0x60, 0x8157}, - {0x00, 0x00, 0x8190}, - {0x00, 0x00, 0x81a1}, - {0x00, 0x00, 0x81b2}, - {0x00, 0x27, 0x8191}, - {0x00, 0x27, 0x81a2}, - {0x00, 0x27, 0x81b3}, - {0x00, 0x4b, 0x8192}, - {0x00, 0x4b, 0x81a3}, - {0x00, 0x4b, 0x81b4}, - {0x00, 0x66, 0x8193}, - {0x00, 0x66, 0x81a4}, - {0x00, 0x66, 0x81b5}, - {0x00, 0x79, 0x8194}, - {0x00, 0x79, 0x81a5}, - {0x00, 0x79, 0x81b6}, - {0x00, 0x8a, 0x8195}, - {0x00, 0x8a, 0x81a6}, - {0x00, 0x8a, 0x81b7}, - {0x00, 0x9b, 0x8196}, - {0x00, 0x9b, 0x81a7}, - {0x00, 0x9b, 0x81b8}, - {0x00, 0xa6, 0x8197}, - {0x00, 0xa6, 0x81a8}, - {0x00, 0xa6, 0x81b9}, - {0x00, 0xb2, 0x8198}, - {0x00, 0xb2, 0x81a9}, - {0x00, 0xb2, 0x81ba}, - {0x00, 0xbe, 0x8199}, - {0x00, 0xbe, 0x81aa}, - {0x00, 0xbe, 0x81bb}, - {0x00, 0xc8, 0x819a}, - {0x00, 0xc8, 0x81ab}, - {0x00, 0xc8, 0x81bc}, - {0x00, 0xd2, 0x819b}, - {0x00, 0xd2, 0x81ac}, - {0x00, 0xd2, 0x81bd}, - {0x00, 0xdb, 0x819c}, - {0x00, 0xdb, 0x81ad}, - {0x00, 0xdb, 0x81be}, - {0x00, 0xe4, 0x819d}, - {0x00, 0xe4, 0x81ae}, - {0x00, 0xe4, 0x81bf}, - {0x00, 0xed, 0x819e}, - {0x00, 0xed, 0x81af}, - {0x00, 0xed, 0x81c0}, - {0x00, 0xf7, 0x819f}, - {0x00, 0xf7, 0x81b0}, - {0x00, 0xf7, 0x81c1}, - {0x00, 0xff, 0x81a0}, - {0x00, 0xff, 0x81b1}, - {0x00, 0xff, 0x81c2}, - {0x00, 0x03, 0x8156}, - {0x00, 0x00, 0x8211}, - {0x00, 0x20, 0x8168}, - {0x00, 0x01, 0x8202}, - {0x00, 0x30, 0x8101}, - {0x00, 0x00, 0x8111}, - {0x00, 0x00, 0x8112}, - {0x00, 0x00, 0x8113}, - {0x00, 0x00, 0x8114}, - {} -}; - -static const __u8 qtable_creative_pccam[2][64] = { - { /* Q-table Y-components */ - 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, - 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, - 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, - 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, - 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, - 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, - 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, - 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, - { /* Q-table C-components */ - 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, - 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} -}; - -static const __u8 qtable_kodak_ez200[2][64] = { - { /* Q-table Y-components */ - 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, - 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, - 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06, - 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06, - 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08, - 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09, - 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a, - 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a}, - { /* Q-table C-components */ - 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, - 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, - 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} -}; - -static const __u8 qtable_pocketdv[2][64] = { - { /* Q-table Y-components start registers 0x8800 */ - 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, - 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, - 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, - 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19, - 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f, - 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25, - 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, - 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, - }, - { /* Q-table C-components start registers 0x8840 */ - 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, - 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, - 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} -}; - -/* read 'len' bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 index, - __u16 length) -{ - usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, length, 500); -} - -static int reg_w(struct gspca_dev *gspca_dev, - __u16 req, __u16 index, __u16 value) -{ - int ret; - - PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - if (ret < 0) - pr_err("reg write: error %d\n", ret); - return ret; -} - -/* returns: negative is error, pos or zero is data */ -static int reg_r_12(struct gspca_dev *gspca_dev, - __u16 req, /* bRequest */ - __u16 index, /* wIndex */ - __u16 length) /* wLength (1 or 2 only) */ -{ - int ret; - - gspca_dev->usb_buf[1] = 0; - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - gspca_dev->usb_buf, length, - 500); /* timeout */ - if (ret < 0) { - pr_err("reg_r_12 err %d\n", ret); - return ret; - } - return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; -} - -/* - * Simple function to wait for a given 8-bit value to be returned from - * a reg_read call. - * Returns: negative is error or timeout, zero is success. - */ -static int reg_r_wait(struct gspca_dev *gspca_dev, - __u16 reg, __u16 index, __u16 value) -{ - int ret, cnt = 20; - - while (--cnt > 0) { - ret = reg_r_12(gspca_dev, reg, index, 1); - if (ret == value) - return 0; - msleep(50); - } - return -EIO; -} - -static int write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][3]) -{ - int ret, i = 0; - - while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]); - if (ret < 0) - return ret; - i++; - } - return 0; -} - -static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, - unsigned int request, - unsigned int ybase, - unsigned int cbase, - const __u8 qtable[2][64]) -{ - int i, err; - - /* loop over y components */ - for (i = 0; i < 64; i++) { - err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]); - if (err < 0) - return err; - } - - /* loop over c components */ - for (i = 0; i < 64; i++) { - err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]); - if (err < 0) - return err; - } - return 0; -} - -static void spca500_ping310(struct gspca_dev *gspca_dev) -{ - reg_r(gspca_dev, 0x0d04, 2); - PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); -} - -static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) -{ - reg_r(gspca_dev, 0x0d05, 2); - PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); - reg_w(gspca_dev, 0x00, 0x8167, 0x5a); - spca500_ping310(gspca_dev); - - reg_w(gspca_dev, 0x00, 0x8168, 0x22); - reg_w(gspca_dev, 0x00, 0x816a, 0xc0); - reg_w(gspca_dev, 0x00, 0x816b, 0x0b); - reg_w(gspca_dev, 0x00, 0x8169, 0x25); - reg_w(gspca_dev, 0x00, 0x8157, 0x5b); - reg_w(gspca_dev, 0x00, 0x8158, 0x5b); - reg_w(gspca_dev, 0x00, 0x813f, 0x03); - reg_w(gspca_dev, 0x00, 0x8151, 0x4a); - reg_w(gspca_dev, 0x00, 0x8153, 0x78); - reg_w(gspca_dev, 0x00, 0x0d01, 0x04); - /* 00 for adjust shutter */ - reg_w(gspca_dev, 0x00, 0x0d02, 0x01); - reg_w(gspca_dev, 0x00, 0x8169, 0x25); - reg_w(gspca_dev, 0x00, 0x0d01, 0x02); -} - -static void spca500_setmode(struct gspca_dev *gspca_dev, - __u8 xmult, __u8 ymult) -{ - int mode; - - /* set x multiplier */ - reg_w(gspca_dev, 0, 0x8001, xmult); - - /* set y multiplier */ - reg_w(gspca_dev, 0, 0x8002, ymult); - - /* use compressed mode, VGA, with mode specific subsample */ - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg_w(gspca_dev, 0, 0x8003, mode << 4); -} - -static int spca500_full_reset(struct gspca_dev *gspca_dev) -{ - int err; - - /* send the reset command */ - err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000); - if (err < 0) - return err; - - /* wait for the reset to complete */ - err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000); - if (err < 0) - return err; - err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000); - if (err < 0) - return err; - err = reg_r_wait(gspca_dev, 0x06, 0, 0); - if (err < 0) { - PDEBUG(D_ERR, "reg_r_wait() failed"); - return err; - } - /* all ok */ - return 0; -} - -/* Synchro the Bridge with sensor */ -/* Maybe that will work on all spca500 chip */ -/* because i only own a clicksmart310 try for that chip */ -/* using spca50x_set_packet_size() cause an Ooops here */ -/* usb_set_interface from kernel 2.6.x clear all the urb stuff */ -/* up-port the same feature as in 2.4.x kernel */ -static int spca500_synch310(struct gspca_dev *gspca_dev) -{ - if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { - PDEBUG(D_ERR, "Set packet size: set interface error"); - goto error; - } - spca500_ping310(gspca_dev); - - reg_r(gspca_dev, 0x0d00, 1); - - /* need alt setting here */ - PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); - - /* Windoze use pipe with altsetting 6 why 7 here */ - if (usb_set_interface(gspca_dev->dev, - gspca_dev->iface, - gspca_dev->alt) < 0) { - PDEBUG(D_ERR, "Set packet size: set interface error"); - goto error; - } - return 0; -error: - return -EBUSY; -} - -static void spca500_reinit(struct gspca_dev *gspca_dev) -{ - int err; - __u8 Data; - - /* some unknown command from Aiptek pocket dv and family300 */ - - reg_w(gspca_dev, 0x00, 0x0d01, 0x01); - reg_w(gspca_dev, 0x00, 0x0d03, 0x00); - reg_w(gspca_dev, 0x00, 0x0d02, 0x01); - - /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - - err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, - qtable_pocketdv); - if (err < 0) - PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); - - /* set qtable index */ - reg_w(gspca_dev, 0x00, 0x8880, 2); - /* family cam Quicksmart stuff */ - reg_w(gspca_dev, 0x00, 0x800a, 0x00); - /* Set agc transfer: synced between frames */ - reg_w(gspca_dev, 0x00, 0x820f, 0x01); - /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev, 0x00, 0x870a, 0x04); - /*Start init sequence or stream */ - reg_w(gspca_dev, 0, 0x8003, 0x00); - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - msleep(2000); - if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) { - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - sd->subtype = id->driver_info; - if (sd->subtype != LogitechClickSmart310) { - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - } else { - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - } - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* initialisation of spca500 based cameras is deferred */ - PDEBUG(D_STREAM, "SPCA500 init"); - if (sd->subtype == LogitechClickSmart310) - spca500_clksmart310_init(gspca_dev); -/* else - spca500_initialise(gspca_dev); */ - PDEBUG(D_STREAM, "SPCA500 init done"); - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - __u8 Data; - __u8 xmult, ymult; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, QUALITY); - - if (sd->subtype == LogitechClickSmart310) { - xmult = 0x16; - ymult = 0x12; - } else { - xmult = 0x28; - ymult = 0x1e; - } - - /* is there a sensor here ? */ - reg_r(gspca_dev, 0x8a04, 1); - PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x", - gspca_dev->usb_buf[0]); - PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x", - gspca_dev->curr_mode, xmult, ymult); - - /* setup qtable */ - switch (sd->subtype) { - case LogitechClickSmart310: - spca500_setmode(gspca_dev, xmult, ymult); - - /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - reg_w(gspca_dev, 0x00, 0x8880, 3); - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, 0x8840, - qtable_creative_pccam); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev, 0x00, 0x870a, 0x04); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - msleep(500); - if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - - spca500_synch310(gspca_dev); - - write_vector(gspca_dev, spca500_visual_defaults); - spca500_setmode(gspca_dev, xmult, ymult); - /* enable drop packet */ - err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - if (err < 0) - PDEBUG(D_ERR, "failed to enable drop packet"); - reg_w(gspca_dev, 0x00, 0x8880, 3); - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, 0x8840, - qtable_creative_pccam); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - - /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev, 0x00, 0x870a, 0x04); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - - if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - break; - case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ - case IntelPocketPCCamera: /* FIXME: Temporary fix for - * Intel Pocket PC Camera - * - NWG (Sat 29th March 2003) */ - - /* do a full reset */ - err = spca500_full_reset(gspca_dev); - if (err < 0) - PDEBUG(D_ERR, "spca500_full_reset failed"); - - /* enable drop packet */ - err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - if (err < 0) - PDEBUG(D_ERR, "failed to enable drop packet"); - reg_w(gspca_dev, 0x00, 0x8880, 3); - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, 0x8840, - qtable_creative_pccam); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - - spca500_setmode(gspca_dev, xmult, ymult); - reg_w(gspca_dev, 0x20, 0x0001, 0x0004); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - - if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - -/* write_vector(gspca_dev, spca500_visual_defaults); */ - break; - case KodakEZ200: /* Kodak EZ200 */ - - /* do a full reset */ - err = spca500_full_reset(gspca_dev); - if (err < 0) - PDEBUG(D_ERR, "spca500_full_reset failed"); - /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - reg_w(gspca_dev, 0x00, 0x8880, 0); - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, 0x8840, - qtable_kodak_ez200); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - spca500_setmode(gspca_dev, xmult, ymult); - - reg_w(gspca_dev, 0x20, 0x0001, 0x0004); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - - if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_r_wait() failed"); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - -/* write_vector(gspca_dev, spca500_visual_defaults); */ - break; - - case BenqDC1016: - case DLinkDSC350: /* FamilyCam 300 */ - case AiptekPocketDV: /* Aiptek PocketDV */ - case Gsmartmini: /*Mustek Gsmart Mini */ - case MustekGsmart300: /* Mustek Gsmart 300 */ - case PalmPixDC85: - case Optimedia: - case ToptroIndus: - case AgfaCl20: - spca500_reinit(gspca_dev); - reg_w(gspca_dev, 0x00, 0x0d01, 0x01); - /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, 0x8840, qtable_pocketdv); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_w(gspca_dev, 0x00, 0x8880, 2); - - /* familycam Quicksmart pocketDV stuff */ - reg_w(gspca_dev, 0x00, 0x800a, 0x00); - /* Set agc transfer: synced between frames */ - reg_w(gspca_dev, 0x00, 0x820f, 0x01); - /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev, 0x00, 0x870a, 0x04); - - spca500_setmode(gspca_dev, xmult, ymult); - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - - reg_r_wait(gspca_dev, 0, 0x8000, 0x44); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - break; - case LogitechTraveler: - case LogitechClickSmart510: - reg_w(gspca_dev, 0x02, 0x00, 0x00); - /* enable drop packet */ - reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - - err = spca50x_setup_qtable(gspca_dev, - 0x00, 0x8800, - 0x8840, qtable_creative_pccam); - if (err < 0) - PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_w(gspca_dev, 0x00, 0x8880, 3); - reg_w(gspca_dev, 0x00, 0x800a, 0x00); - /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev, 0x00, 0x870a, 0x04); - - spca500_setmode(gspca_dev, xmult, ymult); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - reg_r_wait(gspca_dev, 0, 0x8000, 0x44); - - reg_r(gspca_dev, 0x816b, 1); - Data = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0x00, 0x816b, Data); - write_vector(gspca_dev, Clicksmart510_defaults); - break; - } - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, 0, 0x8003, 0x00); - - /* switch to video camera mode */ - reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - reg_r(gspca_dev, 0x8000, 1); - PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", - gspca_dev->usb_buf[0]); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - static __u8 ffd9[] = {0xff, 0xd9}; - -/* frames are jpeg 4.1.1 without 0xff escape */ - if (data[0] == 0xff) { - if (data[1] != 0x01) { /* drop packet */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - } - gspca_frame_add(gspca_dev, LAST_PACKET, - ffd9, 2); - - /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - - data += SPCA500_OFFSET_DATA; - len -= SPCA500_OFFSET_DATA; - } else { - data += 1; - len -= 1; - } - - /* add 0x00 after 0xff */ - i = 0; - do { - if (data[i] == 0xff) { - gspca_frame_add(gspca_dev, INTER_PACKET, - data, i + 1); - len -= i; - data += i; - *data = 0x00; - i = 0; - } - i++; - } while (i < len); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0x00, 0x8167, - (__u8) (val - 128)); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0x00, 0x8168, val); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, 0x00, 0x8169, val); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 3); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 63, 1, 31); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 63, 1, 31); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, - {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, - {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, - {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310}, - {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510}, - {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016}, - {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85}, - {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300}, - {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini}, - {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20}, - {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia}, - {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350}, - {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV}, - {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus}, - {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c deleted file mode 100644 index 3b7f777785b4..000000000000 --- a/drivers/media/video/gspca/spca501.c +++ /dev/null @@ -1,2054 +0,0 @@ -/* - * SPCA501 chip based cameras initialization data - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca501" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - unsigned short contrast; - __u8 brightness; - __u8 colors; - __u8 blue_balance; - __u8 red_balance; - - char subtype; -#define Arowana300KCMOSCamera 0 -#define IntelCreateAndShare 1 -#define KodakDVC325 2 -#define MystFromOriUnknownCamera 3 -#define SmileIntlCamera 4 -#define ThreeComHomeConnectLite 5 -#define ViewQuestM318B 6 -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -#define SPCA50X_REG_USB 0x2 /* spca505 501 */ -/* - * Data to initialize a SPCA501. From a capture file provided by Bill Roehl - * With SPCA501 chip description - */ -#define CCDSP_SET /* set CCDSP parameters */ -#define TG_SET /* set time generator set */ -#undef DSPWIN_SET /* set DSP windows parameters */ -#undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */ -#define SPCA501_SNAPBIT 0x80 -#define SPCA501_SNAPCTRL 0x10 -/* Frame packet header offsets for the spca501 */ -#define SPCA501_OFFSET_GPIO 1 -#define SPCA501_OFFSET_TYPE 2 -#define SPCA501_OFFSET_TURN3A 3 -#define SPCA501_OFFSET_FRAMSEQ 4 -#define SPCA501_OFFSET_COMPRESS 5 -#define SPCA501_OFFSET_QUANT 6 -#define SPCA501_OFFSET_QUANT2 7 -#define SPCA501_OFFSET_DATA 8 - -#define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1) -#define SPCA501_PROP_SNAP(d) ((d) & 0x40) -#define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10) -#define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1) -#define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4) - -/* SPCA501 CCDSP control */ -#define SPCA501_REG_CCDSP 0x01 -/* SPCA501 control/status registers */ -#define SPCA501_REG_CTLRL 0x02 - -/* registers for color correction and YUV transformation */ -#define SPCA501_A11 0x08 -#define SPCA501_A12 0x09 -#define SPCA501_A13 0x0A -#define SPCA501_A21 0x0B -#define SPCA501_A22 0x0C -#define SPCA501_A23 0x0D -#define SPCA501_A31 0x0E -#define SPCA501_A32 0x0F -#define SPCA501_A33 0x10 - -/* Data for video camera initialization before capturing */ -static const __u16 spca501_open_data[][3] = { - /* bmRequest,value,index */ - - {0x2, 0x50, 0x00}, /* C/S enable soft reset */ - {0x2, 0x40, 0x00}, /* C/S disable soft reset */ - {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */ - {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */ - -#ifdef CCDSP_SET - {0x1, 0x38, 0x01}, /* CCDSP options */ - {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */ - {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */ - - {0x1, 0x67, 0x07}, - {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */ - {0x1, 0x03, 0x56}, /* Add gamma correction */ - - {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */ - {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */ - -/* Color correction and RGB-to-YUV transformation coefficients changing */ -#ifdef ALTER_GAMA - {0x0, 0x00, 0x08}, /* A11 */ - {0x0, 0x00, 0x09}, /* A12 */ - {0x0, 0x90, 0x0A}, /* A13 */ - {0x0, 0x12, 0x0B}, /* A21 */ - {0x0, 0x00, 0x0C}, /* A22 */ - {0x0, 0x00, 0x0D}, /* A23 */ - {0x0, 0x00, 0x0E}, /* A31 */ - {0x0, 0x02, 0x0F}, /* A32 */ - {0x0, 0x00, 0x10}, /* A33 */ -#else - {0x1, 0x2a, 0x08}, /* A11 0x31 */ - {0x1, 0xf8, 0x09}, /* A12 f8 */ - {0x1, 0xf8, 0x0A}, /* A13 f8 */ - {0x1, 0xf8, 0x0B}, /* A21 f8 */ - {0x1, 0x14, 0x0C}, /* A22 0x14 */ - {0x1, 0xf8, 0x0D}, /* A23 f8 */ - {0x1, 0xf8, 0x0E}, /* A31 f8 */ - {0x1, 0xf8, 0x0F}, /* A32 f8 */ - {0x1, 0x20, 0x10}, /* A33 0x20 */ -#endif - {0x1, 0x00, 0x11}, /* R offset */ - {0x1, 0x00, 0x12}, /* G offset */ - {0x1, 0x00, 0x13}, /* B offset */ - {0x1, 0x00, 0x14}, /* GB offset */ - -#endif - -#ifdef TG_SET - /* Time generator manipulations */ - {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */ - {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */ - - {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */ - {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */ - {0x0, 0x03, 0x06}, /* FR phase adjustment */ - {0x0, 0x01, 0x07}, /* FCDS phase adjustment */ - {0x0, 0x39, 0x08}, /* FS phase adjustment */ - {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */ - {0x0, 0x03, 0x0f}, /* pixel identification */ - {0x0, 0x00, 0x11}, /* clock source selection (default) */ - - /*VERY strange manipulations with - * select DMCLP or OBPX to be ADCLP output (0x0C) - * OPB always toggle or not (0x0D) but they allow - * us to set up brightness - */ - {0x0, 0x01, 0x0c}, - {0x0, 0xe0, 0x0d}, - /* Done */ -#endif - -#ifdef DSPWIN_SET - {0x1, 0xa0, 0x01}, /* Setting image processing parameters */ - {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */ - {0x1, 0xe2, 0x19}, /* X2 */ - {0x1, 0x1c, 0x1b}, /* X3 */ - {0x1, 0xe2, 0x1d}, /* X4 */ - {0x1, 0x5f, 0x1f}, /* X5 */ - {0x1, 0x32, 0x20}, /* Y5 */ - {0x1, 0x01, 0x10}, /* Changing A33 */ -#endif - - {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */ - {0x2, 0x94, 0x06}, /* Setting video no compression */ - {} -}; - -/* - The SPCAxxx docs from Sunplus document these values - in tables, one table per register number. In the data - below, dmRequest is the register number, index is the Addr, - and value is a combination of Bit values. - Bit Value (hex) - 0 01 - 1 02 - 2 04 - 3 08 - 4 10 - 5 20 - 6 40 - 7 80 - */ - -/* Data for chip initialization (set default values) */ -static const __u16 spca501_init_data[][3] = { - /* Set all the values to powerup defaults */ - /* bmRequest,value,index */ - {0x0, 0xAA, 0x00}, - {0x0, 0x02, 0x01}, - {0x0, 0x01, 0x02}, - {0x0, 0x02, 0x03}, - {0x0, 0xCE, 0x04}, - {0x0, 0x00, 0x05}, - {0x0, 0x00, 0x06}, - {0x0, 0x00, 0x07}, - {0x0, 0x00, 0x08}, - {0x0, 0x00, 0x09}, - {0x0, 0x90, 0x0A}, - {0x0, 0x12, 0x0B}, - {0x0, 0x00, 0x0C}, - {0x0, 0x00, 0x0D}, - {0x0, 0x00, 0x0E}, - {0x0, 0x02, 0x0F}, - {0x0, 0x00, 0x10}, - {0x0, 0x00, 0x11}, - {0x0, 0x00, 0x12}, - {0x0, 0x00, 0x13}, - {0x0, 0x00, 0x14}, - {0x0, 0x00, 0x15}, - {0x0, 0x00, 0x16}, - {0x0, 0x00, 0x17}, - {0x0, 0x00, 0x18}, - {0x0, 0x00, 0x19}, - {0x0, 0x00, 0x1A}, - {0x0, 0x00, 0x1B}, - {0x0, 0x00, 0x1C}, - {0x0, 0x00, 0x1D}, - {0x0, 0x00, 0x1E}, - {0x0, 0x00, 0x1F}, - {0x0, 0x00, 0x20}, - {0x0, 0x00, 0x21}, - {0x0, 0x00, 0x22}, - {0x0, 0x00, 0x23}, - {0x0, 0x00, 0x24}, - {0x0, 0x00, 0x25}, - {0x0, 0x00, 0x26}, - {0x0, 0x00, 0x27}, - {0x0, 0x00, 0x28}, - {0x0, 0x00, 0x29}, - {0x0, 0x00, 0x2A}, - {0x0, 0x00, 0x2B}, - {0x0, 0x00, 0x2C}, - {0x0, 0x00, 0x2D}, - {0x0, 0x00, 0x2E}, - {0x0, 0x00, 0x2F}, - {0x0, 0x00, 0x30}, - {0x0, 0x00, 0x31}, - {0x0, 0x00, 0x32}, - {0x0, 0x00, 0x33}, - {0x0, 0x00, 0x34}, - {0x0, 0x00, 0x35}, - {0x0, 0x00, 0x36}, - {0x0, 0x00, 0x37}, - {0x0, 0x00, 0x38}, - {0x0, 0x00, 0x39}, - {0x0, 0x00, 0x3A}, - {0x0, 0x00, 0x3B}, - {0x0, 0x00, 0x3C}, - {0x0, 0x00, 0x3D}, - {0x0, 0x00, 0x3E}, - {0x0, 0x00, 0x3F}, - {0x0, 0x00, 0x40}, - {0x0, 0x00, 0x41}, - {0x0, 0x00, 0x42}, - {0x0, 0x00, 0x43}, - {0x0, 0x00, 0x44}, - {0x0, 0x00, 0x45}, - {0x0, 0x00, 0x46}, - {0x0, 0x00, 0x47}, - {0x0, 0x00, 0x48}, - {0x0, 0x00, 0x49}, - {0x0, 0x00, 0x4A}, - {0x0, 0x00, 0x4B}, - {0x0, 0x00, 0x4C}, - {0x0, 0x00, 0x4D}, - {0x0, 0x00, 0x4E}, - {0x0, 0x00, 0x4F}, - {0x0, 0x00, 0x50}, - {0x0, 0x00, 0x51}, - {0x0, 0x00, 0x52}, - {0x0, 0x00, 0x53}, - {0x0, 0x00, 0x54}, - {0x0, 0x00, 0x55}, - {0x0, 0x00, 0x56}, - {0x0, 0x00, 0x57}, - {0x0, 0x00, 0x58}, - {0x0, 0x00, 0x59}, - {0x0, 0x00, 0x5A}, - {0x0, 0x00, 0x5B}, - {0x0, 0x00, 0x5C}, - {0x0, 0x00, 0x5D}, - {0x0, 0x00, 0x5E}, - {0x0, 0x00, 0x5F}, - {0x0, 0x00, 0x60}, - {0x0, 0x00, 0x61}, - {0x0, 0x00, 0x62}, - {0x0, 0x00, 0x63}, - {0x0, 0x00, 0x64}, - {0x0, 0x00, 0x65}, - {0x0, 0x00, 0x66}, - {0x0, 0x00, 0x67}, - {0x0, 0x00, 0x68}, - {0x0, 0x00, 0x69}, - {0x0, 0x00, 0x6A}, - {0x0, 0x00, 0x6B}, - {0x0, 0x00, 0x6C}, - {0x0, 0x00, 0x6D}, - {0x0, 0x00, 0x6E}, - {0x0, 0x00, 0x6F}, - {0x0, 0x00, 0x70}, - {0x0, 0x00, 0x71}, - {0x0, 0x00, 0x72}, - {0x0, 0x00, 0x73}, - {0x0, 0x00, 0x74}, - {0x0, 0x00, 0x75}, - {0x0, 0x00, 0x76}, - {0x0, 0x00, 0x77}, - {0x0, 0x00, 0x78}, - {0x0, 0x00, 0x79}, - {0x0, 0x00, 0x7A}, - {0x0, 0x00, 0x7B}, - {0x0, 0x00, 0x7C}, - {0x0, 0x00, 0x7D}, - {0x0, 0x00, 0x7E}, - {0x0, 0x00, 0x7F}, - {0x0, 0x00, 0x80}, - {0x0, 0x00, 0x81}, - {0x0, 0x00, 0x82}, - {0x0, 0x00, 0x83}, - {0x0, 0x00, 0x84}, - {0x0, 0x00, 0x85}, - {0x0, 0x00, 0x86}, - {0x0, 0x00, 0x87}, - {0x0, 0x00, 0x88}, - {0x0, 0x00, 0x89}, - {0x0, 0x00, 0x8A}, - {0x0, 0x00, 0x8B}, - {0x0, 0x00, 0x8C}, - {0x0, 0x00, 0x8D}, - {0x0, 0x00, 0x8E}, - {0x0, 0x00, 0x8F}, - {0x0, 0x00, 0x90}, - {0x0, 0x00, 0x91}, - {0x0, 0x00, 0x92}, - {0x0, 0x00, 0x93}, - {0x0, 0x00, 0x94}, - {0x0, 0x00, 0x95}, - {0x0, 0x00, 0x96}, - {0x0, 0x00, 0x97}, - {0x0, 0x00, 0x98}, - {0x0, 0x00, 0x99}, - {0x0, 0x00, 0x9A}, - {0x0, 0x00, 0x9B}, - {0x0, 0x00, 0x9C}, - {0x0, 0x00, 0x9D}, - {0x0, 0x00, 0x9E}, - {0x0, 0x00, 0x9F}, - {0x0, 0x00, 0xA0}, - {0x0, 0x00, 0xA1}, - {0x0, 0x00, 0xA2}, - {0x0, 0x00, 0xA3}, - {0x0, 0x00, 0xA4}, - {0x0, 0x00, 0xA5}, - {0x0, 0x00, 0xA6}, - {0x0, 0x00, 0xA7}, - {0x0, 0x00, 0xA8}, - {0x0, 0x00, 0xA9}, - {0x0, 0x00, 0xAA}, - {0x0, 0x00, 0xAB}, - {0x0, 0x00, 0xAC}, - {0x0, 0x00, 0xAD}, - {0x0, 0x00, 0xAE}, - {0x0, 0x00, 0xAF}, - {0x0, 0x00, 0xB0}, - {0x0, 0x00, 0xB1}, - {0x0, 0x00, 0xB2}, - {0x0, 0x00, 0xB3}, - {0x0, 0x00, 0xB4}, - {0x0, 0x00, 0xB5}, - {0x0, 0x00, 0xB6}, - {0x0, 0x00, 0xB7}, - {0x0, 0x00, 0xB8}, - {0x0, 0x00, 0xB9}, - {0x0, 0x00, 0xBA}, - {0x0, 0x00, 0xBB}, - {0x0, 0x00, 0xBC}, - {0x0, 0x00, 0xBD}, - {0x0, 0x00, 0xBE}, - {0x0, 0x00, 0xBF}, - {0x0, 0x00, 0xC0}, - {0x0, 0x00, 0xC1}, - {0x0, 0x00, 0xC2}, - {0x0, 0x00, 0xC3}, - {0x0, 0x00, 0xC4}, - {0x0, 0x00, 0xC5}, - {0x0, 0x00, 0xC6}, - {0x0, 0x00, 0xC7}, - {0x0, 0x00, 0xC8}, - {0x0, 0x00, 0xC9}, - {0x0, 0x00, 0xCA}, - {0x0, 0x00, 0xCB}, - {0x0, 0x00, 0xCC}, - {0x1, 0xF4, 0x00}, - {0x1, 0x38, 0x01}, - {0x1, 0x40, 0x02}, - {0x1, 0x0A, 0x03}, - {0x1, 0x40, 0x04}, - {0x1, 0x40, 0x05}, - {0x1, 0x40, 0x06}, - {0x1, 0x67, 0x07}, - {0x1, 0x31, 0x08}, - {0x1, 0x00, 0x09}, - {0x1, 0x00, 0x0A}, - {0x1, 0x00, 0x0B}, - {0x1, 0x14, 0x0C}, - {0x1, 0x00, 0x0D}, - {0x1, 0x00, 0x0E}, - {0x1, 0x00, 0x0F}, - {0x1, 0x1E, 0x10}, - {0x1, 0x00, 0x11}, - {0x1, 0x00, 0x12}, - {0x1, 0x00, 0x13}, - {0x1, 0x00, 0x14}, - {0x1, 0xFF, 0x15}, - {0x1, 0x01, 0x16}, - {0x1, 0x32, 0x17}, - {0x1, 0x23, 0x18}, - {0x1, 0xCE, 0x19}, - {0x1, 0x23, 0x1A}, - {0x1, 0x32, 0x1B}, - {0x1, 0x8D, 0x1C}, - {0x1, 0xCE, 0x1D}, - {0x1, 0x8D, 0x1E}, - {0x1, 0x00, 0x1F}, - {0x1, 0x00, 0x20}, - {0x1, 0xFF, 0x3E}, - {0x1, 0x02, 0x3F}, - {0x1, 0x00, 0x40}, - {0x1, 0x00, 0x41}, - {0x1, 0x00, 0x42}, - {0x1, 0x00, 0x43}, - {0x1, 0x00, 0x44}, - {0x1, 0x00, 0x45}, - {0x1, 0x00, 0x46}, - {0x1, 0x00, 0x47}, - {0x1, 0x00, 0x48}, - {0x1, 0x00, 0x49}, - {0x1, 0x00, 0x4A}, - {0x1, 0x00, 0x4B}, - {0x1, 0x00, 0x4C}, - {0x1, 0x00, 0x4D}, - {0x1, 0x00, 0x4E}, - {0x1, 0x00, 0x4F}, - {0x1, 0x00, 0x50}, - {0x1, 0x00, 0x51}, - {0x1, 0x00, 0x52}, - {0x1, 0x00, 0x53}, - {0x1, 0x00, 0x54}, - {0x1, 0x00, 0x55}, - {0x1, 0x00, 0x56}, - {0x1, 0x00, 0x57}, - {0x1, 0x00, 0x58}, - {0x1, 0x00, 0x59}, - {0x1, 0x00, 0x5A}, - {0x2, 0x03, 0x00}, - {0x2, 0x00, 0x01}, - {0x2, 0x00, 0x05}, - {0x2, 0x00, 0x06}, - {0x2, 0x00, 0x07}, - {0x2, 0x00, 0x10}, - {0x2, 0x00, 0x11}, - /* Strange - looks like the 501 driver doesn't do anything - * at insert time except read the EEPROM - */ - {} -}; - -/* Data for video camera init before capture. - * Capture and decoding by Colin Peart. - * This is is for the 3com HomeConnect Lite which is spca501a based. - */ -static const __u16 spca501_3com_open_data[][3] = { - /* bmRequest,value,index */ - {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */ - {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */ - {0x2, 0x0002, 0x0005}, /* C/S GPIO */ - {0x2, 0x0003, 0x0005}, /* C/S GPIO */ - -#ifdef CCDSP_SET - {0x1, 0x0020, 0x0001}, /* CCDSP Options */ - - {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */ - {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */ - {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */ - {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */ - {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */ - -#ifdef ALTER_GAMMA - {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */ - {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */ - {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */ - {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */ - {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */ - {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */ - {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */ - {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */ - {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */ - {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */ - {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */ - {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */ - {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */ - {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */ -#endif -#endif - -#ifdef TG_SET - {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */ - {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */ - {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */ - {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */ - {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */ - {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */ - {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */ - {0x0, 0x0088, 0x000a}, /* TG MH1 */ - {0x0, 0x0003, 0x000f}, /* TG Pixel ID */ - - /* Like below, unexplained toglleing */ - {0x0, 0x0080, 0x000c}, - {0x0, 0x0000, 0x000d}, - {0x0, 0x0080, 0x000c}, - {0x0, 0x0004, 0x000d}, - {0x0, 0x0000, 0x000c}, - {0x0, 0x0000, 0x000d}, - {0x0, 0x0040, 0x000c}, - {0x0, 0x0017, 0x000d}, - {0x0, 0x00c0, 0x000c}, - {0x0, 0x0000, 0x000d}, - {0x0, 0x0080, 0x000c}, - {0x0, 0x0006, 0x000d}, - {0x0, 0x0080, 0x000c}, - {0x0, 0x0004, 0x000d}, - {0x0, 0x0002, 0x0003}, -#endif - -#ifdef DSPWIN_SET - {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */ - {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */ - {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */ - {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */ - {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */ - {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */ -#endif - {0x0, 0x0001, 0x0010}, /* TG Start Clock */ - -/* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */ - {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */ - {0x2, 0x0000, 0x0005}, - {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ - {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ - {0x2, 0x0002, 0x0005}, /* C/S GPIO */ - {0x2, 0x0003, 0x0005}, /* C/S GPIO */ - - {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */ - {} -}; - -/* - * Data used to initialize a SPCA501C with HV7131B sensor. - * From a capture file taken with USBSnoop v 1.5 - * I have a "SPCA501C pc camera chipset" manual by sunplus, but some - * of the value meanings are obscure or simply "reserved". - * to do list: - * 1) Understand what every value means - * 2) Understand why some values seem to appear more than once - * 3) Write a small comment for each line of the following arrays. - */ -static const __u16 spca501c_arowana_open_data[][3] = { - /* bmRequest,value,index */ - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x01, 0x0006, 0x0011}, - {0x01, 0x00ff, 0x0012}, - {0x01, 0x0014, 0x0013}, - {0x01, 0x0000, 0x0014}, - {0x01, 0x0042, 0x0051}, - {0x01, 0x0040, 0x0052}, - {0x01, 0x0051, 0x0053}, - {0x01, 0x0040, 0x0054}, - {0x01, 0x0000, 0x0055}, - {0x00, 0x0025, 0x0000}, - {0x00, 0x0026, 0x0000}, - {0x00, 0x0001, 0x0000}, - {0x00, 0x0027, 0x0000}, - {0x00, 0x008a, 0x0000}, - {} -}; - -static const __u16 spca501c_arowana_init_data[][3] = { - /* bmRequest,value,index */ - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x01, 0x0006, 0x0011}, - {0x01, 0x00ff, 0x0012}, - {0x01, 0x0014, 0x0013}, - {0x01, 0x0000, 0x0014}, - {0x01, 0x0042, 0x0051}, - {0x01, 0x0040, 0x0052}, - {0x01, 0x0051, 0x0053}, - {0x01, 0x0040, 0x0054}, - {0x01, 0x0000, 0x0055}, - {0x00, 0x0025, 0x0000}, - {0x00, 0x0026, 0x0000}, - {0x00, 0x0001, 0x0000}, - {0x00, 0x0027, 0x0000}, - {0x00, 0x008a, 0x0000}, - {0x02, 0x0000, 0x0005}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0xfffd, 0x000a}, - {0x01, 0x0023, 0x000b}, - {0x01, 0xffea, 0x000c}, - {0x01, 0xfff4, 0x000d}, - {0x01, 0xfffc, 0x000e}, - {0x01, 0xffe3, 0x000f}, - {0x01, 0x001f, 0x0010}, - {0x01, 0x00a8, 0x0001}, - {0x01, 0x0067, 0x0007}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x00c8, 0x0015}, - {0x01, 0x0032, 0x0016}, - {0x01, 0x0000, 0x0011}, - {0x01, 0x0000, 0x0012}, - {0x01, 0x0000, 0x0013}, - {0x01, 0x000a, 0x0003}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xc000, 0x0001}, - {0x02, 0x0000, 0x0005}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x000f, 0x0000}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0xfffd, 0x000a}, - {0x01, 0x0023, 0x000b}, - {0x01, 0xffea, 0x000c}, - {0x01, 0xfff4, 0x000d}, - {0x01, 0xfffc, 0x000e}, - {0x01, 0xffe3, 0x000f}, - {0x01, 0x001f, 0x0010}, - {0x01, 0x00a8, 0x0001}, - {0x01, 0x0067, 0x0007}, - {0x01, 0x0042, 0x0051}, - {0x01, 0x0051, 0x0053}, - {0x01, 0x000a, 0x0003}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xc000, 0x0001}, - {0x02, 0x0000, 0x0005}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x000c, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0000, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, - {0x00, 0x0000, 0x0024}, - {0x00, 0x00d5, 0x0025}, - {0x00, 0x0000, 0x0026}, - {0x00, 0x000b, 0x0027}, - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, - {0xff, 0x0000, 0x00d0}, - {0xff, 0x00d8, 0x00d1}, - {0xff, 0x0000, 0x00d4}, - {0xff, 0x0000, 0x00d5}, - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0x00fd, 0x000a}, - {0x01, 0x0038, 0x000b}, - {0x01, 0x00d1, 0x000c}, - {0x01, 0x00f7, 0x000d}, - {0x01, 0x00ed, 0x000e}, - {0x01, 0x00d8, 0x000f}, - {0x01, 0x0038, 0x0010}, - {0x01, 0x00ff, 0x0015}, - {0x01, 0x0001, 0x0016}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, - {0x01, 0x00ff, 0x003e}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0060, 0x0057}, - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x100a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x001e, 0x0000}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x0011, 0x0008}, - {0x01, 0x0032, 0x0009}, - {0x01, 0xfffd, 0x000a}, - {0x01, 0x0023, 0x000b}, - {0x01, 0xffea, 0x000c}, - {0x01, 0xfff4, 0x000d}, - {0x01, 0xfffc, 0x000e}, - {0x01, 0xffe3, 0x000f}, - {0x01, 0x001f, 0x0010}, - {0x01, 0x00a8, 0x0001}, - {0x01, 0x0067, 0x0007}, - {0x01, 0x0042, 0x0051}, - {0x01, 0x0051, 0x0053}, - {0x01, 0x000a, 0x0003}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x0007, 0x0005}, - {0x01, 0x0042, 0x0051}, - {0x01, 0x0051, 0x0053}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x002d, 0x0000}, - {0x01, 0x0003, 0x003f}, - {0x01, 0x0001, 0x0056}, - {0x02, 0xc000, 0x0001}, - {0x02, 0x0000, 0x0005}, - {} -}; - -/* Unknown camera from Ori Usbid 0x0000:0x0000 */ -/* Based on snoops from Ori Cohen */ -static const __u16 spca501c_mysterious_open_data[][3] = { - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, -/* DSP Registers */ - {0x01, 0x0016, 0x0011}, /* RGB offset */ - {0x01, 0x0000, 0x0012}, - {0x01, 0x0006, 0x0013}, - {0x01, 0x0078, 0x0051}, - {0x01, 0x0040, 0x0052}, - {0x01, 0x0046, 0x0053}, - {0x01, 0x0040, 0x0054}, - {0x00, 0x0025, 0x0000}, -/* {0x00, 0x0000, 0x0000 }, */ -/* Part 2 */ -/* TG Registers */ - {0x00, 0x0026, 0x0000}, - {0x00, 0x0001, 0x0000}, - {0x00, 0x0027, 0x0000}, - {0x00, 0x008a, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x2000, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0015, 0x0001}, - {0x05, 0x00ea, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0023, 0x0001}, - {0x05, 0x0003, 0x0000}, - {0x05, 0x0030, 0x0001}, - {0x05, 0x002b, 0x0000}, - {0x05, 0x0031, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0032, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0033, 0x0001}, - {0x05, 0x0023, 0x0000}, - {0x05, 0x0034, 0x0001}, - {0x05, 0x0002, 0x0000}, - {0x05, 0x0050, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0051, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0052, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0054, 0x0001}, - {0x05, 0x0001, 0x0000}, - {} -}; - -/* Based on snoops from Ori Cohen */ -static const __u16 spca501c_mysterious_init_data[][3] = { -/* Part 3 */ -/* TG registers */ -/* {0x00, 0x0000, 0x0000}, */ - {0x00, 0x0000, 0x0001}, - {0x00, 0x0000, 0x0002}, - {0x00, 0x0006, 0x0003}, - {0x00, 0x0000, 0x0004}, - {0x00, 0x0090, 0x0005}, - {0x00, 0x0000, 0x0006}, - {0x00, 0x0040, 0x0007}, - {0x00, 0x00c0, 0x0008}, - {0x00, 0x004a, 0x0009}, - {0x00, 0x0000, 0x000a}, - {0x00, 0x0000, 0x000b}, - {0x00, 0x0001, 0x000c}, - {0x00, 0x0001, 0x000d}, - {0x00, 0x0000, 0x000e}, - {0x00, 0x0002, 0x000f}, - {0x00, 0x0001, 0x0010}, - {0x00, 0x0000, 0x0011}, - {0x00, 0x0001, 0x0012}, - {0x00, 0x0002, 0x0020}, - {0x00, 0x0080, 0x0021}, /* 640 */ - {0x00, 0x0001, 0x0022}, - {0x00, 0x00e0, 0x0023}, /* 480 */ - {0x00, 0x0000, 0x0024}, /* Offset H hight */ - {0x00, 0x00d3, 0x0025}, /* low */ - {0x00, 0x0000, 0x0026}, /* Offset V */ - {0x00, 0x000d, 0x0027}, /* low */ - {0x00, 0x0000, 0x0046}, - {0x00, 0x0000, 0x0047}, - {0x00, 0x0000, 0x0048}, - {0x00, 0x0000, 0x0049}, - {0x00, 0x0008, 0x004a}, -/* DSP Registers */ - {0x01, 0x00a6, 0x0000}, - {0x01, 0x0028, 0x0001}, - {0x01, 0x0000, 0x0002}, - {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */ - {0x01, 0x0040, 0x0004}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */ - {0x01, 0x002d, 0x0009}, /* A12 */ - {0x01, 0x0005, 0x000a}, /* A13 */ - {0x01, 0x0023, 0x000b}, /* A21 */ - {0x01, 0x00e0, 0x000c}, /* A22 */ - {0x01, 0x00fd, 0x000d}, /* A23 */ - {0x01, 0x00f4, 0x000e}, /* A31 */ - {0x01, 0x00e4, 0x000f}, /* A32 */ - {0x01, 0x0028, 0x0010}, /* A33 */ - {0x01, 0x00ff, 0x0015}, /* Reserved */ - {0x01, 0x0001, 0x0016}, /* Reserved */ - {0x01, 0x0032, 0x0017}, /* Win1 Start begin */ - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x0000, 0x001f}, - {0x01, 0x0000, 0x0020}, /* Win1 Start end */ - {0x01, 0x00ff, 0x003e}, /* Reserved begin */ - {0x01, 0x0002, 0x003f}, - {0x01, 0x0000, 0x0040}, - {0x01, 0x0035, 0x0041}, - {0x01, 0x0053, 0x0042}, - {0x01, 0x0069, 0x0043}, - {0x01, 0x007c, 0x0044}, - {0x01, 0x008c, 0x0045}, - {0x01, 0x009a, 0x0046}, - {0x01, 0x00a8, 0x0047}, - {0x01, 0x00b4, 0x0048}, - {0x01, 0x00bf, 0x0049}, - {0x01, 0x00ca, 0x004a}, - {0x01, 0x00d4, 0x004b}, - {0x01, 0x00dd, 0x004c}, - {0x01, 0x00e7, 0x004d}, - {0x01, 0x00ef, 0x004e}, - {0x01, 0x00f8, 0x004f}, - {0x01, 0x00ff, 0x0050}, - {0x01, 0x0003, 0x0056}, /* Reserved end */ - {0x01, 0x0060, 0x0057}, /* Edge Gain */ - {0x01, 0x0040, 0x0058}, - {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */ - {0x01, 0x0001, 0x005a}, - {0x02, 0x0007, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x02, 0x0007, 0x0005}, - {0x02, 0x0015, 0x0006}, - {0x02, 0x200a, 0x0007}, - {0x02, 0xa048, 0x0000}, - {0x02, 0xc000, 0x0001}, - {0x02, 0x000f, 0x0005}, - {0x02, 0xa048, 0x0000}, - {0x05, 0x0022, 0x0004}, - {0x05, 0x0025, 0x0001}, - {0x05, 0x0000, 0x0000}, -/* Part 4 */ - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0001, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x05, 0x0021, 0x0001}, - {0x05, 0x00d2, 0x0000}, - {0x05, 0x0020, 0x0001}, - {0x05, 0x0000, 0x0000}, - {0x00, 0x0090, 0x0005}, - {0x01, 0x00a6, 0x0000}, - {0x02, 0x0000, 0x0005}, - {0x05, 0x0026, 0x0001}, - {0x05, 0x0001, 0x0000}, - {0x05, 0x0027, 0x0001}, - {0x05, 0x004e, 0x0000}, -/* Part 5 */ - {0x01, 0x0003, 0x003f}, - {0x01, 0x0001, 0x0056}, - {0x01, 0x000f, 0x0008}, - {0x01, 0x002d, 0x0009}, - {0x01, 0x0005, 0x000a}, - {0x01, 0x0023, 0x000b}, - {0x01, 0xffe0, 0x000c}, - {0x01, 0xfffd, 0x000d}, - {0x01, 0xfff4, 0x000e}, - {0x01, 0xffe4, 0x000f}, - {0x01, 0x0028, 0x0010}, - {0x01, 0x00a8, 0x0001}, - {0x01, 0x0066, 0x0007}, - {0x01, 0x0032, 0x0017}, - {0x01, 0x0023, 0x0018}, - {0x01, 0x00ce, 0x0019}, - {0x01, 0x0023, 0x001a}, - {0x01, 0x0032, 0x001b}, - {0x01, 0x008d, 0x001c}, - {0x01, 0x00ce, 0x001d}, - {0x01, 0x008d, 0x001e}, - {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */ - {0x01, 0x0032, 0x0016}, /* 32 */ - {0x01, 0x0016, 0x0011}, /* R 00 */ - {0x01, 0x0016, 0x0012}, /* G 00 */ - {0x01, 0x0016, 0x0013}, /* B 00 */ - {0x01, 0x000a, 0x0003}, - {0x02, 0xc002, 0x0001}, - {0x02, 0x0007, 0x0005}, - {} -}; - -static int reg_write(struct usb_device *dev, - __u16 req, __u16 index, __u16 value) -{ - int ret; - - ret = usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - req, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", - req, index, value); - if (ret < 0) - pr_err("reg write: error %d\n", ret); - return ret; -} - - -static int write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][3]) -{ - struct usb_device *dev = gspca_dev->dev; - int ret, i = 0; - - while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); - if (ret < 0) { - PDEBUG(D_ERR, - "Reg write failed for 0x%02x,0x%02x,0x%02x", - data[i][0], data[i][1], data[i][2]); - return ret; - } - i++; - } - return 0; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - reg_write(gspca_dev->dev, 0x00, 0x00, - (val >> 8) & 0xff); - reg_write(gspca_dev->dev, 0x00, 0x01, - val & 0xff); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, val); -} - -static void setblue_balance(struct gspca_dev *gspca_dev, s32 val) -{ - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, val); -} - -static void setred_balance(struct gspca_dev *gspca_dev, s32 val) -{ - reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, val); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - sd->subtype = id->driver_info; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->subtype) { - case Arowana300KCMOSCamera: - case SmileIntlCamera: - /* Arowana 300k CMOS Camera data */ - if (write_vector(gspca_dev, spca501c_arowana_init_data)) - goto error; - break; - case MystFromOriUnknownCamera: - /* Unknown Ori CMOS Camera data */ - if (write_vector(gspca_dev, spca501c_mysterious_open_data)) - goto error; - break; - default: - /* generic spca501 init data */ - if (write_vector(gspca_dev, spca501_init_data)) - goto error; - break; - } - PDEBUG(D_STREAM, "Initializing SPCA501 finished"); - return 0; -error: - return -EINVAL; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - int mode; - - switch (sd->subtype) { - case ThreeComHomeConnectLite: - /* Special handling for 3com data */ - write_vector(gspca_dev, spca501_3com_open_data); - break; - case Arowana300KCMOSCamera: - case SmileIntlCamera: - /* Arowana 300k CMOS Camera data */ - write_vector(gspca_dev, spca501c_arowana_open_data); - break; - case MystFromOriUnknownCamera: - /* Unknown CMOS Camera data */ - write_vector(gspca_dev, spca501c_mysterious_init_data); - break; - default: - /* Generic 501 open data */ - write_vector(gspca_dev, spca501_open_data); - } - - /* memorize the wanted pixel format */ - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - - /* Enable ISO packet machine CTRL reg=2, - * index=1 bitmask=0x2 (bit ordinal 1) */ - reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94); - switch (mode) { - case 0: /* 640x480 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a); - break; - case 1: /* 320x240 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a); - break; - default: -/* case 2: * 160x120 */ - reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a); - break; - } - reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* Disable ISO packet - * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */ - reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); -} - -/* called on streamoff with alt 0 and on disconnect */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - if (!gspca_dev->present) - return; - reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - switch (data[0]) { - case 0: /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - data += SPCA501_OFFSET_DATA; - len -= SPCA501_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - return; - case 0xff: /* drop */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - } - data++; - len--; - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_BLUE_BALANCE: - setblue_balance(gspca_dev, ctrl->val); - break; - case V4L2_CID_RED_BALANCE: - setred_balance(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 127, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 64725, 1, 64725); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 63, 1, 20); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 127, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325}, - {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera}, - {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite}, - {USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare}, - {USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B}, - {USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera}, - {USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c deleted file mode 100644 index bc7d67c3cb04..000000000000 --- a/drivers/media/video/gspca/spca505.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * SPCA505 chip based cameras initialization data - * - * V4L2 by Jean-Francis Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca505" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - u8 subtype; -#define IntelPCCameraPro 0 -#define Nxultra 1 -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, - {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -#define SPCA50X_OFFSET_DATA 10 - -#define SPCA50X_REG_USB 0x02 /* spca505 501 */ - -#define SPCA50X_USB_CTRL 0x00 /* spca505 */ -#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ - -#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ -#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ -#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ - -#define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */ -#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ -#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ - -/* Image format and compression control */ -#define SPCA50X_REG_COMPRESS 0x04 - -/* - * Data to initialize a SPCA505. Common to the CCD and external modes - */ -static const u8 spca505_init_data[][3] = { - /* bmRequest,value,index */ - {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, - /* Sensor reset */ - {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, - {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, - /* Block USB reset */ - {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0}, - - {0x05, 0x01, 0x10}, - /* Maybe power down some stuff */ - {0x05, 0x0f, 0x11}, - - /* Setup internal CCD ? */ - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, - {} -}; - -/* - * Data to initialize the camera using the internal CCD - */ -static const u8 spca505_open_data_ccd[][3] = { - /* bmRequest,value,index */ - /* Internal CCD data set */ - {0x03, 0x04, 0x01}, - /* This could be a reset */ - {0x03, 0x00, 0x01}, - - /* Setup compression and image registers. 0x6 and 0x7 seem to be - related to H&V hold, and are resolution mode specific */ - {0x04, 0x10, 0x01}, - /* DIFF(0x50), was (0x10) */ - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x20, 0x06}, - {0x04, 0x20, 0x07}, - - {0x08, 0x0a, 0x00}, - /* DIFF (0x4a), was (0xa) */ - - {0x05, 0x00, 0x10}, - {0x05, 0x00, 0x11}, - {0x05, 0x00, 0x00}, - /* DIFF not written */ - {0x05, 0x00, 0x01}, - /* DIFF not written */ - {0x05, 0x00, 0x02}, - /* DIFF not written */ - {0x05, 0x00, 0x03}, - /* DIFF not written */ - {0x05, 0x00, 0x04}, - /* DIFF not written */ - {0x05, 0x80, 0x05}, - /* DIFF not written */ - {0x05, 0xe0, 0x06}, - /* DIFF not written */ - {0x05, 0x20, 0x07}, - /* DIFF not written */ - {0x05, 0xa0, 0x08}, - /* DIFF not written */ - {0x05, 0x0, 0x12}, - /* DIFF not written */ - {0x05, 0x02, 0x0f}, - /* DIFF not written */ - {0x05, 0x10, 0x46}, - /* DIFF not written */ - {0x05, 0x8, 0x4a}, - /* DIFF not written */ - - {0x03, 0x08, 0x03}, - /* DIFF (0x3,0x28,0x3) */ - {0x03, 0x08, 0x01}, - {0x03, 0x0c, 0x03}, - /* DIFF not written */ - {0x03, 0x21, 0x00}, - /* DIFF (0x39) */ - -/* Extra block copied from init to hopefully ensure CCD is in a sane state */ - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, - /* End of extra block */ - - {0x06, 0x3f, 0x1}, - /* Block skipped */ - {0x06, 0x10, 0x02}, - {0x06, 0x64, 0x07}, - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, - {0x06, 0x60, 0x57}, - {0x06, 0x20, 0x58}, - {0x06, 0x15, 0x59}, - {0x06, 0x05, 0x5a}, - - {0x05, 0x01, 0xc0}, - {0x05, 0x10, 0xcb}, - {0x05, 0x80, 0xc1}, - /* */ - {0x05, 0x0, 0xc2}, - /* 4 was 0 */ - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, - /* */ - {0x05, 0x04, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x0, 0xc1}, - /* */ - {0x05, 0x00, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x40, 0xc1}, - /* */ - {0x05, 0x17, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, - /* */ - {0x05, 0x06, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, - /* */ - {0x05, 0x04, 0xc2}, - {0x05, 0x00, 0xca}, - - {0x03, 0x4c, 0x3}, - {0x03, 0x18, 0x1}, - - {0x06, 0x70, 0x51}, - {0x06, 0xbe, 0x53}, - {0x06, 0x71, 0x57}, - {0x06, 0x20, 0x58}, - {0x06, 0x05, 0x59}, - {0x06, 0x15, 0x5a}, - - {0x04, 0x00, 0x08}, - /* Compress = OFF (0x1 to turn on) */ - {0x04, 0x12, 0x09}, - {0x04, 0x21, 0x0a}, - {0x04, 0x10, 0x0b}, - {0x04, 0x21, 0x0c}, - {0x04, 0x05, 0x00}, - /* was 5 (Image Type ? ) */ - {0x04, 0x00, 0x01}, - - {0x06, 0x3f, 0x01}, - - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x40, 0x06}, - {0x04, 0x40, 0x07}, - - {0x06, 0x1c, 0x17}, - {0x06, 0xe2, 0x19}, - {0x06, 0x1c, 0x1b}, - {0x06, 0xe2, 0x1d}, - {0x06, 0xaa, 0x1f}, - {0x06, 0x70, 0x20}, - - {0x05, 0x01, 0x10}, - {0x05, 0x00, 0x11}, - {0x05, 0x01, 0x00}, - {0x05, 0x05, 0x01}, - {0x05, 0x00, 0xc1}, - /* */ - {0x05, 0x00, 0xc2}, - {0x05, 0x00, 0xca}, - - {0x06, 0x70, 0x51}, - {0x06, 0xbe, 0x53}, - {} -}; - -/* - * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) - * SPCA505b chip based cameras initialization data - */ -/* jfm */ -#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ -/* #define initial_brightness 0x0 //0x0(white)-0xff(black) */ -/* - * Data to initialize a SPCA505. Common to the CCD and external modes - */ -static const u8 spca505b_init_data[][3] = { -/* start */ - {0x02, 0x00, 0x00}, /* init */ - {0x02, 0x00, 0x01}, - {0x02, 0x00, 0x02}, - {0x02, 0x00, 0x03}, - {0x02, 0x00, 0x04}, - {0x02, 0x00, 0x05}, - {0x02, 0x00, 0x06}, - {0x02, 0x00, 0x07}, - {0x02, 0x00, 0x08}, - {0x02, 0x00, 0x09}, - {0x03, 0x00, 0x00}, - {0x03, 0x00, 0x01}, - {0x03, 0x00, 0x02}, - {0x03, 0x00, 0x03}, - {0x03, 0x00, 0x04}, - {0x03, 0x00, 0x05}, - {0x03, 0x00, 0x06}, - {0x04, 0x00, 0x00}, - {0x04, 0x00, 0x02}, - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x00, 0x06}, - {0x04, 0x00, 0x07}, - {0x04, 0x00, 0x08}, - {0x04, 0x00, 0x09}, - {0x04, 0x00, 0x0a}, - {0x04, 0x00, 0x0b}, - {0x04, 0x00, 0x0c}, - {0x07, 0x00, 0x00}, - {0x07, 0x00, 0x03}, - {0x08, 0x00, 0x00}, - {0x08, 0x00, 0x01}, - {0x08, 0x00, 0x02}, - {0x06, 0x18, 0x08}, - {0x06, 0xfc, 0x09}, - {0x06, 0xfc, 0x0a}, - {0x06, 0xfc, 0x0b}, - {0x06, 0x18, 0x0c}, - {0x06, 0xfc, 0x0d}, - {0x06, 0xfc, 0x0e}, - {0x06, 0xfc, 0x0f}, - {0x06, 0x18, 0x10}, - {0x06, 0xfe, 0x12}, - {0x06, 0x00, 0x11}, - {0x06, 0x00, 0x14}, - {0x06, 0x00, 0x13}, - {0x06, 0x28, 0x51}, - {0x06, 0xff, 0x53}, - {0x02, 0x00, 0x08}, - - {0x03, 0x00, 0x03}, - {0x03, 0x10, 0x03}, - {} -}; - -/* - * Data to initialize the camera using the internal CCD - */ -static const u8 spca505b_open_data_ccd[][3] = { - -/* {0x02,0x00,0x00}, */ - {0x03, 0x04, 0x01}, /* rst */ - {0x03, 0x00, 0x01}, - {0x03, 0x00, 0x00}, - {0x03, 0x21, 0x00}, - {0x03, 0x00, 0x04}, - {0x03, 0x00, 0x03}, - {0x03, 0x18, 0x03}, - {0x03, 0x08, 0x01}, - {0x03, 0x1c, 0x03}, - {0x03, 0x5c, 0x03}, - {0x03, 0x5c, 0x03}, - {0x03, 0x18, 0x01}, - -/* same as 505 */ - {0x04, 0x10, 0x01}, - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x20, 0x06}, - {0x04, 0x20, 0x07}, - - {0x08, 0x0a, 0x00}, - - {0x05, 0x00, 0x10}, - {0x05, 0x00, 0x11}, - {0x05, 0x00, 0x12}, - {0x05, 0x6f, 0x00}, - {0x05, initial_brightness >> 6, 0x00}, - {0x05, (initial_brightness << 2) & 0xff, 0x01}, - {0x05, 0x00, 0x02}, - {0x05, 0x01, 0x03}, - {0x05, 0x00, 0x04}, - {0x05, 0x03, 0x05}, - {0x05, 0xe0, 0x06}, - {0x05, 0x20, 0x07}, - {0x05, 0xa0, 0x08}, - {0x05, 0x00, 0x12}, - {0x05, 0x02, 0x0f}, - {0x05, 0x80, 0x14}, /* max exposure off (0=on) */ - {0x05, 0x01, 0xb0}, - {0x05, 0x01, 0xbf}, - {0x03, 0x02, 0x06}, - {0x05, 0x10, 0x46}, - {0x05, 0x08, 0x4a}, - - {0x06, 0x00, 0x01}, - {0x06, 0x10, 0x02}, - {0x06, 0x64, 0x07}, - {0x06, 0x18, 0x08}, - {0x06, 0xfc, 0x09}, - {0x06, 0xfc, 0x0a}, - {0x06, 0xfc, 0x0b}, - {0x04, 0x00, 0x01}, - {0x06, 0x18, 0x0c}, - {0x06, 0xfc, 0x0d}, - {0x06, 0xfc, 0x0e}, - {0x06, 0xfc, 0x0f}, - {0x06, 0x11, 0x10}, /* contrast */ - {0x06, 0x00, 0x11}, - {0x06, 0xfe, 0x12}, - {0x06, 0x00, 0x13}, - {0x06, 0x00, 0x14}, - {0x06, 0x9d, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0x7c, 0x53}, - {0x06, 0x40, 0x54}, - {0x06, 0x02, 0x57}, - {0x06, 0x03, 0x58}, - {0x06, 0x15, 0x59}, - {0x06, 0x05, 0x5a}, - {0x06, 0x03, 0x56}, - {0x06, 0x02, 0x3f}, - {0x06, 0x00, 0x40}, - {0x06, 0x39, 0x41}, - {0x06, 0x69, 0x42}, - {0x06, 0x87, 0x43}, - {0x06, 0x9e, 0x44}, - {0x06, 0xb1, 0x45}, - {0x06, 0xbf, 0x46}, - {0x06, 0xcc, 0x47}, - {0x06, 0xd5, 0x48}, - {0x06, 0xdd, 0x49}, - {0x06, 0xe3, 0x4a}, - {0x06, 0xe8, 0x4b}, - {0x06, 0xed, 0x4c}, - {0x06, 0xf2, 0x4d}, - {0x06, 0xf7, 0x4e}, - {0x06, 0xfc, 0x4f}, - {0x06, 0xff, 0x50}, - - {0x05, 0x01, 0xc0}, - {0x05, 0x10, 0xcb}, - {0x05, 0x40, 0xc1}, - {0x05, 0x04, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x40, 0xc1}, - {0x05, 0x09, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0xc0, 0xc1}, - {0x05, 0x09, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x40, 0xc1}, - {0x05, 0x59, 0xc2}, - {0x05, 0x00, 0xca}, - {0x04, 0x00, 0x01}, - {0x05, 0x80, 0xc1}, - {0x05, 0xec, 0xc2}, - {0x05, 0x0, 0xca}, - - {0x06, 0x02, 0x57}, - {0x06, 0x01, 0x58}, - {0x06, 0x15, 0x59}, - {0x06, 0x0a, 0x5a}, - {0x06, 0x01, 0x57}, - {0x06, 0x8a, 0x03}, - {0x06, 0x0a, 0x6c}, - {0x06, 0x30, 0x01}, - {0x06, 0x20, 0x02}, - {0x06, 0x00, 0x03}, - - {0x05, 0x8c, 0x25}, - - {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ - {0x06, 0x84, 0x53}, /* making green (84) */ - {0x06, 0x00, 0x57}, /* sharpness (1) */ - {0x06, 0x18, 0x08}, - {0x06, 0xfc, 0x09}, - {0x06, 0xfc, 0x0a}, - {0x06, 0xfc, 0x0b}, - {0x06, 0x18, 0x0c}, /* maybe hue (18) */ - {0x06, 0xfc, 0x0d}, - {0x06, 0xfc, 0x0e}, - {0x06, 0xfc, 0x0f}, - {0x06, 0x18, 0x10}, /* maybe contrast (18) */ - - {0x05, 0x01, 0x02}, - - {0x04, 0x00, 0x08}, /* compression */ - {0x04, 0x12, 0x09}, - {0x04, 0x21, 0x0a}, - {0x04, 0x10, 0x0b}, - {0x04, 0x21, 0x0c}, - {0x04, 0x1d, 0x00}, /* imagetype (1d) */ - {0x04, 0x41, 0x01}, /* hardware snapcontrol */ - - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x10, 0x06}, - {0x04, 0x10, 0x07}, - {0x04, 0x40, 0x06}, - {0x04, 0x40, 0x07}, - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - - {0x06, 0x1c, 0x17}, - {0x06, 0xe2, 0x19}, - {0x06, 0x1c, 0x1b}, - {0x06, 0xe2, 0x1d}, - {0x06, 0x5f, 0x1f}, - {0x06, 0x32, 0x20}, - - {0x05, initial_brightness >> 6, 0x00}, - {0x05, (initial_brightness << 2) & 0xff, 0x01}, - {0x05, 0x06, 0xc1}, - {0x05, 0x58, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x00, 0x11}, - {} -}; - -static int reg_write(struct usb_device *dev, - u16 req, u16 index, u16 value) -{ - int ret; - - ret = usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - req, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", - req, index, value, ret); - if (ret < 0) - pr_err("reg write: error %d\n", ret); - return ret; -} - -/* returns: negative is error, pos or zero is data */ -static int reg_read(struct gspca_dev *gspca_dev, - u16 req, /* bRequest */ - u16 index) /* wIndex */ -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - gspca_dev->usb_buf, 2, - 500); /* timeout */ - if (ret < 0) - return ret; - return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; -} - -static int write_vector(struct gspca_dev *gspca_dev, - const u8 data[][3]) -{ - struct usb_device *dev = gspca_dev->dev; - int ret, i = 0; - - while (data[i][0] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); - if (ret < 0) - return ret; - i++; - } - return 0; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - sd->subtype = id->driver_info; - if (sd->subtype != IntelPCCameraPro) - cam->nmodes = ARRAY_SIZE(vga_mode); - else /* no 640x480 for IntelPCCameraPro */ - cam->nmodes = ARRAY_SIZE(vga_mode) - 1; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (write_vector(gspca_dev, - sd->subtype == Nxultra - ? spca505b_init_data - : spca505_init_data)) - return -EIO; - return 0; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) -{ - reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); - reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - int ret, mode; - static u8 mode_tb[][3] = { - /* r00 r06 r07 */ - {0x00, 0x10, 0x10}, /* 640x480 */ - {0x01, 0x1a, 0x1a}, /* 352x288 */ - {0x02, 0x1c, 0x1d}, /* 320x240 */ - {0x04, 0x34, 0x34}, /* 176x144 */ - {0x05, 0x40, 0x40} /* 160x120 */ - }; - - if (sd->subtype == Nxultra) - write_vector(gspca_dev, spca505b_open_data_ccd); - else - write_vector(gspca_dev, spca505_open_data_ccd); - ret = reg_read(gspca_dev, 0x06, 0x16); - - if (ret < 0) { - PDEBUG(D_ERR|D_CONF, - "register read failed err: %d", - ret); - return ret; - } - if (ret != 0x0101) { - pr_err("After vector read returns 0x%04x should be 0x0101\n", - ret); - } - - ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); - if (ret < 0) - return ret; - reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); - - /* necessary because without it we can see stream - * only once after loading module */ - /* stopping usb registers Tomasz change */ - reg_write(dev, 0x02, 0x00, 0x00); - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); - - return reg_write(dev, SPCA50X_REG_USB, - SPCA50X_USB_CTRL, - SPCA50X_CUSB_ENABLE); -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* Disable ISO packet machine */ - reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); -} - -/* called on streamoff with alt 0 and on disconnect */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - if (!gspca_dev->present) - return; - - /* This maybe reset or power control */ - reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); - reg_write(gspca_dev->dev, 0x03, 0x01, 0x00); - reg_write(gspca_dev->dev, 0x03, 0x00, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x10, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - switch (data[0]) { - case 0: /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - data += SPCA50X_OFFSET_DATA; - len -= SPCA50X_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - break; - case 0xff: /* drop */ - break; - default: - data += 1; - len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - break; - } -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init_controls = sd_init_controls, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, - {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, -/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c deleted file mode 100644 index 969bb5a4cd93..000000000000 --- a/drivers/media/video/gspca/spca506.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * SPCA506 chip based cameras function - * M Xhaard 15/04/2004 based on different work Mark Taylor and others - * and my own snoopy file on a pv-321c donate by a german compagny - * "Firma Frank Gmbh" from Saarbruecken - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MODULE_NAME "spca506" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - char norme; - char channel; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 5}, - {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, - {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -#define SPCA50X_OFFSET_DATA 10 - -#define SAA7113_bright 0x0a /* defaults 0x80 */ -#define SAA7113_contrast 0x0b /* defaults 0x47 */ -#define SAA7113_saturation 0x0c /* defaults 0x40 */ -#define SAA7113_hue 0x0d /* defaults 0x00 */ -#define SAA7113_I2C_BASE_WRITE 0x4a - -/* read 'len' bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 req, - __u16 index, - __u16 length) -{ - usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, length, - 500); -} - -static void reg_w(struct usb_device *dev, - __u16 req, - __u16 value, - __u16 index) -{ - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, - NULL, 0, 500); -} - -static void spca506_Initi2c(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); -} - -static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, - __u16 reg) -{ - int retry = 60; - - reg_w(gspca_dev->dev, 0x07, reg, 0x0001); - reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); - while (retry--) { - reg_r(gspca_dev, 0x07, 0x0003, 2); - if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) - break; - } -} - -static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, - __u16 norme, - __u16 channel) -{ - struct sd *sd = (struct sd *) gspca_dev; -/* fixme: check if channel == 0..3 and 6..9 (8 values) */ - __u8 setbit0 = 0x00; - __u8 setbit1 = 0x00; - __u8 videomask = 0x00; - - PDEBUG(D_STREAM, "** Open Set Norme **"); - spca506_Initi2c(gspca_dev); - /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */ - /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */ - /* and exclude SAA7113 reserved channel set default 0 otherwise */ - if (norme & V4L2_STD_NTSC) - setbit0 = 0x01; - if (channel == 4 || channel == 5 || channel > 9) - channel = 0; - if (channel < 4) - setbit1 = 0x02; - videomask = (0x48 | setbit0 | setbit1); - reg_w(gspca_dev->dev, 0x08, videomask, 0x0000); - spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02); - - if (norme & V4L2_STD_NTSC) - spca506_WriteI2c(gspca_dev, 0x33, 0x0e); - /* Chrominance Control NTSC N */ - else if (norme & V4L2_STD_SECAM) - spca506_WriteI2c(gspca_dev, 0x53, 0x0e); - /* Chrominance Control SECAM */ - else - spca506_WriteI2c(gspca_dev, 0x03, 0x0e); - /* Chrominance Control PAL BGHIV */ - - sd->norme = norme; - sd->channel = channel; - PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask); - PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel); -} - -static void spca506_GetNormeInput(struct gspca_dev *gspca_dev, - __u16 *norme, __u16 *channel) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Read the register is not so good value change so - we use your own copy in spca50x struct */ - *norme = sd->norme; - *channel = sd->channel; - PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel); -} - -static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, - __u16 xmult, __u16 ymult) -{ - struct usb_device *dev = gspca_dev->dev; - - PDEBUG(D_STREAM, "** SetSize **"); - reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000); - /* Soft snap 0x40 Hard 0x41 */ - reg_w(dev, 0x04, 0x41, 0x0001); - reg_w(dev, 0x04, 0x00, 0x0002); - /* reserved */ - reg_w(dev, 0x04, 0x00, 0x0003); - - /* reserved */ - reg_w(dev, 0x04, 0x00, 0x0004); - /* reserved */ - reg_w(dev, 0x04, 0x01, 0x0005); - /* reserced */ - reg_w(dev, 0x04, xmult, 0x0006); - /* reserved */ - reg_w(dev, 0x04, ymult, 0x0007); - /* compression 1 */ - reg_w(dev, 0x04, 0x00, 0x0008); - /* T=64 -> 2 */ - reg_w(dev, 0x04, 0x00, 0x0009); - /* threshold2D */ - reg_w(dev, 0x04, 0x21, 0x000a); - /* quantization */ - reg_w(dev, 0x04, 0x00, 0x000b); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct usb_device *dev = gspca_dev->dev; - - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0xFF, 0x0003); - reg_w(dev, 0x03, 0x00, 0x0000); - reg_w(dev, 0x03, 0x1c, 0x0001); - reg_w(dev, 0x03, 0x18, 0x0001); - /* Init on PAL and composite input0 */ - spca506_SetNormeInput(gspca_dev, 0, 0); - reg_w(dev, 0x03, 0x1c, 0x0001); - reg_w(dev, 0x03, 0x18, 0x0001); - reg_w(dev, 0x05, 0x00, 0x0000); - reg_w(dev, 0x05, 0xef, 0x0001); - reg_w(dev, 0x05, 0x00, 0x00c1); - reg_w(dev, 0x05, 0x00, 0x00c2); - reg_w(dev, 0x06, 0x18, 0x0002); - reg_w(dev, 0x06, 0xf5, 0x0011); - reg_w(dev, 0x06, 0x02, 0x0012); - reg_w(dev, 0x06, 0xfb, 0x0013); - reg_w(dev, 0x06, 0x00, 0x0014); - reg_w(dev, 0x06, 0xa4, 0x0051); - reg_w(dev, 0x06, 0x40, 0x0052); - reg_w(dev, 0x06, 0x71, 0x0053); - reg_w(dev, 0x06, 0x40, 0x0054); - /************************************************/ - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0x00, 0x0003); - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0xFF, 0x0003); - reg_w(dev, 0x02, 0x00, 0x0000); - reg_w(dev, 0x03, 0x60, 0x0000); - reg_w(dev, 0x03, 0x18, 0x0001); - /* for a better reading mx :) */ - /*sdca506_WriteI2c(value,register) */ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, 0x08, 0x01); - spca506_WriteI2c(gspca_dev, 0xc0, 0x02); - /* input composite video */ - spca506_WriteI2c(gspca_dev, 0x33, 0x03); - spca506_WriteI2c(gspca_dev, 0x00, 0x04); - spca506_WriteI2c(gspca_dev, 0x00, 0x05); - spca506_WriteI2c(gspca_dev, 0x0d, 0x06); - spca506_WriteI2c(gspca_dev, 0xf0, 0x07); - spca506_WriteI2c(gspca_dev, 0x98, 0x08); - spca506_WriteI2c(gspca_dev, 0x03, 0x09); - spca506_WriteI2c(gspca_dev, 0x80, 0x0a); - spca506_WriteI2c(gspca_dev, 0x47, 0x0b); - spca506_WriteI2c(gspca_dev, 0x48, 0x0c); - spca506_WriteI2c(gspca_dev, 0x00, 0x0d); - spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */ - spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); - spca506_WriteI2c(gspca_dev, 0x00, 0x10); - spca506_WriteI2c(gspca_dev, 0x0c, 0x11); - spca506_WriteI2c(gspca_dev, 0xb8, 0x12); - spca506_WriteI2c(gspca_dev, 0x01, 0x13); - spca506_WriteI2c(gspca_dev, 0x00, 0x14); - spca506_WriteI2c(gspca_dev, 0x00, 0x15); - spca506_WriteI2c(gspca_dev, 0x00, 0x16); - spca506_WriteI2c(gspca_dev, 0x00, 0x17); - spca506_WriteI2c(gspca_dev, 0x00, 0x18); - spca506_WriteI2c(gspca_dev, 0x00, 0x19); - spca506_WriteI2c(gspca_dev, 0x00, 0x1a); - spca506_WriteI2c(gspca_dev, 0x00, 0x1b); - spca506_WriteI2c(gspca_dev, 0x00, 0x1c); - spca506_WriteI2c(gspca_dev, 0x00, 0x1d); - spca506_WriteI2c(gspca_dev, 0x00, 0x1e); - spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); - spca506_WriteI2c(gspca_dev, 0x02, 0x40); - spca506_WriteI2c(gspca_dev, 0xff, 0x41); - spca506_WriteI2c(gspca_dev, 0xff, 0x42); - spca506_WriteI2c(gspca_dev, 0xff, 0x43); - spca506_WriteI2c(gspca_dev, 0xff, 0x44); - spca506_WriteI2c(gspca_dev, 0xff, 0x45); - spca506_WriteI2c(gspca_dev, 0xff, 0x46); - spca506_WriteI2c(gspca_dev, 0xff, 0x47); - spca506_WriteI2c(gspca_dev, 0xff, 0x48); - spca506_WriteI2c(gspca_dev, 0xff, 0x49); - spca506_WriteI2c(gspca_dev, 0xff, 0x4a); - spca506_WriteI2c(gspca_dev, 0xff, 0x4b); - spca506_WriteI2c(gspca_dev, 0xff, 0x4c); - spca506_WriteI2c(gspca_dev, 0xff, 0x4d); - spca506_WriteI2c(gspca_dev, 0xff, 0x4e); - spca506_WriteI2c(gspca_dev, 0xff, 0x4f); - spca506_WriteI2c(gspca_dev, 0xff, 0x50); - spca506_WriteI2c(gspca_dev, 0xff, 0x51); - spca506_WriteI2c(gspca_dev, 0xff, 0x52); - spca506_WriteI2c(gspca_dev, 0xff, 0x53); - spca506_WriteI2c(gspca_dev, 0xff, 0x54); - spca506_WriteI2c(gspca_dev, 0xff, 0x55); - spca506_WriteI2c(gspca_dev, 0xff, 0x56); - spca506_WriteI2c(gspca_dev, 0xff, 0x57); - spca506_WriteI2c(gspca_dev, 0x00, 0x58); - spca506_WriteI2c(gspca_dev, 0x54, 0x59); - spca506_WriteI2c(gspca_dev, 0x07, 0x5a); - spca506_WriteI2c(gspca_dev, 0x83, 0x5b); - spca506_WriteI2c(gspca_dev, 0x00, 0x5c); - spca506_WriteI2c(gspca_dev, 0x00, 0x5d); - spca506_WriteI2c(gspca_dev, 0x00, 0x5e); - spca506_WriteI2c(gspca_dev, 0x00, 0x5f); - spca506_WriteI2c(gspca_dev, 0x00, 0x60); - spca506_WriteI2c(gspca_dev, 0x05, 0x61); - spca506_WriteI2c(gspca_dev, 0x9f, 0x62); - PDEBUG(D_STREAM, "** Close Init *"); - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct usb_device *dev = gspca_dev->dev; - __u16 norme; - __u16 channel; - - /**************************************/ - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0x00, 0x0003); - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0xFF, 0x0003); - reg_w(dev, 0x02, 0x00, 0x0000); - reg_w(dev, 0x03, 0x60, 0x0000); - reg_w(dev, 0x03, 0x18, 0x0001); - - /*sdca506_WriteI2c(value,register) */ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */ -/* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */ - spca506_WriteI2c(gspca_dev, 0x33, 0x03); - /* Analog Input Control 2 */ - spca506_WriteI2c(gspca_dev, 0x00, 0x04); - /* Analog Input Control 3 */ - spca506_WriteI2c(gspca_dev, 0x00, 0x05); - /* Analog Input Control 4 */ - spca506_WriteI2c(gspca_dev, 0x0d, 0x06); - /* Horizontal Sync Start 0xe9-0x0d */ - spca506_WriteI2c(gspca_dev, 0xf0, 0x07); - /* Horizontal Sync Stop 0x0d-0xf0 */ - - spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */ -/* Defaults value */ - spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */ - spca506_WriteI2c(gspca_dev, 0x80, 0x0a); - /* Luminance Brightness */ - spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */ - spca506_WriteI2c(gspca_dev, 0x48, 0x0c); - /* Chrominance Saturation */ - spca506_WriteI2c(gspca_dev, 0x00, 0x0d); - /* Chrominance Hue Control */ - spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); - /* Chrominance Gain Control */ - /**************************************/ - spca506_WriteI2c(gspca_dev, 0x00, 0x10); - /* Format/Delay Control */ - spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */ - spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */ - spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */ - spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */ - spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */ - spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */ - spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */ - spca506_WriteI2c(gspca_dev, 0x00, 0x18); - spca506_WriteI2c(gspca_dev, 0x00, 0x19); - spca506_WriteI2c(gspca_dev, 0x00, 0x1a); - spca506_WriteI2c(gspca_dev, 0x00, 0x1b); - spca506_WriteI2c(gspca_dev, 0x00, 0x1c); - spca506_WriteI2c(gspca_dev, 0x00, 0x1d); - spca506_WriteI2c(gspca_dev, 0x00, 0x1e); - spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); - spca506_WriteI2c(gspca_dev, 0x02, 0x40); - spca506_WriteI2c(gspca_dev, 0xff, 0x41); - spca506_WriteI2c(gspca_dev, 0xff, 0x42); - spca506_WriteI2c(gspca_dev, 0xff, 0x43); - spca506_WriteI2c(gspca_dev, 0xff, 0x44); - spca506_WriteI2c(gspca_dev, 0xff, 0x45); - spca506_WriteI2c(gspca_dev, 0xff, 0x46); - spca506_WriteI2c(gspca_dev, 0xff, 0x47); - spca506_WriteI2c(gspca_dev, 0xff, 0x48); - spca506_WriteI2c(gspca_dev, 0xff, 0x49); - spca506_WriteI2c(gspca_dev, 0xff, 0x4a); - spca506_WriteI2c(gspca_dev, 0xff, 0x4b); - spca506_WriteI2c(gspca_dev, 0xff, 0x4c); - spca506_WriteI2c(gspca_dev, 0xff, 0x4d); - spca506_WriteI2c(gspca_dev, 0xff, 0x4e); - spca506_WriteI2c(gspca_dev, 0xff, 0x4f); - spca506_WriteI2c(gspca_dev, 0xff, 0x50); - spca506_WriteI2c(gspca_dev, 0xff, 0x51); - spca506_WriteI2c(gspca_dev, 0xff, 0x52); - spca506_WriteI2c(gspca_dev, 0xff, 0x53); - spca506_WriteI2c(gspca_dev, 0xff, 0x54); - spca506_WriteI2c(gspca_dev, 0xff, 0x55); - spca506_WriteI2c(gspca_dev, 0xff, 0x56); - spca506_WriteI2c(gspca_dev, 0xff, 0x57); - spca506_WriteI2c(gspca_dev, 0x00, 0x58); - spca506_WriteI2c(gspca_dev, 0x54, 0x59); - spca506_WriteI2c(gspca_dev, 0x07, 0x5a); - spca506_WriteI2c(gspca_dev, 0x83, 0x5b); - spca506_WriteI2c(gspca_dev, 0x00, 0x5c); - spca506_WriteI2c(gspca_dev, 0x00, 0x5d); - spca506_WriteI2c(gspca_dev, 0x00, 0x5e); - spca506_WriteI2c(gspca_dev, 0x00, 0x5f); - spca506_WriteI2c(gspca_dev, 0x00, 0x60); - spca506_WriteI2c(gspca_dev, 0x05, 0x61); - spca506_WriteI2c(gspca_dev, 0x9f, 0x62); - /**************************************/ - reg_w(dev, 0x05, 0x00, 0x0003); - reg_w(dev, 0x05, 0x00, 0x0004); - reg_w(dev, 0x03, 0x10, 0x0001); - reg_w(dev, 0x03, 0x78, 0x0000); - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - case 0: - spca506_Setsize(gspca_dev, 0, 0x10, 0x10); - break; - case 1: - spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a); - break; - case 2: - spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c); - break; - case 4: - spca506_Setsize(gspca_dev, 4, 0x34, 0x34); - break; - default: -/* case 5: */ - spca506_Setsize(gspca_dev, 5, 0x40, 0x40); - break; - } - - /* compress setting and size */ - /* set i2c luma */ - reg_w(dev, 0x02, 0x01, 0x0000); - reg_w(dev, 0x03, 0x12, 0x0000); - reg_r(gspca_dev, 0x04, 0x0001, 2); - PDEBUG(D_STREAM, "webcam started"); - spca506_GetNormeInput(gspca_dev, &norme, &channel); - spca506_SetNormeInput(gspca_dev, norme, channel); - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct usb_device *dev = gspca_dev->dev; - - reg_w(dev, 0x02, 0x00, 0x0000); - reg_w(dev, 0x03, 0x00, 0x0004); - reg_w(dev, 0x03, 0x00, 0x0003); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - switch (data[0]) { - case 0: /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - data += SPCA50X_OFFSET_DATA; - len -= SPCA50X_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - break; - case 0xff: /* drop */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - break; - default: - data += 1; - len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - break; - } -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, val, SAA7113_bright); - spca506_WriteI2c(gspca_dev, 0x01, 0x09); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, val, SAA7113_contrast); - spca506_WriteI2c(gspca_dev, 0x01, 0x09); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, val, SAA7113_saturation); - spca506_WriteI2c(gspca_dev, 0x01, 0x09); -} - -static void sethue(struct gspca_dev *gspca_dev, s32 val) -{ - spca506_Initi2c(gspca_dev); - spca506_WriteI2c(gspca_dev, val, SAA7113_hue); - spca506_WriteI2c(gspca_dev, 0x01, 0x09); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_HUE: - sethue(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 0x47); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 0x40); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, 0, 255, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] __devinitconst = { - {USB_DEVICE(0x06e1, 0xa190)}, -/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 - {USB_DEVICE(0x0733, 0x0430)}, */ - {USB_DEVICE(0x0734, 0x043b)}, - {USB_DEVICE(0x99fa, 0x8988)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c deleted file mode 100644 index 1286b4170b88..000000000000 --- a/drivers/media/video/gspca/spca508.c +++ /dev/null @@ -1,1540 +0,0 @@ -/* - * SPCA508 chip based cameras subdriver - * - * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca508" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - u8 subtype; -#define CreativeVista 0 -#define HamaUSBSightcam 1 -#define HamaUSBSightcam2 2 -#define IntelEasyPCCamera 3 -#define MicroInnovationIC200 4 -#define ViewQuestVQ110 5 -}; - -static const struct v4l2_pix_format sif_mode[] = { - {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* Frame packet header offsets for the spca508 */ -#define SPCA508_OFFSET_DATA 37 - -/* - * Initialization data: this is the first set-up data written to the - * device (before the open data). - */ -static const u16 spca508_init_data[][2] = { - {0x0000, 0x870b}, - - {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ - {0x0003, 0x8111}, /* Reset compression & memory */ - {0x0000, 0x8110}, /* Disable all outputs */ - /* READ {0x0000, 0x8114} -> 0000: 00 */ - {0x0000, 0x8114}, /* SW GPIO data */ - {0x0008, 0x8110}, /* Enable charge pump output */ - {0x0002, 0x8116}, /* 200 kHz pump clock */ - /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ - {0x0003, 0x8111}, /* Reset compression & memory */ - {0x0000, 0x8111}, /* Normal mode (not reset) */ - {0x0098, 0x8110}, - /* Enable charge pump output, sync.serial,external 2x clock */ - {0x000d, 0x8114}, /* SW GPIO data */ - {0x0002, 0x8116}, /* 200 kHz pump clock */ - {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ -/* --------------------------------------- */ - {0x000f, 0x8402}, /* memory bank */ - {0x0000, 0x8403}, /* ... address */ -/* --------------------------------------- */ -/* 0x88__ is Synchronous Serial Interface. */ -/* TBD: This table could be expressed more compactly */ -/* using spca508_write_i2c_vector(). */ -/* TBD: Should see if the values in spca50x_i2c_data */ -/* would work with the VQ110 instead of the values */ -/* below. */ - {0x00c0, 0x8804}, /* SSI slave addr */ - {0x0008, 0x8802}, /* 375 Khz SSI clock */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, /* 375 Khz SSI clock */ - {0x0012, 0x8801}, /* SSI reg addr */ - {0x0080, 0x8800}, /* SSI data to write */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, /* 375 Khz SSI clock */ - {0x0012, 0x8801}, /* SSI reg addr */ - {0x0000, 0x8800}, /* SSI data to write */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, /* 375 Khz SSI clock */ - {0x0011, 0x8801}, /* SSI reg addr */ - {0x0040, 0x8800}, /* SSI data to write */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0013, 0x8801}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0014, 0x8801}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0015, 0x8801}, - {0x0001, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0016, 0x8801}, - {0x0003, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0017, 0x8801}, - {0x0036, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0018, 0x8801}, - {0x00ec, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x001a, 0x8801}, - {0x0094, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x001b, 0x8801}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0027, 0x8801}, - {0x00a2, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0028, 0x8801}, - {0x0040, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x002a, 0x8801}, - {0x0084, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x002b, 0x8801}, - {0x00a8, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x002c, 0x8801}, - {0x00fe, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x002d, 0x8801}, - {0x0003, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0038, 0x8801}, - {0x0083, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0033, 0x8801}, - {0x0081, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0034, 0x8801}, - {0x004a, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0039, 0x8801}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0010, 0x8801}, - {0x00a8, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0006, 0x8801}, - {0x0058, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0000, 0x8801}, - {0x0004, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0040, 0x8801}, - {0x0080, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0041, 0x8801}, - {0x000c, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0042, 0x8801}, - {0x000c, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0043, 0x8801}, - {0x0028, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0044, 0x8801}, - {0x0080, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0045, 0x8801}, - {0x0020, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0046, 0x8801}, - {0x0020, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0047, 0x8801}, - {0x0080, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0048, 0x8801}, - {0x004c, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x0049, 0x8801}, - {0x0084, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x004a, 0x8801}, - {0x0084, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x0008, 0x8802}, - {0x004b, 0x8801}, - {0x0084, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* --------------------------------------- */ - {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ - {0x0000, 0x8701}, /* CKx1 clock delay adj */ - {0x0000, 0x8701}, /* CKx1 clock delay adj */ - {0x0001, 0x870c}, /* CKOx2 output */ - /* --------------------------------------- */ - {0x0080, 0x8600}, /* Line memory read counter (L) */ - {0x0001, 0x8606}, /* reserved */ - {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */ - {0x002a, 0x8601}, /* CDSP sharp interpolation mode, - * line sel for color sep, edge enhance enab */ - {0x0000, 0x8602}, /* optical black level for user settng = 0 */ - {0x0080, 0x8600}, /* Line memory read counter (L) */ - {0x000a, 0x8603}, /* optical black level calc mode: - * auto; optical black offset = 10 */ - {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */ - {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */ - -/* The following two lines seem to be the "wrong" resolution. */ -/* But perhaps these indicate the actual size of the sensor */ -/* rather than the size of the current video mode. */ - {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */ - {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */ - - {0x0015, 0x8608}, /* A11 Coef ... */ - {0x0030, 0x8609}, - {0x00fb, 0x860a}, - {0x003e, 0x860b}, - {0x00ce, 0x860c}, - {0x00f4, 0x860d}, - {0x00eb, 0x860e}, - {0x00dc, 0x860f}, - {0x0039, 0x8610}, - {0x0001, 0x8611}, /* R offset for white balance ... */ - {0x0000, 0x8612}, - {0x0001, 0x8613}, - {0x0000, 0x8614}, - {0x005b, 0x8651}, /* R gain for white balance ... */ - {0x0040, 0x8652}, - {0x0060, 0x8653}, - {0x0040, 0x8654}, - {0x0000, 0x8655}, - {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control, - * lum filter disable, lum noise clip disable */ - {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64, - * gamma look-up disable, - * new edge enhancement enable */ - {0x0018, 0x8657}, /* Edge gain high thresh */ - {0x0020, 0x8658}, /* Edge gain low thresh */ - {0x000a, 0x8659}, /* Edge bandwidth high threshold */ - {0x0005, 0x865a}, /* Edge bandwidth low threshold */ - /* -------------------------------- */ - {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0xa908, 0x8802}, - {0x0034, 0x8801}, /* SSI reg addr */ - {0x00ca, 0x8800}, - /* SSI data to write */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0x1f08, 0x8802}, - {0x0006, 0x8801}, - {0x0080, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - -/* ----- Read back coefs we wrote earlier. */ - /* READ { 0x0000, 0x8608 } -> 0000: 15 */ - /* READ { 0x0000, 0x8609 } -> 0000: 30 */ - /* READ { 0x0000, 0x860a } -> 0000: fb */ - /* READ { 0x0000, 0x860b } -> 0000: 3e */ - /* READ { 0x0000, 0x860c } -> 0000: ce */ - /* READ { 0x0000, 0x860d } -> 0000: f4 */ - /* READ { 0x0000, 0x860e } -> 0000: eb */ - /* READ { 0x0000, 0x860f } -> 0000: dc */ - /* READ { 0x0000, 0x8610 } -> 0000: 39 */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 08 */ - {0xb008, 0x8802}, - {0x0006, 0x8801}, - {0x007d, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - - /* This chunk is seemingly redundant with */ - /* earlier commands (A11 Coef...), but if I disable it, */ - /* the image appears too dark. Maybe there was some kind of */ - /* reset since the earlier commands, so this is necessary again. */ - {0x0015, 0x8608}, - {0x0030, 0x8609}, - {0xfffb, 0x860a}, - {0x003e, 0x860b}, - {0xffce, 0x860c}, - {0xfff4, 0x860d}, - {0xffeb, 0x860e}, - {0xffdc, 0x860f}, - {0x0039, 0x8610}, - {0x0018, 0x8657}, - - {0x0000, 0x8508}, /* Disable compression. */ - /* Previous line was: - {0x0021, 0x8508}, * Enable compression. */ - {0x0032, 0x850b}, /* compression stuff */ - {0x0003, 0x8509}, /* compression stuff */ - {0x0011, 0x850a}, /* compression stuff */ - {0x0021, 0x850d}, /* compression stuff */ - {0x0010, 0x850c}, /* compression stuff */ - {0x0003, 0x8500}, /* *** Video mode: 160x120 */ - {0x0001, 0x8501}, /* Hardware-dominated snap control */ - {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, - * gamma look-up disable, - * new edge enhancement enable */ - {0x0018, 0x8617}, /* Window1 start X (*2) */ - {0x0008, 0x8618}, /* Window1 start Y (*2) */ - {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, - * gamma look-up disable, - * new edge enhancement enable */ - {0x0058, 0x8619}, /* Window2 start X (*2) */ - {0x0008, 0x861a}, /* Window2 start Y (*2) */ - {0x00ff, 0x8615}, /* High lum thresh for white balance */ - {0x0000, 0x8616}, /* Low lum thresh for white balance */ - {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ - {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ - /* READ { 0x0000, 0x8656 } -> 0000: 61 */ - {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 28 */ - {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ - {0x0010, 0x8801}, /* SSI reg addr */ - {0x003e, 0x8800}, /* SSI data to write */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - {0x0028, 0x8802}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 28 */ - {0x1f28, 0x8802}, - {0x0000, 0x8801}, - {0x001f, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - {0x0001, 0x8602}, /* optical black level for user settning = 1 */ - - /* Original: */ - {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ - {0x000f, 0x8602}, /* optical black level for user settning = 15 */ - - {0x0028, 0x8802}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 28 */ - {0x1f28, 0x8802}, - {0x0010, 0x8801}, - {0x007b, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - {0x002f, 0x8651}, /* R gain for white balance ... */ - {0x0080, 0x8653}, - /* READ { 0x0000, 0x8655 } -> 0000: 00 */ - {0x0000, 0x8655}, - - {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ - {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ - /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ - {} -}; - -/* - * Initialization data for Intel EasyPC Camera CS110 - */ -static const u16 spca508cs110_init_data[][2] = { - {0x0000, 0x870b}, /* Reset CTL3 */ - {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ - {0x0000, 0x8111}, /* Normal operation on reset */ - {0x0090, 0x8110}, - /* External Clock 2x & Synchronous Serial Interface Output */ - {0x0020, 0x8112}, /* Video Drop packet enable */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0003, 0x8114}, - - /* Initial sequence Synchronous Serial Interface */ - {0x000f, 0x8402}, /* Memory bank Address */ - {0x0000, 0x8403}, /* Memory bank Address */ - {0x00ba, 0x8804}, /* SSI Slave address */ - {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ - {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ - - {0x0001, 0x8801}, - {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */ - {0x0000, 0x8800}, - {0x0010, 0x8802}, - - {0x0002, 0x8801}, - {0x0000, 0x8805}, - {0x0000, 0x8800}, - {0x0010, 0x8802}, - - {0x0003, 0x8801}, - {0x0027, 0x8805}, - {0x0001, 0x8800}, - {0x0010, 0x8802}, - - {0x0004, 0x8801}, - {0x0065, 0x8805}, - {0x0001, 0x8800}, - {0x0010, 0x8802}, - - {0x0005, 0x8801}, - {0x0003, 0x8805}, - {0x0000, 0x8800}, - {0x0010, 0x8802}, - - {0x0006, 0x8801}, - {0x001c, 0x8805}, - {0x0000, 0x8800}, - {0x0010, 0x8802}, - - {0x0007, 0x8801}, - {0x002a, 0x8805}, - {0x0000, 0x8800}, - {0x0010, 0x8802}, - - {0x0002, 0x8704}, /* External input CKIx1 */ - {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ - {0x009a, 0x8600}, /* Line memory Read Counter (L) */ - {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ - {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ - {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ - - {0x0006, 0x8660}, /* Nibble data + input order */ - - {0x000a, 0x8602}, /* Optical black level set to 0x0a */ - {0x0000, 0x8603}, /* Optical black level Offset */ - -/* {0x0000, 0x8611}, * 0 R Offset for white Balance */ -/* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */ -/* {0x0000, 0x8613}, * 1f B Offset for white Balance */ -/* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */ - - {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ - {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ - {0x0035, 0x8653}, /* 26 RED gain for white balance */ - {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ - {0x0041, 0x863f}, - /* Fixed Gamma correction enabled (makes colours look better) */ - - {0x0000, 0x8655}, - /* High bits for white balance*****brightness control*** */ - {} -}; - -static const u16 spca508_sightcam_init_data[][2] = { -/* This line seems to setup the frame/canvas */ - {0x000f, 0x8402}, - -/* These 6 lines are needed to startup the webcam */ - {0x0090, 0x8110}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0003, 0x8114}, - {0x0080, 0x8804}, - -/* This part seems to make the pictures darker? (autobrightness?) */ - {0x0001, 0x8801}, - {0x0004, 0x8800}, - {0x0003, 0x8801}, - {0x00e0, 0x8800}, - {0x0004, 0x8801}, - {0x00b4, 0x8800}, - {0x0005, 0x8801}, - {0x0000, 0x8800}, - - {0x0006, 0x8801}, - {0x00e0, 0x8800}, - {0x0007, 0x8801}, - {0x000c, 0x8800}, - -/* This section is just needed, it probably - * does something like the previous section, - * but the cam won't start if it's not included. - */ - {0x0014, 0x8801}, - {0x0008, 0x8800}, - {0x0015, 0x8801}, - {0x0067, 0x8800}, - {0x0016, 0x8801}, - {0x0000, 0x8800}, - {0x0017, 0x8801}, - {0x0020, 0x8800}, - {0x0018, 0x8801}, - {0x0044, 0x8800}, - -/* Makes the picture darker - and the - * cam won't start if not included - */ - {0x001e, 0x8801}, - {0x00ea, 0x8800}, - {0x001f, 0x8801}, - {0x0001, 0x8800}, - {0x0003, 0x8801}, - {0x00e0, 0x8800}, - -/* seems to place the colors ontop of each other #1 */ - {0x0006, 0x8704}, - {0x0001, 0x870c}, - {0x0016, 0x8600}, - {0x0002, 0x8606}, - -/* if not included the pictures becomes _very_ dark */ - {0x0064, 0x8607}, - {0x003a, 0x8601}, - {0x0000, 0x8602}, - -/* seems to place the colors ontop of each other #2 */ - {0x0016, 0x8600}, - {0x0018, 0x8617}, - {0x0008, 0x8618}, - {0x00a1, 0x8656}, - -/* webcam won't start if not included */ - {0x0007, 0x865b}, - {0x0001, 0x865c}, - {0x0058, 0x865d}, - {0x0048, 0x865e}, - -/* adjusts the colors */ - {0x0049, 0x8651}, - {0x0040, 0x8652}, - {0x004c, 0x8653}, - {0x0040, 0x8654}, - {} -}; - -static const u16 spca508_sightcam2_init_data[][2] = { - {0x0020, 0x8112}, - - {0x000f, 0x8402}, - {0x0000, 0x8403}, - - {0x0008, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x0009, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000a, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000b, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000c, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000d, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000e, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x0007, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x000f, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - - {0x0018, 0x8660}, - {0x0010, 0x8201}, - - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x0011, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - - {0x0000, 0x86b0}, - {0x0034, 0x86b1}, - {0x0000, 0x86b2}, - {0x0049, 0x86b3}, - {0x0000, 0x86b4}, - {0x0000, 0x86b4}, - - {0x0012, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - {0x0013, 0x8201}, - {0x0008, 0x8200}, - {0x0001, 0x8200}, - - {0x0001, 0x86b0}, - {0x00aa, 0x86b1}, - {0x0000, 0x86b2}, - {0x00e4, 0x86b3}, - {0x0000, 0x86b4}, - {0x0000, 0x86b4}, - - {0x0018, 0x8660}, - - {0x0090, 0x8110}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0003, 0x8114}, - - {0x0080, 0x8804}, - {0x0003, 0x8801}, - {0x0012, 0x8800}, - {0x0004, 0x8801}, - {0x0005, 0x8800}, - {0x0005, 0x8801}, - {0x0000, 0x8800}, - {0x0006, 0x8801}, - {0x0000, 0x8800}, - {0x0007, 0x8801}, - {0x0000, 0x8800}, - {0x0008, 0x8801}, - {0x0005, 0x8800}, - {0x000a, 0x8700}, - {0x000e, 0x8801}, - {0x0004, 0x8800}, - {0x0005, 0x8801}, - {0x0047, 0x8800}, - {0x0006, 0x8801}, - {0x0000, 0x8800}, - {0x0007, 0x8801}, - {0x00c0, 0x8800}, - {0x0008, 0x8801}, - {0x0003, 0x8800}, - {0x0013, 0x8801}, - {0x0001, 0x8800}, - {0x0009, 0x8801}, - {0x0000, 0x8800}, - {0x000a, 0x8801}, - {0x0000, 0x8800}, - {0x000b, 0x8801}, - {0x0000, 0x8800}, - {0x000c, 0x8801}, - {0x0000, 0x8800}, - {0x000e, 0x8801}, - {0x0004, 0x8800}, - {0x000f, 0x8801}, - {0x0000, 0x8800}, - {0x0010, 0x8801}, - {0x0006, 0x8800}, - {0x0011, 0x8801}, - {0x0006, 0x8800}, - {0x0012, 0x8801}, - {0x0000, 0x8800}, - {0x0013, 0x8801}, - {0x0001, 0x8800}, - - {0x000a, 0x8700}, - {0x0000, 0x8702}, - {0x0000, 0x8703}, - {0x00c2, 0x8704}, - {0x0001, 0x870c}, - - {0x0044, 0x8600}, - {0x0002, 0x8606}, - {0x0064, 0x8607}, - {0x003a, 0x8601}, - {0x0008, 0x8602}, - {0x0044, 0x8600}, - {0x0018, 0x8617}, - {0x0008, 0x8618}, - {0x00a1, 0x8656}, - {0x0004, 0x865b}, - {0x0002, 0x865c}, - {0x0058, 0x865d}, - {0x0048, 0x865e}, - {0x0012, 0x8608}, - {0x002c, 0x8609}, - {0x0002, 0x860a}, - {0x002c, 0x860b}, - {0x00db, 0x860c}, - {0x00f9, 0x860d}, - {0x00f1, 0x860e}, - {0x00e3, 0x860f}, - {0x002c, 0x8610}, - {0x006c, 0x8651}, - {0x0041, 0x8652}, - {0x0059, 0x8653}, - {0x0040, 0x8654}, - {0x00fa, 0x8611}, - {0x00ff, 0x8612}, - {0x00f8, 0x8613}, - {0x0000, 0x8614}, - {0x0001, 0x863f}, - {0x0000, 0x8640}, - {0x0026, 0x8641}, - {0x0045, 0x8642}, - {0x0060, 0x8643}, - {0x0075, 0x8644}, - {0x0088, 0x8645}, - {0x009b, 0x8646}, - {0x00b0, 0x8647}, - {0x00c5, 0x8648}, - {0x00d2, 0x8649}, - {0x00dc, 0x864a}, - {0x00e5, 0x864b}, - {0x00eb, 0x864c}, - {0x00f0, 0x864d}, - {0x00f6, 0x864e}, - {0x00fa, 0x864f}, - {0x00ff, 0x8650}, - {0x0060, 0x8657}, - {0x0010, 0x8658}, - {0x0018, 0x8659}, - {0x0005, 0x865a}, - {0x0018, 0x8660}, - {0x0003, 0x8509}, - {0x0011, 0x850a}, - {0x0032, 0x850b}, - {0x0010, 0x850c}, - {0x0021, 0x850d}, - {0x0001, 0x8500}, - {0x0000, 0x8508}, - {0x0012, 0x8608}, - {0x002c, 0x8609}, - {0x0002, 0x860a}, - {0x0039, 0x860b}, - {0x00d0, 0x860c}, - {0x00f7, 0x860d}, - {0x00ed, 0x860e}, - {0x00db, 0x860f}, - {0x0039, 0x8610}, - {0x0012, 0x8657}, - {0x000c, 0x8619}, - {0x0004, 0x861a}, - {0x00a1, 0x8656}, - {0x00c8, 0x8615}, - {0x0032, 0x8616}, - - {0x0030, 0x8112}, - {0x0020, 0x8112}, - {0x0020, 0x8112}, - {0x000f, 0x8402}, - {0x0000, 0x8403}, - - {0x0090, 0x8110}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0003, 0x8114}, - {0x0080, 0x8804}, - - {0x0003, 0x8801}, - {0x0012, 0x8800}, - {0x0004, 0x8801}, - {0x0005, 0x8800}, - {0x0005, 0x8801}, - {0x0047, 0x8800}, - {0x0006, 0x8801}, - {0x0000, 0x8800}, - {0x0007, 0x8801}, - {0x00c0, 0x8800}, - {0x0008, 0x8801}, - {0x0003, 0x8800}, - {0x000a, 0x8700}, - {0x000e, 0x8801}, - {0x0004, 0x8800}, - {0x0005, 0x8801}, - {0x0047, 0x8800}, - {0x0006, 0x8801}, - {0x0000, 0x8800}, - {0x0007, 0x8801}, - {0x00c0, 0x8800}, - {0x0008, 0x8801}, - {0x0003, 0x8800}, - {0x0013, 0x8801}, - {0x0001, 0x8800}, - {0x0009, 0x8801}, - {0x0000, 0x8800}, - {0x000a, 0x8801}, - {0x0000, 0x8800}, - {0x000b, 0x8801}, - {0x0000, 0x8800}, - {0x000c, 0x8801}, - {0x0000, 0x8800}, - {0x000e, 0x8801}, - {0x0004, 0x8800}, - {0x000f, 0x8801}, - {0x0000, 0x8800}, - {0x0010, 0x8801}, - {0x0006, 0x8800}, - {0x0011, 0x8801}, - {0x0006, 0x8800}, - {0x0012, 0x8801}, - {0x0000, 0x8800}, - {0x0013, 0x8801}, - {0x0001, 0x8800}, - {0x000a, 0x8700}, - {0x0000, 0x8702}, - {0x0000, 0x8703}, - {0x00c2, 0x8704}, - {0x0001, 0x870c}, - {0x0044, 0x8600}, - {0x0002, 0x8606}, - {0x0064, 0x8607}, - {0x003a, 0x8601}, - {0x0008, 0x8602}, - {0x0044, 0x8600}, - {0x0018, 0x8617}, - {0x0008, 0x8618}, - {0x00a1, 0x8656}, - {0x0004, 0x865b}, - {0x0002, 0x865c}, - {0x0058, 0x865d}, - {0x0048, 0x865e}, - {0x0012, 0x8608}, - {0x002c, 0x8609}, - {0x0002, 0x860a}, - {0x002c, 0x860b}, - {0x00db, 0x860c}, - {0x00f9, 0x860d}, - {0x00f1, 0x860e}, - {0x00e3, 0x860f}, - {0x002c, 0x8610}, - {0x006c, 0x8651}, - {0x0041, 0x8652}, - {0x0059, 0x8653}, - {0x0040, 0x8654}, - {0x00fa, 0x8611}, - {0x00ff, 0x8612}, - {0x00f8, 0x8613}, - {0x0000, 0x8614}, - {0x0001, 0x863f}, - {0x0000, 0x8640}, - {0x0026, 0x8641}, - {0x0045, 0x8642}, - {0x0060, 0x8643}, - {0x0075, 0x8644}, - {0x0088, 0x8645}, - {0x009b, 0x8646}, - {0x00b0, 0x8647}, - {0x00c5, 0x8648}, - {0x00d2, 0x8649}, - {0x00dc, 0x864a}, - {0x00e5, 0x864b}, - {0x00eb, 0x864c}, - {0x00f0, 0x864d}, - {0x00f6, 0x864e}, - {0x00fa, 0x864f}, - {0x00ff, 0x8650}, - {0x0060, 0x8657}, - {0x0010, 0x8658}, - {0x0018, 0x8659}, - {0x0005, 0x865a}, - {0x0018, 0x8660}, - {0x0003, 0x8509}, - {0x0011, 0x850a}, - {0x0032, 0x850b}, - {0x0010, 0x850c}, - {0x0021, 0x850d}, - {0x0001, 0x8500}, - {0x0000, 0x8508}, - - {0x0012, 0x8608}, - {0x002c, 0x8609}, - {0x0002, 0x860a}, - {0x0039, 0x860b}, - {0x00d0, 0x860c}, - {0x00f7, 0x860d}, - {0x00ed, 0x860e}, - {0x00db, 0x860f}, - {0x0039, 0x8610}, - {0x0012, 0x8657}, - {0x0064, 0x8619}, - -/* This line starts it all, it is not needed here */ -/* since it has been build into the driver */ -/* jfm: don't start now */ -/* {0x0030, 0x8112}, */ - {} -}; - -/* - * Initialization data for Creative Webcam Vista - */ -static const u16 spca508_vista_init_data[][2] = { - {0x0008, 0x8200}, /* Clear register */ - {0x0000, 0x870b}, /* Reset CTL3 */ - {0x0020, 0x8112}, /* Video Drop packet enable */ - {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ - {0x0000, 0x8110}, /* Disable everything */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8114}, - - {0x0003, 0x8111}, - {0x0000, 0x8111}, - {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ - {0x0020, 0x8112}, - {0x0000, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0001, 0x8114}, - {0x0003, 0x8114}, - - {0x000f, 0x8402}, /* Memory bank Address */ - {0x0000, 0x8403}, /* Memory bank Address */ - {0x00ba, 0x8804}, /* SSI Slave address */ - {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ - {0x0020, 0x8801}, /* Register address for SSI read/write */ - {0x0044, 0x8805}, /* DATA2 */ - {0x0004, 0x8800}, /* DATA1 -> write triggered */ - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0009, 0x8801}, - {0x0042, 0x8805}, - {0x0001, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x003c, 0x8801}, - {0x0001, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0001, 0x8801}, - {0x000a, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0002, 0x8801}, - {0x0000, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0003, 0x8801}, - {0x0027, 0x8805}, - {0x0001, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0004, 0x8801}, - {0x0065, 0x8805}, - {0x0001, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0005, 0x8801}, - {0x0003, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0006, 0x8801}, - {0x001c, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0007, 0x8801}, - {0x002a, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x000e, 0x8801}, - {0x0000, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0028, 0x8801}, - {0x002e, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0039, 0x8801}, - {0x0013, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x003b, 0x8801}, - {0x000c, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0035, 0x8801}, - {0x0028, 0x8805}, - {0x0000, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - /* READ { 0x0001, 0x8802 } -> 0000: 10 */ - {0x0010, 0x8802}, - {0x0009, 0x8801}, - {0x0042, 0x8805}, - {0x0001, 0x8800}, - /* READ { 0x0001, 0x8803 } -> 0000: 00 */ - - {0x0050, 0x8703}, - {0x0002, 0x8704}, /* External input CKIx1 */ - {0x0001, 0x870c}, /* Select CKOx2 output */ - {0x009a, 0x8600}, /* Line memory Read Counter (L) */ - {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ - {0x0023, 0x8601}, - {0x0010, 0x8602}, - {0x000a, 0x8603}, - {0x009a, 0x8600}, - {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ - {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ - {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ - {0x0048, 0x865e}, /* Vertical valid lines window (L) */ - {0x0000, 0x865f}, - - {0x0006, 0x8660}, - /* Enable nibble data input, select nibble input order */ - - {0x0013, 0x8608}, /* A11 Coeficients for color correction */ - {0x0028, 0x8609}, - /* Note: these values are confirmed at the end of array */ - {0x0005, 0x860a}, /* ... */ - {0x0025, 0x860b}, - {0x00e1, 0x860c}, - {0x00fa, 0x860d}, - {0x00f4, 0x860e}, - {0x00e8, 0x860f}, - {0x0025, 0x8610}, /* A33 Coef. */ - {0x00fc, 0x8611}, /* White balance offset: R */ - {0x0001, 0x8612}, /* White balance offset: Gr */ - {0x00fe, 0x8613}, /* White balance offset: B */ - {0x0000, 0x8614}, /* White balance offset: Gb */ - - {0x0064, 0x8651}, /* R gain for white balance (L) */ - {0x0040, 0x8652}, /* Gr gain for white balance (L) */ - {0x0066, 0x8653}, /* B gain for white balance (L) */ - {0x0040, 0x8654}, /* Gb gain for white balance (L) */ - {0x0001, 0x863f}, /* Enable fixed gamma correction */ - - {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128, - * UV division: UV no change, - * Enable New edge enhancement */ - {0x0018, 0x8657}, /* Edge gain high threshold */ - {0x0020, 0x8658}, /* Edge gain low threshold */ - {0x000a, 0x8659}, /* Edge bandwidth high threshold */ - {0x0005, 0x865a}, /* Edge bandwidth low threshold */ - {0x0064, 0x8607}, /* UV filter enable */ - - {0x0016, 0x8660}, - {0x0000, 0x86b0}, /* Bad pixels compensation address */ - {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */ - {0x0000, 0x86b2}, - {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */ - {0x0000, 0x86b4}, - - {0x0001, 0x86b0}, - {0x00f5, 0x86b1}, - {0x0000, 0x86b2}, - {0x00c6, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0002, 0x86b0}, - {0x001c, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d7, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0003, 0x86b0}, - {0x001c, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d8, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0004, 0x86b0}, - {0x001d, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d8, 0x86b3}, - {0x0000, 0x86b4}, - {0x001e, 0x8660}, - - /* READ { 0x0000, 0x8608 } -> 0000: 13 */ - /* READ { 0x0000, 0x8609 } -> 0000: 28 */ - /* READ { 0x0000, 0x8610 } -> 0000: 05 */ - /* READ { 0x0000, 0x8611 } -> 0000: 25 */ - /* READ { 0x0000, 0x8612 } -> 0000: e1 */ - /* READ { 0x0000, 0x8613 } -> 0000: fa */ - /* READ { 0x0000, 0x8614 } -> 0000: f4 */ - /* READ { 0x0000, 0x8615 } -> 0000: e8 */ - /* READ { 0x0000, 0x8616 } -> 0000: 25 */ - {} -}; - -static int reg_write(struct usb_device *dev, - u16 index, u16 value) -{ - int ret; - - ret = usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, /* request */ - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", - index, value); - if (ret < 0) - pr_err("reg write: error %d\n", ret); - return ret; -} - -/* read 1 byte */ -/* returns: negative is error, pos or zero is data */ -static int reg_read(struct gspca_dev *gspca_dev, - u16 index) /* wIndex */ -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, /* register */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - gspca_dev->usb_buf, 1, - 500); /* timeout */ - PDEBUG(D_USBI, "reg read i:%04x --> %02x", - index, gspca_dev->usb_buf[0]); - if (ret < 0) { - pr_err("reg_read err %d\n", ret); - return ret; - } - return gspca_dev->usb_buf[0]; -} - -/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */ -static int ssi_w(struct gspca_dev *gspca_dev, - u16 reg, u16 val) -{ - struct usb_device *dev = gspca_dev->dev; - int ret, retry; - - ret = reg_write(dev, 0x8802, reg >> 8); - if (ret < 0) - goto out; - ret = reg_write(dev, 0x8801, reg & 0x00ff); - if (ret < 0) - goto out; - if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */ - ret = reg_write(dev, 0x8805, val & 0x00ff); - if (ret < 0) - goto out; - val >>= 8; - } - ret = reg_write(dev, 0x8800, val); - if (ret < 0) - goto out; - - /* poll until not busy */ - retry = 10; - for (;;) { - ret = reg_read(gspca_dev, 0x8803); - if (ret < 0) - break; - if (gspca_dev->usb_buf[0] == 0) - break; - if (--retry <= 0) { - PDEBUG(D_ERR, "ssi_w busy %02x", - gspca_dev->usb_buf[0]); - ret = -1; - break; - } - msleep(8); - } - -out: - return ret; -} - -static int write_vector(struct gspca_dev *gspca_dev, - const u16 (*data)[2]) -{ - struct usb_device *dev = gspca_dev->dev; - int ret = 0; - - while ((*data)[1] != 0) { - if ((*data)[1] & 0x8000) { - if ((*data)[1] == 0xdd00) /* delay */ - msleep((*data)[0]); - else - ret = reg_write(dev, (*data)[1], (*data)[0]); - } else { - ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]); - } - if (ret < 0) - break; - data++; - } - return ret; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - const u16 (*init_data)[2]; - static const u16 (*(init_data_tb[]))[2] = { - spca508_vista_init_data, /* CreativeVista 0 */ - spca508_sightcam_init_data, /* HamaUSBSightcam 1 */ - spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */ - spca508cs110_init_data, /* IntelEasyPCCamera 3 */ - spca508cs110_init_data, /* MicroInnovationIC200 4 */ - spca508_init_data, /* ViewQuestVQ110 5 */ - }; - -#ifdef GSPCA_DEBUG - int data1, data2; - - /* Read from global register the USB product and vendor IDs, just to - * prove that we can communicate with the device. This works, which - * confirms at we are communicating properly and that the device - * is a 508. */ - data1 = reg_read(gspca_dev, 0x8104); - data2 = reg_read(gspca_dev, 0x8105); - PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1); - - data1 = reg_read(gspca_dev, 0x8106); - data2 = reg_read(gspca_dev, 0x8107); - PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1); - - data1 = reg_read(gspca_dev, 0x8621); - PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); -#endif - - cam = &gspca_dev->cam; - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - - sd->subtype = id->driver_info; - - init_data = init_data_tb[sd->subtype]; - return write_vector(gspca_dev, init_data); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - int mode; - - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - reg_write(gspca_dev->dev, 0x8500, mode); - switch (mode) { - case 0: - case 1: - reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */ - break; - default: -/* case 2: */ -/* case 3: */ - reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */ - break; - } - reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* Video ISO disable, Video Drop Packet enable: */ - reg_write(gspca_dev->dev, 0x8112, 0x20); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - switch (data[0]) { - case 0: /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - data += SPCA508_OFFSET_DATA; - len -= SPCA508_OFFSET_DATA; - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - break; - case 0xff: /* drop */ - break; - default: - data += 1; - len -= 1; - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - break; - } -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) -{ - /* MX seem contrast */ - reg_write(gspca_dev->dev, 0x8651, brightness); - reg_write(gspca_dev->dev, 0x8652, brightness); - reg_write(gspca_dev->dev, 0x8653, brightness); - reg_write(gspca_dev->dev, 0x8654, brightness); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam}, - {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista}, - {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110}, - {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam}, - {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2}, - {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c deleted file mode 100644 index cfe71dd6747d..000000000000 --- a/drivers/media/video/gspca/spca561.c +++ /dev/null @@ -1,936 +0,0 @@ -/* - * Sunplus spca561 subdriver - * - * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "spca561" - -#include <linux/input.h> -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define EXPOSURE_MAX (2047 + 325) - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct { /* hue/contrast control cluster */ - struct v4l2_ctrl *contrast; - struct v4l2_ctrl *hue; - }; - struct v4l2_ctrl *autogain; - -#define EXPO12A_DEF 3 - __u8 expo12a; /* expo/gain? for rev 12a */ - - __u8 chip_revision; -#define Rev012A 0 -#define Rev072A 1 - - signed char ag_cnt; -#define AG_CNT_START 13 -}; - -static const struct v4l2_pix_format sif_012a_mode[] = { - {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 4 / 8, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -static const struct v4l2_pix_format sif_072a_mode[] = { - {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* - * Initialization data - * I'm not very sure how to split initialization from open data - * chunks. For now, we'll consider everything as initialization - */ -/* Frame packet header offsets for the spca561 */ -#define SPCA561_OFFSET_SNAP 1 -#define SPCA561_OFFSET_TYPE 2 -#define SPCA561_OFFSET_COMPRESS 3 -#define SPCA561_OFFSET_FRAMSEQ 4 -#define SPCA561_OFFSET_GPIO 5 -#define SPCA561_OFFSET_USBBUFF 6 -#define SPCA561_OFFSET_WIN2GRAVE 7 -#define SPCA561_OFFSET_WIN2RAVE 8 -#define SPCA561_OFFSET_WIN2BAVE 9 -#define SPCA561_OFFSET_WIN2GBAVE 10 -#define SPCA561_OFFSET_WIN1GRAVE 11 -#define SPCA561_OFFSET_WIN1RAVE 12 -#define SPCA561_OFFSET_WIN1BAVE 13 -#define SPCA561_OFFSET_WIN1GBAVE 14 -#define SPCA561_OFFSET_FREQ 15 -#define SPCA561_OFFSET_VSYNC 16 -#define SPCA561_INDEX_I2C_BASE 0x8800 -#define SPCA561_SNAPBIT 0x20 -#define SPCA561_SNAPCTRL 0x40 - -static const u16 rev72a_reset[][2] = { - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0001, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8112}, /* Some kind of reset */ - {} -}; -static const __u16 rev72a_init_data1[][2] = { - {0x0003, 0x8701}, /* PCLK clock delay adjustment */ - {0x0001, 0x8703}, /* HSYNC from cmos inverted */ - {0x0011, 0x8118}, /* Enable and conf sensor */ - {0x0001, 0x8118}, /* Conf sensor */ - {0x0092, 0x8804}, /* I know nothing about these */ - {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ - {} -}; -static const u16 rev72a_init_sensor1[][2] = { - {0x0001, 0x000d}, - {0x0002, 0x0018}, - {0x0004, 0x0165}, - {0x0005, 0x0021}, - {0x0007, 0x00aa}, - {0x0020, 0x1504}, - {0x0039, 0x0002}, - {0x0035, 0x0010}, - {0x0009, 0x1049}, - {0x0028, 0x000b}, - {0x003b, 0x000f}, - {0x003c, 0x0000}, - {} -}; -static const __u16 rev72a_init_data2[][2] = { - {0x0018, 0x8601}, /* Pixel/line selection for color separation */ - {0x0000, 0x8602}, /* Optical black level for user setting */ - {0x0060, 0x8604}, /* Optical black horizontal offset */ - {0x0002, 0x8605}, /* Optical black vertical offset */ - {0x0000, 0x8603}, /* Non-automatic optical black level */ - {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ - {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */ - {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */ - {0x0090, 0x865e}, /* Vertical valid lines window (x2) */ - {0x00e0, 0x8406}, /* Memory buffer threshold */ - {0x0000, 0x8660}, /* Compensation memory stuff */ - {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ - {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ - {0x0001, 0x8200}, /* OprMode to be executed by hardware */ -/* from ms-win */ - {0x0000, 0x8611}, /* R offset for white balance */ - {0x00fd, 0x8612}, /* Gr offset for white balance */ - {0x0003, 0x8613}, /* B offset for white balance */ - {0x0000, 0x8614}, /* Gb offset for white balance */ -/* from ms-win */ - {0x0035, 0x8651}, /* R gain for white balance */ - {0x0040, 0x8652}, /* Gr gain for white balance */ - {0x005f, 0x8653}, /* B gain for white balance */ - {0x0040, 0x8654}, /* Gb gain for white balance */ - {0x0002, 0x8502}, /* Maximum average bit rate stuff */ - {0x0011, 0x8802}, - - {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ - {0x0081, 0x8702}, /* Master clock output enable */ - - {0x0000, 0x8500}, /* Set image type (352x288 no compression) */ - /* Originally was 0x0010 (352x288 compression) */ - - {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ - {0x0003, 0x865c}, /* Vertical offset for valid lines */ - {} -}; -static const u16 rev72a_init_sensor2[][2] = { - {0x0003, 0x0121}, - {0x0004, 0x0165}, - {0x0005, 0x002f}, /* blanking control column */ - {0x0006, 0x0000}, /* blanking mode row*/ - {0x000a, 0x0002}, - {0x0009, 0x1061}, /* setexposure times && pixel clock - * 0001 0 | 000 0110 0001 */ - {0x0035, 0x0014}, - {} -}; - -/******************** QC Express etch2 stuff ********************/ -static const __u16 Pb100_1map8300[][2] = { - /* reg, value */ - {0x8320, 0x3304}, - - {0x8303, 0x0125}, /* image area */ - {0x8304, 0x0169}, - {0x8328, 0x000b}, - {0x833c, 0x0001}, /*fixme: win:07*/ - - {0x832f, 0x1904}, /*fixme: was 0419*/ - {0x8307, 0x00aa}, - {0x8301, 0x0003}, - {0x8302, 0x000e}, - {} -}; -static const __u16 Pb100_2map8300[][2] = { - /* reg, value */ - {0x8339, 0x0000}, - {0x8307, 0x00aa}, - {} -}; - -static const __u16 spca561_161rev12A_data1[][2] = { - {0x29, 0x8118}, /* Control register (various enable bits) */ - {0x08, 0x8114}, /* GPIO: Led off */ - {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */ - {0x00, 0x8102}, /* white balance - new */ - {0x92, 0x8804}, - {0x04, 0x8802}, /* windows uses 08 */ - {} -}; -static const __u16 spca561_161rev12A_data2[][2] = { - {0x21, 0x8118}, - {0x10, 0x8500}, - {0x07, 0x8601}, - {0x07, 0x8602}, - {0x04, 0x8501}, - - {0x07, 0x8201}, /* windows uses 02 */ - {0x08, 0x8200}, - {0x01, 0x8200}, - - {0x90, 0x8604}, - {0x00, 0x8605}, - {0xb0, 0x8603}, - - /* sensor gains */ - {0x07, 0x8601}, /* white balance - new */ - {0x07, 0x8602}, /* white balance - new */ - {0x00, 0x8610}, /* *red */ - {0x00, 0x8611}, /* 3f *green */ - {0x00, 0x8612}, /* green *blue */ - {0x00, 0x8613}, /* blue *green */ - {0x43, 0x8614}, /* green *red - white balance - was 0x35 */ - {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */ - {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */ - {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */ - - {0x0c, 0x8620}, /* 0c */ - {0xc8, 0x8631}, /* c8 */ - {0xc8, 0x8634}, /* c8 */ - {0x23, 0x8635}, /* 23 */ - {0x1f, 0x8636}, /* 1f */ - {0xdd, 0x8637}, /* dd */ - {0xe1, 0x8638}, /* e1 */ - {0x1d, 0x8639}, /* 1d */ - {0x21, 0x863a}, /* 21 */ - {0xe3, 0x863b}, /* e3 */ - {0xdf, 0x863c}, /* df */ - {0xf0, 0x8505}, - {0x32, 0x850a}, -/* {0x99, 0x8700}, * - white balance - new (removed) */ - /* HDG we used to do this in stop0, making the init state and the state - after a start / stop different, so do this here instead. */ - {0x29, 0x8118}, - {} -}; - -static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) -{ - int ret; - - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); - if (ret < 0) - pr_err("reg write: error %d\n", ret); -} - -static void write_vector(struct gspca_dev *gspca_dev, - const __u16 data[][2]) -{ - struct usb_device *dev = gspca_dev->dev; - int i; - - i = 0; - while (data[i][1] != 0) { - reg_w_val(dev, data[i][1], data[i][0]); - i++; - } -} - -/* read 'len' bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - __u16 index, __u16 length) -{ - usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, length, 500); -} - -/* write 'len' bytes from gspca_dev->usb_buf */ -static void reg_w_buf(struct gspca_dev *gspca_dev, - __u16 index, __u16 len) -{ - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, len, 500); -} - -static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) -{ - int retry = 60; - - reg_w_val(gspca_dev->dev, 0x8801, reg); - reg_w_val(gspca_dev->dev, 0x8805, value); - reg_w_val(gspca_dev->dev, 0x8800, value >> 8); - do { - reg_r(gspca_dev, 0x8803, 1); - if (!gspca_dev->usb_buf[0]) - return; - msleep(10); - } while (--retry); -} - -static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) -{ - int retry = 60; - __u8 value; - - reg_w_val(gspca_dev->dev, 0x8804, 0x92); - reg_w_val(gspca_dev->dev, 0x8801, reg); - reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01); - do { - reg_r(gspca_dev, 0x8803, 1); - if (!gspca_dev->usb_buf[0]) { - reg_r(gspca_dev, 0x8800, 1); - value = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8805, 1); - return ((int) value << 8) | gspca_dev->usb_buf[0]; - } - msleep(10); - } while (--retry); - return -1; -} - -static void sensor_mapwrite(struct gspca_dev *gspca_dev, - const __u16 (*sensormap)[2]) -{ - while ((*sensormap)[0]) { - gspca_dev->usb_buf[0] = (*sensormap)[1]; - gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8; - reg_w_buf(gspca_dev, (*sensormap)[0], 2); - sensormap++; - } -} - -static void write_sensor_72a(struct gspca_dev *gspca_dev, - const __u16 (*sensor)[2]) -{ - while ((*sensor)[0]) { - i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]); - sensor++; - } -} - -static void init_161rev12A(struct gspca_dev *gspca_dev) -{ - write_vector(gspca_dev, spca561_161rev12A_data1); - sensor_mapwrite(gspca_dev, Pb100_1map8300); -/*fixme: should be in sd_start*/ - write_vector(gspca_dev, spca561_161rev12A_data2); - sensor_mapwrite(gspca_dev, Pb100_2map8300); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - __u16 vendor, product; - __u8 data1, data2; - - /* Read frm global register the USB product and vendor IDs, just to - * prove that we can communicate with the device. This works, which - * confirms at we are communicating properly and that the device - * is a 561. */ - reg_r(gspca_dev, 0x8104, 1); - data1 = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8105, 1); - data2 = gspca_dev->usb_buf[0]; - vendor = (data2 << 8) | data1; - reg_r(gspca_dev, 0x8106, 1); - data1 = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8107, 1); - data2 = gspca_dev->usb_buf[0]; - product = (data2 << 8) | data1; - if (vendor != id->idVendor || product != id->idProduct) { - PDEBUG(D_PROBE, "Bad vendor / product from device"); - return -EINVAL; - } - - cam = &gspca_dev->cam; - cam->needs_full_bandwidth = 1; - - sd->chip_revision = id->driver_info; - if (sd->chip_revision == Rev012A) { - cam->cam_mode = sif_012a_mode; - cam->nmodes = ARRAY_SIZE(sif_012a_mode); - } else { - cam->cam_mode = sif_072a_mode; - cam->nmodes = ARRAY_SIZE(sif_072a_mode); - } - sd->expo12a = EXPO12A_DEF; - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init_12a(struct gspca_dev *gspca_dev) -{ - PDEBUG(D_STREAM, "Chip revision: 012a"); - init_161rev12A(gspca_dev); - return 0; -} -static int sd_init_72a(struct gspca_dev *gspca_dev) -{ - PDEBUG(D_STREAM, "Chip revision: 072a"); - write_vector(gspca_dev, rev72a_reset); - msleep(200); - write_vector(gspca_dev, rev72a_init_data1); - write_sensor_72a(gspca_dev, rev72a_init_sensor1); - write_vector(gspca_dev, rev72a_init_data2); - write_sensor_72a(gspca_dev, rev72a_init_sensor2); - reg_w_val(gspca_dev->dev, 0x8112, 0x30); - return 0; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - __u16 reg; - - if (sd->chip_revision == Rev012A) - reg = 0x8610; - else - reg = 0x8611; - - reg_w_val(dev, reg + 0, val); /* R */ - reg_w_val(dev, reg + 1, val); /* Gr */ - reg_w_val(dev, reg + 2, val); /* B */ - reg_w_val(dev, reg + 3, val); /* Gb */ -} - -static void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - __u8 blue, red; - __u16 reg; - - /* try to emulate MS-win as possible */ - red = 0x20 + white * 3 / 8; - blue = 0x90 - white * 5 / 8; - if (sd->chip_revision == Rev012A) { - reg = 0x8614; - } else { - reg = 0x8651; - red += contrast - 0x20; - blue += contrast - 0x20; - reg_w_val(dev, 0x8652, contrast + 0x20); /* Gr */ - reg_w_val(dev, 0x8654, contrast + 0x20); /* Gb */ - } - reg_w_val(dev, reg, red); - reg_w_val(dev, reg + 2, blue); -} - -/* rev 12a only */ -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - int i, expo = 0; - - /* Register 0x8309 controls exposure for the spca561, - the basic exposure setting goes from 1-2047, where 1 is completely - dark and 2047 is very bright. It not only influences exposure but - also the framerate (to allow for longer exposure) from 1 - 300 it - only raises the exposure time then from 300 - 600 it halves the - framerate to be able to further raise the exposure time and for every - 300 more it halves the framerate again. This allows for a maximum - exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps). - Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12 - configure a divider for the base framerate which us used at the - exposure setting of 1-300. These bits configure the base framerate - according to the following formula: fps = 60 / (value + 2) */ - - /* We choose to use the high bits setting the fixed framerate divisor - asap, as setting high basic exposure setting without the fixed - divider in combination with high gains makes the cam stop */ - int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; - - for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { - if (val <= table[i + 1]) { - expo = val - table[i]; - if (i) - expo += 300; - expo |= i << 11; - break; - } - } - - gspca_dev->usb_buf[0] = expo; - gspca_dev->usb_buf[1] = expo >> 8; - reg_w_buf(gspca_dev, 0x8309, 2); -} - -/* rev 12a only */ -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the - sensitivity when set, so 31 + one of them set == 63, and 15 - with both of them set == 63 */ - if (val < 64) - gspca_dev->usb_buf[0] = val; - else if (val < 128) - gspca_dev->usb_buf[0] = (val / 2) | 0x40; - else - gspca_dev->usb_buf[0] = (val / 4) | 0xc0; - - gspca_dev->usb_buf[1] = 0; - reg_w_buf(gspca_dev, 0x8335, 2); -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (val) - sd->ag_cnt = AG_CNT_START; - else - sd->ag_cnt = -1; -} - -static int sd_start_12a(struct gspca_dev *gspca_dev) -{ - struct usb_device *dev = gspca_dev->dev; - int mode; - static const __u8 Reg8391[8] = - {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00}; - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - if (mode <= 1) { - /* Use compression on 320x240 and above */ - reg_w_val(dev, 0x8500, 0x10 | mode); - } else { - /* I couldn't get the compression to work below 320x240 - * Fortunately at these resolutions the bandwidth - * is sufficient to push raw frames at ~20fps */ - reg_w_val(dev, 0x8500, mode); - } /* -- qq@kuku.eu.org */ - - gspca_dev->usb_buf[0] = 0xaa; - gspca_dev->usb_buf[1] = 0x00; - reg_w_buf(gspca_dev, 0x8307, 2); - /* clock - lower 0x8X values lead to fps > 30 */ - reg_w_val(gspca_dev->dev, 0x8700, 0x8a); - /* 0x8f 0x85 0x27 clock */ - reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); - reg_w_val(gspca_dev->dev, 0x850b, 0x03); - memcpy(gspca_dev->usb_buf, Reg8391, 8); - reg_w_buf(gspca_dev, 0x8391, 8); - reg_w_buf(gspca_dev, 0x8390, 8); - - /* Led ON (bit 3 -> 0 */ - reg_w_val(gspca_dev->dev, 0x8114, 0x00); - return 0; -} -static int sd_start_72a(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - int Clck; - int mode; - - write_vector(gspca_dev, rev72a_reset); - msleep(200); - write_vector(gspca_dev, rev72a_init_data1); - write_sensor_72a(gspca_dev, rev72a_init_sensor1); - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - switch (mode) { - default: - case 0: - Clck = 0x27; /* ms-win 0x87 */ - break; - case 1: - Clck = 0x25; - break; - case 2: - Clck = 0x22; - break; - case 3: - Clck = 0x21; - break; - } - reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8702, 0x81); - reg_w_val(dev, 0x8500, mode); /* mode */ - write_sensor_72a(gspca_dev, rev72a_init_sensor2); - setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue), - v4l2_ctrl_g_ctrl(sd->contrast)); -/* setbrightness(gspca_dev); * fixme: bad values */ - setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); - reg_w_val(dev, 0x8112, 0x10 | 0x20); - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->chip_revision == Rev012A) { - reg_w_val(gspca_dev->dev, 0x8112, 0x0e); - /* Led Off (bit 3 -> 1 */ - reg_w_val(gspca_dev->dev, 0x8114, 0x08); - } else { - reg_w_val(gspca_dev->dev, 0x8112, 0x20); -/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */ - } -} - -static void do_autogain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int expotimes; - int pixelclk; - int gainG; - __u8 R, Gr, Gb, B; - int y; - __u8 luma_mean = 110; - __u8 luma_delta = 20; - __u8 spring = 4; - - if (sd->ag_cnt < 0) - return; - if (--sd->ag_cnt >= 0) - return; - sd->ag_cnt = AG_CNT_START; - - switch (sd->chip_revision) { - case Rev072A: - reg_r(gspca_dev, 0x8621, 1); - Gr = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8622, 1); - R = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8623, 1); - B = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0x8624, 1); - Gb = gspca_dev->usb_buf[0]; - y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; - /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ - /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ - /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */ - - if (y < luma_mean - luma_delta || - y > luma_mean + luma_delta) { - expotimes = i2c_read(gspca_dev, 0x09, 0x10); - pixelclk = 0x0800; - expotimes = expotimes & 0x07ff; - /* PDEBUG(D_PACK, - "Exposition Times 0x%03X Clock 0x%04X ", - expotimes,pixelclk); */ - gainG = i2c_read(gspca_dev, 0x35, 0x10); - /* PDEBUG(D_PACK, - "reading Gain register %d", gainG); */ - - expotimes += (luma_mean - y) >> spring; - gainG += (luma_mean - y) / 50; - /* PDEBUG(D_PACK, - "compute expotimes %d gain %d", - expotimes,gainG); */ - - if (gainG > 0x3f) - gainG = 0x3f; - else if (gainG < 3) - gainG = 3; - i2c_write(gspca_dev, gainG, 0x35); - - if (expotimes > 0x0256) - expotimes = 0x0256; - else if (expotimes < 3) - expotimes = 3; - i2c_write(gspca_dev, expotimes | pixelclk, 0x09); - } - break; - } -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - len--; - switch (*data++) { /* sequence number */ - case 0: /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - /* This should never happen */ - if (len < 2) { - PDEBUG(D_ERR, "Short SOF packet, ignoring"); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - if (data[0] & 0x20) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - } -#endif - - if (data[1] & 0x10) { - /* compressed bayer */ - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - } else { - /* raw bayer (with a header, which we skip) */ - if (sd->chip_revision == Rev012A) { - data += 20; - len -= 20; - } else { - data += 16; - len -= 16; - } - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - } - return; - case 0xff: /* drop (empty mpackets) */ - return; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - /* hue/contrast control cluster for 72a */ - setwhite(gspca_dev, sd->hue->val, ctrl->val); - break; - case V4L2_CID_HUE: - /* just plain hue control for 12a */ - setwhite(gspca_dev, ctrl->val, 0); - break; - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - setautogain(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls_12a(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 3); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, 1, 0x7f, 1, 0x40); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 63); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -static int sd_init_controls_72a(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20); - sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, 1, 0x7f, 1, 0x40); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20); - sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_cluster(2, &sd->contrast); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc_12a = { - .name = MODULE_NAME, - .init_controls = sd_init_controls_12a, - .config = sd_config, - .init = sd_init_12a, - .start = sd_start_12a, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; -static const struct sd_desc sd_desc_72a = { - .name = MODULE_NAME, - .init_controls = sd_init_controls_72a, - .config = sd_config, - .init = sd_init_72a, - .start = sd_start_72a, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = do_autogain, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; -static const struct sd_desc *sd_desc[2] = { - &sd_desc_12a, - &sd_desc_72a -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A}, - {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A}, - {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A}, - {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A}, - {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A}, - {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A}, - {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A}, - {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A}, - {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A}, - {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - sd_desc[id->driver_info], - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c deleted file mode 100644 index a8ac97931ad6..000000000000 --- a/drivers/media/video/gspca/sq905.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * SQ905 subdriver - * - * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * History and Acknowledgments - * - * The original Linux driver for SQ905 based cameras was written by - * Marcell Lengyel and furter developed by many other contributors - * and is available from http://sourceforge.net/projects/sqcam/ - * - * This driver takes advantage of the reverse engineering work done for - * that driver and for libgphoto2 but shares no code with them. - * - * This driver has used as a base the finepix driver and other gspca - * based drivers and may still contain code fragments taken from those - * drivers. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sq905" - -#include <linux/workqueue.h> -#include <linux/slab.h> -#include "gspca.h" - -MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, " - "Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define SQ905_CMD_TIMEOUT 500 -#define SQ905_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define SQ905_MAX_TRANSFER 0x8000 -#define FRAME_HEADER_LEN 64 - -/* The known modes, or registers. These go in the "value" slot. */ - -/* 00 is "none" obviously */ - -#define SQ905_BULK_READ 0x03 /* precedes any bulk read */ -#define SQ905_COMMAND 0x06 /* precedes the command codes below */ -#define SQ905_PING 0x07 /* when reading an "idling" command */ -#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */ - -/* Any non-zero value in the bottom 2 bits of the 2nd byte of - * the ID appears to indicate the camera can do 640*480. If the - * LSB of that byte is set the image is just upside down, otherwise - * it is rotated 180 degrees. */ -#define SQ905_HIRES_MASK 0x00000300 -#define SQ905_ORIENTATION_MASK 0x00000100 - -/* Some command codes. These go in the "index" slot. */ - -#define SQ905_ID 0xf0 /* asks for model string */ -#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */ -#define SQ905_DATA 0x30 /* accesses photo data, not used here */ -#define SQ905_CLEAR 0xa0 /* clear everything */ -#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */ -#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */ -#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */ -/* note that the capture command also controls the output dimensions */ - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - /* - * Driver stuff - */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -static struct v4l2_pix_format sq905_mode[] = { - { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* - * Send a command to the camera. - */ -static int sq905_command(struct gspca_dev *gspca_dev, u16 index) -{ - int ret; - - gspca_dev->usb_buf[0] = '\0'; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_COMMAND, index, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret); - return ret; - } - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_PING, 0, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - pr_err("%s: usb_control_msg failed 2 (%d)\n", __func__, ret); - return ret; - } - - return 0; -} - -/* - * Acknowledge the end of a frame - see warning on sq905_command. - */ -static int sq905_ack_frame(struct gspca_dev *gspca_dev) -{ - int ret; - - gspca_dev->usb_buf[0] = '\0'; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret); - return ret; - } - - return 0; -} - -/* - * request and read a block of data - see warning on sq905_command. - */ -static int -sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) -{ - int ret; - int act_len; - - gspca_dev->usb_buf[0] = '\0'; - if (need_lock) - mutex_lock(&gspca_dev->usb_lock); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_BULK_READ, size, gspca_dev->usb_buf, - 1, SQ905_CMD_TIMEOUT); - if (need_lock) - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) { - pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret); - return ret; - } - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - data, size, &act_len, SQ905_DATA_TIMEOUT); - - /* successful, it returns 0, otherwise negative */ - if (ret < 0 || act_len != size) { - pr_err("bulk read fail (%d) len %d/%d\n", ret, act_len, size); - return -EIO; - } - return 0; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface we take the gspca - * usb_lock when performing USB operations. In practice the only thing we need - * to protect against is the usb_set_interface call that gspca makes during - * stream_off as the camera doesn't provide any controls that the user could try - * to change. - */ -static void sq905_dostream(struct work_struct *work) -{ - struct sd *dev = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - int bytes_left; /* bytes remaining in current frame. */ - int data_len; /* size to use for the next read. */ - int header_read; /* true if we have already read the frame header. */ - int packet_type; - int frame_sz; - int ret; - u8 *data; - u8 *buffer; - - buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - if (!buffer) { - pr_err("Couldn't allocate USB buffer\n"); - goto quit_stream; - } - - frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage - + FRAME_HEADER_LEN; - - while (gspca_dev->dev && gspca_dev->streaming) { -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - /* request some data and then read it until we have - * a complete frame. */ - bytes_left = frame_sz; - header_read = 0; - - /* Note we do not check for gspca_dev->streaming here, as - we must finish reading an entire frame, otherwise the - next time we stream we start reading in the middle of a - frame. */ - while (bytes_left > 0 && gspca_dev->dev) { - data_len = bytes_left > SQ905_MAX_TRANSFER ? - SQ905_MAX_TRANSFER : bytes_left; - ret = sq905_read_data(gspca_dev, buffer, data_len, 1); - if (ret < 0) - goto quit_stream; - PDEBUG(D_PACK, - "Got %d bytes out of %d for frame", - data_len, bytes_left); - bytes_left -= data_len; - data = buffer; - if (!header_read) { - packet_type = FIRST_PACKET; - /* The first 64 bytes of each frame are - * a header full of FF 00 bytes */ - data += FRAME_HEADER_LEN; - data_len -= FRAME_HEADER_LEN; - header_read = 1; - } else if (bytes_left == 0) { - packet_type = LAST_PACKET; - } else { - packet_type = INTER_PACKET; - } - gspca_frame_add(gspca_dev, packet_type, - data, data_len); - /* If entire frame fits in one packet we still - need to add a LAST_PACKET */ - if (packet_type == FIRST_PACKET && - bytes_left == 0) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - } - if (gspca_dev->dev) { - /* acknowledge the frame */ - mutex_lock(&gspca_dev->usb_lock); - ret = sq905_ack_frame(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) - goto quit_stream; - } - } -quit_stream: - if (gspca_dev->dev) { - mutex_lock(&gspca_dev->usb_lock); - sq905_command(gspca_dev, SQ905_CLEAR); - mutex_unlock(&gspca_dev->usb_lock); - } - kfree(buffer); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *dev = (struct sd *) gspca_dev; - - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk = 1; - cam->bulk_size = 64; - - INIT_WORK(&dev->work_struct, sq905_dostream); - - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for sq905_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - u32 ident; - int ret; - - /* connect to the camera and read - * the model ID and process that and put it away. - */ - ret = sq905_command(gspca_dev, SQ905_CLEAR); - if (ret < 0) - return ret; - ret = sq905_command(gspca_dev, SQ905_ID); - if (ret < 0) - return ret; - ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0); - if (ret < 0) - return ret; - /* usb_buf is allocated with kmalloc so is aligned. - * Camera model number is the right way round if we assume this - * reverse engineered ID is supposed to be big endian. */ - ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf); - ret = sq905_command(gspca_dev, SQ905_CLEAR); - if (ret < 0) - return ret; - PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident); - gspca_dev->cam.cam_mode = sq905_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode); - if (!(ident & SQ905_HIRES_MASK)) - gspca_dev->cam.nmodes--; - - if (ident & SQ905_ORIENTATION_MASK) - gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP; - else - gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP | - V4L2_IN_ST_HFLIP; - return 0; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - int ret; - - /* "Open the shutter" and set size, to start capture */ - switch (gspca_dev->curr_mode) { - default: -/* case 2: */ - PDEBUG(D_STREAM, "Start streaming at high resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH); - break; - case 1: - PDEBUG(D_STREAM, "Start streaming at medium resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED); - break; - case 0: - PDEBUG(D_STREAM, "Start streaming at low resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW); - } - - if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); - return ret; - } - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); - - return 0; -} - -/* Table of supported USB devices */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x2770, 0x9120)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c deleted file mode 100644 index 70fae6982e96..000000000000 --- a/drivers/media/video/gspca/sq905c.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * SQ905C subdriver - * - * Copyright (C) 2009 Theodore Kilgore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * - * This driver uses work done in - * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore. - * - * This driver has also used as a base the sq905c driver - * and may contain code fragments from it. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sq905c" - -#include <linux/workqueue.h> -#include <linux/slab.h> -#include "gspca.h" - -MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>"); -MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define SQ905C_CMD_TIMEOUT 500 -#define SQ905C_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define SQ905C_MAX_TRANSFER 0x8000 - -#define FRAME_HEADER_LEN 0x50 - -/* Commands. These go in the "value" slot. */ -#define SQ905C_CLEAR 0xa0 /* clear everything */ -#define SQ905C_GET_ID 0x14f4 /* Read version number */ -#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ -#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ -#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ - -/* For capture, this must go in the "index" slot. */ -#define SQ905C_CAPTURE_INDEX 0x110f - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - const struct v4l2_pix_format *cap_mode; - /* Driver stuff */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -/* - * Most of these cameras will do 640x480 and 320x240. 160x120 works - * in theory but gives very poor output. Therefore, not supported. - * The 0x2770:0x9050 cameras have max resolution of 320x240. - */ -static struct v4l2_pix_format sq905c_mode[] = { - { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* Send a command to the camera. */ -static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index) -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - command, index, NULL, 0, - SQ905C_CMD_TIMEOUT); - if (ret < 0) { - pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret); - return ret; - } - - return 0; -} - -static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index, - int size) -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - command, index, gspca_dev->usb_buf, size, - SQ905C_CMD_TIMEOUT); - if (ret < 0) { - pr_err("%s: usb_control_msg failed (%d)\n", __func__, ret); - return ret; - } - - return 0; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface the gspca usb_lock is - * used when performing the one USB control operation inside the workqueue, - * which tells the camera to close the stream. In practice the only thing - * which needs to be protected against is the usb_set_interface call that - * gspca makes during stream_off. Otherwise the camera doesn't provide any - * controls that the user could try to change. - */ -static void sq905c_dostream(struct work_struct *work) -{ - struct sd *dev = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - int bytes_left; /* bytes remaining in current frame. */ - int data_len; /* size to use for the next read. */ - int act_len; - int packet_type; - int ret; - u8 *buffer; - - buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - if (!buffer) { - pr_err("Couldn't allocate USB buffer\n"); - goto quit_stream; - } - - while (gspca_dev->dev && gspca_dev->streaming) { -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - /* Request the header, which tells the size to download */ - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - buffer, FRAME_HEADER_LEN, &act_len, - SQ905C_DATA_TIMEOUT); - PDEBUG(D_STREAM, - "Got %d bytes out of %d for header", - act_len, FRAME_HEADER_LEN); - if (ret < 0 || act_len < FRAME_HEADER_LEN) - goto quit_stream; - /* size is read from 4 bytes starting 0x40, little endian */ - bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16) - |(buffer[0x43]<<24); - PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left); - /* We keep the header. It has other information, too. */ - packet_type = FIRST_PACKET; - gspca_frame_add(gspca_dev, packet_type, - buffer, FRAME_HEADER_LEN); - while (bytes_left > 0 && gspca_dev->dev) { - data_len = bytes_left > SQ905C_MAX_TRANSFER ? - SQ905C_MAX_TRANSFER : bytes_left; - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - buffer, data_len, &act_len, - SQ905C_DATA_TIMEOUT); - if (ret < 0 || act_len < data_len) - goto quit_stream; - PDEBUG(D_STREAM, - "Got %d bytes out of %d for frame", - data_len, bytes_left); - bytes_left -= data_len; - if (bytes_left == 0) - packet_type = LAST_PACKET; - else - packet_type = INTER_PACKET; - gspca_frame_add(gspca_dev, packet_type, - buffer, data_len); - } - } -quit_stream: - if (gspca_dev->dev) { - mutex_lock(&gspca_dev->usb_lock); - sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - mutex_unlock(&gspca_dev->usb_lock); - } - kfree(buffer); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *dev = (struct sd *) gspca_dev; - int ret; - - PDEBUG(D_PROBE, - "SQ9050 camera detected" - " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); - - ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0); - if (ret < 0) { - PDEBUG(D_ERR, "Get version command failed"); - return ret; - } - - ret = sq905c_read(gspca_dev, 0xf5, 0, 20); - if (ret < 0) { - PDEBUG(D_ERR, "Reading version command failed"); - return ret; - } - /* Note we leave out the usb id and the manufacturing date */ - PDEBUG(D_PROBE, - "SQ9050 ID string: %02x - %*ph", - gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14); - - cam->cam_mode = sq905c_mode; - cam->nmodes = 2; - if (gspca_dev->usb_buf[15] == 0) - cam->nmodes = 1; - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk_size = 32; - cam->bulk = 1; - INIT_WORK(&dev->work_struct, sq905c_dostream); - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for sq905c_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - int ret; - - /* connect to the camera and reset it. */ - ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - return ret; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - int ret; - - dev->cap_mode = gspca_dev->cam.cam_mode; - /* "Open the shutter" and set size, to start capture */ - switch (gspca_dev->width) { - case 640: - PDEBUG(D_STREAM, "Start streaming at high resolution"); - dev->cap_mode++; - ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI, - SQ905C_CAPTURE_INDEX); - break; - default: /* 320 */ - PDEBUG(D_STREAM, "Start streaming at medium resolution"); - ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED, - SQ905C_CAPTURE_INDEX); - } - - if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); - return ret; - } - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); - - return 0; -} - -/* Table of supported USB devices */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x2770, 0x905c)}, - {USB_DEVICE(0x2770, 0x9050)}, - {USB_DEVICE(0x2770, 0x9051)}, - {USB_DEVICE(0x2770, 0x9052)}, - {USB_DEVICE(0x2770, 0x913d)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c deleted file mode 100644 index 7e8748b31e85..000000000000 --- a/drivers/media/video/gspca/sq930x.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * SQ930x subdriver - * - * Copyright (C) 2010 Jean-François Moine <http://moinejf.free.fr> - * Copyright (C) 2006 -2008 Gerard Klaver <gerard at gkall dot hobby dot nl> - * Copyright (C) 2007 Sam Revitch <samr7@cs.washington.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sq930x" - -#include "gspca.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n" - "Gerard Klaver <gerard at gkall dot hobby dot nl\n" - "Sam Revitch <samr7@cs.washington.edu>"); -MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct { /* exposure/gain control cluster */ - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; - }; - - u8 do_ctrl; - u8 gpio[2]; - u8 sensor; - u8 type; -#define Generic 0 -#define Creative_live_motion 1 -}; -enum sensors { - SENSOR_ICX098BQ, - SENSOR_LZ24BP, - SENSOR_MI0360, - SENSOR_MT9V111, /* = MI360SOC */ - SENSOR_OV7660, - SENSOR_OV9630, -}; - -static struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - {640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, -}; - -/* sq930x registers */ -#define SQ930_CTRL_UCBUS_IO 0x0001 -#define SQ930_CTRL_I2C_IO 0x0002 -#define SQ930_CTRL_GPIO 0x0005 -#define SQ930_CTRL_CAP_START 0x0010 -#define SQ930_CTRL_CAP_STOP 0x0011 -#define SQ930_CTRL_SET_EXPOSURE 0x001d -#define SQ930_CTRL_RESET 0x001e -#define SQ930_CTRL_GET_DEV_INFO 0x001f - -/* gpio 1 (8..15) */ -#define SQ930_GPIO_DFL_I2C_SDA 0x0001 -#define SQ930_GPIO_DFL_I2C_SCL 0x0002 -#define SQ930_GPIO_RSTBAR 0x0004 -#define SQ930_GPIO_EXTRA1 0x0040 -#define SQ930_GPIO_EXTRA2 0x0080 -/* gpio 3 (24..31) */ -#define SQ930_GPIO_POWER 0x0200 -#define SQ930_GPIO_DFL_LED 0x1000 - -struct ucbus_write_cmd { - u16 bw_addr; - u8 bw_data; -}; -struct i2c_write_cmd { - u8 reg; - u16 val; -}; - -static const struct ucbus_write_cmd icx098bq_start_0[] = { - {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xce}, - {0xf802, 0xc1}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x0e}, - {0xf80a, 0x01}, {0xf80b, 0xee}, {0xf807, 0x60}, {0xf80c, 0x02}, - {0xf80d, 0xf0}, {0xf80e, 0x03}, {0xf80f, 0x0a}, {0xf81c, 0x02}, - {0xf81d, 0xf0}, {0xf81e, 0x03}, {0xf81f, 0x0a}, {0xf83a, 0x00}, - {0xf83b, 0x10}, {0xf83c, 0x00}, {0xf83d, 0x4e}, {0xf810, 0x04}, - {0xf811, 0x00}, {0xf812, 0x02}, {0xf813, 0x10}, {0xf803, 0x00}, - {0xf814, 0x01}, {0xf815, 0x18}, {0xf816, 0x00}, {0xf817, 0x48}, - {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c}, - {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff}, - {0xf823, 0x07}, {0xf824, 0xff}, {0xf825, 0x03}, {0xf826, 0xff}, - {0xf827, 0x06}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff}, - {0xf82b, 0x0c}, {0xf82c, 0xfd}, {0xf82d, 0x01}, {0xf82e, 0x00}, - {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00}, - {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24}, - {0xf854, 0x00}, {0xf855, 0x18}, {0xf856, 0x00}, {0xf857, 0x3c}, - {0xf858, 0x00}, {0xf859, 0x0c}, {0xf85a, 0x00}, {0xf85b, 0x30}, - {0xf85c, 0x00}, {0xf85d, 0x0c}, {0xf85e, 0x00}, {0xf85f, 0x30}, - {0xf860, 0x00}, {0xf861, 0x48}, {0xf862, 0x01}, {0xf863, 0xdc}, - {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0}, - {0xf868, 0xff}, {0xf869, 0x70}, {0xf86c, 0xff}, {0xf86d, 0x00}, - {0xf86a, 0xff}, {0xf86b, 0x48}, {0xf86e, 0xff}, {0xf86f, 0x00}, - {0xf870, 0x01}, {0xf871, 0xdb}, {0xf872, 0x01}, {0xf873, 0xfa}, - {0xf874, 0x01}, {0xf875, 0xdb}, {0xf876, 0x01}, {0xf877, 0xfa}, - {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff}, - {0xf800, 0x03} -}; -static const struct ucbus_write_cmd icx098bq_start_1[] = { - {0xf5f0, 0x00}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xc0}, - {0xf5f0, 0x49}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xc0}, - {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00}, - {0xf5f9, 0x00} -}; - -static const struct ucbus_write_cmd icx098bq_start_2[] = { - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x82}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x40}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xcf}, {0xf806, 0xd0}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03} -}; - -static const struct ucbus_write_cmd lz24bp_start_0[] = { - {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xbe}, - {0xf802, 0xc6}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x06}, - {0xf80a, 0x01}, {0xf80b, 0xfe}, {0xf807, 0x84}, {0xf80c, 0x02}, - {0xf80d, 0xf7}, {0xf80e, 0x03}, {0xf80f, 0x0b}, {0xf81c, 0x00}, - {0xf81d, 0x49}, {0xf81e, 0x03}, {0xf81f, 0x0b}, {0xf83a, 0x00}, - {0xf83b, 0x01}, {0xf83c, 0x00}, {0xf83d, 0x6b}, {0xf810, 0x03}, - {0xf811, 0x10}, {0xf812, 0x02}, {0xf813, 0x6f}, {0xf803, 0x00}, - {0xf814, 0x00}, {0xf815, 0x44}, {0xf816, 0x00}, {0xf817, 0x48}, - {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c}, - {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff}, - {0xf823, 0x07}, {0xf824, 0xfd}, {0xf825, 0x07}, {0xf826, 0xf0}, - {0xf827, 0x0c}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff}, - {0xf82b, 0x0c}, {0xf82c, 0xfc}, {0xf82d, 0x01}, {0xf82e, 0x00}, - {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00}, - {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24}, - {0xf854, 0x00}, {0xf855, 0x0c}, {0xf856, 0x00}, {0xf857, 0x30}, - {0xf858, 0x00}, {0xf859, 0x18}, {0xf85a, 0x00}, {0xf85b, 0x3c}, - {0xf85c, 0x00}, {0xf85d, 0x18}, {0xf85e, 0x00}, {0xf85f, 0x3c}, - {0xf860, 0xff}, {0xf861, 0x37}, {0xf862, 0xff}, {0xf863, 0x1d}, - {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0}, - {0xf868, 0x00}, {0xf869, 0x37}, {0xf86c, 0x02}, {0xf86d, 0x1d}, - {0xf86a, 0x00}, {0xf86b, 0x37}, {0xf86e, 0x02}, {0xf86f, 0x1d}, - {0xf870, 0x01}, {0xf871, 0xc6}, {0xf872, 0x02}, {0xf873, 0x04}, - {0xf874, 0x01}, {0xf875, 0xc6}, {0xf876, 0x02}, {0xf877, 0x04}, - {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff}, - {0xf800, 0x03} -}; -static const struct ucbus_write_cmd lz24bp_start_1_gen[] = { - {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xb3}, - {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xb3}, - {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00}, - {0xf5f9, 0x00} -}; - -static const struct ucbus_write_cmd lz24bp_start_1_clm[] = { - {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88}, - {0xf5f4, 0xc0}, - {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88}, - {0xf5f4, 0xc0}, - {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00}, - {0xf5f9, 0x00} -}; - -static const struct ucbus_write_cmd lz24bp_start_2[] = { - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x80}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x4e}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xc0}, {0xf806, 0x48}, - {0xf807, 0x7f}, {0xf800, 0x03}, - {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00}, - {0xf807, 0x7f}, {0xf800, 0x03} -}; - -static const struct ucbus_write_cmd mi0360_start_0[] = { - {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0xcc}, {0xf333, 0xcc}, - {0xf334, 0xcc}, {0xf335, 0xcc}, {0xf33f, 0x00} -}; -static const struct i2c_write_cmd mi0360_init_23[] = { - {0x30, 0x0040}, /* reserved - def 0x0005 */ - {0x31, 0x0000}, /* reserved - def 0x002a */ - {0x34, 0x0100}, /* reserved - def 0x0100 */ - {0x3d, 0x068f}, /* reserved - def 0x068f */ -}; -static const struct i2c_write_cmd mi0360_init_24[] = { - {0x03, 0x01e5}, /* window height */ - {0x04, 0x0285}, /* window width */ -}; -static const struct i2c_write_cmd mi0360_init_25[] = { - {0x35, 0x0020}, /* global gain */ - {0x2b, 0x0020}, /* green1 gain */ - {0x2c, 0x002a}, /* blue gain */ - {0x2d, 0x0028}, /* red gain */ - {0x2e, 0x0020}, /* green2 gain */ -}; -static const struct ucbus_write_cmd mi0360_start_1[] = { - {0xf5f0, 0x11}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xa6}, - {0xf5f0, 0x51}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xa6}, - {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00}, - {0xf5f9, 0x00} -}; -static const struct i2c_write_cmd mi0360_start_2[] = { - {0x62, 0x041d}, /* reserved - def 0x0418 */ -}; -static const struct i2c_write_cmd mi0360_start_3[] = { - {0x05, 0x007b}, /* horiz blanking */ -}; -static const struct i2c_write_cmd mi0360_start_4[] = { - {0x05, 0x03f5}, /* horiz blanking */ -}; - -static const struct i2c_write_cmd mt9v111_init_0[] = { - {0x01, 0x0001}, /* select IFP/SOC registers */ - {0x06, 0x300c}, /* operating mode control */ - {0x08, 0xcc00}, /* output format control (RGB) */ - {0x01, 0x0004}, /* select sensor core registers */ -}; -static const struct i2c_write_cmd mt9v111_init_1[] = { - {0x03, 0x01e5}, /* window height */ - {0x04, 0x0285}, /* window width */ -}; -static const struct i2c_write_cmd mt9v111_init_2[] = { - {0x30, 0x7800}, - {0x31, 0x0000}, - {0x07, 0x3002}, /* output control */ - {0x35, 0x0020}, /* global gain */ - {0x2b, 0x0020}, /* green1 gain */ - {0x2c, 0x0020}, /* blue gain */ - {0x2d, 0x0020}, /* red gain */ - {0x2e, 0x0020}, /* green2 gain */ -}; -static const struct ucbus_write_cmd mt9v111_start_1[] = { - {0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xaa}, - {0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80}, - {0xf5f4, 0xaa}, - {0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a}, - {0xf5f9, 0x0a} -}; -static const struct i2c_write_cmd mt9v111_init_3[] = { - {0x62, 0x0405}, -}; -static const struct i2c_write_cmd mt9v111_init_4[] = { -/* {0x05, 0x00ce}, */ - {0x05, 0x005d}, /* horizontal blanking */ -}; - -static const struct ucbus_write_cmd ov7660_start_0[] = { - {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0}, - {0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03} -}; - -static const struct ucbus_write_cmd ov9630_start_0[] = { - {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00}, - {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03} -}; - -/* start parameters indexed by [sensor][mode] */ -static const struct cap_s { - u8 cc_sizeid; - u8 cc_bytes[32]; -} capconfig[4][2] = { - [SENSOR_ICX098BQ] = { - {2, /* Bayer 320x240 */ - {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, - 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - {4, /* Bayer 640x480 */ - {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, - 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - }, - [SENSOR_LZ24BP] = { - {2, /* Bayer 320x240 */ - {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee, - 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - {4, /* Bayer 640x480 */ - {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee, - 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - }, - [SENSOR_MI0360] = { - {2, /* Bayer 320x240 */ - {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, - 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - {4, /* Bayer 640x480 */ - {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, - 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - }, - [SENSOR_MT9V111] = { - {2, /* Bayer 320x240 */ - {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, - 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - {4, /* Bayer 640x480 */ - {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1, - 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, - }, -}; - -struct sensor_s { - const char *name; - u8 i2c_addr; - u8 i2c_dum; - u8 gpio[5]; - u8 cmd_len; - const struct ucbus_write_cmd *cmd; -}; - -static const struct sensor_s sensor_tb[] = { - [SENSOR_ICX098BQ] = { - "icx098bp", - 0x00, 0x00, - {0, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - SQ930_GPIO_RSTBAR - }, - 8, icx098bq_start_0 - }, - [SENSOR_LZ24BP] = { - "lz24bp", - 0x00, 0x00, - {0, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - SQ930_GPIO_RSTBAR - }, - 8, lz24bp_start_0 - }, - [SENSOR_MI0360] = { - "mi0360", - 0x5d, 0x80, - {SQ930_GPIO_RSTBAR, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - 0 - }, - 7, mi0360_start_0 - }, - [SENSOR_MT9V111] = { - "mt9v111", - 0x5c, 0x7f, - {SQ930_GPIO_RSTBAR, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - 0 - }, - 7, mi0360_start_0 - }, - [SENSOR_OV7660] = { - "ov7660", - 0x21, 0x00, - {0, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - SQ930_GPIO_RSTBAR - }, - 7, ov7660_start_0 - }, - [SENSOR_OV9630] = { - "ov9630", - 0x30, 0x00, - {0, - SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL, - SQ930_GPIO_DFL_I2C_SDA, - 0, - SQ930_GPIO_RSTBAR - }, - 7, ov9630_start_0 - }, -}; - -static void reg_r(struct gspca_dev *gspca_dev, - u16 value, int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0x0c, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0, gspca_dev->usb_buf, len, - 500); - if (ret < 0) { - pr_err("reg_r %04x failed %d\n", value, ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x0c, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, - 500); - msleep(30); - if (ret < 0) { - pr_err("reg_w %04x %04x failed %d\n", value, index, ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index, - const u8 *data, int len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x", - value, index, *data, data[len - 1]); - memcpy(gspca_dev->usb_buf, data, len); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x0c, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, gspca_dev->usb_buf, len, - 1000); - msleep(30); - if (ret < 0) { - pr_err("reg_wb %04x %04x failed %d\n", value, index, ret); - gspca_dev->usb_err = ret; - } -} - -static void i2c_write(struct sd *sd, - const struct i2c_write_cmd *cmd, - int ncmds) -{ - struct gspca_dev *gspca_dev = &sd->gspca_dev; - const struct sensor_s *sensor; - u16 val, idx; - u8 *buf; - int ret; - - if (gspca_dev->usb_err < 0) - return; - - sensor = &sensor_tb[sd->sensor]; - - val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO; - idx = (cmd->val & 0xff00) | cmd->reg; - - buf = gspca_dev->usb_buf; - *buf++ = sensor->i2c_dum; - *buf++ = cmd->val; - - while (--ncmds > 0) { - cmd++; - *buf++ = cmd->reg; - *buf++ = cmd->val >> 8; - *buf++ = sensor->i2c_dum; - *buf++ = cmd->val; - } - - PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x", - val, idx, gspca_dev->usb_buf[0], buf[-1]); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x0c, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - val, idx, - gspca_dev->usb_buf, buf - gspca_dev->usb_buf, - 500); - if (ret < 0) { - pr_err("i2c_write failed %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void ucbus_write(struct gspca_dev *gspca_dev, - const struct ucbus_write_cmd *cmd, - int ncmds, - int batchsize) -{ - u8 *buf; - u16 val, idx; - int len, ret; - - if (gspca_dev->usb_err < 0) - return; - -#ifdef GSPCA_DEBUG - if ((batchsize - 1) * 3 > USB_BUF_SZ) { - pr_err("Bug: usb_buf overflow\n"); - gspca_dev->usb_err = -ENOMEM; - return; - } -#endif - - for (;;) { - len = ncmds; - if (len > batchsize) - len = batchsize; - ncmds -= len; - - val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO; - idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8); - - buf = gspca_dev->usb_buf; - while (--len > 0) { - cmd++; - *buf++ = cmd->bw_addr; - *buf++ = cmd->bw_addr >> 8; - *buf++ = cmd->bw_data; - } - if (buf != gspca_dev->usb_buf) - PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x", - val, idx, - gspca_dev->usb_buf[0], buf[-1]); - else - PDEBUG(D_USBO, "ucbus v: %04x i: %04x", - val, idx); - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x0c, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - val, idx, - gspca_dev->usb_buf, buf - gspca_dev->usb_buf, - 500); - if (ret < 0) { - pr_err("ucbus_write failed %d\n", ret); - gspca_dev->usb_err = ret; - return; - } - msleep(30); - if (ncmds <= 0) - break; - cmd++; - } -} - -static void gpio_set(struct sd *sd, u16 val, u16 mask) -{ - struct gspca_dev *gspca_dev = &sd->gspca_dev; - - if (mask & 0x00ff) { - sd->gpio[0] &= ~mask; - sd->gpio[0] |= val; - reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO, - ~sd->gpio[0] << 8); - } - mask >>= 8; - val >>= 8; - if (mask) { - sd->gpio[1] &= ~mask; - sd->gpio[1] |= val; - reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO, - ~sd->gpio[1] << 8); - } -} - -static void gpio_init(struct sd *sd, - const u8 *gpio) -{ - gpio_set(sd, *gpio++, 0x000f); - gpio_set(sd, *gpio++, 0x000f); - gpio_set(sd, *gpio++, 0x000f); - gpio_set(sd, *gpio++, 0x000f); - gpio_set(sd, *gpio, 0x000f); -} - -static void bridge_init(struct sd *sd) -{ - static const struct ucbus_write_cmd clkfreq_cmd = { - 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */ - }; - - ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1); - - gpio_set(sd, SQ930_GPIO_POWER, 0xff00); -} - -static void cmos_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - const struct sensor_s *sensor; - static const u8 probe_order[] = { -/* SENSOR_LZ24BP, (tested as ccd) */ - SENSOR_OV9630, - SENSOR_MI0360, - SENSOR_OV7660, - SENSOR_MT9V111, - }; - - for (i = 0; i < ARRAY_SIZE(probe_order); i++) { - sensor = &sensor_tb[probe_order[i]]; - ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8); - gpio_init(sd, sensor->gpio); - msleep(100); - reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1); - msleep(100); - if (gspca_dev->usb_buf[0] != 0) - break; - } - if (i >= ARRAY_SIZE(probe_order)) { - pr_err("Unknown sensor\n"); - gspca_dev->usb_err = -EINVAL; - return; - } - sd->sensor = probe_order[i]; - switch (sd->sensor) { - case SENSOR_OV7660: - case SENSOR_OV9630: - pr_err("Sensor %s not yet treated\n", - sensor_tb[sd->sensor].name); - gspca_dev->usb_err = -EINVAL; - break; - } -} - -static void mt9v111_init(struct gspca_dev *gspca_dev) -{ - int i, nwait; - static const u8 cmd_001b[] = { - 0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00 - }; - static const u8 cmd_011b[][7] = { - {0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00}, - {0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00}, - {0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00}, - {0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00}, - }; - - reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b); - for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) { - reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i], - ARRAY_SIZE(cmd_011b[0])); - msleep(400); - nwait = 20; - for (;;) { - reg_r(gspca_dev, 0x031b, 1); - if (gspca_dev->usb_buf[0] == 0 - || gspca_dev->usb_err != 0) - break; - if (--nwait < 0) { - PDEBUG(D_PROBE, "mt9v111_init timeout"); - gspca_dev->usb_err = -ETIME; - return; - } - msleep(50); - } - } -} - -static void global_init(struct sd *sd, int first_time) -{ - switch (sd->sensor) { - case SENSOR_ICX098BQ: - if (first_time) - ucbus_write(&sd->gspca_dev, - icx098bq_start_0, - 8, 8); - gpio_init(sd, sensor_tb[sd->sensor].gpio); - break; - case SENSOR_LZ24BP: - if (sd->type != Creative_live_motion) - gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff); - else - gpio_set(sd, 0, 0x00ff); - msleep(50); - if (first_time) - ucbus_write(&sd->gspca_dev, - lz24bp_start_0, - 8, 8); - gpio_init(sd, sensor_tb[sd->sensor].gpio); - break; - case SENSOR_MI0360: - if (first_time) - ucbus_write(&sd->gspca_dev, - mi0360_start_0, - ARRAY_SIZE(mi0360_start_0), - 8); - gpio_init(sd, sensor_tb[sd->sensor].gpio); - gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2); - break; - default: -/* case SENSOR_MT9V111: */ - if (first_time) - mt9v111_init(&sd->gspca_dev); - else - gpio_init(sd, sensor_tb[sd->sensor].gpio); - break; - } -} - -static void lz24bp_ppl(struct sd *sd, u16 ppl) -{ - struct ucbus_write_cmd cmds[2] = { - {0xf810, ppl >> 8}, - {0xf811, ppl} - }; - - ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, integclks, intstartclk, frameclks, min_frclk; - const struct sensor_s *sensor; - u16 cmd; - u8 buf[15]; - - integclks = expo; - i = 0; - cmd = SQ930_CTRL_SET_EXPOSURE; - - switch (sd->sensor) { - case SENSOR_ICX098BQ: /* ccd */ - case SENSOR_LZ24BP: - min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f; - if (integclks >= min_frclk) { - intstartclk = 0; - frameclks = integclks; - } else { - intstartclk = min_frclk - integclks; - frameclks = min_frclk; - } - buf[i++] = intstartclk >> 8; - buf[i++] = intstartclk; - buf[i++] = frameclks >> 8; - buf[i++] = frameclks; - buf[i++] = gain; - break; - default: /* cmos */ -/* case SENSOR_MI0360: */ -/* case SENSOR_MT9V111: */ - cmd |= 0x0100; - sensor = &sensor_tb[sd->sensor]; - buf[i++] = sensor->i2c_addr; /* i2c_slave_addr */ - buf[i++] = 0x08; /* 2 * ni2c */ - buf[i++] = 0x09; /* reg = shutter width */ - buf[i++] = integclks >> 8; /* val H */ - buf[i++] = sensor->i2c_dum; - buf[i++] = integclks; /* val L */ - buf[i++] = 0x35; /* reg = global gain */ - buf[i++] = 0x00; /* val H */ - buf[i++] = sensor->i2c_dum; - buf[i++] = 0x80 + gain / 2; /* val L */ - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x83; - break; - } - reg_wb(gspca_dev, cmd, 0, buf, i); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - sd->sensor = id->driver_info >> 8; - sd->type = id->driver_info; - - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - - cam->bulk = 1; - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */ - -/*fixme: is this needed for icx098bp and mi0360? - if (sd->sensor != SENSOR_LZ24BP) - reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000); - */ - - reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8); - if (gspca_dev->usb_err < 0) - return gspca_dev->usb_err; - -/* it returns: - * 03 00 12 93 0b f6 c9 00 live! ultra - * 03 00 07 93 0b f6 ca 00 live! ultra for notebook - * 03 00 12 93 0b fe c8 00 Trust WB-3500T - * 02 00 06 93 0b fe c8 00 Joy-IT 318S - * 03 00 12 93 0b f6 cf 00 icam tracer - sensor icx098bq - * 02 00 12 93 0b fe cf 00 ProQ Motion Webcam - * - * byte - * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit) - * 1: 00 - * 2: 06 / 07 / 12 = mode webcam? firmware?? - * 3: 93 chip = 930b (930b or 930c) - * 4: 0b - * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors) - * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam? - * 7: 00 - */ - PDEBUG(D_PROBE, "info: %*ph", 8, gspca_dev->usb_buf); - - bridge_init(sd); - - if (sd->sensor == SENSOR_MI0360) { - - /* no sensor probe for icam tracer */ - if (gspca_dev->usb_buf[5] == 0xf6) /* if ccd */ - sd->sensor = SENSOR_ICX098BQ; - else - cmos_probe(gspca_dev); - } - if (gspca_dev->usb_err >= 0) { - PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name); - global_init(sd, 1); - } - return gspca_dev->usb_err; -} - -/* send the start/stop commands to the webcam */ -static void send_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - const struct cap_s *cap; - int mode; - - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - cap = &capconfig[sd->sensor][mode]; - reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START, - 0x0a00 | cap->cc_sizeid, - cap->cc_bytes, 32); -} - -static void send_stop(struct gspca_dev *gspca_dev) -{ - reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0); -} - -/* function called at start time before URB creation */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */ - sd->do_ctrl = 0; - gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8; - return 0; -} - -/* start the capture */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int mode; - - bridge_init(sd); - global_init(sd, 0); - msleep(100); - - switch (sd->sensor) { - case SENSOR_ICX098BQ: - ucbus_write(gspca_dev, icx098bq_start_0, - ARRAY_SIZE(icx098bq_start_0), - 8); - ucbus_write(gspca_dev, icx098bq_start_1, - ARRAY_SIZE(icx098bq_start_1), - 5); - ucbus_write(gspca_dev, icx098bq_start_2, - ARRAY_SIZE(icx098bq_start_2), - 6); - msleep(50); - - /* 1st start */ - send_start(gspca_dev); - gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff); - msleep(70); - reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000); - gpio_set(sd, 0x7f, 0x00ff); - - /* 2nd start */ - send_start(gspca_dev); - gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff); - goto out; - case SENSOR_LZ24BP: - ucbus_write(gspca_dev, lz24bp_start_0, - ARRAY_SIZE(lz24bp_start_0), - 8); - if (sd->type != Creative_live_motion) - ucbus_write(gspca_dev, lz24bp_start_1_gen, - ARRAY_SIZE(lz24bp_start_1_gen), - 5); - else - ucbus_write(gspca_dev, lz24bp_start_1_clm, - ARRAY_SIZE(lz24bp_start_1_clm), - 5); - ucbus_write(gspca_dev, lz24bp_start_2, - ARRAY_SIZE(lz24bp_start_2), - 6); - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310); - msleep(10); - break; - case SENSOR_MI0360: - ucbus_write(gspca_dev, mi0360_start_0, - ARRAY_SIZE(mi0360_start_0), - 8); - i2c_write(sd, mi0360_init_23, - ARRAY_SIZE(mi0360_init_23)); - i2c_write(sd, mi0360_init_24, - ARRAY_SIZE(mi0360_init_24)); - i2c_write(sd, mi0360_init_25, - ARRAY_SIZE(mi0360_init_25)); - ucbus_write(gspca_dev, mi0360_start_1, - ARRAY_SIZE(mi0360_start_1), - 5); - i2c_write(sd, mi0360_start_2, - ARRAY_SIZE(mi0360_start_2)); - i2c_write(sd, mi0360_start_3, - ARRAY_SIZE(mi0360_start_3)); - - /* 1st start */ - send_start(gspca_dev); - msleep(60); - send_stop(gspca_dev); - - i2c_write(sd, - mi0360_start_4, ARRAY_SIZE(mi0360_start_4)); - break; - default: -/* case SENSOR_MT9V111: */ - ucbus_write(gspca_dev, mi0360_start_0, - ARRAY_SIZE(mi0360_start_0), - 8); - i2c_write(sd, mt9v111_init_0, - ARRAY_SIZE(mt9v111_init_0)); - i2c_write(sd, mt9v111_init_1, - ARRAY_SIZE(mt9v111_init_1)); - i2c_write(sd, mt9v111_init_2, - ARRAY_SIZE(mt9v111_init_2)); - ucbus_write(gspca_dev, mt9v111_start_1, - ARRAY_SIZE(mt9v111_start_1), - 5); - i2c_write(sd, mt9v111_init_3, - ARRAY_SIZE(mt9v111_init_3)); - i2c_write(sd, mt9v111_init_4, - ARRAY_SIZE(mt9v111_init_4)); - break; - } - - send_start(gspca_dev); -out: - msleep(1000); - - if (sd->sensor == SENSOR_MT9V111) - gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED); - - sd->do_ctrl = 1; /* set the exposure */ - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_MT9V111) - gpio_set(sd, 0, SQ930_GPIO_DFL_LED); - send_stop(gspca_dev); -} - -/* function called when the application gets a new frame */ -/* It sets the exposure if required and restart the bulk transfer. */ -static void sd_dq_callback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0) - return; - sd->do_ctrl = 0; - - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure), - v4l2_ctrl_g_ctrl(sd->gain)); - - gspca_dev->cam.bulk_nurbs = 1; - ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC); - if (ret < 0) - pr_err("sd_dq_callback() err %d\n", ret); - - /* wait a little time, otherwise the webcam crashes */ - msleep(100); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->do_ctrl) - gspca_dev->cam.bulk_nurbs = 0; - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8); - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *) gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, ctrl->val, sd->gain->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - struct sd *sd = (struct sd *) gspca_dev; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 2); - sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 1, 0xfff, 1, 0x356); - sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 1, 255, 1, 0x8d); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_cluster(2, &sd->exposure); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_dq_callback, -}; - -/* Table of supported USB devices */ -#define ST(sensor, type) \ - .driver_info = (SENSOR_ ## sensor << 8) \ - | (type) -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)}, - {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)}, - {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)}, - {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)}, - {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)}, - {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c deleted file mode 100644 index 8c0982607f25..000000000000 --- a/drivers/media/video/gspca/stk014.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Syntek DV4000 (STK014) subdriver - * - * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "stk014" - -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define QUALITY 50 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* -- read a register -- */ -static u8 reg_r(struct gspca_dev *gspca_dev, - __u16 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return 0; - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x00, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, - index, - gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - return 0; - } - return gspca_dev->usb_buf[0]; -} - -/* -- write a register -- */ -static void reg_w(struct gspca_dev *gspca_dev, - __u16 index, __u16 value) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x01, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - NULL, - 0, - 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* -- get a bulk value (4 bytes) -- */ -static void rcv_val(struct gspca_dev *gspca_dev, - int ads) -{ - struct usb_device *dev = gspca_dev->dev; - int alen, ret; - - reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); - reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); - reg_w(gspca_dev, 0x636, ads & 0xff); - reg_w(gspca_dev, 0x637, 0); - reg_w(gspca_dev, 0x638, 4); /* len & 0xff */ - reg_w(gspca_dev, 0x639, 0); /* len >> 8 */ - reg_w(gspca_dev, 0x63a, 0); - reg_w(gspca_dev, 0x63b, 0); - reg_w(gspca_dev, 0x630, 5); - if (gspca_dev->usb_err < 0) - return; - ret = usb_bulk_msg(dev, - usb_rcvbulkpipe(dev, 0x05), - gspca_dev->usb_buf, - 4, /* length */ - &alen, - 500); /* timeout in milliseconds */ - if (ret < 0) { - pr_err("rcv_val err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* -- send a bulk value -- */ -static void snd_val(struct gspca_dev *gspca_dev, - int ads, - unsigned int val) -{ - struct usb_device *dev = gspca_dev->dev; - int alen, ret; - __u8 seq = 0; - - if (ads == 0x003f08) { - reg_r(gspca_dev, 0x0704); - seq = reg_r(gspca_dev, 0x0705); - reg_r(gspca_dev, 0x0650); - reg_w(gspca_dev, 0x654, seq); - } else { - reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); - } - reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); - reg_w(gspca_dev, 0x656, ads & 0xff); - reg_w(gspca_dev, 0x657, 0); - reg_w(gspca_dev, 0x658, 0x04); /* size */ - reg_w(gspca_dev, 0x659, 0); - reg_w(gspca_dev, 0x65a, 0); - reg_w(gspca_dev, 0x65b, 0); - reg_w(gspca_dev, 0x650, 5); - if (gspca_dev->usb_err < 0) - return; - gspca_dev->usb_buf[0] = val >> 24; - gspca_dev->usb_buf[1] = val >> 16; - gspca_dev->usb_buf[2] = val >> 8; - gspca_dev->usb_buf[3] = val; - ret = usb_bulk_msg(dev, - usb_sndbulkpipe(dev, 6), - gspca_dev->usb_buf, - 4, - &alen, - 500); /* timeout in milliseconds */ - if (ret < 0) { - pr_err("snd_val err %d\n", ret); - gspca_dev->usb_err = ret; - } else { - if (ads == 0x003f08) { - seq += 4; - seq &= 0x3f; - reg_w(gspca_dev, 0x705, seq); - } - } -} - -/* set a camera parameter */ -static void set_par(struct gspca_dev *gspca_dev, - int parval) -{ - snd_val(gspca_dev, 0x003f08, parval); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - int parval; - - parval = 0x06000000 /* whiteness */ - + (val << 16); - set_par(gspca_dev, parval); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - int parval; - - parval = 0x07000000 /* contrast */ - + (val << 16); - set_par(gspca_dev, parval); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - int parval; - - parval = 0x08000000 /* saturation */ - + (val << 16); - set_par(gspca_dev, parval); -} - -static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) -{ - set_par(gspca_dev, val == 1 - ? 0x33640000 /* 50 Hz */ - : 0x33780000); /* 60 Hz */ -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - u8 ret; - - /* check if the device responds */ - usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - ret = reg_r(gspca_dev, 0x0740); - if (gspca_dev->usb_err >= 0) { - if (ret != 0xff) { - pr_err("init reg: 0x%02x\n", ret); - gspca_dev->usb_err = -EIO; - } - } - return gspca_dev->usb_err; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret, value; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, QUALITY); - - /* work on alternate 1 */ - usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - - set_par(gspca_dev, 0x10000000); - set_par(gspca_dev, 0x00000000); - set_par(gspca_dev, 0x8002e001); - set_par(gspca_dev, 0x14000000); - if (gspca_dev->width > 320) - value = 0x8002e001; /* 640x480 */ - else - value = 0x4001f000; /* 320x240 */ - set_par(gspca_dev, value); - ret = usb_set_interface(gspca_dev->dev, - gspca_dev->iface, - gspca_dev->alt); - if (ret < 0) { - pr_err("set intf %d %d failed\n", - gspca_dev->iface, gspca_dev->alt); - gspca_dev->usb_err = ret; - goto out; - } - reg_r(gspca_dev, 0x0630); - rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ - reg_r(gspca_dev, 0x0650); - snd_val(gspca_dev, 0x000020, 0xffffffff); - reg_w(gspca_dev, 0x0620, 0); - reg_w(gspca_dev, 0x0630, 0); - reg_w(gspca_dev, 0x0640, 0); - reg_w(gspca_dev, 0x0650, 0); - reg_w(gspca_dev, 0x0660, 0); - set_par(gspca_dev, 0x09800000); /* Red ? */ - set_par(gspca_dev, 0x0a800000); /* Green ? */ - set_par(gspca_dev, 0x0b800000); /* Blue ? */ - set_par(gspca_dev, 0x0d030000); /* Gamma ? */ - - /* start the video flow */ - set_par(gspca_dev, 0x01000000); - set_par(gspca_dev, 0x01000000); - if (gspca_dev->usb_err >= 0) - PDEBUG(D_STREAM, "camera started alt: 0x%02x", - gspca_dev->alt); -out: - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct usb_device *dev = gspca_dev->dev; - - set_par(gspca_dev, 0x02000000); - set_par(gspca_dev, 0x02000000); - usb_set_interface(dev, gspca_dev->iface, 1); - reg_r(gspca_dev, 0x0630); - rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ - reg_r(gspca_dev, 0x0650); - snd_val(gspca_dev, 0x000020, 0xffffffff); - reg_w(gspca_dev, 0x0620, 0); - reg_w(gspca_dev, 0x0630, 0); - reg_w(gspca_dev, 0x0640, 0); - reg_w(gspca_dev, 0x0650, 0); - reg_w(gspca_dev, 0x0660, 0); - PDEBUG(D_STREAM, "camera stopped"); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - static unsigned char ffd9[] = {0xff, 0xd9}; - - /* a frame starts with: - * - 0xff 0xfe - * - 0x08 0x00 - length (little endian ?!) - * - 4 bytes = size of whole frame (BE - including header) - * - 0x00 0x0c - * - 0xff 0xd8 - * - .. JPEG image with escape sequences (ff 00) - * (without ending - ff d9) - */ - if (data[0] == 0xff && data[1] == 0xfe) { - gspca_frame_add(gspca_dev, LAST_PACKET, - ffd9, 2); - - /* put the JPEG 411 header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - - /* beginning of the frame */ -#define STKHDRSZ 12 - data += STKHDRSZ; - len -= STKHDRSZ; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setlightfreq(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 127); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 127); - v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x05e1, 0x0893)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c deleted file mode 100644 index 67605272aaa8..000000000000 --- a/drivers/media/video/gspca/stv0680.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * STV0680 USB Camera Driver - * - * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> - * - * This module is adapted from the in kernel v4l1 stv680 driver: - * - * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net) - * - * Thanks to STMicroelectronics for information on the usb commands, and - * to Steve Miller at STM for his help and encouragement while I was - * writing this driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "stv0680" - -#include "gspca.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("STV0680 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct v4l2_pix_format mode; - u8 orig_mode; - u8 video_mode; - u8 current_mode; -}; - -static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, - int size) -{ - int ret = -1; - u8 req_type = 0; - unsigned int pipe = 0; - - switch (set) { - case 0: /* 0xc1 */ - req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; - pipe = usb_rcvctrlpipe(gspca_dev->dev, 0); - break; - case 1: /* 0x41 */ - req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; - pipe = usb_sndctrlpipe(gspca_dev->dev, 0); - break; - case 2: /* 0x80 */ - req_type = USB_DIR_IN | USB_RECIP_DEVICE; - pipe = usb_rcvctrlpipe(gspca_dev->dev, 0); - break; - case 3: /* 0x40 */ - req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - pipe = usb_sndctrlpipe(gspca_dev->dev, 0); - break; - } - - ret = usb_control_msg(gspca_dev->dev, pipe, - req, req_type, - val, 0, gspca_dev->usb_buf, size, 500); - - if ((ret < 0) && (req != 0x0a)) - pr_err("usb_control_msg error %i, request = 0x%x, error = %i\n", - set, req, ret); - - return ret; -} - -static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret) -{ - stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */ - PDEBUG(D_ERR, "last error: %i, command = 0x%x", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); - return ret; -} - -static int stv0680_get_video_mode(struct gspca_dev *gspca_dev) -{ - /* Note not sure if this init of usb_buf is really necessary */ - memset(gspca_dev->usb_buf, 0, 8); - gspca_dev->usb_buf[0] = 0x0f; - - if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) { - PDEBUG(D_ERR, "Get_Camera_Mode failed"); - return stv0680_handle_error(gspca_dev, -EIO); - } - - return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */ -} - -static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->current_mode == mode) - return 0; - - memset(gspca_dev->usb_buf, 0, 8); - gspca_dev->usb_buf[0] = mode; - - if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) { - PDEBUG(D_ERR, "Set_Camera_Mode failed"); - return stv0680_handle_error(gspca_dev, -EIO); - } - - /* Verify we got what we've asked for */ - if (stv0680_get_video_mode(gspca_dev) != mode) { - PDEBUG(D_ERR, "Error setting camera video mode!"); - return -EIO; - } - - sd->current_mode = mode; - - return 0; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - int ret; - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam = &gspca_dev->cam; - - /* Give the camera some time to settle, otherwise initalization will - fail on hotplug, and yes it really needs a full second. */ - msleep(1000); - - /* ping camera to be sure STV0680 is present */ - if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || - gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { - PDEBUG(D_ERR, "STV(e): camera ping failed!!"); - return stv0680_handle_error(gspca_dev, -ENODEV); - } - - /* get camera descriptor */ - if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09) - return stv0680_handle_error(gspca_dev, -ENODEV); - - if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 || - gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) { - PDEBUG(D_ERR, "Could not get descriptor 0200."); - return stv0680_handle_error(gspca_dev, -ENODEV); - } - if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02) - return stv0680_handle_error(gspca_dev, -ENODEV); - if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24) - return stv0680_handle_error(gspca_dev, -ENODEV); - if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) - return stv0680_handle_error(gspca_dev, -ENODEV); - - if (!(gspca_dev->usb_buf[7] & 0x09)) { - PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode"); - return -ENODEV; - } - if (gspca_dev->usb_buf[7] & 0x01) - PDEBUG(D_PROBE, "Camera supports CIF mode"); - if (gspca_dev->usb_buf[7] & 0x02) - PDEBUG(D_PROBE, "Camera supports VGA mode"); - if (gspca_dev->usb_buf[7] & 0x04) - PDEBUG(D_PROBE, "Camera supports QCIF mode"); - if (gspca_dev->usb_buf[7] & 0x08) - PDEBUG(D_PROBE, "Camera supports QVGA mode"); - - if (gspca_dev->usb_buf[7] & 0x01) - sd->video_mode = 0x00; /* CIF */ - else - sd->video_mode = 0x03; /* QVGA */ - - /* FW rev, ASIC rev, sensor ID */ - PDEBUG(D_PROBE, "Firmware rev is %i.%i", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); - PDEBUG(D_PROBE, "ASIC rev is %i.%i", - gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]); - PDEBUG(D_PROBE, "Sensor ID is %i", - (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4)); - - - ret = stv0680_get_video_mode(gspca_dev); - if (ret < 0) - return ret; - sd->current_mode = sd->orig_mode = ret; - - ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); - if (ret < 0) - return ret; - - /* Get mode details */ - if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10) - return stv0680_handle_error(gspca_dev, -EIO); - - cam->bulk = 1; - cam->bulk_nurbs = 1; /* The cam cannot handle more */ - cam->bulk_size = (gspca_dev->usb_buf[0] << 24) | - (gspca_dev->usb_buf[1] << 16) | - (gspca_dev->usb_buf[2] << 8) | - (gspca_dev->usb_buf[3]); - sd->mode.width = (gspca_dev->usb_buf[4] << 8) | - (gspca_dev->usb_buf[5]); /* 322, 356, 644 */ - sd->mode.height = (gspca_dev->usb_buf[6] << 8) | - (gspca_dev->usb_buf[7]); /* 242, 292, 484 */ - sd->mode.pixelformat = V4L2_PIX_FMT_STV0680; - sd->mode.field = V4L2_FIELD_NONE; - sd->mode.bytesperline = sd->mode.width; - sd->mode.sizeimage = cam->bulk_size; - sd->mode.colorspace = V4L2_COLORSPACE_SRGB; - - /* origGain = gspca_dev->usb_buf[12]; */ - - cam->cam_mode = &sd->mode; - cam->nmodes = 1; - - - ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode); - if (ret < 0) - return ret; - - if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 || - gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) { - pr_err("Could not get descriptor 0100\n"); - return stv0680_handle_error(gspca_dev, -EIO); - } - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - int ret; - struct sd *sd = (struct sd *) gspca_dev; - - ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); - if (ret < 0) - return ret; - - if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) - return stv0680_handle_error(gspca_dev, -EIO); - - /* Start stream at: - 0x0000 = CIF (352x288) - 0x0100 = VGA (640x480) - 0x0300 = QVGA (320x240) */ - if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0) - return stv0680_handle_error(gspca_dev, -EIO); - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - /* This is a high priority command; it stops all lower order cmds */ - if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0) - stv0680_handle_error(gspca_dev, -EIO); -} - -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!sd->gspca_dev.present) - return; - - stv0680_set_video_mode(gspca_dev, sd->orig_mode); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* Every now and then the camera sends a 16 byte packet, no idea - what it contains, but it is not image data, when this - happens the frame received before this packet is corrupt, - so discard it. */ - if (len != sd->mode.sizeimage) { - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - - /* Finish the previous frame, we do this upon reception of the next - packet, even though it is already complete so that the strange 16 - byte packets send after a corrupt frame can discard it. */ - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - - /* Store the just received frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0553, 0x0202)}, - {USB_DEVICE(0x041e, 0x4007)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/video/gspca/stv06xx/Kconfig deleted file mode 100644 index 634ad38d9fb8..000000000000 --- a/drivers/media/video/gspca/stv06xx/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config USB_STV06XX - tristate "STV06XX USB Camera Driver" - depends on USB_GSPCA - help - Say Y here if you want support for cameras based on - the ST STV06XX chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_stv06xx. diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile deleted file mode 100644 index 38bc41061d83..000000000000 --- a/drivers/media/video/gspca/stv06xx/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o - -gspca_stv06xx-objs := stv06xx.o \ - stv06xx_vv6410.o \ - stv06xx_hdcs.o \ - stv06xx_pb0100.o \ - stv06xx_st6422.o - -ccflags-y += -I$(srctree)/drivers/media/video/gspca - diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c deleted file mode 100644 index 999ec7764449..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/input.h> -#include "stv06xx_sensor.h" - -MODULE_AUTHOR("Erik Andrén"); -MODULE_DESCRIPTION("STV06XX USB Camera Driver"); -MODULE_LICENSE("GPL"); - -static bool dump_bridge; -static bool dump_sensor; - -int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - u8 len = (i2c_data > 0xff) ? 2 : 1; - - buf[0] = i2c_data & 0xff; - buf[1] = (i2c_data >> 8) & 0xff; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, address, 0, buf, len, - STV06XX_URB_MSG_TIMEOUT); - - PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d", - i2c_data, address, err); - - return (err < 0) ? err : 0; -} - -int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, address, 0, buf, 1, - STV06XX_URB_MSG_TIMEOUT); - - *i2c_data = buf[0]; - - PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d", - *i2c_data, address, err); - - return (err < 0) ? err : 0; -} - -/* Wraps the normal write sensor bytes / words functions for writing a - single value */ -int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value) -{ - if (sd->sensor->i2c_len == 2) { - u16 data[2] = { address, value }; - return stv06xx_write_sensor_words(sd, data, 1); - } else { - u8 data[2] = { address, value }; - return stv06xx_write_sensor_bytes(sd, data, 1); - } -} - -static int stv06xx_write_sensor_finish(struct sd *sd) -{ - int err = 0; - - if (sd->bridge == BRIDGE_STV610) { - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - buf[0] = 0; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x1704, 0, buf, 1, - STV06XX_URB_MSG_TIMEOUT); - } - - return (err < 0) ? err : 0; -} - -int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len) -{ - int err, i, j; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); - for (i = 0; i < len;) { - /* Build the command buffer */ - memset(buf, 0, I2C_BUFFER_LENGTH); - for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) { - buf[j] = data[2*i]; - buf[0x10 + j] = data[2*i+1]; - PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x", - data[2*i+1], data[2*i]); - } - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = j - 1; /* Number of commands to send - 1 */ - buf[0x22] = I2C_WRITE_CMD; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x0400, 0, buf, - I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) - return err; - } - return stv06xx_write_sensor_finish(sd); -} - -int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) -{ - int err, i, j; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); - - for (i = 0; i < len;) { - /* Build the command buffer */ - memset(buf, 0, I2C_BUFFER_LENGTH); - for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) { - buf[j] = data[2*i]; - buf[0x10 + j * 2] = data[2*i+1]; - buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8; - PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x", - data[2*i+1], data[2*i]); - } - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = j - 1; /* Number of commands to send - 1 */ - buf[0x22] = I2C_WRITE_CMD; - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x0400, 0, buf, - I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) - return err; - } - return stv06xx_write_sensor_finish(sd); -} - -int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush); - if (err < 0) - return err; - - /* Clear mem */ - memset(buf, 0, I2C_BUFFER_LENGTH); - - buf[0] = address; - buf[0x20] = sd->sensor->i2c_addr; - buf[0x21] = 0; - - /* Read I2C register */ - buf[0x22] = I2C_READ_CMD; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, - STV06XX_URB_MSG_TIMEOUT); - if (err < 0) { - pr_err("I2C: Read error writing address: %d\n", err); - return err; - } - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len, - STV06XX_URB_MSG_TIMEOUT); - if (sd->sensor->i2c_len == 2) - *value = buf[0] | (buf[1] << 8); - else - *value = buf[0]; - - PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d", - *value, address, err); - - return (err < 0) ? err : 0; -} - -/* Dumps all bridge registers */ -static void stv06xx_dump_bridge(struct sd *sd) -{ - int i; - u8 data, buf; - - pr_info("Dumping all stv06xx bridge registers\n"); - for (i = 0x1400; i < 0x160f; i++) { - stv06xx_read_bridge(sd, i, &data); - - pr_info("Read 0x%x from address 0x%x\n", data, i); - } - - pr_info("Testing stv06xx bridge registers for writability\n"); - for (i = 0x1400; i < 0x160f; i++) { - stv06xx_read_bridge(sd, i, &data); - buf = data; - - stv06xx_write_bridge(sd, i, 0xff); - stv06xx_read_bridge(sd, i, &data); - if (data == 0xff) - pr_info("Register 0x%x is read/write\n", i); - else if (data != buf) - pr_info("Register 0x%x is read/write, but only partially\n", - i); - else - pr_info("Register 0x%x is read-only\n", i); - - stv06xx_write_bridge(sd, i, buf); - } -} - -/* this function is called at probe and resume time */ -static int stv06xx_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - PDEBUG(D_PROBE, "Initializing camera"); - - /* Let the usb init settle for a bit - before performing the initialization */ - msleep(250); - - err = sd->sensor->init(sd); - - if (dump_sensor && sd->sensor->dump) - sd->sensor->dump(sd); - - return (err < 0) ? err : 0; -} - -/* this function is called at probe time */ -static int stv06xx_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PROBE, "Initializing controls"); - - gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler; - return sd->sensor->init_controls(sd); -} - -/* Start the camera */ -static int stv06xx_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_host_interface *alt; - struct usb_interface *intf; - int err, packet_size; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); - if (err < 0) - return err; - - /* Prepare the sensor for start */ - err = sd->sensor->start(sd); - if (err < 0) - goto out; - - /* Start isochronous streaming */ - err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1); - -out: - if (err < 0) - PDEBUG(D_STREAM, "Starting stream failed"); - else - PDEBUG(D_STREAM, "Started streaming"); - - return (err < 0) ? err : 0; -} - -static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) -{ - struct usb_host_interface *alt; - struct sd *sd = (struct sd *) gspca_dev; - - /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - alt->endpoint[0].desc.wMaxPacketSize = - cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); - - return 0; -} - -static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) -{ - int ret, packet_size, min_packet_size; - struct usb_host_interface *alt; - struct sd *sd = (struct sd *) gspca_dev; - - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; - if (packet_size <= min_packet_size) - return -EIO; - - packet_size -= 100; - if (packet_size < min_packet_size) - packet_size = min_packet_size; - alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); - - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - if (ret < 0) - PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); - - return ret; -} - -static void stv06xx_stopN(struct gspca_dev *gspca_dev) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - - /* stop ISO-streaming */ - err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0); - if (err < 0) - goto out; - - err = sd->sensor->stop(sd); - -out: - if (err < 0) - PDEBUG(D_STREAM, "Failed to stop stream"); - else - PDEBUG(D_STREAM, "Stopped streaming"); -} - -/* - * Analyse an USB packet of the data stream and store it appropriately. - * Each packet contains an integral number of chunks. Each chunk has - * 2-bytes identification, followed by 2-bytes that describe the chunk - * length. Known/guessed chunk identifications are: - * 8001/8005/C001/C005 - Begin new frame - * 8002/8006/C002/C006 - End frame - * 0200/4200 - Contains actual image data, bayer or compressed - * 0005 - 11 bytes of unknown data - * 0100 - 2 bytes of unknown data - * The 0005 and 0100 chunks seem to appear only in compressed stream. - */ -static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PACK, "Packet of length %d arrived", len); - - /* A packet may contain several frames - loop until the whole packet is reached */ - while (len) { - int id, chunk_len; - - if (len < 4) { - PDEBUG(D_PACK, "Packet is smaller than 4 bytes"); - return; - } - - /* Capture the id */ - id = (data[0] << 8) | data[1]; - - /* Capture the chunk length */ - chunk_len = (data[2] << 8) | data[3]; - PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len); - - data += 4; - len -= 4; - - if (len < chunk_len) { - PDEBUG(D_ERR, "URB packet length is smaller" - " than the specified chunk length"); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - - /* First byte seem to be 02=data 2nd byte is unknown??? */ - if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200) - goto frame_data; - - switch (id) { - case 0x0200: - case 0x4200: -frame_data: - PDEBUG(D_PACK, "Frame data packet detected"); - - if (sd->to_skip) { - int skip = (sd->to_skip < chunk_len) ? - sd->to_skip : chunk_len; - data += skip; - len -= skip; - chunk_len -= skip; - sd->to_skip -= skip; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, - data, chunk_len); - break; - - case 0x8001: - case 0x8005: - case 0xc001: - case 0xc005: - PDEBUG(D_PACK, "Starting new frame"); - - /* Create a new frame, chunk length should be zero */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - NULL, 0); - - if (sd->bridge == BRIDGE_ST6422) - sd->to_skip = gspca_dev->width * 4; - - if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " - "non-zero on a SOF"); - break; - - case 0x8002: - case 0x8006: - case 0xc002: - PDEBUG(D_PACK, "End of frame detected"); - - /* Complete the last frame (if any) */ - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - - if (chunk_len) - PDEBUG(D_ERR, "Chunk length is " - "non-zero on a EOF"); - break; - - case 0x0005: - PDEBUG(D_PACK, "Chunk 0x005 detected"); - /* Unknown chunk with 11 bytes of data, - occurs just before end of each frame - in compressed mode */ - break; - - case 0x0100: - PDEBUG(D_PACK, "Chunk 0x0100 detected"); - /* Unknown chunk with 2 bytes of data, - occurs 2-3 times per USB interrupt */ - break; - case 0x42ff: - PDEBUG(D_PACK, "Chunk 0x42ff detected"); - /* Special chunk seen sometimes on the ST6422 */ - break; - default: - PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id); - /* Unknown chunk */ - } - data += chunk_len; - len -= chunk_len; - } -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrupt packet length */ -{ - int ret = -EINVAL; - - if (len == 1 && data[0] == 0x80) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - if (len == 1 && data[0] == 0x88) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - ret = 0; - } - - return ret; -} -#endif - -static int stv06xx_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = stv06xx_config, - .init = stv06xx_init, - .init_controls = stv06xx_init_controls, - .start = stv06xx_start, - .stopN = stv06xx_stopN, - .pkt_scan = stv06xx_pkt_scan, - .isoc_init = stv06xx_isoc_init, - .isoc_nego = stv06xx_isoc_nego, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -/* This function is called at probe time */ -static int stv06xx_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_PROBE, "Configuring camera"); - - sd->bridge = id->driver_info; - gspca_dev->sd_desc = &sd_desc; - - if (dump_bridge) - stv06xx_dump_bridge(sd); - - sd->sensor = &stv06xx_sensor_st6422; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_vv6410; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_hdcs1x00; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_hdcs1020; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = &stv06xx_sensor_pb0100; - if (!sd->sensor->probe(sd)) - return 0; - - sd->sensor = NULL; - return -ENODEV; -} - - - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - /* QuickCam Express */ - {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, - /* LEGO cam / QuickCam Web */ - {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, - /* Dexxa WebCam USB */ - {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, - /* QuickCam Messenger */ - {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Communicate */ - {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - PDEBUG(D_PROBE, "Probing for a stv06xx device"); - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static void sd_disconnect(struct usb_interface *intf) -{ - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - struct sd *sd = (struct sd *) gspca_dev; - void *priv = sd->sensor_priv; - PDEBUG(D_PROBE, "Disconnecting the stv06xx device"); - - sd->sensor = NULL; - gspca_disconnect(intf); - kfree(priv); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = sd_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); - -module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup"); diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h deleted file mode 100644 index 34957a4ec150..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_H_ -#define STV06XX_H_ - -#include <linux/slab.h> -#include "gspca.h" - -#define MODULE_NAME "STV06xx" - -#define STV_ISOC_ENDPOINT_ADDR 0x81 - -#define STV_R 0x0509 - -#define STV_REG23 0x0423 - -/* Control registers of the STV0600 ASIC */ -#define STV_I2C_PARTNER 0x1420 -#define STV_I2C_VAL_REG_VAL_PAIRS_MIN1 0x1421 -#define STV_I2C_READ_WRITE_TOGGLE 0x1422 -#define STV_I2C_FLUSH 0x1423 -#define STV_I2C_SUCC_READ_REG_VALS 0x1424 - -#define STV_ISO_ENABLE 0x1440 -#define STV_SCAN_RATE 0x1443 -#define STV_LED_CTRL 0x1445 -#define STV_STV0600_EMULATION 0x1446 -#define STV_REG00 0x1500 -#define STV_REG01 0x1501 -#define STV_REG02 0x1502 -#define STV_REG03 0x1503 -#define STV_REG04 0x1504 - -#define STV_ISO_SIZE_L 0x15c1 -#define STV_ISO_SIZE_H 0x15c2 - -/* Refers to the CIF 352x288 and QCIF 176x144 */ -/* 1: 288 lines, 2: 144 lines */ -#define STV_Y_CTRL 0x15c3 - -#define STV_RESET 0x1620 - -/* 0xa: 352 columns, 0x6: 176 columns */ -#define STV_X_CTRL 0x1680 - -#define STV06XX_URB_MSG_TIMEOUT 5000 - -#define I2C_MAX_BYTES 16 -#define I2C_MAX_WORDS 8 - -#define I2C_BUFFER_LENGTH 0x23 -#define I2C_READ_CMD 3 -#define I2C_WRITE_CMD 1 - -#define LED_ON 1 -#define LED_OFF 0 - -/* STV06xx device descriptor */ -struct sd { - struct gspca_dev gspca_dev; - - /* A pointer to the currently connected sensor */ - const struct stv06xx_sensor *sensor; - - /* Sensor private data */ - void *sensor_priv; - - /* The first 4 lines produced by the stv6422 are no good, this keeps - track of how many bytes we still need to skip during a frame */ - int to_skip; - - /* Bridge / Camera type */ - u8 bridge; - #define BRIDGE_STV600 0 - #define BRIDGE_STV602 1 - #define BRIDGE_STV610 2 - #define BRIDGE_ST6422 3 /* With integrated sensor */ -}; - -int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data); -int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data); - -int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len); -int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len); - -int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value); -int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value); - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c deleted file mode 100644 index 06fa54c5efb2..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2008 Chia-I Wu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_hdcs.h" - -static struct v4l2_pix_format hdcs1x00_mode[] = { - { - HDCS_1X00_DEF_WIDTH, - HDCS_1X00_DEF_HEIGHT, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, - .bytesperline = HDCS_1X00_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - -static struct v4l2_pix_format hdcs1020_mode[] = { - { - HDCS_1020_DEF_WIDTH, - HDCS_1020_DEF_HEIGHT, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, - .bytesperline = HDCS_1020_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - -enum hdcs_power_state { - HDCS_STATE_SLEEP, - HDCS_STATE_IDLE, - HDCS_STATE_RUN -}; - -/* no lock? */ -struct hdcs { - enum hdcs_power_state state; - int w, h; - - /* visible area of the sensor array */ - struct { - int left, top; - int width, height; - int border; - } array; - - struct { - /* Column timing overhead */ - u8 cto; - /* Column processing overhead */ - u8 cpo; - /* Row sample period constant */ - u16 rs; - /* Exposure reset duration */ - u16 er; - } exp; - - int psmp; -}; - -static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) -{ - u8 regs[I2C_MAX_BYTES * 2]; - int i; - - if (unlikely((len <= 0) || (len >= I2C_MAX_BYTES) || - (reg + len > 0xff))) - return -EINVAL; - - for (i = 0; i < len; i++) { - regs[2 * i] = reg; - regs[2 * i + 1] = vals[i]; - /* All addresses are shifted left one bit - * as bit 0 toggles r/w */ - reg += 2; - } - - return stv06xx_write_sensor_bytes(sd, regs, len); -} - -static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) -{ - struct hdcs *hdcs = sd->sensor_priv; - u8 val; - int ret; - - if (hdcs->state == state) - return 0; - - /* we need to go idle before running or sleeping */ - if (hdcs->state != HDCS_STATE_IDLE) { - ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); - if (ret) - return ret; - } - - hdcs->state = HDCS_STATE_IDLE; - - if (state == HDCS_STATE_IDLE) - return 0; - - switch (state) { - case HDCS_STATE_SLEEP: - val = HDCS_SLEEP_MODE; - break; - - case HDCS_STATE_RUN: - val = HDCS_RUN_ENABLE; - break; - - default: - return -EINVAL; - } - - ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); - - /* Update the state if the write succeeded */ - if (!ret) - hdcs->state = state; - - return ret; -} - -static int hdcs_reset(struct sd *sd) -{ - struct hdcs *hdcs = sd->sensor_priv; - int err; - - err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 1); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), 0); - if (err < 0) - hdcs->state = HDCS_STATE_IDLE; - - return err; -} - -static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct hdcs *hdcs = sd->sensor_priv; - int rowexp, srowexp; - int max_srowexp; - /* Column time period */ - int ct; - /* Column processing period */ - int cp; - /* Row processing period */ - int rp; - /* Minimum number of column timing periods - within the column processing period */ - int mnct; - int cycles, err; - u8 exp[14]; - - cycles = val * HDCS_CLK_FREQ_MHZ * 257; - - ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); - cp = hdcs->exp.cto + (hdcs->w * ct / 2); - - /* the cycles one row takes */ - rp = hdcs->exp.rs + cp; - - rowexp = cycles / rp; - - /* the remaining cycles */ - cycles -= rowexp * rp; - - /* calculate sub-row exposure */ - if (IS_1020(sd)) { - /* see HDCS-1020 datasheet 3.5.6.4, p. 63 */ - srowexp = hdcs->w - (cycles + hdcs->exp.er + 13) / ct; - - mnct = (hdcs->exp.er + 12 + ct - 1) / ct; - max_srowexp = hdcs->w - mnct; - } else { - /* see HDCS-1000 datasheet 3.4.5.5, p. 61 */ - srowexp = cp - hdcs->exp.er - 6 - cycles; - - mnct = (hdcs->exp.er + 5 + ct - 1) / ct; - max_srowexp = cp - mnct * ct - 1; - } - - if (srowexp < 0) - srowexp = 0; - else if (srowexp > max_srowexp) - srowexp = max_srowexp; - - if (IS_1020(sd)) { - exp[0] = HDCS20_CONTROL; - exp[1] = 0x00; /* Stop streaming */ - exp[2] = HDCS_ROWEXPL; - exp[3] = rowexp & 0xff; - exp[4] = HDCS_ROWEXPH; - exp[5] = rowexp >> 8; - exp[6] = HDCS20_SROWEXP; - exp[7] = (srowexp >> 2) & 0xff; - exp[8] = HDCS20_ERROR; - exp[9] = 0x10; /* Clear exposure error flag*/ - exp[10] = HDCS20_CONTROL; - exp[11] = 0x04; /* Restart streaming */ - err = stv06xx_write_sensor_bytes(sd, exp, 6); - } else { - exp[0] = HDCS00_CONTROL; - exp[1] = 0x00; /* Stop streaming */ - exp[2] = HDCS_ROWEXPL; - exp[3] = rowexp & 0xff; - exp[4] = HDCS_ROWEXPH; - exp[5] = rowexp >> 8; - exp[6] = HDCS00_SROWEXPL; - exp[7] = srowexp & 0xff; - exp[8] = HDCS00_SROWEXPH; - exp[9] = srowexp >> 8; - exp[10] = HDCS_STATUS; - exp[11] = 0x10; /* Clear exposure error flag*/ - exp[12] = HDCS00_CONTROL; - exp[13] = 0x04; /* Restart streaming */ - err = stv06xx_write_sensor_bytes(sd, exp, 7); - if (err < 0) - return err; - } - PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", - val, rowexp, srowexp); - return err; -} - -static int hdcs_set_gains(struct sd *sd, u8 g) -{ - int err; - u8 gains[4]; - - /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ - if (g > 127) - g = 0x80 | (g / 2); - - gains[0] = g; - gains[1] = g; - gains[2] = g; - gains[3] = g; - - err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); - return err; -} - -static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - PDEBUG(D_V4L2, "Writing gain %d", val); - return hdcs_set_gains((struct sd *) gspca_dev, - val & 0xff); -} - -static int hdcs_set_size(struct sd *sd, - unsigned int width, unsigned int height) -{ - struct hdcs *hdcs = sd->sensor_priv; - u8 win[4]; - unsigned int x, y; - int err; - - /* must be multiple of 4 */ - width = (width + 3) & ~0x3; - height = (height + 3) & ~0x3; - - if (width > hdcs->array.width) - width = hdcs->array.width; - - if (IS_1020(sd)) { - /* the borders are also invalid */ - if (height + 2 * hdcs->array.border + HDCS_1020_BOTTOM_Y_SKIP - > hdcs->array.height) - height = hdcs->array.height - 2 * hdcs->array.border - - HDCS_1020_BOTTOM_Y_SKIP; - - y = (hdcs->array.height - HDCS_1020_BOTTOM_Y_SKIP - height) / 2 - + hdcs->array.top; - } else { - if (height > hdcs->array.height) - height = hdcs->array.height; - - y = hdcs->array.top + (hdcs->array.height - height) / 2; - } - - x = hdcs->array.left + (hdcs->array.width - width) / 2; - - win[0] = y / 4; - win[1] = x / 4; - win[2] = (y + height) / 4 - 1; - win[3] = (x + width) / 4 - 1; - - err = hdcs_reg_write_seq(sd, HDCS_FWROW, win, 4); - if (err < 0) - return err; - - /* Update the current width and height */ - hdcs->w = width; - hdcs->h = height; - return err; -} - -static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - err = hdcs_set_gain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = hdcs_set_exposure(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops hdcs_ctrl_ops = { - .s_ctrl = hdcs_s_ctrl, -}; - -static int hdcs_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 2); - v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE); - v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops, - V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN); - return hdl->error; -} - -static int hdcs_probe_1x00(struct sd *sd) -{ - struct hdcs *hdcs; - u16 sensor; - int ret; - - ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); - if (ret < 0 || sensor != 0x08) - return -ENODEV; - - pr_info("HDCS-1000/1100 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); - - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); - if (!hdcs) - return -ENOMEM; - - hdcs->array.left = 8; - hdcs->array.top = 8; - hdcs->array.width = HDCS_1X00_DEF_WIDTH; - hdcs->array.height = HDCS_1X00_DEF_HEIGHT; - hdcs->array.border = 4; - - hdcs->exp.cto = 4; - hdcs->exp.cpo = 2; - hdcs->exp.rs = 186; - hdcs->exp.er = 100; - - /* - * Frame rate on HDCS-1000 with STV600 depends on PSMP: - * 4 = doesn't work at all - * 5 = 7.8 fps, - * 6 = 6.9 fps, - * 8 = 6.3 fps, - * 10 = 5.5 fps, - * 15 = 4.4 fps, - * 31 = 2.8 fps - * - * Frame rate on HDCS-1000 with STV602 depends on PSMP: - * 15 = doesn't work at all - * 18 = doesn't work at all - * 19 = 7.3 fps - * 20 = 7.4 fps - * 21 = 7.4 fps - * 22 = 7.4 fps - * 24 = 6.3 fps - * 30 = 5.4 fps - */ - hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5; - - sd->sensor_priv = hdcs; - - return 0; -} - -static int hdcs_probe_1020(struct sd *sd) -{ - struct hdcs *hdcs; - u16 sensor; - int ret; - - ret = stv06xx_read_sensor(sd, HDCS_IDENT, &sensor); - if (ret < 0 || sensor != 0x10) - return -ENODEV; - - pr_info("HDCS-1020 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = hdcs1020_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); - - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); - if (!hdcs) - return -ENOMEM; - - /* - * From Andrey's test image: looks like HDCS-1020 upper-left - * visible pixel is at 24,8 (y maybe even smaller?) and lower-right - * visible pixel at 375,299 (x maybe even larger?) - */ - hdcs->array.left = 24; - hdcs->array.top = 4; - hdcs->array.width = HDCS_1020_DEF_WIDTH; - hdcs->array.height = 304; - hdcs->array.border = 4; - - hdcs->psmp = 6; - - hdcs->exp.cto = 3; - hdcs->exp.cpo = 3; - hdcs->exp.rs = 155; - hdcs->exp.er = 96; - - sd->sensor_priv = hdcs; - - return 0; -} - -static int hdcs_start(struct sd *sd) -{ - PDEBUG(D_STREAM, "Starting stream"); - - return hdcs_set_state(sd, HDCS_STATE_RUN); -} - -static int hdcs_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "Halting stream"); - - return hdcs_set_state(sd, HDCS_STATE_SLEEP); -} - -static int hdcs_init(struct sd *sd) -{ - struct hdcs *hdcs = sd->sensor_priv; - int i, err = 0; - - /* Set the STV0602AA in STV0600 emulation mode */ - if (sd->bridge == BRIDGE_STV602) - stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1); - - /* Execute the bridge init */ - for (i = 0; i < ARRAY_SIZE(stv_bridge_init) && !err; i++) { - err = stv06xx_write_bridge(sd, stv_bridge_init[i][0], - stv_bridge_init[i][1]); - } - if (err < 0) - return err; - - /* sensor soft reset */ - hdcs_reset(sd); - - /* Execute the sensor init */ - for (i = 0; i < ARRAY_SIZE(stv_sensor_init) && !err; i++) { - err = stv06xx_write_sensor(sd, stv_sensor_init[i][0], - stv_sensor_init[i][1]); - } - if (err < 0) - return err; - - /* Enable continuous frame capture, bit 2: stop when frame complete */ - err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3)); - if (err < 0) - return err; - - /* Set PGA sample duration - (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */ - if (IS_1020(sd)) - err = stv06xx_write_sensor(sd, HDCS_TCTRL, - (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp); - else - err = stv06xx_write_sensor(sd, HDCS_TCTRL, - (HDCS_ADC_START_SIG_DUR << 5) | hdcs->psmp); - if (err < 0) - return err; - - return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); -} - -static int hdcs_dump(struct sd *sd) -{ - u16 reg, val; - - pr_info("Dumping sensor registers:\n"); - - for (reg = HDCS_IDENT; reg <= HDCS_ROWEXPH; reg++) { - stv06xx_read_sensor(sd, reg, &val); - pr_info("reg 0x%02x = 0x%02x\n", reg, val); - } - return 0; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h deleted file mode 100644 index 1ba9158d0102..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * Copyright (c) 2008 Chia-I Wu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_HDCS_H_ -#define STV06XX_HDCS_H_ - -#include "stv06xx_sensor.h" - -#define HDCS_REG_CONFIG(sd) (IS_1020(sd) ? HDCS20_CONFIG : HDCS00_CONFIG) -#define HDCS_REG_CONTROL(sd) (IS_1020(sd) ? HDCS20_CONTROL : HDCS00_CONTROL) - -#define HDCS_1X00_DEF_WIDTH 360 -#define HDCS_1X00_DEF_HEIGHT 296 - -#define HDCS_1020_DEF_WIDTH 352 -#define HDCS_1020_DEF_HEIGHT 292 - -#define HDCS_1020_BOTTOM_Y_SKIP 4 - -#define HDCS_CLK_FREQ_MHZ 25 - -#define HDCS_ADC_START_SIG_DUR 3 - -/* LSB bit of I2C or register address signifies write (0) or read (1) */ -/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */ -/* Identifications Register */ -#define HDCS_IDENT (0x00 << 1) -/* Status Register */ -#define HDCS_STATUS (0x01 << 1) -/* Interrupt Mask Register */ -#define HDCS_IMASK (0x02 << 1) -/* Pad Control Register */ -#define HDCS_PCTRL (0x03 << 1) -/* Pad Drive Control Register */ -#define HDCS_PDRV (0x04 << 1) -/* Interface Control Register */ -#define HDCS_ICTRL (0x05 << 1) -/* Interface Timing Register */ -#define HDCS_ITMG (0x06 << 1) -/* Baud Fraction Register */ -#define HDCS_BFRAC (0x07 << 1) -/* Baud Rate Register */ -#define HDCS_BRATE (0x08 << 1) -/* ADC Control Register */ -#define HDCS_ADCCTRL (0x09 << 1) -/* First Window Row Register */ -#define HDCS_FWROW (0x0a << 1) -/* First Window Column Register */ -#define HDCS_FWCOL (0x0b << 1) -/* Last Window Row Register */ -#define HDCS_LWROW (0x0c << 1) -/* Last Window Column Register */ -#define HDCS_LWCOL (0x0d << 1) -/* Timing Control Register */ -#define HDCS_TCTRL (0x0e << 1) -/* PGA Gain Register: Even Row, Even Column */ -#define HDCS_ERECPGA (0x0f << 1) -/* PGA Gain Register: Even Row, Odd Column */ -#define HDCS_EROCPGA (0x10 << 1) -/* PGA Gain Register: Odd Row, Even Column */ -#define HDCS_ORECPGA (0x11 << 1) -/* PGA Gain Register: Odd Row, Odd Column */ -#define HDCS_OROCPGA (0x12 << 1) -/* Row Exposure Low Register */ -#define HDCS_ROWEXPL (0x13 << 1) -/* Row Exposure High Register */ -#define HDCS_ROWEXPH (0x14 << 1) - -/* I2C Registers only for HDCS-1000/1100 */ -/* Sub-Row Exposure Low Register */ -#define HDCS00_SROWEXPL (0x15 << 1) -/* Sub-Row Exposure High Register */ -#define HDCS00_SROWEXPH (0x16 << 1) -/* Configuration Register */ -#define HDCS00_CONFIG (0x17 << 1) -/* Control Register */ -#define HDCS00_CONTROL (0x18 << 1) - -/* I2C Registers only for HDCS-1020 */ -/* Sub-Row Exposure Register */ -#define HDCS20_SROWEXP (0x15 << 1) -/* Error Control Register */ -#define HDCS20_ERROR (0x16 << 1) -/* Interface Timing 2 Register */ -#define HDCS20_ITMG2 (0x17 << 1) -/* Interface Control 2 Register */ -#define HDCS20_ICTRL2 (0x18 << 1) -/* Horizontal Blank Register */ -#define HDCS20_HBLANK (0x19 << 1) -/* Vertical Blank Register */ -#define HDCS20_VBLANK (0x1a << 1) -/* Configuration Register */ -#define HDCS20_CONFIG (0x1b << 1) -/* Control Register */ -#define HDCS20_CONTROL (0x1c << 1) - -#define HDCS_RUN_ENABLE (1 << 2) -#define HDCS_SLEEP_MODE (1 << 1) - -#define HDCS_DEFAULT_EXPOSURE 48 -#define HDCS_DEFAULT_GAIN 50 - -static int hdcs_probe_1x00(struct sd *sd); -static int hdcs_probe_1020(struct sd *sd); -static int hdcs_start(struct sd *sd); -static int hdcs_init(struct sd *sd); -static int hdcs_init_controls(struct sd *sd); -static int hdcs_stop(struct sd *sd); -static int hdcs_dump(struct sd *sd); - -static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { - .name = "HP HDCS-1000/1100", - .i2c_flush = 0, - .i2c_addr = (0x55 << 1), - .i2c_len = 1, - - /* FIXME (see if we can lower min_packet_size, needs testing, and also - adjusting framerate when the bandwidth gets lower) */ - .min_packet_size = { 847 }, - .max_packet_size = { 847 }, - - .init = hdcs_init, - .init_controls = hdcs_init_controls, - .probe = hdcs_probe_1x00, - .start = hdcs_start, - .stop = hdcs_stop, - .dump = hdcs_dump, -}; - -const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { - .name = "HDCS-1020", - .i2c_flush = 0, - .i2c_addr = (0x55 << 1), - .i2c_len = 1, - - /* FIXME (see if we can lower min_packet_size, needs testing, and also - adjusting framerate when the bandwidthm gets lower) */ - .min_packet_size = { 847 }, - .max_packet_size = { 847 }, - - .init = hdcs_init, - .init_controls = hdcs_init_controls, - .probe = hdcs_probe_1020, - .start = hdcs_start, - .stop = hdcs_stop, - .dump = hdcs_dump, -}; - -static const u16 stv_bridge_init[][2] = { - {STV_ISO_ENABLE, 0}, - {STV_REG23, 0}, - {STV_REG00, 0x1d}, - {STV_REG01, 0xb5}, - {STV_REG02, 0xa8}, - {STV_REG03, 0x95}, - {STV_REG04, 0x07}, - - {STV_SCAN_RATE, 0x20}, - {STV_Y_CTRL, 0x01}, - {STV_X_CTRL, 0x0a} -}; - -static const u8 stv_sensor_init[][2] = { - /* Clear status (writing 1 will clear the corresponding status bit) */ - {HDCS_STATUS, BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1)}, - /* Disable all interrupts */ - {HDCS_IMASK, 0x00}, - {HDCS_PCTRL, BIT(6) | BIT(5) | BIT(1) | BIT(0)}, - {HDCS_PDRV, 0x00}, - {HDCS_ICTRL, BIT(5)}, - {HDCS_ITMG, BIT(4) | BIT(1)}, - /* ADC output resolution to 10 bits */ - {HDCS_ADCCTRL, 10} -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c deleted file mode 100644 index cdfc3d05ab6b..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -/* - * The spec file for the PB-0100 suggests the following for best quality - * images after the sensor has been reset : - * - * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC - to produce good black level - * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes - through R53 - * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for - auto-exposure - * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain - * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value - * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on - auto-exposure routine - * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_pb0100.h" - -struct pb0100_ctrls { - struct { /* one big happy control cluster... */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *gain; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *red; - struct v4l2_ctrl *blue; - struct v4l2_ctrl *natural; - }; - struct v4l2_ctrl *target; -}; - -static struct v4l2_pix_format pb0100_mode[] = { -/* low res / subsample modes disabled as they are only half res horizontal, - halving the vertical resolution does not seem to work */ - { - 320, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 320 * 240, - .bytesperline = 320, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_CROP_TO_VGA - }, - { - 352, - 288, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 352 * 288, - .bytesperline = 352, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static int pb0100_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - err = pb0100_set_autogain(gspca_dev, ctrl->val); - if (err) - break; - if (ctrl->val) - break; - err = pb0100_set_gain(gspca_dev, ctrls->gain->val); - if (err) - break; - err = pb0100_set_exposure(gspca_dev, ctrls->exposure->val); - break; - case V4L2_CTRL_CLASS_USER + 0x1001: - err = pb0100_set_autogain_target(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops pb0100_ctrl_ops = { - .s_ctrl = pb0100_s_ctrl, -}; - -static int pb0100_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - struct pb0100_ctrls *ctrls; - static const struct v4l2_ctrl_config autogain_target = { - .ops = &pb0100_ctrl_ops, - .id = V4L2_CTRL_CLASS_USER + 0x1000, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Automatic Gain Target", - .max = 255, - .step = 1, - .def = 128, - }; - static const struct v4l2_ctrl_config natural_light = { - .ops = &pb0100_ctrl_ops, - .id = V4L2_CTRL_CLASS_USER + 0x1001, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Natural Light Source", - .max = 1, - .step = 1, - .def = 1, - }; - - ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL); - if (!ctrls) - return -ENOMEM; - - v4l2_ctrl_handler_init(hdl, 6); - ctrls->autogain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - ctrls->exposure = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 511, 1, 12); - ctrls->gain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 128); - ctrls->red = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_RED_BALANCE, -255, 255, 1, 0); - ctrls->blue = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops, - V4L2_CID_BLUE_BALANCE, -255, 255, 1, 0); - ctrls->natural = v4l2_ctrl_new_custom(hdl, &natural_light, NULL); - ctrls->target = v4l2_ctrl_new_custom(hdl, &autogain_target, NULL); - if (hdl->error) { - kfree(ctrls); - return hdl->error; - } - sd->sensor_priv = ctrls; - v4l2_ctrl_auto_cluster(5, &ctrls->autogain, 0, false); - return 0; -} - -static int pb0100_probe(struct sd *sd) -{ - u16 sensor; - int err; - - err = stv06xx_read_sensor(sd, PB_IDENT, &sensor); - - if (err < 0) - return -ENODEV; - if ((sensor >> 8) != 0x64) - return -ENODEV; - - pr_info("Photobit pb0100 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = pb0100_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode); - - return 0; -} - -static int pb0100_start(struct sd *sd) -{ - int err, packet_size, max_packet_size; - struct usb_host_interface *alt; - struct usb_interface *intf; - struct cam *cam = &sd->gspca_dev.cam; - u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) - return -ENODEV; - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - - /* If we don't have enough bandwidth use a lower framerate */ - max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode]; - if (packet_size < max_packet_size) - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); - else - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1)); - - /* Setup sensor window */ - if (mode & PB0100_CROP_TO_VGA) { - stv06xx_write_sensor(sd, PB_RSTART, 30); - stv06xx_write_sensor(sd, PB_CSTART, 20); - stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1); - stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1); - } else { - stv06xx_write_sensor(sd, PB_RSTART, 8); - stv06xx_write_sensor(sd, PB_CSTART, 4); - stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1); - stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1); - } - - if (mode & PB0100_SUBSAMPLE) { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */ - stv06xx_write_bridge(sd, STV_X_CTRL, 0x06); - - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10); - } else { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a); - /* larger -> slower */ - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20); - } - - err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1)); - PDEBUG(D_STREAM, "Started stream, status: %d", err); - - return (err < 0) ? err : 0; -} - -static int pb0100_stop(struct sd *sd) -{ - int err; - - err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1); - - if (err < 0) - goto out; - - /* Set bit 1 to zero */ - err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)); - - PDEBUG(D_STREAM, "Halting stream"); -out: - return (err < 0) ? err : 0; -} - -/* FIXME: Sort the init commands out and put them into tables, - this is only for getting the camera to work */ -/* FIXME: No error handling for now, - add this once the init has been converted to proper tables */ -static int pb0100_init(struct sd *sd) -{ - stv06xx_write_bridge(sd, STV_REG00, 1); - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0); - - /* Reset sensor */ - stv06xx_write_sensor(sd, PB_RESET, 1); - stv06xx_write_sensor(sd, PB_RESET, 0); - - /* Disable chip */ - stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)); - - /* Gain stuff...*/ - stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6)); - stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12); - - /* Set up auto-exposure */ - /* ADC VREF_HI new setting for a transition - from the Expose1 to the Expose2 setting */ - stv06xx_write_sensor(sd, PB_R28, 12); - /* gain max for autoexposure */ - stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180); - /* gain min for autoexposure */ - stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12); - /* Maximum frame integration time (programmed into R8) - allowed for auto-exposure routine */ - stv06xx_write_sensor(sd, PB_R54, 3); - /* Minimum frame integration time (programmed into R8) - allowed for auto-exposure routine */ - stv06xx_write_sensor(sd, PB_R55, 0); - stv06xx_write_sensor(sd, PB_UPDATEINT, 1); - /* R15 Expose0 (maximum that auto-exposure may use) */ - stv06xx_write_sensor(sd, PB_R15, 800); - /* R17 Expose2 (minimum that auto-exposure may use) */ - stv06xx_write_sensor(sd, PB_R17, 10); - - stv06xx_write_sensor(sd, PB_EXPGAIN, 0); - - /* 0x14 */ - stv06xx_write_sensor(sd, PB_VOFFSET, 0); - /* 0x0D */ - stv06xx_write_sensor(sd, PB_ADCGAINH, 11); - /* Set black level (important!) */ - stv06xx_write_sensor(sd, PB_ADCGAINL, 0); - - /* ??? */ - stv06xx_write_bridge(sd, STV_REG00, 0x11); - stv06xx_write_bridge(sd, STV_REG03, 0x45); - stv06xx_write_bridge(sd, STV_REG04, 0x07); - - /* Scan/timing for the sensor */ - stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); - stv06xx_write_sensor(sd, PB_CFILLIN, 14); - stv06xx_write_sensor(sd, PB_VBL, 0); - stv06xx_write_sensor(sd, PB_FINTTIME, 0); - stv06xx_write_sensor(sd, PB_RINTTIME, 123); - - stv06xx_write_bridge(sd, STV_REG01, 0xc2); - stv06xx_write_bridge(sd, STV_REG02, 0xb0); - return 0; -} - -static int pb0100_dump(struct sd *sd) -{ - return 0; -} - -static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - err = stv06xx_write_sensor(sd, PB_G1GAIN, val); - if (!err) - err = stv06xx_write_sensor(sd, PB_G2GAIN, val); - PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err); - - if (!err) - err = pb0100_set_red_balance(gspca_dev, ctrls->red->val); - if (!err) - err = pb0100_set_blue_balance(gspca_dev, ctrls->blue->val); - - return err; -} - -static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - val += ctrls->gain->val; - if (val < 0) - val = 0; - else if (val > 255) - val = 255; - - err = stv06xx_write_sensor(sd, PB_RGAIN, val); - PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - val += ctrls->gain->val; - if (val < 0) - val = 0; - else if (val > 255) - val = 255; - - err = stv06xx_write_sensor(sd, PB_BGAIN, val); - PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - err = stv06xx_write_sensor(sd, PB_RINTTIME, val); - PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err); - - return err; -} - -static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - struct pb0100_ctrls *ctrls = sd->sensor_priv; - - if (val) { - if (ctrls->natural->val) - val = BIT(6)|BIT(4)|BIT(0); - else - val = BIT(4)|BIT(0); - } else - val = 0; - - err = stv06xx_write_sensor(sd, PB_EXPGAIN, val); - PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d", - val, ctrls->natural->val, err); - - return err; -} - -static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val) -{ - int err, totalpixels, brightpixels, darkpixels; - struct sd *sd = (struct sd *) gspca_dev; - - /* Number of pixels counted by the sensor when subsampling the pixels. - * Slightly larger than the real value to avoid oscillation */ - totalpixels = gspca_dev->width * gspca_dev->height; - totalpixels = totalpixels/(8*8) + totalpixels/(64*64); - - brightpixels = (totalpixels * val) >> 8; - darkpixels = totalpixels - brightpixels; - err = stv06xx_write_sensor(sd, PB_R21, brightpixels); - if (!err) - err = stv06xx_write_sensor(sd, PB_R22, darkpixels); - - PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err); - - return err; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h deleted file mode 100644 index 5071e5353fd3..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_PB0100_H_ -#define STV06XX_PB0100_H_ - -#include "stv06xx_sensor.h" - -/* mode priv field flags */ -#define PB0100_CROP_TO_VGA 0x01 -#define PB0100_SUBSAMPLE 0x02 - -/* I2C Registers */ -#define PB_IDENT 0x00 /* Chip Version */ -#define PB_RSTART 0x01 /* Row Window Start */ -#define PB_CSTART 0x02 /* Column Window Start */ -#define PB_RWSIZE 0x03 /* Row Window Size */ -#define PB_CWSIZE 0x04 /* Column Window Size */ -#define PB_CFILLIN 0x05 /* Column Fill-In */ -#define PB_VBL 0x06 /* Vertical Blank Count */ -#define PB_CONTROL 0x07 /* Control Mode */ -#define PB_FINTTIME 0x08 /* Integration Time/Frame Unit Count */ -#define PB_RINTTIME 0x09 /* Integration Time/Row Unit Count */ -#define PB_ROWSPEED 0x0a /* Row Speed Control */ -#define PB_ABORTFRAME 0x0b /* Abort Frame */ -#define PB_R12 0x0c /* Reserved */ -#define PB_RESET 0x0d /* Reset */ -#define PB_EXPGAIN 0x0e /* Exposure Gain Command */ -#define PB_R15 0x0f /* Expose0 */ -#define PB_R16 0x10 /* Expose1 */ -#define PB_R17 0x11 /* Expose2 */ -#define PB_R18 0x12 /* Low0_DAC */ -#define PB_R19 0x13 /* Low1_DAC */ -#define PB_R20 0x14 /* Low2_DAC */ -#define PB_R21 0x15 /* Threshold11 */ -#define PB_R22 0x16 /* Threshold0x */ -#define PB_UPDATEINT 0x17 /* Update Interval */ -#define PB_R24 0x18 /* High_DAC */ -#define PB_R25 0x19 /* Trans0H */ -#define PB_R26 0x1a /* Trans1L */ -#define PB_R27 0x1b /* Trans1H */ -#define PB_R28 0x1c /* Trans2L */ -#define PB_R29 0x1d /* Reserved */ -#define PB_R30 0x1e /* Reserved */ -#define PB_R31 0x1f /* Wait to Read */ -#define PB_PREADCTRL 0x20 /* Pixel Read Control Mode */ -#define PB_R33 0x21 /* IREF_VLN */ -#define PB_R34 0x22 /* IREF_VLP */ -#define PB_R35 0x23 /* IREF_VLN_INTEG */ -#define PB_R36 0x24 /* IREF_MASTER */ -#define PB_R37 0x25 /* IDACP */ -#define PB_R38 0x26 /* IDACN */ -#define PB_R39 0x27 /* DAC_Control_Reg */ -#define PB_R40 0x28 /* VCL */ -#define PB_R41 0x29 /* IREF_VLN_ADCIN */ -#define PB_R42 0x2a /* Reserved */ -#define PB_G1GAIN 0x2b /* Green 1 Gain */ -#define PB_BGAIN 0x2c /* Blue Gain */ -#define PB_RGAIN 0x2d /* Red Gain */ -#define PB_G2GAIN 0x2e /* Green 2 Gain */ -#define PB_R47 0x2f /* Dark Row Address */ -#define PB_R48 0x30 /* Dark Row Options */ -#define PB_R49 0x31 /* Reserved */ -#define PB_R50 0x32 /* Image Test Data */ -#define PB_ADCMAXGAIN 0x33 /* Maximum Gain */ -#define PB_ADCMINGAIN 0x34 /* Minimum Gain */ -#define PB_ADCGLOBALGAIN 0x35 /* Global Gain */ -#define PB_R54 0x36 /* Maximum Frame */ -#define PB_R55 0x37 /* Minimum Frame */ -#define PB_R56 0x38 /* Reserved */ -#define PB_VOFFSET 0x39 /* VOFFSET */ -#define PB_R58 0x3a /* Snap-Shot Sequence Trigger */ -#define PB_ADCGAINH 0x3b /* VREF_HI */ -#define PB_ADCGAINL 0x3c /* VREF_LO */ -#define PB_R61 0x3d /* Reserved */ -#define PB_R62 0x3e /* Reserved */ -#define PB_R63 0x3f /* Reserved */ -#define PB_R64 0x40 /* Red/Blue Gain */ -#define PB_R65 0x41 /* Green 2/Green 1 Gain */ -#define PB_R66 0x42 /* VREF_HI/LO */ -#define PB_R67 0x43 /* Integration Time/Row Unit Count */ -#define PB_R240 0xf0 /* ADC Test */ -#define PB_R241 0xf1 /* Chip Enable */ -#define PB_R242 0xf2 /* Reserved */ - -static int pb0100_probe(struct sd *sd); -static int pb0100_start(struct sd *sd); -static int pb0100_init(struct sd *sd); -static int pb0100_init_controls(struct sd *sd); -static int pb0100_stop(struct sd *sd); -static int pb0100_dump(struct sd *sd); - -/* V4L2 controls supported by the driver */ -static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val); -static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_pb0100 = { - .name = "PB-0100", - .i2c_flush = 1, - .i2c_addr = 0xba, - .i2c_len = 2, - - .min_packet_size = { 635, 847 }, - .max_packet_size = { 847, 923 }, - - .init = pb0100_init, - .init_controls = pb0100_init_controls, - .probe = pb0100_probe, - .start = pb0100_start, - .stop = pb0100_stop, - .dump = pb0100_dump, -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h deleted file mode 100644 index 3a498c2495c6..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_SENSOR_H_ -#define STV06XX_SENSOR_H_ - -#include "stv06xx.h" - -#define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020) - -extern const struct stv06xx_sensor stv06xx_sensor_vv6410; -extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; -extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; -extern const struct stv06xx_sensor stv06xx_sensor_pb0100; -extern const struct stv06xx_sensor stv06xx_sensor_st6422; - -struct stv06xx_sensor { - /* Defines the name of a sensor */ - char name[32]; - - /* Sensor i2c address */ - u8 i2c_addr; - - /* Flush value*/ - u8 i2c_flush; - - /* length of an i2c word */ - u8 i2c_len; - - /* Isoc packet size (per mode) */ - int min_packet_size[4]; - int max_packet_size[4]; - - /* Probes if the sensor is connected */ - int (*probe)(struct sd *sd); - - /* Performs a initialization sequence */ - int (*init)(struct sd *sd); - - /* Initializes the controls */ - int (*init_controls)(struct sd *sd); - - /* Reads a sensor register */ - int (*read_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - /* Writes to a sensor register */ - int (*write_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - /* Instructs the sensor to start streaming */ - int (*start)(struct sd *sd); - - /* Instructs the sensor to stop streaming */ - int (*stop)(struct sd *sd); - - /* Instructs the sensor to dump all its contents */ - int (*dump)(struct sd *sd); -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c deleted file mode 100644 index 8a57990dfe0f..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com> - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_st6422.h" - -static struct v4l2_pix_format st6422_mode[] = { - /* Note we actually get 124 lines of data, of which we skip the 4st - 4 as they are garbage */ - { - 162, - 120, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 162 * 120, - .bytesperline = 162, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - /* Note we actually get 248 lines of data, of which we skip the 4st - 4 as they are garbage, and we tell the app it only gets the - first 240 of the 244 lines it actually gets, so that it ignores - the last 4. */ - { - 324, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 324 * 244, - .bytesperline = 324, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, -}; - -/* V4L2 controls supported by the driver */ -static int setbrightness(struct sd *sd, s32 val); -static int setcontrast(struct sd *sd, s32 val); -static int setgain(struct sd *sd, u8 gain); -static int setexposure(struct sd *sd, s16 expo); - -static int st6422_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - err = setbrightness(sd, ctrl->val); - break; - case V4L2_CID_CONTRAST: - err = setcontrast(sd, ctrl->val); - break; - case V4L2_CID_GAIN: - err = setgain(sd, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = setexposure(sd, ctrl->val); - break; - } - - /* commit settings */ - if (err >= 0) - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - sd->gspca_dev.usb_err = err; - return err; -} - -static const struct v4l2_ctrl_ops st6422_ctrl_ops = { - .s_ctrl = st6422_s_ctrl, -}; - -static int st6422_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 31, 1, 3); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_CONTRAST, 0, 15, 1, 11); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 1023, 1, 256); - v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops, - V4L2_CID_GAIN, 0, 255, 1, 64); - - return hdl->error; -} - -static int st6422_probe(struct sd *sd) -{ - if (sd->bridge != BRIDGE_ST6422) - return -ENODEV; - - pr_info("st6422 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = st6422_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); - return 0; -} - -static int st6422_init(struct sd *sd) -{ - int err = 0, i; - - const u16 st6422_bridge_init[][2] = { - { STV_ISO_ENABLE, 0x00 }, /* disable capture */ - { 0x1436, 0x00 }, - { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ - { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */ - { 0x0509, 0x38 }, /* R */ - { 0x050a, 0x38 }, /* G */ - { 0x050b, 0x38 }, /* B */ - { 0x050c, 0x2a }, - { 0x050d, 0x01 }, - - - { 0x1431, 0x00 }, /* 0x00-0x07 ??? */ - { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */ - { 0x1438, 0x18 }, /* 640x480 */ -/* 18 bayes */ -/* 10 compressed? */ - - { 0x1439, 0x00 }, -/* anti-noise? 0xa2 gives a perfect image */ - - { 0x143b, 0x05 }, - { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ - - -/* shutter time 0x0000-0x03FF */ -/* low value give good picures on moving objects (but requires much light) */ -/* high value gives good picures in darkness (but tends to be overexposed) */ - { 0x143e, 0x01 }, - { 0x143d, 0x00 }, - - { 0x1442, 0xe2 }, -/* write: 1x1x xxxx */ -/* read: 1x1x xxxx */ -/* bit 5 == button pressed and hold if 0 */ -/* write 0xe2,0xea */ - -/* 0x144a */ -/* 0x00 init */ -/* bit 7 == button has been pressed, but not handled */ - -/* interrupt */ -/* if(urb->iso_frame_desc[i].status == 0x80) { */ -/* if(urb->iso_frame_desc[i].status == 0x88) { */ - - { 0x1500, 0xd0 }, - { 0x1500, 0xd0 }, - { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ - - { 0x1501, 0xaf }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1502, 0xc2 }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1503, 0x45 }, -/* high val-> light area gets darker */ -/* low val -> light area gets lighter */ - { 0x1505, 0x02 }, -/* 2 : 324x248 80352 bytes */ -/* 7 : 248x162 40176 bytes */ -/* c+f: 162*124 20088 bytes */ - - { 0x150e, 0x8e }, - { 0x150f, 0x37 }, - { 0x15c0, 0x00 }, - { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ - - - { 0x143f, 0x01 }, /* commit settings */ - - }; - - for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) { - err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0], - st6422_bridge_init[i][1]); - } - - return err; -} - -static int setbrightness(struct sd *sd, s32 val) -{ - /* val goes from 0 -> 31 */ - return stv06xx_write_bridge(sd, 0x1432, val); -} - -static int setcontrast(struct sd *sd, s32 val) -{ - /* Val goes from 0 -> 15 */ - return stv06xx_write_bridge(sd, 0x143a, val | 0xf0); -} - -static int setgain(struct sd *sd, u8 gain) -{ - int err; - - /* Set red, green, blue, gain */ - err = stv06xx_write_bridge(sd, 0x0509, gain); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050a, gain); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050b, gain); - if (err < 0) - return err; - - /* 2 mystery writes */ - err = stv06xx_write_bridge(sd, 0x050c, 0x2a); - if (err < 0) - return err; - - return stv06xx_write_bridge(sd, 0x050d, 0x01); -} - -static int setexposure(struct sd *sd, s16 expo) -{ - int err; - - err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff); - if (err < 0) - return err; - - return stv06xx_write_bridge(sd, 0x143e, expo >> 8); -} - -static int st6422_start(struct sd *sd) -{ - int err; - struct cam *cam = &sd->gspca_dev.cam; - - if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) - err = stv06xx_write_bridge(sd, 0x1505, 0x0f); - else - err = stv06xx_write_bridge(sd, 0x1505, 0x02); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} - -static int st6422_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "Halting stream"); - - return 0; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h deleted file mode 100644 index 8f20fbf30f33..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com> - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef STV06XX_ST6422_H_ -#define STV06XX_ST6422_H_ - -#include "stv06xx_sensor.h" - -static int st6422_probe(struct sd *sd); -static int st6422_start(struct sd *sd); -static int st6422_init(struct sd *sd); -static int st6422_init_controls(struct sd *sd); -static int st6422_stop(struct sd *sd); - -const struct stv06xx_sensor stv06xx_sensor_st6422 = { - .name = "ST6422", - /* No known way to lower framerate in case of less bandwidth */ - .min_packet_size = { 300, 847 }, - .max_packet_size = { 300, 847 }, - .init = st6422_init, - .init_controls = st6422_init_controls, - .probe = st6422_probe, - .start = st6422_start, - .stop = st6422_stop, -}; - -#endif diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c deleted file mode 100644 index 748e1421d6d8..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "stv06xx_vv6410.h" - -static struct v4l2_pix_format vv6410_mode[] = { - { - 356, - 292, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 356 * 292, - .bytesperline = 356, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static int vv6410_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - int err = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_HFLIP: - err = vv6410_set_hflip(gspca_dev, ctrl->val); - break; - case V4L2_CID_VFLIP: - err = vv6410_set_vflip(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - err = vv6410_set_analog_gain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - err = vv6410_set_exposure(gspca_dev, ctrl->val); - break; - } - return err; -} - -static const struct v4l2_ctrl_ops vv6410_ctrl_ops = { - .s_ctrl = vv6410_s_ctrl, -}; - -static int vv6410_probe(struct sd *sd) -{ - u16 data; - int err; - - err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); - if (err < 0) - return -ENODEV; - - if (data != 0x19) - return -ENODEV; - - pr_info("vv6410 sensor detected\n"); - - sd->gspca_dev.cam.cam_mode = vv6410_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); - return 0; -} - -static int vv6410_init_controls(struct sd *sd) -{ - struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; - - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 32768, 1, 20000); - v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops, - V4L2_CID_GAIN, 0, 15, 1, 10); - return hdl->error; -} - -static int vv6410_init(struct sd *sd) -{ - int err = 0, i; - - for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) - stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data); - - if (err < 0) - return err; - - err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, - ARRAY_SIZE(vv6410_sensor_init)); - return (err < 0) ? err : 0; -} - -static int vv6410_start(struct sd *sd) -{ - int err; - struct cam *cam = &sd->gspca_dev.cam; - u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv; - - if (priv & VV6410_SUBSAMPLE) { - PDEBUG(D_CONF, "Enabling subsampling"); - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x06); - - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10); - } else { - stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01); - stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a); - stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x00); - - } - - /* Turn on LED */ - err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0); - if (err < 0) - return err; - - PDEBUG(D_STREAM, "Starting stream"); - - return 0; -} - -static int vv6410_stop(struct sd *sd) -{ - int err; - - /* Turn off LED */ - err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF); - if (err < 0) - return err; - - err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE); - if (err < 0) - return err; - - PDEBUG(D_STREAM, "Halting stream"); - - return (err < 0) ? err : 0; -} - -static int vv6410_dump(struct sd *sd) -{ - u8 i; - int err = 0; - - pr_info("Dumping all vv6410 sensor registers\n"); - for (i = 0; i < 0xff && !err; i++) { - u16 data; - err = stv06xx_read_sensor(sd, i, &data); - pr_info("Register 0x%x contained 0x%x\n", i, data); - } - return (err < 0) ? err : 0; -} - -static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u16 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - if (err < 0) - return err; - - if (val) - i2c_data |= VV6410_HFLIP; - else - i2c_data &= ~VV6410_HFLIP; - - PDEBUG(D_V4L2, "Set horizontal flip to %d", val); - err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u16 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); - if (err < 0) - return err; - - if (val) - i2c_data |= VV6410_VFLIP; - else - i2c_data &= ~VV6410_VFLIP; - - PDEBUG(D_V4L2, "Set vertical flip to %d", val); - err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_V4L2, "Set analog gain to %d", val); - err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); - - return (err < 0) ? err : 0; -} - -static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - unsigned int fine, coarse; - - val = (val * val >> 14) + val / 4; - - fine = val % VV6410_CIF_LINELENGTH; - coarse = min(512, val / VV6410_CIF_LINELENGTH); - - PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", - coarse, fine); - - err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8); - if (err < 0) - goto out; - - err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff); - -out: - return err; -} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h deleted file mode 100644 index 53e67b40ca05..000000000000 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * Copyright (c) 2008 Erik Andrén - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * P/N 861037: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 - * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express - * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam - * P/N 861075-0040: Sensor HDCS1000 ASIC - * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB - * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web - */ - -#ifndef STV06XX_VV6410_H_ -#define STV06XX_VV6410_H_ - -#include "stv06xx_sensor.h" - -#define VV6410_COLS 416 -#define VV6410_ROWS 320 - -/* Status registers */ -/* Chip identification number including revision indicator */ -#define VV6410_DEVICEH 0x00 -#define VV6410_DEVICEL 0x01 - -/* User can determine whether timed I2C data - has been consumed by interrogating flag states */ -#define VV6410_STATUS0 0x02 - -/* Current line counter value */ -#define VV6410_LINECOUNTH 0x03 -#define VV6410_LINECOUNTL 0x04 - -/* End x coordinate of image size */ -#define VV6410_XENDH 0x05 -#define VV6410_XENDL 0x06 - -/* End y coordinate of image size */ -#define VV6410_YENDH 0x07 -#define VV6410_YENDL 0x08 - -/* This is the average pixel value returned from the - dark line offset cancellation algorithm */ -#define VV6410_DARKAVGH 0x09 -#define VV6410_DARKAVGL 0x0a - -/* This is the average pixel value returned from the - black line offset cancellation algorithm */ -#define VV6410_BLACKAVGH 0x0b -#define VV6410_BLACKAVGL 0x0c - -/* Flags to indicate whether the x or y image coordinates have been clipped */ -#define VV6410_STATUS1 0x0d - -/* Setup registers */ - -/* Low-power/sleep modes & video timing */ -#define VV6410_SETUP0 0x10 - -/* Various parameters */ -#define VV6410_SETUP1 0x11 - -/* Contains pixel counter reset value used by external sync */ -#define VV6410_SYNCVALUE 0x12 - -/* Frame grabbing modes (FST, LST and QCK) */ -#define VV6410_FGMODES 0x14 - -/* FST and QCK mapping modes. */ -#define VV6410_PINMAPPING 0x15 - -/* Data resolution */ -#define VV6410_DATAFORMAT 0x16 - -/* Output coding formats */ -#define VV6410_OPFORMAT 0x17 - -/* Various mode select bits */ -#define VV6410_MODESELECT 0x18 - -/* Exposure registers */ -/* Fine exposure. */ -#define VV6410_FINEH 0x20 -#define VV6410_FINEL 0x21 - -/* Coarse exposure */ -#define VV6410_COARSEH 0x22 -#define VV6410_COARSEL 0x23 - -/* Analog gain setting */ -#define VV6410_ANALOGGAIN 0x24 - -/* Clock division */ -#define VV6410_CLKDIV 0x25 - -/* Dark line offset cancellation value */ -#define VV6410_DARKOFFSETH 0x2c -#define VV6410_DARKOFFSETL 0x2d - -/* Dark line offset cancellation enable */ -#define VV6410_DARKOFFSETSETUP 0x2e - -/* Video timing registers */ -/* Line Length (Pixel Clocks) */ -#define VV6410_LINELENGTHH 0x52 -#define VV6410_LINELENGTHL 0x53 - -/* X-co-ordinate of top left corner of region of interest (x-offset) */ -#define VV6410_XOFFSETH 0x57 -#define VV6410_XOFFSETL 0x58 - -/* Y-coordinate of top left corner of region of interest (y-offset) */ -#define VV6410_YOFFSETH 0x59 -#define VV6410_YOFFSETL 0x5a - -/* Field length (Lines) */ -#define VV6410_FIELDLENGTHH 0x61 -#define VV6410_FIELDLENGTHL 0x62 - -/* System registers */ -/* Black offset cancellation default value */ -#define VV6410_BLACKOFFSETH 0x70 -#define VV6410_BLACKOFFSETL 0x71 - -/* Black offset cancellation setup */ -#define VV6410_BLACKOFFSETSETUP 0x72 - -/* Analog Control Register 0 */ -#define VV6410_CR0 0x75 - -/* Analog Control Register 1 */ -#define VV6410_CR1 0x76 - -/* ADC Setup Register */ -#define VV6410_AS0 0x77 - -/* Analog Test Register */ -#define VV6410_AT0 0x78 - -/* Audio Amplifier Setup Register */ -#define VV6410_AT1 0x79 - -#define VV6410_HFLIP (1 << 3) -#define VV6410_VFLIP (1 << 4) - -#define VV6410_LOW_POWER_MODE (1 << 0) -#define VV6410_SOFT_RESET (1 << 2) -#define VV6410_PAL_25_FPS (0 << 3) - -#define VV6410_CLK_DIV_2 (1 << 1) - -#define VV6410_FINE_EXPOSURE 320 -#define VV6410_COARSE_EXPOSURE 192 -#define VV6410_DEFAULT_GAIN 5 - -#define VV6410_SUBSAMPLE 0x01 -#define VV6410_CROP_TO_QVGA 0x02 - -#define VV6410_CIF_LINELENGTH 415 - -static int vv6410_probe(struct sd *sd); -static int vv6410_start(struct sd *sd); -static int vv6410_init(struct sd *sd); -static int vv6410_init_controls(struct sd *sd); -static int vv6410_stop(struct sd *sd); -static int vv6410_dump(struct sd *sd); - -/* V4L2 controls supported by the driver */ -static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); -static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_vv6410 = { - .name = "ST VV6410", - .i2c_flush = 5, - .i2c_addr = 0x20, - .i2c_len = 1, - /* FIXME (see if we can lower packet_size-s, needs testing, and also - adjusting framerate when the bandwidth gets lower) */ - .min_packet_size = { 1023 }, - .max_packet_size = { 1023 }, - .init = vv6410_init, - .init_controls = vv6410_init_controls, - .probe = vv6410_probe, - .start = vv6410_start, - .stop = vv6410_stop, - .dump = vv6410_dump, -}; - -/* If NULL, only single value to write, stored in len */ -struct stv_init { - u16 addr; - u8 data; -}; - -static const struct stv_init stv_bridge_init[] = { - /* This reg is written twice. Some kind of reset? */ - {STV_RESET, 0x80}, - {STV_RESET, 0x00}, - {STV_SCAN_RATE, 0x00}, - {STV_I2C_FLUSH, 0x04}, - {STV_REG00, 0x0b}, - {STV_REG01, 0xa7}, - {STV_REG02, 0xb7}, - {STV_REG03, 0x00}, - {STV_REG04, 0x00}, - {0x1536, 0x02}, - {0x1537, 0x00}, - {0x1538, 0x60}, - {0x1539, 0x01}, - {0x153a, 0x20}, - {0x153b, 0x01}, -}; - -static const u8 vv6410_sensor_init[][2] = { - /* Setup registers */ - {VV6410_SETUP0, VV6410_SOFT_RESET}, - {VV6410_SETUP0, VV6410_LOW_POWER_MODE}, - /* Use shuffled read-out mode */ - {VV6410_SETUP1, BIT(6)}, - /* All modes to 1, FST, Fast QCK, Free running QCK, Free running LST, FST will qualify visible pixels */ - {VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)}, - {VV6410_PINMAPPING, 0x00}, - /* Pre-clock generator divide off */ - {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, - - {VV6410_CLKDIV, VV6410_CLK_DIV_2}, - - /* System registers */ - /* Enable voltage doubler */ - {VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)}, - {VV6410_AT0, 0x00}, - /* Power up audio, differential */ - {VV6410_AT1, BIT(4) | BIT(0)}, -}; - -#endif diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c deleted file mode 100644 index 9ccfcb1c6479..000000000000 --- a/drivers/media/video/gspca/sunplus.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* - * Sunplus spca504(abc) spca533 spca536 library - * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "sunplus" - -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); -MODULE_LICENSE("GPL"); - -#define QUALITY 85 - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - bool autogain; - - u8 bridge; -#define BRIDGE_SPCA504 0 -#define BRIDGE_SPCA504B 1 -#define BRIDGE_SPCA504C 2 -#define BRIDGE_SPCA533 3 -#define BRIDGE_SPCA536 4 - u8 subtype; -#define AiptekMiniPenCam13 1 -#define LogitechClickSmart420 2 -#define LogitechClickSmart820 3 -#define MegapixV4 4 -#define MegaImageVI 5 - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -}; - -static const struct v4l2_pix_format custom_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 464, - .sizeimage = 464 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -}; - -static const struct v4l2_pix_format vga_mode2[] = { - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 4}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -}; - -#define SPCA50X_OFFSET_DATA 10 -#define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3 -#define SPCA504_PCCAM600_OFFSET_COMPRESS 4 -#define SPCA504_PCCAM600_OFFSET_MODE 5 -#define SPCA504_PCCAM600_OFFSET_DATA 14 - /* Frame packet header offsets for the spca533 */ -#define SPCA533_OFFSET_DATA 16 -#define SPCA533_OFFSET_FRAMSEQ 15 -/* Frame packet header offsets for the spca536 */ -#define SPCA536_OFFSET_DATA 4 -#define SPCA536_OFFSET_FRAMSEQ 1 - -struct cmd { - u8 req; - u16 val; - u16 idx; -}; - -/* Initialisation data for the Creative PC-CAM 600 */ -static const struct cmd spca504_pccam600_init_data[] = { -/* {0xa0, 0x0000, 0x0503}, * capture mode */ - {0x00, 0x0000, 0x2000}, - {0x00, 0x0013, 0x2301}, - {0x00, 0x0003, 0x2000}, - {0x00, 0x0001, 0x21ac}, - {0x00, 0x0001, 0x21a6}, - {0x00, 0x0000, 0x21a7}, /* brightness */ - {0x00, 0x0020, 0x21a8}, /* contrast */ - {0x00, 0x0001, 0x21ac}, /* sat/hue */ - {0x00, 0x0000, 0x21ad}, /* hue */ - {0x00, 0x001a, 0x21ae}, /* saturation */ - {0x00, 0x0002, 0x21a3}, /* gamma */ - {0x30, 0x0154, 0x0008}, - {0x30, 0x0004, 0x0006}, - {0x30, 0x0258, 0x0009}, - {0x30, 0x0004, 0x0000}, - {0x30, 0x0093, 0x0004}, - {0x30, 0x0066, 0x0005}, - {0x00, 0x0000, 0x2000}, - {0x00, 0x0013, 0x2301}, - {0x00, 0x0003, 0x2000}, - {0x00, 0x0013, 0x2301}, - {0x00, 0x0003, 0x2000}, -}; - -/* Creative PC-CAM 600 specific open data, sent before using the - * generic initialisation data from spca504_open_data. - */ -static const struct cmd spca504_pccam600_open_data[] = { - {0x00, 0x0001, 0x2501}, - {0x20, 0x0500, 0x0001}, /* snapshot mode */ - {0x00, 0x0003, 0x2880}, - {0x00, 0x0001, 0x2881}, -}; - -/* Initialisation data for the logitech clicksmart 420 */ -static const struct cmd spca504A_clicksmart420_init_data[] = { -/* {0xa0, 0x0000, 0x0503}, * capture mode */ - {0x00, 0x0000, 0x2000}, - {0x00, 0x0013, 0x2301}, - {0x00, 0x0003, 0x2000}, - {0x00, 0x0001, 0x21ac}, - {0x00, 0x0001, 0x21a6}, - {0x00, 0x0000, 0x21a7}, /* brightness */ - {0x00, 0x0020, 0x21a8}, /* contrast */ - {0x00, 0x0001, 0x21ac}, /* sat/hue */ - {0x00, 0x0000, 0x21ad}, /* hue */ - {0x00, 0x001a, 0x21ae}, /* saturation */ - {0x00, 0x0002, 0x21a3}, /* gamma */ - {0x30, 0x0004, 0x000a}, - {0xb0, 0x0001, 0x0000}, - - {0xa1, 0x0080, 0x0001}, - {0x30, 0x0049, 0x0000}, - {0x30, 0x0060, 0x0005}, - {0x0c, 0x0004, 0x0000}, - {0x00, 0x0000, 0x0000}, - {0x00, 0x0000, 0x2000}, - {0x00, 0x0013, 0x2301}, - {0x00, 0x0003, 0x2000}, -}; - -/* clicksmart 420 open data ? */ -static const struct cmd spca504A_clicksmart420_open_data[] = { - {0x00, 0x0001, 0x2501}, - {0x20, 0x0502, 0x0000}, - {0x06, 0x0000, 0x0000}, - {0x00, 0x0004, 0x2880}, - {0x00, 0x0001, 0x2881}, - - {0xa0, 0x0000, 0x0503}, -}; - -static const u8 qtable_creative_pccam[2][64] = { - { /* Q-table Y-components */ - 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, - 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, - 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, - 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, - 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, - 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, - 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, - 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, - { /* Q-table C-components */ - 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, - 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} -}; - -/* FIXME: This Q-table is identical to the Creative PC-CAM one, - * except for one byte. Possibly a typo? - * NWG: 18/05/2003. - */ -static const u8 qtable_spca504_default[2][64] = { - { /* Q-table Y-components */ - 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, - 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, - 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, - 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, - 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, - 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, - 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, - 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e, - }, - { /* Q-table C-components */ - 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, - 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, - 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} -}; - -/* read <len> bytes to gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, - u8 req, - u16 index, - u16 len) -{ - int ret; - -#ifdef GSPCA_DEBUG - if (len > USB_BUF_SZ) { - pr_err("reg_r: buffer overflow\n"); - return; - } -#endif - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - len ? gspca_dev->usb_buf : NULL, len, - 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* write one byte */ -static void reg_w_1(struct gspca_dev *gspca_dev, - u8 req, - u16 value, - u16 index, - u16 byte) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - gspca_dev->usb_buf[0] = byte; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, - gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_w_1 err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* write req / index / value */ -static void reg_w_riv(struct gspca_dev *gspca_dev, - u8 req, u16 index, u16 value) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - if (ret < 0) { - pr_err("reg_w_riv err %d\n", ret); - gspca_dev->usb_err = ret; - return; - } - PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x", - req, index, value); -} - -static void write_vector(struct gspca_dev *gspca_dev, - const struct cmd *data, int ncmds) -{ - while (--ncmds >= 0) { - reg_w_riv(gspca_dev, data->req, data->idx, data->val); - data++; - } -} - -static void setup_qtable(struct gspca_dev *gspca_dev, - const u8 qtable[2][64]) -{ - int i; - - /* loop over y components */ - for (i = 0; i < 64; i++) - reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]); - - /* loop over c components */ - for (i = 0; i < 64; i++) - reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]); -} - -static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, - u8 req, u16 idx, u16 val) -{ - reg_w_riv(gspca_dev, req, idx, val); - reg_r(gspca_dev, 0x01, 0x0001, 1); - PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]); - reg_w_riv(gspca_dev, req, idx, val); - - msleep(200); - reg_r(gspca_dev, 0x01, 0x0001, 1); - PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]); -} - -#ifdef GSPCA_DEBUG -static void spca504_read_info(struct gspca_dev *gspca_dev) -{ - int i; - u8 info[6]; - - for (i = 0; i < 6; i++) { - reg_r(gspca_dev, 0, i, 1); - info[i] = gspca_dev->usb_buf[0]; - } - PDEBUG(D_STREAM, - "Read info: %d %d %d %d %d %d." - " Should be 1,0,2,2,0,0", - info[0], info[1], info[2], - info[3], info[4], info[5]); -} -#endif - -static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, - u8 req, - u16 idx, u16 val, u8 endcode, u8 count) -{ - u16 status; - - reg_w_riv(gspca_dev, req, idx, val); - reg_r(gspca_dev, 0x01, 0x0001, 1); - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x", - gspca_dev->usb_buf[0], endcode); - if (!count) - return; - count = 200; - while (--count > 0) { - msleep(10); - /* gsmart mini2 write a each wait setting 1 ms is enough */ -/* reg_w_riv(gspca_dev, req, idx, val); */ - reg_r(gspca_dev, 0x01, 0x0001, 1); - status = gspca_dev->usb_buf[0]; - if (status == endcode) { - PDEBUG(D_FRAM, "status 0x%04x after wait %d", - status, 200 - count); - break; - } - } -} - -static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev) -{ - int count = 10; - - while (--count > 0) { - reg_r(gspca_dev, 0x21, 0, 1); - if ((gspca_dev->usb_buf[0] & 0x01) == 0) - break; - msleep(10); - } -} - -static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) -{ - int count = 50; - - while (--count > 0) { - reg_r(gspca_dev, 0x21, 1, 1); - if (gspca_dev->usb_buf[0] != 0) { - reg_w_1(gspca_dev, 0x21, 0, 1, 0); - reg_r(gspca_dev, 0x21, 1, 1); - spca504B_PollingDataReady(gspca_dev); - break; - } - msleep(10); - } -} - -#ifdef GSPCA_DEBUG -static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) -{ - u8 *data; - - data = gspca_dev->usb_buf; - reg_r(gspca_dev, 0x20, 0, 5); - PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d", - data[0], data[1], data[2], data[3], data[4]); - reg_r(gspca_dev, 0x23, 0, 64); - reg_r(gspca_dev, 0x23, 1, 64); -} -#endif - -static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 Size; - - Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - switch (sd->bridge) { - case BRIDGE_SPCA533: - reg_w_riv(gspca_dev, 0x31, 0, 0); - spca504B_WaitCmdStatus(gspca_dev); - spca504B_PollingDataReady(gspca_dev); -#ifdef GSPCA_DEBUG - spca50x_GetFirmware(gspca_dev); -#endif - reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ - reg_r(gspca_dev, 0x24, 8, 1); - - reg_w_1(gspca_dev, 0x25, 0, 4, Size); - reg_r(gspca_dev, 0x25, 4, 1); /* size */ - spca504B_PollingDataReady(gspca_dev); - - /* Init the cam width height with some values get on init ? */ - reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00); - spca504B_WaitCmdStatus(gspca_dev); - spca504B_PollingDataReady(gspca_dev); - break; - default: -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA536: */ - reg_w_1(gspca_dev, 0x25, 0, 4, Size); - reg_r(gspca_dev, 0x25, 4, 1); /* size */ - reg_w_1(gspca_dev, 0x27, 0, 0, 6); - reg_r(gspca_dev, 0x27, 0, 1); /* type */ - spca504B_PollingDataReady(gspca_dev); - break; - case BRIDGE_SPCA504: - Size += 3; - if (sd->subtype == AiptekMiniPenCam13) { - /* spca504a aiptek */ - spca504A_acknowledged_command(gspca_dev, - 0x08, Size, 0, - 0x80 | (Size & 0x0f), 1); - spca504A_acknowledged_command(gspca_dev, - 1, 3, 0, 0x9f, 0); - } else { - spca504_acknowledged_command(gspca_dev, 0x08, Size, 0); - } - break; - case BRIDGE_SPCA504C: - /* capture mode */ - reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); - reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); - break; - } -} - -static void spca504_wait_status(struct gspca_dev *gspca_dev) -{ - int cnt; - - cnt = 256; - while (--cnt > 0) { - /* With this we get the status, when return 0 it's all ok */ - reg_r(gspca_dev, 0x06, 0x00, 1); - if (gspca_dev->usb_buf[0] == 0) - return; - msleep(10); - } -} - -static void spca504B_setQtable(struct gspca_dev *gspca_dev) -{ - reg_w_1(gspca_dev, 0x26, 0, 0, 3); - reg_r(gspca_dev, 0x26, 0, 1); - spca504B_PollingDataReady(gspca_dev); -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 reg; - - reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; - reg_w_riv(gspca_dev, 0x00, reg, val); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 reg; - - reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; - reg_w_riv(gspca_dev, 0x00, reg, val); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u16 reg; - - reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; - reg_w_riv(gspca_dev, 0x00, reg, val); -} - -static void init_ctl_reg(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int pollreg = 1; - - switch (sd->bridge) { - case BRIDGE_SPCA504: - case BRIDGE_SPCA504C: - pollreg = 0; - /* fall thru */ - default: -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA504B: */ - reg_w_riv(gspca_dev, 0, 0x21ad, 0x00); /* hue */ - reg_w_riv(gspca_dev, 0, 0x21ac, 0x01); /* sat/hue */ - reg_w_riv(gspca_dev, 0, 0x21a3, 0x00); /* gamma */ - break; - case BRIDGE_SPCA536: - reg_w_riv(gspca_dev, 0, 0x20f5, 0x40); - reg_w_riv(gspca_dev, 0, 0x20f4, 0x01); - reg_w_riv(gspca_dev, 0, 0x2089, 0x00); - break; - } - if (pollreg) - spca504B_PollingDataReady(gspca_dev); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - cam = &gspca_dev->cam; - - sd->bridge = id->driver_info >> 8; - sd->subtype = id->driver_info; - - if (sd->subtype == AiptekMiniPenCam13) { - - /* try to get the firmware as some cam answer 2.0.1.2.2 - * and should be a spca504b then overwrite that setting */ - reg_r(gspca_dev, 0x20, 0, 1); - switch (gspca_dev->usb_buf[0]) { - case 1: - break; /* (right bridge/subtype) */ - case 2: - sd->bridge = BRIDGE_SPCA504B; - sd->subtype = 0; - break; - default: - return -ENODEV; - } - } - - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA504: */ -/* case BRIDGE_SPCA536: */ - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - break; - case BRIDGE_SPCA533: - cam->cam_mode = custom_mode; - if (sd->subtype == MegaImageVI) /* 320x240 only */ - cam->nmodes = ARRAY_SIZE(custom_mode) - 1; - else - cam->nmodes = ARRAY_SIZE(custom_mode); - break; - case BRIDGE_SPCA504C: - cam->cam_mode = vga_mode2; - cam->nmodes = ARRAY_SIZE(vga_mode2); - break; - } - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - case BRIDGE_SPCA504B: - reg_w_riv(gspca_dev, 0x1d, 0x00, 0); - reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01); - reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00); - reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00); - reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13); - reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00); - /* fall thru */ - case BRIDGE_SPCA533: - spca504B_PollingDataReady(gspca_dev); -#ifdef GSPCA_DEBUG - spca50x_GetFirmware(gspca_dev); -#endif - break; - case BRIDGE_SPCA536: -#ifdef GSPCA_DEBUG - spca50x_GetFirmware(gspca_dev); -#endif - reg_r(gspca_dev, 0x00, 0x5002, 1); - reg_w_1(gspca_dev, 0x24, 0, 0, 0); - reg_r(gspca_dev, 0x24, 0, 1); - spca504B_PollingDataReady(gspca_dev); - reg_w_riv(gspca_dev, 0x34, 0, 0); - spca504B_WaitCmdStatus(gspca_dev); - break; - case BRIDGE_SPCA504C: /* pccam600 */ - PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); - reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000); - reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */ - spca504_wait_status(gspca_dev); - if (sd->subtype == LogitechClickSmart420) - write_vector(gspca_dev, - spca504A_clicksmart420_open_data, - ARRAY_SIZE(spca504A_clicksmart420_open_data)); - else - write_vector(gspca_dev, spca504_pccam600_open_data, - ARRAY_SIZE(spca504_pccam600_open_data)); - setup_qtable(gspca_dev, qtable_creative_pccam); - break; - default: -/* case BRIDGE_SPCA504: */ - PDEBUG(D_STREAM, "Opening SPCA504"); - if (sd->subtype == AiptekMiniPenCam13) { -#ifdef GSPCA_DEBUG - spca504_read_info(gspca_dev); -#endif - - /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ - spca504A_acknowledged_command(gspca_dev, 0x24, - 8, 3, 0x9e, 1); - /* Twice sequential need status 0xff->0x9e->0x9d */ - spca504A_acknowledged_command(gspca_dev, 0x24, - 8, 3, 0x9e, 0); - - spca504A_acknowledged_command(gspca_dev, 0x24, - 0, 0, 0x9d, 1); - /******************************/ - /* spca504a aiptek */ - spca504A_acknowledged_command(gspca_dev, 0x08, - 6, 0, 0x86, 1); -/* reg_write (dev, 0, 0x2000, 0); */ -/* reg_write (dev, 0, 0x2883, 1); */ -/* spca504A_acknowledged_command (gspca_dev, 0x08, - 6, 0, 0x86, 1); */ -/* spca504A_acknowledged_command (gspca_dev, 0x24, - 0, 0, 0x9D, 1); */ - reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); - /* L92 sno1t.txt */ - reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); - spca504A_acknowledged_command(gspca_dev, 0x01, - 0x0f, 0, 0xff, 0); - } - /* setup qtable */ - reg_w_riv(gspca_dev, 0, 0x2000, 0); - reg_w_riv(gspca_dev, 0, 0x2883, 1); - setup_qtable(gspca_dev, qtable_spca504_default); - break; - } - return gspca_dev->usb_err; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int enable; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, QUALITY); - - if (sd->bridge == BRIDGE_SPCA504B) - spca504B_setQtable(gspca_dev); - spca504B_SetSizeType(gspca_dev); - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA504B: */ -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA536: */ - switch (sd->subtype) { - case MegapixV4: - case LogitechClickSmart820: - case MegaImageVI: - reg_w_riv(gspca_dev, 0xf0, 0, 0); - spca504B_WaitCmdStatus(gspca_dev); - reg_r(gspca_dev, 0xf0, 4, 0); - spca504B_WaitCmdStatus(gspca_dev); - break; - default: - reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00); - spca504B_WaitCmdStatus(gspca_dev); - spca504B_PollingDataReady(gspca_dev); - break; - } - break; - case BRIDGE_SPCA504: - if (sd->subtype == AiptekMiniPenCam13) { -#ifdef GSPCA_DEBUG - spca504_read_info(gspca_dev); -#endif - - /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ - spca504A_acknowledged_command(gspca_dev, 0x24, - 8, 3, 0x9e, 1); - /* Twice sequential need status 0xff->0x9e->0x9d */ - spca504A_acknowledged_command(gspca_dev, 0x24, - 8, 3, 0x9e, 0); - spca504A_acknowledged_command(gspca_dev, 0x24, - 0, 0, 0x9d, 1); - } else { - spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); -#ifdef GSPCA_DEBUG - spca504_read_info(gspca_dev); -#endif - spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); - spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); - } - spca504B_SetSizeType(gspca_dev); - reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); - /* L92 sno1t.txt */ - reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); - break; - case BRIDGE_SPCA504C: - if (sd->subtype == LogitechClickSmart420) { - write_vector(gspca_dev, - spca504A_clicksmart420_init_data, - ARRAY_SIZE(spca504A_clicksmart420_init_data)); - } else { - write_vector(gspca_dev, spca504_pccam600_init_data, - ARRAY_SIZE(spca504_pccam600_init_data)); - } - enable = (sd->autogain ? 0x04 : 0x01); - reg_w_riv(gspca_dev, 0x0c, 0x0000, enable); - /* auto exposure */ - reg_w_riv(gspca_dev, 0xb0, 0x0000, enable); - /* auto whiteness */ - - /* set default exposure compensation and whiteness balance */ - reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */ - reg_w_riv(gspca_dev, 0x30, 0x0002, 1600); - spca504B_SetSizeType(gspca_dev); - break; - } - init_ctl_reg(gspca_dev); - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->bridge) { - default: -/* case BRIDGE_SPCA533: */ -/* case BRIDGE_SPCA536: */ -/* case BRIDGE_SPCA504B: */ - reg_w_riv(gspca_dev, 0x31, 0, 0); - spca504B_WaitCmdStatus(gspca_dev); - spca504B_PollingDataReady(gspca_dev); - break; - case BRIDGE_SPCA504: - case BRIDGE_SPCA504C: - reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000); - - if (sd->subtype == AiptekMiniPenCam13) { - /* spca504a aiptek */ -/* spca504A_acknowledged_command(gspca_dev, 0x08, - 6, 0, 0x86, 1); */ - spca504A_acknowledged_command(gspca_dev, 0x24, - 0x00, 0x00, 0x9d, 1); - spca504A_acknowledged_command(gspca_dev, 0x01, - 0x0f, 0x00, 0xff, 1); - } else { - spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); - reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000); - } - break; - } -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, sof = 0; - static u8 ffd9[] = {0xff, 0xd9}; - -/* frames are jpeg 4.1.1 without 0xff escape */ - switch (sd->bridge) { - case BRIDGE_SPCA533: - if (data[0] == 0xff) { - if (data[1] != 0x01) { /* drop packet */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - } - sof = 1; - data += SPCA533_OFFSET_DATA; - len -= SPCA533_OFFSET_DATA; - } else { - data += 1; - len -= 1; - } - break; - case BRIDGE_SPCA536: - if (data[0] == 0xff) { - sof = 1; - data += SPCA536_OFFSET_DATA; - len -= SPCA536_OFFSET_DATA; - } else { - data += 2; - len -= 2; - } - break; - default: -/* case BRIDGE_SPCA504: */ -/* case BRIDGE_SPCA504B: */ - switch (data[0]) { - case 0xfe: /* start of frame */ - sof = 1; - data += SPCA50X_OFFSET_DATA; - len -= SPCA50X_OFFSET_DATA; - break; - case 0xff: /* drop packet */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - default: - data += 1; - len -= 1; - break; - } - break; - case BRIDGE_SPCA504C: - switch (data[0]) { - case 0xfe: /* start of frame */ - sof = 1; - data += SPCA504_PCCAM600_OFFSET_DATA; - len -= SPCA504_PCCAM600_OFFSET_DATA; - break; - case 0xff: /* drop packet */ -/* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; - default: - data += 1; - len -= 1; - break; - } - break; - } - if (sof) { /* start of frame */ - gspca_frame_add(gspca_dev, LAST_PACKET, - ffd9, 2); - - /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - } - - /* add 0x00 after 0xff */ - i = 0; - do { - if (data[i] == 0xff) { - gspca_frame_add(gspca_dev, INTER_PACKET, - data, i + 1); - len -= i; - data += i; - *data = 0x00; - i = 0; - } - i++; - } while (i < len); - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - sd->autogain = ctrl->val; - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 0x20); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, 0x1a); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -#define BS(bridge, subtype) \ - .driver_info = (BRIDGE_ ## bridge << 8) \ - | (subtype) -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)}, - {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)}, - {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)}, - {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)}, - {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)}, - {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)}, - {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)}, - {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)}, - {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)}, - {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)}, - {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)}, - {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)}, - {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)}, - {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)}, - {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)}, - {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)}, - {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, - {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, - {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)}, - {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, - {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)}, - {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, - {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)}, - {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)}, - {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)}, - {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)}, - {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)}, - {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)}, - {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)}, - {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)}, - {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)}, - {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)}, - {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)}, - {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)}, - {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)}, - {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)}, - {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)}, - {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)}, - {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)}, - {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)}, - {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)}, - {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)}, - {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)}, - {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)}, - {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)}, - {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)}, - {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)}, - {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c deleted file mode 100644 index 8bc6c3ceec2c..000000000000 --- a/drivers/media/video/gspca/t613.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* - * T613 subdriver - * - * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - *Notes: * t613 + tas5130A - * * Focus to light do not balance well as in win. - * Quality in win is not good, but its kinda better. - * * Fix some "extraneous bytes", most of apps will show the image anyway - * * Gamma table, is there, but its really doing something? - * * 7~8 Fps, its ok, max on win its 10. - * Costantino Leandro - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "t613" - -#include <linux/input.h> -#include <linux/slab.h> -#include "gspca.h" - -MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); -MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); -MODULE_LICENSE("GPL"); - -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct v4l2_ctrl *freq; - struct { /* awb / color gains control cluster */ - struct v4l2_ctrl *awb; - struct v4l2_ctrl *gain; - struct v4l2_ctrl *red_balance; - struct v4l2_ctrl *blue_balance; - }; - - u8 sensor; - u8 button_pressed; -}; -enum sensors { - SENSOR_OM6802, - SENSOR_OTHER, - SENSOR_TAS5130A, - SENSOR_LT168G, /* must verify if this is the actual model */ -}; - -static const struct v4l2_pix_format vga_mode_t16[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 4}, -#if 0 /* HDG: broken with my test cam, so lets disable it */ - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, -#endif - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, -#if 0 /* HDG: broken with my test cam, so lets disable it */ - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -#endif - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* sensor specific data */ -struct additional_sensor_data { - const u8 n3[6]; - const u8 *n4, n4sz; - const u8 reg80, reg8e; - const u8 nset8[6]; - const u8 data1[10]; - const u8 data2[9]; - const u8 data3[9]; - const u8 data5[6]; - const u8 stream[4]; -}; - -static const u8 n4_om6802[] = { - 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, - 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, - 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, - 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, - 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, - 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, - 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, - 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, - 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46 -}; -static const u8 n4_other[] = { - 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69, - 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68, - 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8, - 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8, - 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56, - 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5, - 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0, - 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00 -}; -static const u8 n4_tas5130a[] = { - 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20, - 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4, - 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10, - 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08, - 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a, - 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8, - 0xc6, 0xda -}; -static const u8 n4_lt168g[] = { - 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28, - 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70, - 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3, - 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20, - 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68, - 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40, - 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0, - 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c, - 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80 -}; - -static const struct additional_sensor_data sensor_data[] = { -[SENSOR_OM6802] = { - .n3 = - {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}, - .n4 = n4_om6802, - .n4sz = sizeof n4_om6802, - .reg80 = 0x3c, - .reg8e = 0x33, - .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00}, - .data1 = - {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, - 0xb3, 0xfc}, - .data2 = - {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, - 0xff}, - .data3 = - {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, - 0xff}, - .data5 = /* this could be removed later */ - {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, - .stream = - {0x0b, 0x04, 0x0a, 0x78}, - }, -[SENSOR_OTHER] = { - .n3 = - {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}, - .n4 = n4_other, - .n4sz = sizeof n4_other, - .reg80 = 0xac, - .reg8e = 0xb8, - .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00}, - .data1 = - {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, - 0xe8, 0xfc}, - .data2 = - {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, - 0xd9}, - .data3 = - {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, - 0xd9}, - .data5 = - {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, - .stream = - {0x0b, 0x04, 0x0a, 0x00}, - }, -[SENSOR_TAS5130A] = { - .n3 = - {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08}, - .n4 = n4_tas5130a, - .n4sz = sizeof n4_tas5130a, - .reg80 = 0x3c, - .reg8e = 0xb4, - .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00}, - .data1 = - {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, - 0xc8, 0xfc}, - .data2 = - {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, - 0xe0}, - .data3 = - {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, - 0xe0}, - .data5 = - {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, - .stream = - {0x0b, 0x04, 0x0a, 0x40}, - }, -[SENSOR_LT168G] = { - .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00}, - .n4 = n4_lt168g, - .n4sz = sizeof n4_lt168g, - .reg80 = 0x7c, - .reg8e = 0xb3, - .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00}, - .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40, - 0xb0, 0xf4}, - .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, - 0xff}, - .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, - 0xff}, - .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b}, - .stream = {0x0b, 0x04, 0x0a, 0x28}, - }, -}; - -#define MAX_EFFECTS 7 -static const u8 effects_table[MAX_EFFECTS][6] = { - {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ - {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ - {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ - {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */ - {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */ - {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */ - {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ -}; - -#define GAMMA_MAX (15) -static const u8 gamma_table[GAMMA_MAX+1][17] = { -/* gamma table from cam1690.ini */ - {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */ - 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb, - 0xff}, - {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */ - 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1, - 0xff}, - {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */ - 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3, - 0xff}, - {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */ - 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6, - 0xff}, - {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */ - 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9, - 0xff}, - {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */ - 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec, - 0xff}, - {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */ - 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, - 0xff}, - {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */ - 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0xff}, - {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */ - 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0, - 0xff}, - {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */ - 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2, - 0xff}, - {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */ - 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3, - 0xff}, - {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */ - 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, - 0xff}, - {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ - 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6, - 0xff}, - {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */ - 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9, - 0xff}, - {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */ - 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa, - 0xff}, - {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */ - 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc, - 0xff} -}; - -static const u8 tas5130a_sensor_init[][8] = { - {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, - {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, - {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, -}; - -static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; - -/* read 1 byte */ -static u8 reg_r(struct gspca_dev *gspca_dev, - u16 index) -{ - usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - gspca_dev->usb_buf, 1, 500); - return gspca_dev->usb_buf[0]; -} - -static void reg_w(struct gspca_dev *gspca_dev, - u16 index) -{ - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, - NULL, 0, 500); -} - -static void reg_w_buf(struct gspca_dev *gspca_dev, - const u8 *buffer, u16 len) -{ - if (len <= USB_BUF_SZ) { - memcpy(gspca_dev->usb_buf, buffer, len); - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x01, 0, - gspca_dev->usb_buf, len, 500); - } else { - u8 *tmpbuf; - - tmpbuf = kmemdup(buffer, len, GFP_KERNEL); - if (!tmpbuf) { - pr_err("Out of memory\n"); - return; - } - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x01, 0, - tmpbuf, len, 500); - kfree(tmpbuf); - } -} - -/* write values to consecutive registers */ -static void reg_w_ixbuf(struct gspca_dev *gspca_dev, - u8 reg, - const u8 *buffer, u16 len) -{ - int i; - u8 *p, *tmpbuf; - - if (len * 2 <= USB_BUF_SZ) { - p = tmpbuf = gspca_dev->usb_buf; - } else { - p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); - if (!tmpbuf) { - pr_err("Out of memory\n"); - return; - } - } - i = len; - while (--i >= 0) { - *p++ = reg++; - *p++ = *buffer++; - } - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x01, 0, - tmpbuf, len * 2, 500); - if (len * 2 > USB_BUF_SZ) - kfree(tmpbuf); -} - -static void om6802_sensor_init(struct gspca_dev *gspca_dev) -{ - int i; - const u8 *p; - u8 byte; - u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; - static const u8 sensor_init[] = { - 0xdf, 0x6d, - 0xdd, 0x18, - 0x5a, 0xe0, - 0x5c, 0x07, - 0x5d, 0xb0, - 0x5e, 0x1e, - 0x60, 0x71, - 0xef, 0x00, - 0xe9, 0x00, - 0xea, 0x00, - 0x90, 0x24, - 0x91, 0xb2, - 0x82, 0x32, - 0xfd, 0x41, - 0x00 /* table end */ - }; - - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - msleep(100); - i = 4; - while (--i > 0) { - byte = reg_r(gspca_dev, 0x0060); - if (!(byte & 0x01)) - break; - msleep(100); - } - byte = reg_r(gspca_dev, 0x0063); - if (byte != 0x17) { - pr_err("Bad sensor reset %02x\n", byte); - /* continue? */ - } - - p = sensor_init; - while (*p != 0) { - val[1] = *p++; - val[3] = *p++; - if (*p == 0) - reg_w(gspca_dev, 0x3c80); - reg_w_buf(gspca_dev, val, sizeof val); - i = 4; - while (--i >= 0) { - msleep(15); - byte = reg_r(gspca_dev, 0x60); - if (!(byte & 0x01)) - break; - } - } - msleep(15); - reg_w(gspca_dev, 0x3c80); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - - cam->cam_mode = vga_mode_t16; - cam->nmodes = ARRAY_SIZE(vga_mode_t16); - - return 0; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) -{ - u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; - - if (brightness < 7) { - set6[1] = 0x26; - set6[3] = 0x70 - brightness * 0x10; - } else { - set6[3] = 0x00 + ((brightness - 7) * 0x10); - } - - reg_w_buf(gspca_dev, set6, sizeof set6); -} - -static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast) -{ - u16 reg_to_write; - - if (contrast < 7) - reg_to_write = 0x8ea9 - contrast * 0x200; - else - reg_to_write = 0x00a9 + (contrast - 7) * 0x200; - - reg_w(gspca_dev, reg_to_write); -} - -static void setcolors(struct gspca_dev *gspca_dev, s32 val) -{ - u16 reg_to_write; - - reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */ - reg_w(gspca_dev, reg_to_write); -} - -static void setgamma(struct gspca_dev *gspca_dev, s32 val) -{ - PDEBUG(D_CONF, "Gamma: %d", sd->gamma); - reg_w_ixbuf(gspca_dev, 0x90, - gamma_table[val], sizeof gamma_table[0]); -} - -static void setawb_n_RGB(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 all_gain_reg[8] = { - 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 }; - s32 red_gain, blue_gain, green_gain; - - green_gain = sd->gain->val; - - red_gain = green_gain + sd->red_balance->val; - if (red_gain > 0x40) - red_gain = 0x40; - else if (red_gain < 0x10) - red_gain = 0x10; - - blue_gain = green_gain + sd->blue_balance->val; - if (blue_gain > 0x40) - blue_gain = 0x40; - else if (blue_gain < 0x10) - blue_gain = 0x10; - - all_gain_reg[1] = red_gain; - all_gain_reg[3] = blue_gain; - all_gain_reg[5] = green_gain; - all_gain_reg[7] = sensor_data[sd->sensor].reg80; - if (!sd->awb->val) - all_gain_reg[7] &= ~0x04; /* AWB off */ - - reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - u16 reg_to_write; - - reg_to_write = 0x0aa6 + 0x1000 * val; - - reg_w(gspca_dev, reg_to_write); -} - -static void setfreq(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 reg66; - u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 }; - - switch (sd->sensor) { - case SENSOR_LT168G: - if (val != 0) - freq[3] = 0xa8; - reg66 = 0x41; - break; - case SENSOR_OM6802: - reg66 = 0xca; - break; - default: - reg66 = 0x40; - break; - } - switch (val) { - case 0: /* no flicker */ - freq[3] = 0xf0; - break; - case 2: /* 60Hz */ - reg66 &= ~0x40; - break; - } - freq[1] = reg66; - - reg_w_buf(gspca_dev, freq, sizeof freq); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - /* some of this registers are not really neded, because - * they are overriden by setbrigthness, setcontrast, etc, - * but wont hurt anyway, and can help someone with similar webcam - * to see the initial parameters.*/ - struct sd *sd = (struct sd *) gspca_dev; - const struct additional_sensor_data *sensor; - int i; - u16 sensor_id; - u8 test_byte = 0; - - static const u8 read_indexs[] = - { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, - 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 }; - static const u8 n1[] = - {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; - static const u8 n2[] = - {0x08, 0x00}; - - sensor_id = (reg_r(gspca_dev, 0x06) << 8) - | reg_r(gspca_dev, 0x07); - switch (sensor_id & 0xff0f) { - case 0x0801: - PDEBUG(D_PROBE, "sensor tas5130a"); - sd->sensor = SENSOR_TAS5130A; - break; - case 0x0802: - PDEBUG(D_PROBE, "sensor lt168g"); - sd->sensor = SENSOR_LT168G; - break; - case 0x0803: - PDEBUG(D_PROBE, "sensor 'other'"); - sd->sensor = SENSOR_OTHER; - break; - case 0x0807: - PDEBUG(D_PROBE, "sensor om6802"); - sd->sensor = SENSOR_OM6802; - break; - default: - pr_err("unknown sensor %04x\n", sensor_id); - return -EINVAL; - } - - if (sd->sensor == SENSOR_OM6802) { - reg_w_buf(gspca_dev, n1, sizeof n1); - i = 5; - while (--i >= 0) { - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - test_byte = reg_r(gspca_dev, 0x0063); - msleep(100); - if (test_byte == 0x17) - break; /* OK */ - } - if (i < 0) { - pr_err("Bad sensor reset %02x\n", test_byte); - return -EIO; - } - reg_w_buf(gspca_dev, n2, sizeof n2); - } - - i = 0; - while (read_indexs[i] != 0x00) { - test_byte = reg_r(gspca_dev, read_indexs[i]); - PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i], - test_byte); - i++; - } - - sensor = &sensor_data[sd->sensor]; - reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3); - reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz); - - if (sd->sensor == SENSOR_LT168G) { - test_byte = reg_r(gspca_dev, 0x80); - PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80, - test_byte); - reg_w(gspca_dev, 0x6c80); - } - - reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); - reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); - reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); - - reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); - reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); - reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e); - reg_w(gspca_dev, (0x20 << 8) + 0x87); - reg_w(gspca_dev, (0x20 << 8) + 0x88); - reg_w(gspca_dev, (0x20 << 8) + 0x89); - - reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); - reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); - reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); - - if (sd->sensor == SENSOR_LT168G) { - test_byte = reg_r(gspca_dev, 0x80); - PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80, - test_byte); - reg_w(gspca_dev, 0x6c80); - } - - reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); - reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); - reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); - - return 0; -} - -static void setmirror(struct gspca_dev *gspca_dev, s32 val) -{ - u8 hflipcmd[8] = - {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; - - if (val) - hflipcmd[3] = 0x01; - - reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd); -} - -static void seteffect(struct gspca_dev *gspca_dev, s32 val) -{ - int idx = 0; - - switch (val) { - case V4L2_COLORFX_NONE: - break; - case V4L2_COLORFX_BW: - idx = 2; - break; - case V4L2_COLORFX_SEPIA: - idx = 3; - break; - case V4L2_COLORFX_SKETCH: - idx = 4; - break; - case V4L2_COLORFX_NEGATIVE: - idx = 6; - break; - default: - break; - } - - reg_w_buf(gspca_dev, effects_table[idx], - sizeof effects_table[0]); - - if (val == V4L2_COLORFX_SKETCH) - reg_w(gspca_dev, 0x4aa6); - else - reg_w(gspca_dev, 0xfaa6); -} - -/* Is this really needed? - * i added some module parameters for test with some users */ -static void poll_sensor(struct gspca_dev *gspca_dev) -{ - static const u8 poll1[] = - {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, - 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, - 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, - 0x60, 0x14}; - static const u8 poll2[] = - {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, - 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; - static const u8 noise03[] = /* (some differences / ms-drv) */ - {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, - 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, - 0xc2, 0x80, 0xc3, 0x10}; - - PDEBUG(D_STREAM, "[Sensor requires polling]"); - reg_w_buf(gspca_dev, poll1, sizeof poll1); - reg_w_buf(gspca_dev, poll2, sizeof poll2); - reg_w_buf(gspca_dev, noise03, sizeof noise03); -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - const struct additional_sensor_data *sensor; - int i, mode; - u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; - static const u8 t3[] = - { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 }; - - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - switch (mode) { - case 0: /* 640x480 (0x00) */ - break; - case 1: /* 352x288 */ - t2[1] = 0x40; - break; - case 2: /* 320x240 */ - t2[1] = 0x10; - break; - case 3: /* 176x144 */ - t2[1] = 0x50; - break; - default: -/* case 4: * 160x120 */ - t2[1] = 0x20; - break; - } - - switch (sd->sensor) { - case SENSOR_OM6802: - om6802_sensor_init(gspca_dev); - break; - case SENSOR_TAS5130A: - i = 0; - for (;;) { - reg_w_buf(gspca_dev, tas5130a_sensor_init[i], - sizeof tas5130a_sensor_init[0]); - if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1) - break; - i++; - } - reg_w(gspca_dev, 0x3c80); - /* just in case and to keep sync with logs (for mine) */ - reg_w_buf(gspca_dev, tas5130a_sensor_init[i], - sizeof tas5130a_sensor_init[0]); - reg_w(gspca_dev, 0x3c80); - break; - } - sensor = &sensor_data[sd->sensor]; - setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq)); - reg_r(gspca_dev, 0x0012); - reg_w_buf(gspca_dev, t2, sizeof t2); - reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); - reg_w(gspca_dev, 0x0013); - msleep(15); - reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); - reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); - - if (sd->sensor == SENSOR_OM6802) - poll_sensor(gspca_dev); - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, - sizeof sensor_data[sd->sensor].stream); - reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, - sizeof sensor_data[sd->sensor].stream); - if (sd->sensor == SENSOR_OM6802) { - msleep(20); - reg_w(gspca_dev, 0x0309); - } -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - /* If the last button state is pressed, release it now! */ - if (sd->button_pressed) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - sd->button_pressed = 0; - } -#endif -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int pkt_type; - - if (data[0] == 0x5a) { -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - if (len > 20) { - u8 state = (data[20] & 0x80) ? 1 : 0; - if (sd->button_pressed != state) { - input_report_key(gspca_dev->input_dev, - KEY_CAMERA, state); - input_sync(gspca_dev->input_dev); - sd->button_pressed = state; - } - } -#endif - /* Control Packet, after this came the header again, - * but extra bytes came in the packet before this, - * sometimes an EOF arrives, sometimes not... */ - return; - } - data += 2; - len -= 2; - if (data[0] == 0xff && data[1] == 0xd8) - pkt_type = FIRST_PACKET; - else if (data[len - 2] == 0xff && data[len - 1] == 0xd9) - pkt_type = LAST_PACKET; - else - pkt_type = INTER_PACKET; - gspca_frame_add(gspca_dev, pkt_type, data, len); -} - -static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - s32 red_gain, blue_gain, green_gain; - - gspca_dev->usb_err = 0; - - switch (ctrl->id) { - case V4L2_CID_AUTO_WHITE_BALANCE: - red_gain = reg_r(gspca_dev, 0x0087); - if (red_gain > 0x40) - red_gain = 0x40; - else if (red_gain < 0x10) - red_gain = 0x10; - - blue_gain = reg_r(gspca_dev, 0x0088); - if (blue_gain > 0x40) - blue_gain = 0x40; - else if (blue_gain < 0x10) - blue_gain = 0x10; - - green_gain = reg_r(gspca_dev, 0x0089); - if (green_gain > 0x40) - green_gain = 0x40; - else if (green_gain < 0x10) - green_gain = 0x10; - - sd->gain->val = green_gain; - sd->red_balance->val = red_gain - green_gain; - sd->blue_balance->val = blue_gain - green_gain; - break; - } - return 0; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAMMA: - setgamma(gspca_dev, ctrl->val); - break; - case V4L2_CID_HFLIP: - setmirror(gspca_dev, ctrl->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setfreq(gspca_dev, ctrl->val); - break; - case V4L2_CID_BACKLIGHT_COMPENSATION: - reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e); - break; - case V4L2_CID_AUTO_WHITE_BALANCE: - setawb_n_RGB(gspca_dev); - break; - case V4L2_CID_COLORFX: - seteffect(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .g_volatile_ctrl = sd_g_volatile_ctrl, - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 12); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 14, 1, 8); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 0x0d, 1, 7); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 0, 0xf, 1, 5); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10); - /* Activate lowlight, some apps dont bring up the - backlight_compensation control) */ - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1); - if (sd->sensor == SENSOR_TAS5130A) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); - sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20); - sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0); - sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 15, 1, 6); - v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH, - ~((1 << V4L2_COLORFX_NONE) | - (1 << V4L2_COLORFX_BW) | - (1 << V4L2_COLORFX_SEPIA) | - (1 << V4L2_COLORFX_SKETCH) | - (1 << V4L2_COLORFX_NEGATIVE)), - V4L2_COLORFX_NONE); - sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - - v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true); - - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .other_input = 1, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x17a1, 0x0128)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c deleted file mode 100644 index a6055246cb9d..000000000000 --- a/drivers/media/video/gspca/topro.c +++ /dev/null @@ -1,4969 +0,0 @@ -/* - * Topro TP6800/6810 webcam driver. - * - * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr) - * Copyright (C) 2009 Anders Blomdell (anders.blomdell@control.lth.se) - * Copyright (C) 2008 Thomas Champagne (lafeuil@gmail.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; If not, see <http://www.gnu.org/licenses/>. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "gspca.h" - -MODULE_DESCRIPTION("Topro TP6800/6810 gspca webcam driver"); -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " - "Anders Blomdell <anders.blomdell@control.lth.se>"); -MODULE_LICENSE("GPL"); - -static int force_sensor = -1; - -/* JPEG header */ -static const u8 jpeg_head[] = { - 0xff, 0xd8, /* jpeg */ - -/* quantization table quality 50% */ - 0xff, 0xdb, 0x00, 0x84, /* DQT */ -0, -#define JPEG_QT0_OFFSET 7 - 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, -1, -#define JPEG_QT1_OFFSET 72 - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - - /* Define Huffman table (thanks to Thomas Kaiser) */ - 0xff, 0xc4, 0x01, 0x5e, - 0x00, 0x00, 0x02, 0x03, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, - 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x06, 0x01, 0x00, 0x00, 0x57, - 0x01, 0x02, 0x03, 0x00, 0x11, 0x04, 0x12, 0x21, - 0x31, 0x13, 0x41, 0x51, 0x61, 0x05, 0x22, 0x32, - 0x14, 0x71, 0x81, 0x91, 0x15, 0x23, 0x42, 0x52, - 0x62, 0xa1, 0xb1, 0x06, 0x33, 0x72, 0xc1, 0xd1, - 0x24, 0x43, 0x53, 0x82, 0x16, 0x34, 0x92, 0xa2, - 0xe1, 0xf1, 0xf0, 0x07, 0x08, 0x17, 0x18, 0x25, - 0x26, 0x27, 0x28, 0x35, 0x36, 0x37, 0x38, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x83, 0x84, 0x85, - 0x86, 0x87, 0x88, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xb2, - 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xe2, 0xe3, 0xe4, 0xe5, - 0xe6, 0xe7, 0xe8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, - 0xf7, 0xf8, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x11, 0x00, 0x02, - 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, - 0x04, 0x06, 0x01, 0x00, 0x00, 0x57, 0x00, 0x01, - 0x11, 0x02, 0x21, 0x03, 0x12, 0x31, 0x41, 0x13, - 0x22, 0x51, 0x61, 0x04, 0x32, 0x71, 0x05, 0x14, - 0x23, 0x42, 0x33, 0x52, 0x81, 0x91, 0xa1, 0xb1, - 0xf0, 0x06, 0x15, 0xc1, 0xd1, 0xe1, 0x24, 0x43, - 0x62, 0xf1, 0x16, 0x25, 0x34, 0x53, 0x72, 0x82, - 0x92, 0x07, 0x08, 0x17, 0x18, 0x26, 0x27, 0x28, - 0x35, 0x36, 0x37, 0x38, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x54, 0x55, 0x56, 0x57, 0x58, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x68, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, - 0xd7, 0xd8, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */ - 0x08, /* data precision */ -#define JPEG_HEIGHT_OFFSET 493 - 0x01, 0xe0, /* height */ - 0x02, 0x80, /* width */ - 0x03, /* component number */ - 0x01, - 0x21, /* samples Y = jpeg 422 */ - 0x00, /* quant Y */ - 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ - 0x03, 0x11, 0x01, - - 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */ - 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 -#define JPEG_HDR_SZ 521 -}; - -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct v4l2_ctrl *jpegqual; - struct v4l2_ctrl *sharpness; - struct v4l2_ctrl *gamma; - struct v4l2_ctrl *blue; - struct v4l2_ctrl *red; - - u8 framerate; - u8 quality; /* webcam current JPEG quality (0..16) */ - s8 ag_cnt; /* autogain / start counter for tp6810 */ -#define AG_CNT_START 13 /* check gain every N frames */ - - u8 bridge; - u8 sensor; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; - -enum bridges { - BRIDGE_TP6800, - BRIDGE_TP6810, -}; - -enum sensors { - SENSOR_CX0342, - SENSOR_SOI763A, /* ~= ov7630 / ov7648 */ - NSENSORS -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG} -}; - -/* - * JPEG quality - * index: webcam compression - * value: JPEG quality in % - */ -static const u8 jpeg_q[17] = { - 88, 77, 67, 57, 55, 55, 45, 45, 36, 36, 30, 30, 26, 26, 22, 22, 94 -}; - -#define BULK_OUT_SIZE 0x20 -#if BULK_OUT_SIZE > USB_BUF_SZ -#error "USB buffer too small" -#endif - -static const u8 rates[] = {30, 20, 15, 10, 7, 5}; -static const struct framerates framerates[] = { - { - .rates = rates, - .nrates = ARRAY_SIZE(rates) - }, - { - .rates = rates, - .nrates = ARRAY_SIZE(rates) - } -}; -static const u8 rates_6810[] = {30, 15, 10, 7, 5}; -static const struct framerates framerates_6810[] = { - { - .rates = rates_6810, - .nrates = ARRAY_SIZE(rates_6810) - }, - { - .rates = rates_6810, - .nrates = ARRAY_SIZE(rates_6810) - } -}; - -/* - * webcam quality in % - * the last value is the ultra fine quality - */ - -/* TP6800 register offsets */ -#define TP6800_R10_SIF_TYPE 0x10 -#define TP6800_R11_SIF_CONTROL 0x11 -#define TP6800_R12_SIF_ADDR_S 0x12 -#define TP6800_R13_SIF_TX_DATA 0x13 -#define TP6800_R14_SIF_RX_DATA 0x14 -#define TP6800_R15_GPIO_PU 0x15 -#define TP6800_R16_GPIO_PD 0x16 -#define TP6800_R17_GPIO_IO 0x17 -#define TP6800_R18_GPIO_DATA 0x18 -#define TP6800_R19_SIF_ADDR_S2 0x19 -#define TP6800_R1A_SIF_TX_DATA2 0x1a -#define TP6800_R1B_SIF_RX_DATA2 0x1b -#define TP6800_R21_ENDP_1_CTL 0x21 -#define TP6800_R2F_TIMING_CFG 0x2f -#define TP6800_R30_SENSOR_CFG 0x30 -#define TP6800_R31_PIXEL_START 0x31 -#define TP6800_R32_PIXEL_END_L 0x32 -#define TP6800_R33_PIXEL_END_H 0x33 -#define TP6800_R34_LINE_START 0x34 -#define TP6800_R35_LINE_END_L 0x35 -#define TP6800_R36_LINE_END_H 0x36 -#define TP6800_R37_FRONT_DARK_ST 0x37 -#define TP6800_R38_FRONT_DARK_END 0x38 -#define TP6800_R39_REAR_DARK_ST_L 0x39 -#define TP6800_R3A_REAR_DARK_ST_H 0x3a -#define TP6800_R3B_REAR_DARK_END_L 0x3b -#define TP6800_R3C_REAR_DARK_END_H 0x3c -#define TP6800_R3D_HORIZ_DARK_LINE_L 0x3d -#define TP6800_R3E_HORIZ_DARK_LINE_H 0x3e -#define TP6800_R3F_FRAME_RATE 0x3f -#define TP6800_R50 0x50 -#define TP6800_R51 0x51 -#define TP6800_R52 0x52 -#define TP6800_R53 0x53 -#define TP6800_R54_DARK_CFG 0x54 -#define TP6800_R55_GAMMA_R 0x55 -#define TP6800_R56_GAMMA_G 0x56 -#define TP6800_R57_GAMMA_B 0x57 -#define TP6800_R5C_EDGE_THRLD 0x5c -#define TP6800_R5D_DEMOSAIC_CFG 0x5d -#define TP6800_R78_FORMAT 0x78 -#define TP6800_R79_QUALITY 0x79 -#define TP6800_R7A_BLK_THRLD 0x7a - -/* CX0342 register offsets */ - -#define CX0342_SENSOR_ID 0x00 -#define CX0342_VERSION_NO 0x01 -#define CX0342_ORG_X_L 0x02 -#define CX0342_ORG_X_H 0x03 -#define CX0342_ORG_Y_L 0x04 -#define CX0342_ORG_Y_H 0x05 -#define CX0342_STOP_X_L 0x06 -#define CX0342_STOP_X_H 0x07 -#define CX0342_STOP_Y_L 0x08 -#define CX0342_STOP_Y_H 0x09 -#define CX0342_FRAME_WIDTH_L 0x0a -#define CX0342_FRAME_WIDTH_H 0x0b -#define CX0342_FRAME_HEIGH_L 0x0c -#define CX0342_FRAME_HEIGH_H 0x0d -#define CX0342_EXPO_LINE_L 0x10 -#define CX0342_EXPO_LINE_H 0x11 -#define CX0342_EXPO_CLK_L 0x12 -#define CX0342_EXPO_CLK_H 0x13 -#define CX0342_RAW_GRGAIN_L 0x14 -#define CX0342_RAW_GRGAIN_H 0x15 -#define CX0342_RAW_GBGAIN_L 0x16 -#define CX0342_RAW_GBGAIN_H 0x17 -#define CX0342_RAW_RGAIN_L 0x18 -#define CX0342_RAW_RGAIN_H 0x19 -#define CX0342_RAW_BGAIN_L 0x1a -#define CX0342_RAW_BGAIN_H 0x1b -#define CX0342_GLOBAL_GAIN 0x1c -#define CX0342_SYS_CTRL_0 0x20 -#define CX0342_SYS_CTRL_1 0x21 -#define CX0342_SYS_CTRL_2 0x22 -#define CX0342_BYPASS_MODE 0x23 -#define CX0342_SYS_CTRL_3 0x24 -#define CX0342_TIMING_EN 0x25 -#define CX0342_OUTPUT_CTRL 0x26 -#define CX0342_AUTO_ADC_CALIB 0x27 -#define CX0342_SYS_CTRL_4 0x28 -#define CX0342_ADCGN 0x30 -#define CX0342_SLPCR 0x31 -#define CX0342_SLPFN_LO 0x32 -#define CX0342_ADC_CTL 0x33 -#define CX0342_LVRST_BLBIAS 0x34 -#define CX0342_VTHSEL 0x35 -#define CX0342_RAMP_RIV 0x36 -#define CX0342_LDOSEL 0x37 -#define CX0342_CLOCK_GEN 0x40 -#define CX0342_SOFT_RESET 0x41 -#define CX0342_PLL 0x42 -#define CX0342_DR_ENH_PULSE_OFFSET_L 0x43 -#define CX0342_DR_ENH_PULSE_OFFSET_H 0x44 -#define CX0342_DR_ENH_PULSE_POS_L 0x45 -#define CX0342_DR_ENH_PULSE_POS_H 0x46 -#define CX0342_DR_ENH_PULSE_WIDTH 0x47 -#define CX0342_AS_CURRENT_CNT_L 0x48 -#define CX0342_AS_CURRENT_CNT_H 0x49 -#define CX0342_AS_PREVIOUS_CNT_L 0x4a -#define CX0342_AS_PREVIOUS_CNT_H 0x4b -#define CX0342_SPV_VALUE_L 0x4c -#define CX0342_SPV_VALUE_H 0x4d -#define CX0342_GPXLTHD_L 0x50 -#define CX0342_GPXLTHD_H 0x51 -#define CX0342_RBPXLTHD_L 0x52 -#define CX0342_RBPXLTHD_H 0x53 -#define CX0342_PLANETHD_L 0x54 -#define CX0342_PLANETHD_H 0x55 -#define CX0342_ROWDARK_TH 0x56 -#define CX0342_ROWDARK_TOL 0x57 -#define CX0342_RB_GAP_L 0x58 -#define CX0342_RB_GAP_H 0x59 -#define CX0342_G_GAP_L 0x5a -#define CX0342_G_GAP_H 0x5b -#define CX0342_AUTO_ROW_DARK 0x60 -#define CX0342_MANUAL_DARK_VALUE 0x61 -#define CX0342_GB_DARK_OFFSET 0x62 -#define CX0342_GR_DARK_OFFSET 0x63 -#define CX0342_RED_DARK_OFFSET 0x64 -#define CX0342_BLUE_DARK_OFFSET 0x65 -#define CX0342_DATA_SCALING_MULTI 0x66 -#define CX0342_AUTOD_Q_FRAME 0x67 -#define CX0342_AUTOD_ALLOW_VARI 0x68 -#define CX0342_AUTO_DARK_VALUE_L 0x69 -#define CX0342_AUTO_DARK_VALUE_H 0x6a -#define CX0342_IO_CTRL_0 0x70 -#define CX0342_IO_CTRL_1 0x71 -#define CX0342_IO_CTRL_2 0x72 -#define CX0342_IDLE_CTRL 0x73 -#define CX0342_TEST_MODE 0x74 -#define CX0342_FRAME_FIX_DATA_TEST 0x75 -#define CX0342_FRAME_CNT_TEST 0x76 -#define CX0342_RST_OVERFLOW_L 0x80 -#define CX0342_RST_OVERFLOW_H 0x81 -#define CX0342_RST_UNDERFLOW_L 0x82 -#define CX0342_RST_UNDERFLOW_H 0x83 -#define CX0342_DATA_OVERFLOW_L 0x84 -#define CX0342_DATA_OVERFLOW_H 0x85 -#define CX0342_DATA_UNDERFLOW_L 0x86 -#define CX0342_DATA_UNDERFLOW_H 0x87 -#define CX0342_CHANNEL_0_0_L_irst 0x90 -#define CX0342_CHANNEL_0_0_H_irst 0x91 -#define CX0342_CHANNEL_0_1_L_irst 0x92 -#define CX0342_CHANNEL_0_1_H_irst 0x93 -#define CX0342_CHANNEL_0_2_L_irst 0x94 -#define CX0342_CHANNEL_0_2_H_irst 0x95 -#define CX0342_CHANNEL_0_3_L_irst 0x96 -#define CX0342_CHANNEL_0_3_H_irst 0x97 -#define CX0342_CHANNEL_0_4_L_irst 0x98 -#define CX0342_CHANNEL_0_4_H_irst 0x99 -#define CX0342_CHANNEL_0_5_L_irst 0x9a -#define CX0342_CHANNEL_0_5_H_irst 0x9b -#define CX0342_CHANNEL_0_6_L_irst 0x9c -#define CX0342_CHANNEL_0_6_H_irst 0x9d -#define CX0342_CHANNEL_0_7_L_irst 0x9e -#define CX0342_CHANNEL_0_7_H_irst 0x9f -#define CX0342_CHANNEL_1_0_L_itx 0xa0 -#define CX0342_CHANNEL_1_0_H_itx 0xa1 -#define CX0342_CHANNEL_1_1_L_itx 0xa2 -#define CX0342_CHANNEL_1_1_H_itx 0xa3 -#define CX0342_CHANNEL_1_2_L_itx 0xa4 -#define CX0342_CHANNEL_1_2_H_itx 0xa5 -#define CX0342_CHANNEL_1_3_L_itx 0xa6 -#define CX0342_CHANNEL_1_3_H_itx 0xa7 -#define CX0342_CHANNEL_1_4_L_itx 0xa8 -#define CX0342_CHANNEL_1_4_H_itx 0xa9 -#define CX0342_CHANNEL_1_5_L_itx 0xaa -#define CX0342_CHANNEL_1_5_H_itx 0xab -#define CX0342_CHANNEL_1_6_L_itx 0xac -#define CX0342_CHANNEL_1_6_H_itx 0xad -#define CX0342_CHANNEL_1_7_L_itx 0xae -#define CX0342_CHANNEL_1_7_H_itx 0xaf -#define CX0342_CHANNEL_2_0_L_iwl 0xb0 -#define CX0342_CHANNEL_2_0_H_iwl 0xb1 -#define CX0342_CHANNEL_2_1_L_iwl 0xb2 -#define CX0342_CHANNEL_2_1_H_iwl 0xb3 -#define CX0342_CHANNEL_2_2_L_iwl 0xb4 -#define CX0342_CHANNEL_2_2_H_iwl 0xb5 -#define CX0342_CHANNEL_2_3_L_iwl 0xb6 -#define CX0342_CHANNEL_2_3_H_iwl 0xb7 -#define CX0342_CHANNEL_2_4_L_iwl 0xb8 -#define CX0342_CHANNEL_2_4_H_iwl 0xb9 -#define CX0342_CHANNEL_2_5_L_iwl 0xba -#define CX0342_CHANNEL_2_5_H_iwl 0xbb -#define CX0342_CHANNEL_2_6_L_iwl 0xbc -#define CX0342_CHANNEL_2_6_H_iwl 0xbd -#define CX0342_CHANNEL_2_7_L_iwl 0xbe -#define CX0342_CHANNEL_2_7_H_iwl 0xbf -#define CX0342_CHANNEL_3_0_L_ensp 0xc0 -#define CX0342_CHANNEL_3_0_H_ensp 0xc1 -#define CX0342_CHANNEL_3_1_L_ensp 0xc2 -#define CX0342_CHANNEL_3_1_H_ensp 0xc3 -#define CX0342_CHANNEL_3_2_L_ensp 0xc4 -#define CX0342_CHANNEL_3_2_H_ensp 0xc5 -#define CX0342_CHANNEL_3_3_L_ensp 0xc6 -#define CX0342_CHANNEL_3_3_H_ensp 0xc7 -#define CX0342_CHANNEL_3_4_L_ensp 0xc8 -#define CX0342_CHANNEL_3_4_H_ensp 0xc9 -#define CX0342_CHANNEL_3_5_L_ensp 0xca -#define CX0342_CHANNEL_3_5_H_ensp 0xcb -#define CX0342_CHANNEL_3_6_L_ensp 0xcc -#define CX0342_CHANNEL_3_6_H_ensp 0xcd -#define CX0342_CHANNEL_3_7_L_ensp 0xce -#define CX0342_CHANNEL_3_7_H_ensp 0xcf -#define CX0342_CHANNEL_4_0_L_sela 0xd0 -#define CX0342_CHANNEL_4_0_H_sela 0xd1 -#define CX0342_CHANNEL_4_1_L_sela 0xd2 -#define CX0342_CHANNEL_4_1_H_sela 0xd3 -#define CX0342_CHANNEL_5_0_L_intla 0xe0 -#define CX0342_CHANNEL_5_0_H_intla 0xe1 -#define CX0342_CHANNEL_5_1_L_intla 0xe2 -#define CX0342_CHANNEL_5_1_H_intla 0xe3 -#define CX0342_CHANNEL_5_2_L_intla 0xe4 -#define CX0342_CHANNEL_5_2_H_intla 0xe5 -#define CX0342_CHANNEL_5_3_L_intla 0xe6 -#define CX0342_CHANNEL_5_3_H_intla 0xe7 -#define CX0342_CHANNEL_6_0_L_xa_sel_pos 0xf0 -#define CX0342_CHANNEL_6_0_H_xa_sel_pos 0xf1 -#define CX0342_CHANNEL_7_1_L_cds_pos 0xf2 -#define CX0342_CHANNEL_7_1_H_cds_pos 0xf3 -#define CX0342_SENSOR_HEIGHT_L 0xfb -#define CX0342_SENSOR_HEIGHT_H 0xfc -#define CX0342_SENSOR_WIDTH_L 0xfd -#define CX0342_SENSOR_WIDTH_H 0xfe -#define CX0342_VSYNC_HSYNC_READ 0xff - -struct cmd { - u8 reg; - u8 val; -}; - -static const u8 DQT[17][130] = { - /* Define quantization table (thanks to Thomas Kaiser) */ - { /* Quality 0 */ - 0x00, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x01, - 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0b, 0x06, - 0x06, 0x0b, 0x18, 0x10, 0x0e, 0x10, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - }, - { /* Quality 1 */ - 0x00, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x01, - 0x08, 0x09, 0x09, 0x0c, 0x0a, 0x0c, 0x17, 0x0d, - 0x0d, 0x17, 0x31, 0x21, 0x1c, 0x21, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - }, - { /* Quality 2 */ - 0x00, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x06, 0x06, 0x06, 0x04, 0x04, 0x04, - 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x01, - 0x0c, 0x0d, 0x0d, 0x12, 0x0f, 0x12, 0x23, 0x13, - 0x13, 0x23, 0x4a, 0x31, 0x2a, 0x31, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, - }, - { /* Quality 3 */ - 0x00, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, - 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x01, - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - }, - { /* Quality 4 */ - 0x00, - 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x0a, 0x0a, 0x0a, 0x05, 0x05, 0x05, - 0x05, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x01, - 0x11, 0x16, 0x16, 0x1e, 0x1a, 0x1e, 0x3a, 0x20, - 0x20, 0x3a, 0x7b, 0x52, 0x46, 0x52, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - }, - { /* Quality 5 */ - 0x00, - 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x06, 0x06, 0x06, - 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x01, - 0x11, 0x1b, 0x1b, 0x24, 0x1f, 0x24, 0x46, 0x27, - 0x27, 0x46, 0x94, 0x63, 0x54, 0x63, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - }, - { /* Quality 6 */ - 0x00, - 0x05, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, - 0x07, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x01, - 0x15, 0x1f, 0x1f, 0x2a, 0x24, 0x2a, 0x52, 0x2d, - 0x2d, 0x52, 0xad, 0x73, 0x62, 0x73, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, - }, - { /* Quality 7 */ - 0x00, - 0x05, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, - 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x26, 0x26, 0x26, 0x26, 0x26, - 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, - 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, - 0x01, - 0x15, 0x24, 0x24, 0x30, 0x2a, 0x30, 0x5e, 0x34, - 0x34, 0x5e, 0xc6, 0x84, 0x70, 0x84, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - }, - { /* Quality 8 */ - 0x00, - 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x0a, 0x0a, - 0x0a, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x14, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x01, - 0x19, 0x2d, 0x2d, 0x3c, 0x34, 0x3c, 0x75, 0x41, - 0x41, 0x75, 0xf7, 0xa5, 0x8c, 0xa5, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - }, - { /* Quality 9 */ - 0x00, - 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x0c, - 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x01, - 0x19, 0x36, 0x36, 0x48, 0x3f, 0x48, 0x8d, 0x4e, - 0x4e, 0x8d, 0xff, 0xc6, 0xa8, 0xc6, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 10 */ - 0x00, - 0x07, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x1c, 0x1c, 0x1c, 0x0e, 0x0e, 0x0e, - 0x0e, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x01, - 0x1d, 0x3f, 0x3f, 0x54, 0x49, 0x54, 0xa4, 0x5b, - 0x5b, 0xa4, 0xff, 0xe7, 0xc4, 0xe7, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 11 */ - 0x00, - 0x07, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, - 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, - 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, - 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, - 0x01, - 0x1d, 0x48, 0x48, 0x60, 0x54, 0x60, 0xbc, 0x68, - 0x68, 0xbc, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 12 */ - 0x00, - 0x08, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0x28, 0x28, 0x28, 0x14, 0x14, 0x14, - 0x14, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x28, 0x28, 0x28, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, - 0x01, - 0x22, 0x5a, 0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82, - 0x82, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 13 */ - 0x00, - 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, - 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x01, - 0x22, 0x6c, 0x6c, 0x90, 0x7e, 0x90, 0xff, 0x9c, - 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 14 */ - 0x00, - 0x0a, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x38, 0x38, 0x38, 0x1c, 0x1c, 0x1c, - 0x1c, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, - 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, - 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, - 0x38, 0x38, 0x38, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x01, - 0x2a, 0x7e, 0x7e, 0xa8, 0x93, 0xa8, 0xff, 0xb6, - 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 15 */ - 0x00, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, - 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x01, - 0x2a, 0x90, 0x90, 0xc0, 0xa8, 0xc0, 0xff, 0xd0, - 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }, - { /* Quality 16-31 */ - 0x00, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x01, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - } -}; - -static const struct cmd tp6810_cx_init_common[] = { - {0x1c, 0x00}, - {TP6800_R10_SIF_TYPE, 0x00}, - {0x4e, 0x00}, - {0x4f, 0x00}, - {TP6800_R50, 0xff}, - {TP6800_R51, 0x03}, - {0x00, 0x07}, - {TP6800_R79_QUALITY, 0x03}, - {TP6800_R2F_TIMING_CFG, 0x37}, - {TP6800_R30_SENSOR_CFG, 0x10}, - {TP6800_R21_ENDP_1_CTL, 0x00}, - {TP6800_R52, 0x40}, - {TP6800_R53, 0x40}, - {TP6800_R54_DARK_CFG, 0x40}, - {TP6800_R30_SENSOR_CFG, 0x18}, - {0x4b, 0x00}, - {TP6800_R3F_FRAME_RATE, 0x83}, - {TP6800_R79_QUALITY, 0x05}, - {TP6800_R21_ENDP_1_CTL, 0x00}, - {0x7c, 0x04}, - {0x25, 0x14}, - {0x26, 0x0f}, - {0x7b, 0x10}, -}; - -static const struct cmd tp6810_ov_init_common[] = { - {0x1c, 0x00}, - {TP6800_R10_SIF_TYPE, 0x00}, - {0x4e, 0x00}, - {0x4f, 0x00}, - {TP6800_R50, 0xff}, - {TP6800_R51, 0x03}, - {0x00, 0x07}, - {TP6800_R52, 0x40}, - {TP6800_R53, 0x40}, - {TP6800_R54_DARK_CFG, 0x40}, - {TP6800_R79_QUALITY, 0x03}, - {TP6800_R2F_TIMING_CFG, 0x17}, - {TP6800_R30_SENSOR_CFG, 0x18}, - {TP6800_R21_ENDP_1_CTL, 0x00}, - {TP6800_R3F_FRAME_RATE, 0x86}, - {0x25, 0x18}, - {0x26, 0x0f}, - {0x7b, 0x90}, -}; - -static const struct cmd tp6810_bridge_start[] = { - {0x59, 0x88}, - {0x5a, 0x0f}, - {0x5b, 0x4e}, - {TP6800_R5C_EDGE_THRLD, 0x63}, - {TP6800_R5D_DEMOSAIC_CFG, 0x00}, - {0x03, 0x7f}, - {0x04, 0x80}, - {0x06, 0x00}, - {0x00, 0x00}, -}; - -static const struct cmd tp6810_late_start[] = { - {0x7d, 0x01}, - {0xb0, 0x04}, - {0xb1, 0x04}, - {0xb2, 0x04}, - {0xb3, 0x04}, - {0xb4, 0x04}, - {0xb5, 0x04}, - {0xb6, 0x08}, - {0xb7, 0x08}, - {0xb8, 0x04}, - {0xb9, 0x04}, - {0xba, 0x04}, - {0xbb, 0x04}, - {0xbc, 0x04}, - {0xbd, 0x08}, - {0xbe, 0x08}, - {0xbf, 0x08}, - {0xc0, 0x04}, - {0xc1, 0x04}, - {0xc2, 0x08}, - {0xc3, 0x08}, - {0xc4, 0x08}, - {0xc5, 0x08}, - {0xc6, 0x08}, - {0xc7, 0x13}, - {0xc8, 0x04}, - {0xc9, 0x08}, - {0xca, 0x08}, - {0xcb, 0x08}, - {0xcc, 0x08}, - {0xcd, 0x08}, - {0xce, 0x13}, - {0xcf, 0x13}, - {0xd0, 0x08}, - {0xd1, 0x08}, - {0xd2, 0x08}, - {0xd3, 0x08}, - {0xd4, 0x08}, - {0xd5, 0x13}, - {0xd6, 0x13}, - {0xd7, 0x13}, - {0xd8, 0x08}, - {0xd9, 0x08}, - {0xda, 0x08}, - {0xdb, 0x08}, - {0xdc, 0x13}, - {0xdd, 0x13}, - {0xde, 0x13}, - {0xdf, 0x13}, - {0xe0, 0x08}, - {0xe1, 0x08}, - {0xe2, 0x08}, - {0xe3, 0x13}, - {0xe4, 0x13}, - {0xe5, 0x13}, - {0xe6, 0x13}, - {0xe7, 0x13}, - {0xe8, 0x08}, - {0xe9, 0x08}, - {0xea, 0x13}, - {0xeb, 0x13}, - {0xec, 0x13}, - {0xed, 0x13}, - {0xee, 0x13}, - {0xef, 0x13}, - {0x7d, 0x02}, - - /* later after isoc start */ - {0x7d, 0x08}, - {0x7d, 0x00}, -}; - -static const struct cmd cx0342_timing_seq[] = { - {CX0342_CHANNEL_0_1_L_irst, 0x20}, - {CX0342_CHANNEL_0_2_L_irst, 0x24}, - {CX0342_CHANNEL_0_2_H_irst, 0x00}, - {CX0342_CHANNEL_0_3_L_irst, 0x2f}, - {CX0342_CHANNEL_0_3_H_irst, 0x00}, - {CX0342_CHANNEL_1_0_L_itx, 0x02}, - {CX0342_CHANNEL_1_0_H_itx, 0x00}, - {CX0342_CHANNEL_1_1_L_itx, 0x20}, - {CX0342_CHANNEL_1_1_H_itx, 0x00}, - {CX0342_CHANNEL_1_2_L_itx, 0xe4}, - {CX0342_CHANNEL_1_2_H_itx, 0x00}, - {CX0342_CHANNEL_1_3_L_itx, 0xee}, - {CX0342_CHANNEL_1_3_H_itx, 0x00}, - {CX0342_CHANNEL_2_0_L_iwl, 0x30}, - {CX0342_CHANNEL_2_0_H_iwl, 0x00}, - {CX0342_CHANNEL_3_0_L_ensp, 0x34}, - {CX0342_CHANNEL_3_1_L_ensp, 0xe2}, - {CX0342_CHANNEL_3_1_H_ensp, 0x00}, - {CX0342_CHANNEL_3_2_L_ensp, 0xf6}, - {CX0342_CHANNEL_3_2_H_ensp, 0x00}, - {CX0342_CHANNEL_3_3_L_ensp, 0xf4}, - {CX0342_CHANNEL_3_3_H_ensp, 0x02}, - {CX0342_CHANNEL_4_0_L_sela, 0x26}, - {CX0342_CHANNEL_4_0_H_sela, 0x00}, - {CX0342_CHANNEL_4_1_L_sela, 0xe2}, - {CX0342_CHANNEL_4_1_H_sela, 0x00}, - {CX0342_CHANNEL_5_0_L_intla, 0x26}, - {CX0342_CHANNEL_5_1_L_intla, 0x29}, - {CX0342_CHANNEL_5_2_L_intla, 0xf0}, - {CX0342_CHANNEL_5_2_H_intla, 0x00}, - {CX0342_CHANNEL_5_3_L_intla, 0xf3}, - {CX0342_CHANNEL_5_3_H_intla, 0x00}, - {CX0342_CHANNEL_6_0_L_xa_sel_pos, 0x24}, - {CX0342_CHANNEL_7_1_L_cds_pos, 0x02}, - {CX0342_TIMING_EN, 0x01}, -}; - -/* define the JPEG header */ -static void jpeg_define(u8 *jpeg_hdr, - int height, - int width) -{ - memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head); - jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width; -} - -/* set the JPEG quality for sensor soi763a */ -static void jpeg_set_qual(u8 *jpeg_hdr, - int quality) -{ - int i, sc; - - if (quality < 50) - sc = 5000 / quality; - else - sc = 200 - quality * 2; - for (i = 0; i < 64; i++) { - jpeg_hdr[JPEG_QT0_OFFSET + i] = - (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; - jpeg_hdr[JPEG_QT1_OFFSET + i] = - (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; - } -} - -static void reg_w(struct gspca_dev *gspca_dev, u8 index, u8 value) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x0e, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -/* the returned value is in gspca_dev->usb_buf */ -static void reg_r(struct gspca_dev *gspca_dev, u8 index) -{ - struct usb_device *dev = gspca_dev->dev; - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x0d, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, gspca_dev->usb_buf, 1, 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static void reg_w_buf(struct gspca_dev *gspca_dev, - const struct cmd *p, int l) -{ - do { - reg_w(gspca_dev, p->reg, p->val); - p++; - } while (--l > 0); -} - -static int i2c_w(struct gspca_dev *gspca_dev, u8 index, u8 value) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00); - reg_w(gspca_dev, TP6800_R19_SIF_ADDR_S2, index); - reg_w(gspca_dev, TP6800_R13_SIF_TX_DATA, value); - reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x01); - if (sd->bridge == BRIDGE_TP6800) - return 0; - msleep(5); - reg_r(gspca_dev, TP6800_R11_SIF_CONTROL); - if (gspca_dev->usb_buf[0] == 0) - return 0; - reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00); - return -1; /* error */ -} - -static void i2c_w_buf(struct gspca_dev *gspca_dev, - const struct cmd *p, int l) -{ - do { - i2c_w(gspca_dev, p->reg, p->val); - p++; - } while (--l > 0); -} - -static int i2c_r(struct gspca_dev *gspca_dev, u8 index, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - int v; - - reg_w(gspca_dev, TP6800_R19_SIF_ADDR_S2, index); - reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x02); - msleep(5); - reg_r(gspca_dev, TP6800_R14_SIF_RX_DATA); - v = gspca_dev->usb_buf[0]; - if (sd->bridge == BRIDGE_TP6800) - return v; - if (len > 1) { - reg_r(gspca_dev, TP6800_R1B_SIF_RX_DATA2); - v |= (gspca_dev->usb_buf[0] << 8); - } - reg_r(gspca_dev, TP6800_R11_SIF_CONTROL); - if (gspca_dev->usb_buf[0] == 0) - return v; - reg_w(gspca_dev, TP6800_R11_SIF_CONTROL, 0x00); - return -1; -} - -static void bulk_w(struct gspca_dev *gspca_dev, - u8 tag, - const u8 *data, - int length) -{ - struct usb_device *dev = gspca_dev->dev; - int count, actual_count, ret; - - if (gspca_dev->usb_err < 0) - return; - for (;;) { - count = length > BULK_OUT_SIZE - 1 - ? BULK_OUT_SIZE - 1 : length; - gspca_dev->usb_buf[0] = tag; - memcpy(&gspca_dev->usb_buf[1], data, count); - ret = usb_bulk_msg(dev, - usb_sndbulkpipe(dev, 3), - gspca_dev->usb_buf, count + 1, - &actual_count, 500); - if (ret < 0) { - pr_err("bulk write error %d tag=%02x\n", - ret, tag); - gspca_dev->usb_err = ret; - return; - } - length -= count; - if (length <= 0) - break; - data += count; - } -} - -static int probe_6810(struct gspca_dev *gspca_dev) -{ - u8 gpio; - int ret; - - reg_r(gspca_dev, TP6800_R18_GPIO_DATA); - gpio = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x04); /* i2c 16 bits */ - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x21); /* ov??? */ - reg_w(gspca_dev, TP6800_R1A_SIF_TX_DATA2, 0x00); - if (i2c_w(gspca_dev, 0x00, 0x00) >= 0) - return SENSOR_SOI763A; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */ - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x7f); /* (unknown i2c) */ - if (i2c_w(gspca_dev, 0x00, 0x00) >= 0) - return -2; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */ - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x11); /* tas??? / hv??? */ - ret = i2c_r(gspca_dev, 0x00, 1); - if (ret > 0) - return -3; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x6e); /* po??? */ - ret = i2c_r(gspca_dev, 0x00, 1); - if (ret > 0) - return -4; - - ret = i2c_r(gspca_dev, 0x01, 1); - if (ret > 0) - return -5; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x04); /* i2c 16 bits */ - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x5d); /* mi/mt??? */ - ret = i2c_r(gspca_dev, 0x00, 2); - if (ret > 0) - return -6; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x5c); /* mi/mt??? */ - ret = i2c_r(gspca_dev, 0x36, 2); - if (ret > 0) - return -7; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x61); /* (unknown i2c) */ - reg_w(gspca_dev, TP6800_R1A_SIF_TX_DATA2, 0x10); - if (i2c_w(gspca_dev, 0xff, 0x00) >= 0) - return -8; - - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio); - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, gpio | 0x20); - reg_w(gspca_dev, TP6800_R10_SIF_TYPE, 0x00); /* i2c 8 bits */ - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20); /* cx0342 */ - ret = i2c_r(gspca_dev, 0x00, 1); - if (ret > 0) - return SENSOR_CX0342; - return -9; -} - -static void cx0342_6810_init(struct gspca_dev *gspca_dev) -{ - static const struct cmd reg_init_1[] = { - {TP6800_R2F_TIMING_CFG, 0x2f}, - {0x25, 0x02}, - {TP6800_R21_ENDP_1_CTL, 0x00}, - {TP6800_R3F_FRAME_RATE, 0x80}, - {TP6800_R2F_TIMING_CFG, 0x2f}, - {TP6800_R18_GPIO_DATA, 0xe1}, - {TP6800_R18_GPIO_DATA, 0xc1}, - {TP6800_R18_GPIO_DATA, 0xe1}, - {TP6800_R11_SIF_CONTROL, 0x00}, - }; - static const struct cmd reg_init_2[] = { - {TP6800_R78_FORMAT, 0x48}, - {TP6800_R11_SIF_CONTROL, 0x00}, - }; - static const struct cmd sensor_init[] = { - {CX0342_OUTPUT_CTRL, 0x07}, - {CX0342_BYPASS_MODE, 0x58}, - {CX0342_GPXLTHD_L, 0x28}, - {CX0342_RBPXLTHD_L, 0x28}, - {CX0342_PLANETHD_L, 0x50}, - {CX0342_PLANETHD_H, 0x03}, - {CX0342_RB_GAP_L, 0xff}, - {CX0342_RB_GAP_H, 0x07}, - {CX0342_G_GAP_L, 0xff}, - {CX0342_G_GAP_H, 0x07}, - {CX0342_RST_OVERFLOW_L, 0x5c}, - {CX0342_RST_OVERFLOW_H, 0x01}, - {CX0342_DATA_OVERFLOW_L, 0xfc}, - {CX0342_DATA_OVERFLOW_H, 0x03}, - {CX0342_DATA_UNDERFLOW_L, 0x00}, - {CX0342_DATA_UNDERFLOW_H, 0x00}, - {CX0342_SYS_CTRL_0, 0x40}, - {CX0342_GLOBAL_GAIN, 0x01}, - {CX0342_CLOCK_GEN, 0x00}, - {CX0342_SYS_CTRL_0, 0x02}, - {CX0342_IDLE_CTRL, 0x05}, - {CX0342_ADCGN, 0x00}, - {CX0342_ADC_CTL, 0x00}, - {CX0342_LVRST_BLBIAS, 0x01}, - {CX0342_VTHSEL, 0x0b}, - {CX0342_RAMP_RIV, 0x0b}, - {CX0342_LDOSEL, 0x07}, - {CX0342_SPV_VALUE_L, 0x40}, - {CX0342_SPV_VALUE_H, 0x02}, - - {CX0342_AUTO_ADC_CALIB, 0x81}, - {CX0342_TIMING_EN, 0x01}, - }; - - reg_w_buf(gspca_dev, reg_init_1, ARRAY_SIZE(reg_init_1)); - reg_w_buf(gspca_dev, tp6810_cx_init_common, - ARRAY_SIZE(tp6810_cx_init_common)); - reg_w_buf(gspca_dev, reg_init_2, ARRAY_SIZE(reg_init_2)); - - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20); /* cx0342 I2C addr */ - i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init)); - i2c_w_buf(gspca_dev, cx0342_timing_seq, ARRAY_SIZE(cx0342_timing_seq)); -} - -static void soi763a_6810_init(struct gspca_dev *gspca_dev) -{ - static const struct cmd reg_init_1[] = { - {TP6800_R2F_TIMING_CFG, 0x2f}, - {TP6800_R18_GPIO_DATA, 0xe1}, - {0x25, 0x02}, - {TP6800_R21_ENDP_1_CTL, 0x00}, - {TP6800_R3F_FRAME_RATE, 0x80}, - {TP6800_R2F_TIMING_CFG, 0x2f}, - {TP6800_R18_GPIO_DATA, 0xc1}, - }; - static const struct cmd reg_init_2[] = { - {TP6800_R78_FORMAT, 0x54}, - }; - static const struct cmd sensor_init[] = { - {0x00, 0x00}, - {0x01, 0x80}, - {0x02, 0x80}, - {0x03, 0x90}, - {0x04, 0x20}, - {0x05, 0x20}, - {0x06, 0x80}, - {0x07, 0x00}, - {0x08, 0xff}, - {0x09, 0xff}, - {0x0a, 0x76}, /* 7630 = soi673a */ - {0x0b, 0x30}, - {0x0c, 0x20}, - {0x0d, 0x20}, - {0x0e, 0xff}, - {0x0f, 0xff}, - {0x10, 0x41}, - {0x15, 0x14}, - {0x11, 0x40}, - {0x12, 0x48}, - {0x13, 0x80}, - {0x14, 0x80}, - {0x16, 0x03}, - {0x28, 0xb0}, - {0x71, 0x20}, - {0x75, 0x8e}, - {0x17, 0x1b}, - {0x18, 0xbd}, - {0x19, 0x05}, - {0x1a, 0xf6}, - {0x1b, 0x04}, - {0x1c, 0x7f}, /* omnivision */ - {0x1d, 0xa2}, - {0x1e, 0x00}, - {0x1f, 0x00}, - {0x20, 0x45}, - {0x21, 0x80}, - {0x22, 0x80}, - {0x23, 0xee}, - {0x24, 0x50}, - {0x25, 0x7a}, - {0x26, 0xa0}, - {0x27, 0x9a}, - {0x29, 0x30}, - {0x2a, 0x80}, - {0x2b, 0x00}, - {0x2c, 0xac}, - {0x2d, 0x05}, - {0x2e, 0x80}, - {0x2f, 0x3c}, - {0x30, 0x22}, - {0x31, 0x00}, - {0x32, 0x86}, - {0x33, 0x08}, - {0x34, 0xff}, - {0x35, 0xff}, - {0x36, 0xff}, - {0x37, 0xff}, - {0x38, 0xff}, - {0x39, 0xff}, - {0x3a, 0xfe}, - {0x3b, 0xfe}, - {0x3c, 0xfe}, - {0x3d, 0xfe}, - {0x3e, 0xfe}, - {0x3f, 0x71}, - {0x40, 0xff}, - {0x41, 0xff}, - {0x42, 0xff}, - {0x43, 0xff}, - {0x44, 0xff}, - {0x45, 0xff}, - {0x46, 0xff}, - {0x47, 0xff}, - {0x48, 0xff}, - {0x49, 0xff}, - {0x4a, 0xfe}, - {0x4b, 0xff}, - {0x4c, 0x00}, - {0x4d, 0x00}, - {0x4e, 0xff}, - {0x4f, 0xff}, - {0x50, 0xff}, - {0x51, 0xff}, - {0x52, 0xff}, - {0x53, 0xff}, - {0x54, 0xff}, - {0x55, 0xff}, - {0x56, 0xff}, - {0x57, 0xff}, - {0x58, 0xff}, - {0x59, 0xff}, - {0x5a, 0xff}, - {0x5b, 0xfe}, - {0x5c, 0xff}, - {0x5d, 0x8f}, - {0x5e, 0xff}, - {0x5f, 0x8f}, - {0x60, 0xa2}, - {0x61, 0x4a}, - {0x62, 0xf3}, - {0x63, 0x75}, - {0x64, 0xf0}, - {0x65, 0x00}, - {0x66, 0x55}, - {0x67, 0x92}, - {0x68, 0xa0}, - {0x69, 0x4a}, - {0x6a, 0x22}, - {0x6b, 0x00}, - {0x6c, 0x33}, - {0x6d, 0x44}, - {0x6e, 0x22}, - {0x6f, 0x84}, - {0x70, 0x0b}, - {0x72, 0x10}, - {0x73, 0x50}, - {0x74, 0x21}, - {0x76, 0x00}, - {0x77, 0xa5}, - {0x78, 0x80}, - {0x79, 0x80}, - {0x7a, 0x80}, - {0x7b, 0xe2}, - {0x7c, 0x00}, - {0x7d, 0xf7}, - {0x7e, 0x00}, - {0x7f, 0x00}, - }; - - reg_w_buf(gspca_dev, reg_init_1, ARRAY_SIZE(reg_init_1)); - reg_w_buf(gspca_dev, tp6810_ov_init_common, - ARRAY_SIZE(tp6810_ov_init_common)); - reg_w_buf(gspca_dev, reg_init_2, ARRAY_SIZE(reg_init_2)); - - i2c_w(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(10); - i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init)); -} - -/* set the gain and exposure */ -static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain, - s32 blue, s32 red) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_CX0342) { - expo = (expo << 2) - 1; - i2c_w(gspca_dev, CX0342_EXPO_LINE_L, expo); - i2c_w(gspca_dev, CX0342_EXPO_LINE_H, expo >> 8); - if (sd->bridge == BRIDGE_TP6800) - i2c_w(gspca_dev, CX0342_RAW_GBGAIN_H, - gain >> 8); - i2c_w(gspca_dev, CX0342_RAW_GBGAIN_L, gain); - if (sd->bridge == BRIDGE_TP6800) - i2c_w(gspca_dev, CX0342_RAW_GRGAIN_H, - gain >> 8); - i2c_w(gspca_dev, CX0342_RAW_GRGAIN_L, gain); - if (sd->sensor == SENSOR_CX0342) { - if (sd->bridge == BRIDGE_TP6800) - i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, - blue >> 8); - i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, blue); - if (sd->bridge == BRIDGE_TP6800) - i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, - red >> 8); - i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, red); - } - i2c_w(gspca_dev, CX0342_SYS_CTRL_0, - sd->bridge == BRIDGE_TP6800 ? 0x80 : 0x81); - return; - } - - /* soi763a */ - i2c_w(gspca_dev, 0x10, /* AEC_H (exposure time) */ - expo); -/* i2c_w(gspca_dev, 0x76, 0x02); * AEC_L ([1:0] */ - i2c_w(gspca_dev, 0x00, /* gain */ - gain); -} - -/* set the JPEG quantization tables */ -static void set_dqt(struct gspca_dev *gspca_dev, u8 q) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* update the jpeg quantization tables */ - PDEBUG(D_STREAM, "q %d -> %d", sd->quality, q); - sd->quality = q; - if (q > 16) - q = 16; - if (sd->sensor == SENSOR_SOI763A) - jpeg_set_qual(sd->jpeg_hdr, jpeg_q[q]); - else - memcpy(&sd->jpeg_hdr[JPEG_QT0_OFFSET - 1], - DQT[q], sizeof DQT[0]); -} - -/* set the JPEG compression quality factor */ -static void setquality(struct gspca_dev *gspca_dev, s32 q) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (q != 16) - q = 15 - q; - - reg_w(gspca_dev, TP6800_R7A_BLK_THRLD, 0x00); - reg_w(gspca_dev, TP6800_R79_QUALITY, 0x04); - reg_w(gspca_dev, TP6800_R79_QUALITY, q); - - /* auto quality */ - if (q == 15 && sd->bridge == BRIDGE_TP6810) { - msleep(4); - reg_w(gspca_dev, TP6800_R7A_BLK_THRLD, 0x19); - } -} - -static const u8 color_null[18] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const u8 color_gain[NSENSORS][18] = { -[SENSOR_CX0342] = - {0x4c, 0x00, 0xa9, 0x00, 0x31, 0x00, /* Y R/G/B (LE values) */ - 0xb6, 0x03, 0x6c, 0x03, 0xe0, 0x00, /* U R/G/B */ - 0xdf, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */ -[SENSOR_SOI763A] = - {0x4c, 0x00, 0x95, 0x00, 0x1d, 0x00, /* Y R/G/B (LE values) */ - 0xb6, 0x03, 0x6c, 0x03, 0xd7, 0x00, /* U R/G/B */ - 0xd5, 0x00, 0x46, 0x03, 0xdc, 0x03}, /* V R/G/B */ -}; - -static void setgamma(struct gspca_dev *gspca_dev, s32 gamma) -{ - struct sd *sd = (struct sd *) gspca_dev; -#define NGAMMA 6 - static const u8 gamma_tb[NGAMMA][3][1024] = { - { /* gamma 0 - from tp6800 + soi763a */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, - 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09, - 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11, - 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17, - 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e, - 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23, - 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, - 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f, - 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34, - 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38, - 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, - 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40, - 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, - 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49, - 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, - 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50, - 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54, - 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58, - 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f, - 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, - 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65, - 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, - 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, - 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, - 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, - 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, - 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, - 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86, - 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, - 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, - 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, - 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, - 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, - 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, - 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca, - 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, - 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, - 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, - 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09, - 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11, - 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17, - 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e, - 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23, - 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, - 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f, - 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34, - 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38, - 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, - 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40, - 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, - 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49, - 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, - 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50, - 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54, - 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58, - 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f, - 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, - 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65, - 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, - 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, - 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, - 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, - 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, - 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, - 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86, - 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, - 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, - 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, - 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, - 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, - 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, - 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca, - 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, - 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, - 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, - 0x02, 0x03, 0x05, 0x07, 0x07, 0x08, 0x09, 0x09, - 0x0a, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x10, 0x11, - 0x11, 0x12, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17, - 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e, - 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x23, - 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, - 0x29, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f, - 0x2f, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x34, - 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x38, 0x38, - 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, - 0x3c, 0x3d, 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x40, - 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, - 0x45, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49, 0x49, - 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, - 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x50, - 0x52, 0x52, 0x52, 0x53, 0x53, 0x54, 0x54, 0x54, - 0x55, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58, - 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f, - 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, - 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65, - 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, - 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, - 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, - 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, - 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, - 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, - 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86, - 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, - 0x94, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, - 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, - 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, - 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, - 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, - 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca, - 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, - 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, - 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb} - }, - { /* gamma 1 - from tp6810 + soi763a */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x05, 0x07, 0x08, 0x09, 0x0a, - 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1c, 0x1e, - 0x1f, 0x20, 0x22, 0x22, 0x23, 0x25, 0x26, 0x27, - 0x27, 0x28, 0x29, 0x2b, 0x2b, 0x2c, 0x2d, 0x2f, - 0x2f, 0x30, 0x31, 0x33, 0x33, 0x34, 0x35, 0x35, - 0x37, 0x38, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, - 0x3c, 0x3d, 0x3f, 0x3f, 0x40, 0x42, 0x42, 0x43, - 0x43, 0x44, 0x45, 0x45, 0x47, 0x47, 0x48, 0x49, - 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, - 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53, - 0x54, 0x54, 0x55, 0x56, 0x56, 0x58, 0x58, 0x59, - 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5e, - 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, - 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, - 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69, 0x69, - 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, - 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x79, - 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x80, - 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x84, 0x84, - 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x88, - 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, - 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91, - 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, - 0x93, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, - 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, - 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, - 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, - 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, - 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, - 0xa5, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xab, - 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xad, 0xae, - 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, - 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, - 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, - 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, - 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, - 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, - 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, - 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, - 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, - 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, - 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, - 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, - 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, - 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, - 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, - 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, - 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, - 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, - 0x05, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, - 0x0e, 0x10, 0x10, 0x11, 0x12, 0x14, 0x15, 0x15, - 0x16, 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1c, 0x1e, - 0x1e, 0x1f, 0x20, 0x20, 0x22, 0x23, 0x25, 0x25, - 0x26, 0x27, 0x27, 0x28, 0x29, 0x29, 0x2b, 0x2c, - 0x2c, 0x2d, 0x2d, 0x2f, 0x30, 0x30, 0x31, 0x31, - 0x33, 0x34, 0x34, 0x35, 0x35, 0x37, 0x38, 0x38, - 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, - 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x42, 0x43, - 0x43, 0x44, 0x44, 0x45, 0x45, 0x47, 0x47, 0x48, - 0x48, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, - 0x52, 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x55, - 0x55, 0x56, 0x56, 0x56, 0x58, 0x58, 0x59, 0x59, - 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, - 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, - 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x65, - 0x65, 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, - 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, - 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, - 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, - 0x71, 0x71, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, - 0x75, 0x75, 0x75, 0x77, 0x77, 0x77, 0x78, 0x78, - 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, - 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, - 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, - 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, - 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x86, - 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, - 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, - 0x8b, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, - 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, - 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, - 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, - 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, - 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, - 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, - 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, - 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, - 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, - 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, - 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, - 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, - 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcf, - 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, - 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, - 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, - 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, - 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, - 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x05, 0x05, 0x07, - 0x08, 0x09, 0x0a, 0x0a, 0x0c, 0x0d, 0x0e, 0x0e, - 0x10, 0x11, 0x12, 0x12, 0x14, 0x15, 0x16, 0x16, - 0x17, 0x18, 0x18, 0x1a, 0x1b, 0x1b, 0x1c, 0x1e, - 0x1e, 0x1f, 0x1f, 0x20, 0x22, 0x22, 0x23, 0x23, - 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x29, 0x29, - 0x2b, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2f, 0x30, - 0x30, 0x31, 0x31, 0x33, 0x33, 0x34, 0x34, 0x35, - 0x35, 0x37, 0x37, 0x38, 0x38, 0x39, 0x39, 0x3a, - 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, - 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x42, 0x42, 0x43, - 0x43, 0x44, 0x44, 0x45, 0x45, 0x47, 0x47, 0x47, - 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4b, - 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4f, - 0x4f, 0x50, 0x50, 0x50, 0x52, 0x52, 0x52, 0x53, - 0x53, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56, - 0x56, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a, - 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, - 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, - 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, - 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, - 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, - 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c, - 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, - 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, - 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x74, 0x74, - 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x77, 0x77, - 0x77, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, - 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, - 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, - 0x82, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, - 0x85, 0x86, 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, - 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a, - 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, - 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, - 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, - 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, - 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, - 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, - 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, - 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, - 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, - 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, - 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, - 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, - 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, - 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, - 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, - 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, - 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, - 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, - 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, - 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, - 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, - 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, - 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, - 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, - 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} - }, - { /* gamma 2 */ - {0x00, 0x01, 0x02, 0x05, 0x07, 0x08, 0x0a, 0x0c, - 0x0d, 0x0e, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x22, - 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c, - 0x2d, 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x34, - 0x35, 0x37, 0x38, 0x38, 0x39, 0x3a, 0x3b, 0x3b, - 0x3c, 0x3d, 0x3f, 0x3f, 0x40, 0x42, 0x42, 0x43, - 0x44, 0x44, 0x45, 0x47, 0x47, 0x48, 0x49, 0x49, - 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4f, 0x4f, - 0x50, 0x50, 0x52, 0x53, 0x53, 0x54, 0x54, 0x55, - 0x55, 0x56, 0x56, 0x58, 0x58, 0x59, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5c, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, - 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, - 0x65, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, - 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c, - 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, - 0x70, 0x70, 0x71, 0x71, 0x73, 0x73, 0x73, 0x74, - 0x74, 0x75, 0x75, 0x75, 0x77, 0x77, 0x78, 0x78, - 0x78, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f, - 0x7f, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, - 0x82, 0x82, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, - 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x89, 0x89, - 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94, - 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, - 0x97, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, - 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, - 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, - 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, - 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, - 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, - 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, - 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4, - 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, - 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, - 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, - 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, - 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, - 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, - 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce, - 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, - 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, - 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, - 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, - 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, - 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, - 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, - 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x05, - 0x07, 0x08, 0x09, 0x0a, 0x0d, 0x0e, 0x10, 0x11, - 0x12, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x1a, - 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x20, 0x22, 0x23, - 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x29, 0x2b, - 0x2c, 0x2d, 0x2d, 0x2f, 0x30, 0x30, 0x31, 0x33, - 0x33, 0x34, 0x35, 0x35, 0x37, 0x38, 0x38, 0x39, - 0x3a, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3d, 0x3f, - 0x3f, 0x40, 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, - 0x45, 0x45, 0x47, 0x47, 0x48, 0x48, 0x49, 0x4a, - 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53, - 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x58, - 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, - 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x63, - 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, 0x66, 0x67, - 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, - 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, - 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, - 0x70, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x73, - 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77, 0x77, - 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, - 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, - 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, - 0x7f, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, - 0x82, 0x82, 0x82, 0x82, 0x84, 0x84, 0x84, 0x84, - 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x88, - 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8a, - 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, - 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x91, - 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, - 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, - 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, - 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, - 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, - 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, - 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, - 0xac, 0xac, 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, - 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, - 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, - 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, - 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, - 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, - 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, - 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, - 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, - 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, - 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xca, - 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, - 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, - 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, - 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, - 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, - 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, - 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, - 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, - 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, - 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x00, 0x00, 0x00, 0x01, 0x02, 0x05, 0x07, 0x08, - 0x09, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1e, - 0x1f, 0x20, 0x20, 0x22, 0x23, 0x25, 0x26, 0x27, - 0x28, 0x28, 0x29, 0x2b, 0x2c, 0x2d, 0x2d, 0x2f, - 0x30, 0x31, 0x31, 0x33, 0x34, 0x35, 0x35, 0x37, - 0x38, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3c, - 0x3d, 0x3f, 0x3f, 0x40, 0x40, 0x42, 0x43, 0x43, - 0x44, 0x44, 0x45, 0x47, 0x47, 0x48, 0x48, 0x49, - 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, - 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x52, 0x53, 0x53, - 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x58, 0x58, - 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, - 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, - 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, - 0x65, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, - 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6c, 0x6c, - 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, - 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x73, 0x73, - 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x77, - 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7a, - 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, - 0x7c, 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80, - 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, - 0x82, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, - 0x86, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x89, - 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, - 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, - 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, - 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, - 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, - 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, - 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, - 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, - 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, - 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa5, 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, - 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, - 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, - 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, - 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, - 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, - 0xb3, 0xb3, 0xb3, 0xb4, 0xb3, 0xb4, 0xb4, 0xb4, - 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, - 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, - 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, - 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, - 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, - 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, - 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, - 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, - 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, - 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, - 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, - 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, - 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb} - }, - { /* gamma 3 - from tp6810 + cx0342 */ - {0x08, 0x09, 0x0c, 0x0d, 0x10, 0x11, 0x14, 0x15, - 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x1f, 0x20, 0x23, - 0x25, 0x26, 0x27, 0x28, 0x2b, 0x2c, 0x2d, 0x2f, - 0x30, 0x31, 0x33, 0x34, 0x35, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0x3f, 0x40, 0x42, 0x43, - 0x44, 0x45, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, - 0x4c, 0x4d, 0x4d, 0x4f, 0x50, 0x52, 0x53, 0x53, - 0x54, 0x55, 0x56, 0x56, 0x58, 0x59, 0x5a, 0x5a, - 0x5b, 0x5c, 0x5c, 0x5e, 0x5f, 0x5f, 0x60, 0x61, - 0x61, 0x62, 0x63, 0x63, 0x65, 0x66, 0x66, 0x67, - 0x68, 0x68, 0x69, 0x69, 0x6a, 0x6c, 0x6c, 0x6d, - 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x73, - 0x73, 0x74, 0x74, 0x75, 0x75, 0x77, 0x77, 0x78, - 0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, - 0x82, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, - 0x86, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, - 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, - 0x93, 0x93, 0x94, 0x94, 0x96, 0x96, 0x97, 0x97, - 0x97, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9e, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, - 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, - 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, - 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, - 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, - 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, - 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, - 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, - 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, - 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, - 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, - 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, - 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, - 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, - 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, - 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, - 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, - 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, - 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, - 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, - 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, - 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x03, 0x05, 0x07, 0x09, 0x0a, 0x0c, 0x0d, 0x10, - 0x11, 0x12, 0x14, 0x15, 0x17, 0x18, 0x1a, 0x1b, - 0x1c, 0x1e, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2c, 0x2d, 0x2f, - 0x30, 0x31, 0x33, 0x33, 0x34, 0x35, 0x37, 0x38, - 0x38, 0x39, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3f, - 0x3f, 0x40, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45, - 0x47, 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, 0x4b, - 0x4c, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x52, 0x52, - 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, 0x58, - 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, - 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, - 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, 0x66, - 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69, - 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, - 0x71, 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x79, - 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7d, 0x7f, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x84, - 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, - 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, - 0x8a, 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, - 0x90, 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x96, - 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98, - 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, - 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, - 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, - 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, - 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, - 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, - 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, - 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, - 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, - 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, - 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, - 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, - 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, - 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, - 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, - 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, - 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, - 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, - 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, - 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, - 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, - 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, - 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, - 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, - 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, - 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, - 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, - 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, - 0x16, 0x17, 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, - 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2d, - 0x2f, 0x30, 0x31, 0x33, 0x34, 0x35, 0x37, 0x38, - 0x39, 0x3a, 0x3b, 0x3b, 0x3c, 0x3d, 0x3f, 0x40, - 0x42, 0x43, 0x44, 0x44, 0x45, 0x47, 0x48, 0x49, - 0x4a, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4f, 0x50, - 0x52, 0x52, 0x53, 0x54, 0x55, 0x55, 0x56, 0x58, - 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e, - 0x5f, 0x5f, 0x60, 0x61, 0x61, 0x62, 0x63, 0x63, - 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, - 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, - 0x6f, 0x70, 0x70, 0x71, 0x71, 0x73, 0x73, 0x74, - 0x74, 0x75, 0x75, 0x77, 0x77, 0x78, 0x78, 0x79, - 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, - 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x81, - 0x82, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, - 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x92, 0x92, - 0x92, 0x93, 0x93, 0x94, 0x94, 0x94, 0x96, 0x96, - 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, - 0x99, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0xa0, - 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, - 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xa8, 0xa9, - 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, - 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf, - 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4, - 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, - 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, - 0xb9, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, - 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, - 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc4, - 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, - 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, - 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xcf, - 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, - 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, - 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, - 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, - 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, - 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, - 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, - 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, - 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, - 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} - }, - { /* gamma 4 - from tp6800 + soi763a */ - {0x11, 0x14, 0x15, 0x17, 0x1a, 0x1b, 0x1e, 0x1f, - 0x22, 0x23, 0x25, 0x27, 0x28, 0x2b, 0x2c, 0x2d, - 0x2f, 0x31, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3a, - 0x3b, 0x3c, 0x3d, 0x40, 0x42, 0x43, 0x44, 0x45, - 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4f, - 0x50, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56, 0x58, - 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5f, 0x60, - 0x61, 0x61, 0x62, 0x63, 0x65, 0x65, 0x66, 0x67, - 0x68, 0x68, 0x69, 0x6a, 0x6c, 0x6c, 0x6d, 0x6e, - 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x73, 0x74, 0x74, - 0x75, 0x77, 0x77, 0x78, 0x79, 0x79, 0x7a, 0x7a, - 0x7b, 0x7c, 0x7c, 0x7d, 0x7f, 0x7f, 0x80, 0x80, - 0x81, 0x81, 0x82, 0x84, 0x84, 0x85, 0x85, 0x86, - 0x86, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, - 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x90, 0x91, - 0x91, 0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x96, - 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, - 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, - 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, - 0xb4, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, - 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbc, - 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, - 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, - 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc9, - 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, - 0xd0, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, - 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, - 0xd9, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, - 0xe9, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, - 0xec, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, - 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, - 0xf9, 0xf9, 0xfa, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x14, 0x15, - 0x16, 0x17, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, - 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c, - 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x34, 0x35, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, - 0x3f, 0x40, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45, - 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, 0x4b, 0x4c, - 0x4d, 0x4f, 0x4f, 0x50, 0x52, 0x52, 0x53, 0x54, - 0x54, 0x55, 0x55, 0x56, 0x58, 0x58, 0x59, 0x5a, - 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, - 0x60, 0x60, 0x61, 0x61, 0x62, 0x63, 0x63, 0x65, - 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, - 0x69, 0x6a, 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x73, - 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, 0x77, 0x77, - 0x78, 0x78, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f, - 0x7f, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, - 0x84, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x86, - 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8a, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, - 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, - 0x91, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94, - 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, - 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0xa0, - 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, - 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa6, - 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xa9, 0xab, - 0xaa, 0xab, 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, - 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, - 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, - 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, - 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xb6, 0xb6, - 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, - 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, - 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, - 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, - 0xca, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, - 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, - 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, - 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, - 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, - 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, - 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, - 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, - 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, - 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, - 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb}, - {0x0d, 0x10, 0x11, 0x14, 0x15, 0x17, 0x18, 0x1b, - 0x1c, 0x1e, 0x20, 0x22, 0x23, 0x26, 0x27, 0x28, - 0x29, 0x2b, 0x2d, 0x2f, 0x30, 0x31, 0x33, 0x34, - 0x35, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3f, 0x40, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, - 0x49, 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4f, 0x50, - 0x52, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, - 0x59, 0x5a, 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, - 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x65, 0x65, - 0x66, 0x67, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6c, - 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70, - 0x71, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x77, - 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, - 0x81, 0x81, 0x82, 0x82, 0x84, 0x84, 0x85, 0x85, - 0x86, 0x86, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, - 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, - 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, - 0x93, 0x93, 0x94, 0x94, 0x94, 0x96, 0x96, 0x97, - 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9d, 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, - 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa8, 0xa8, - 0xa8, 0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0xac, - 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, - 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4, - 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, - 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, - 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, - 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0xc2, 0xc2, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, - 0xc7, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, - 0xca, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcd, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, - 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, - 0xd4, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, - 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, - 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, - 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, - 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, - 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, - 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, - 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf3, - 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, - 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, - 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb} - }, - { /* gamma 5 */ - {0x16, 0x18, 0x19, 0x1b, 0x1d, 0x1e, 0x20, 0x21, - 0x23, 0x24, 0x25, 0x27, 0x28, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, - 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, - 0x56, 0x56, 0x57, 0x58, 0x59, 0x59, 0x5a, 0x5b, - 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, - 0x62, 0x62, 0x63, 0x64, 0x64, 0x65, 0x66, 0x66, - 0x67, 0x68, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, - 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70, - 0x71, 0x71, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75, - 0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, - 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, - 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x82, - 0x82, 0x83, 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, - 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, - 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8d, - 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x90, 0x90, - 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x94, - 0x94, 0x94, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, - 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9d, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0xa0, 0xa0, - 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, - 0xa3, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, - 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, - 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, - 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, - 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, - 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, - 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, - 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, - 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, - 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9, - 0xc9, 0xca, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, - 0xcb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, - 0xcd, 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, - 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, - 0xd5, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, - 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, - 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, - 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, 0xeb, - 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, - 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, - 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, - 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, - 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, - 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x0f, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, - 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3e, 0x3f, 0x3f, - 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x44, 0x45, - 0x46, 0x47, 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, - 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0x4e, 0x4f, 0x50, - 0x50, 0x51, 0x51, 0x52, 0x53, 0x53, 0x54, 0x54, - 0x55, 0x55, 0x56, 0x56, 0x57, 0x58, 0x58, 0x59, - 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5d, - 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, - 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x65, - 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68, - 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, - 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, - 0x6f, 0x70, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, - 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75, - 0x76, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, 0x78, - 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, - 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, - 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, - 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, - 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, - 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94, - 0x94, 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, - 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, - 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, - 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0x9f, 0xa0, 0xa0, - 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, - 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa6, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa7, - 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, - 0xa9, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xac, 0xad, - 0xad, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xae, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb2, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, - 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, - 0xb7, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb8, - 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xba, 0xba, - 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, - 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, - 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, - 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, - 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, - 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xca, - 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, - 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, - 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, - 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, - 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, - 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, - 0xe9, 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, - 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, - 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, - 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, - 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, - 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, - 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, - 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x13, 0x15, 0x16, 0x18, 0x19, 0x1b, 0x1c, 0x1e, - 0x1f, 0x20, 0x22, 0x23, 0x24, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, - 0x42, 0x43, 0x44, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, - 0x4f, 0x50, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, - 0x55, 0x55, 0x56, 0x57, 0x57, 0x58, 0x59, 0x59, - 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5f, - 0x5f, 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x63, - 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, - 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, - 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, - 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74, - 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, - 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, - 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, - 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, - 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, - 0x86, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, - 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, - 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x92, 0x92, - 0x92, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x95, - 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, - 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, - 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, - 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, - 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, - 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, - 0xa7, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, 0xa9, - 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, - 0xab, 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, 0xad, - 0xad, 0xae, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, - 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb1, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb3, - 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5, - 0xb6, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, - 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, - 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, - 0xbf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, - 0xc1, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, - 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, - 0xc7, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc8, - 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, - 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xce, - 0xce, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, - 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, - 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, - 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, - 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, - 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, - 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, - 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, - 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, - 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, - 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, - 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, - 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, - 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, - 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - }, - }; - - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); - if (sd->bridge == BRIDGE_TP6810) - reg_w(gspca_dev, 0x02, 0x28); -/* msleep(50); */ - bulk_w(gspca_dev, 0x00, gamma_tb[gamma][0], 1024); - bulk_w(gspca_dev, 0x01, gamma_tb[gamma][1], 1024); - bulk_w(gspca_dev, 0x02, gamma_tb[gamma][2], 1024); - if (sd->bridge == BRIDGE_TP6810) { - int i; - - reg_w(gspca_dev, 0x02, 0x2b); - reg_w(gspca_dev, 0x02, 0x28); - for (i = 0; i < 6; i++) - reg_w(gspca_dev, TP6800_R55_GAMMA_R, - gamma_tb[gamma][0][i]); - reg_w(gspca_dev, 0x02, 0x2b); - reg_w(gspca_dev, 0x02, 0x28); - for (i = 0; i < 6; i++) - reg_w(gspca_dev, TP6800_R56_GAMMA_G, - gamma_tb[gamma][1][i]); - reg_w(gspca_dev, 0x02, 0x2b); - reg_w(gspca_dev, 0x02, 0x28); - for (i = 0; i < 6; i++) - reg_w(gspca_dev, TP6800_R57_GAMMA_B, - gamma_tb[gamma][2][i]); - reg_w(gspca_dev, 0x02, 0x28); - } - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03); -/* msleep(50); */ -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->bridge == BRIDGE_TP6800) { - val |= 0x08; /* grid compensation enable */ - if (gspca_dev->width == 640) - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ - else - val |= 0x04; /* scaling down enable */ - reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, val); - } else { - val = (val << 5) | 0x08; - reg_w(gspca_dev, 0x59, val); - } -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->ag_cnt = val ? AG_CNT_START : -1; -} - -/* set the resolution for sensor cx0342 */ -static void set_resolution(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); - if (gspca_dev->width == 320) { - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06); - msleep(100); - i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); - msleep(100); - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ - reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, 0x0d); - i2c_w(gspca_dev, CX0342_EXPO_LINE_L, 0x37); - i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x01); - } else { - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x05); - msleep(100); - i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); - msleep(100); - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x03); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ - reg_w(gspca_dev, TP6800_R5D_DEMOSAIC_CFG, 0x09); - i2c_w(gspca_dev, CX0342_EXPO_LINE_L, 0xcf); - i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00); - } - i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); - bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], - ARRAY_SIZE(color_gain[0])); - setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); - if (sd->sensor == SENSOR_SOI763A) - setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); -} - -/* convert the frame rate to a tp68x0 value */ -static int get_fr_idx(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - - if (sd->bridge == BRIDGE_TP6800) { - for (i = 0; i < ARRAY_SIZE(rates) - 1; i++) { - if (sd->framerate >= rates[i]) - break; - } - i = 6 - i; /* 1 = 5fps .. 6 = 30fps */ - - /* 640x480 * 30 fps does not work */ - if (i == 6 /* if 30 fps */ - && gspca_dev->width == 640) - i = 0x05; /* 15 fps */ - } else { - for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { - if (sd->framerate >= rates_6810[i]) - break; - } - i = 7 - i; /* 3 = 5fps .. 7 = 30fps */ - - /* 640x480 * 30 fps does not work */ - if (i == 7 /* if 30 fps */ - && gspca_dev->width == 640) - i = 6; /* 15 fps */ - i |= 0x80; /* clock * 1 */ - } - return i; -} - -static void setframerate(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 fr_idx; - - fr_idx = get_fr_idx(gspca_dev); - - if (sd->bridge == BRIDGE_TP6810) { - reg_r(gspca_dev, 0x7b); - reg_w(gspca_dev, 0x7b, - sd->sensor == SENSOR_CX0342 ? 0x10 : 0x90); - if (val >= 128) - fr_idx = 0xf0; /* lower frame rate */ - } - - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, fr_idx); - - if (sd->sensor == SENSOR_CX0342) - i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); -} - -static void setrgain(struct gspca_dev *gspca_dev, s32 rgain) -{ - i2c_w(gspca_dev, CX0342_RAW_RGAIN_H, rgain >> 8); - i2c_w(gspca_dev, CX0342_RAW_RGAIN_L, rgain); - i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); -} - -static int sd_setgain(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 val = gspca_dev->gain->val; - - if (sd->sensor == SENSOR_CX0342) { - s32 old = gspca_dev->gain->cur.val ? - gspca_dev->gain->cur.val : 1; - - sd->blue->val = sd->blue->val * val / old; - if (sd->blue->val > 4095) - sd->blue->val = 4095; - sd->red->val = sd->red->val * val / old; - if (sd->red->val > 4095) - sd->red->val = 4095; - } - if (gspca_dev->streaming) { - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, gspca_dev->exposure->val, - gspca_dev->gain->val, - sd->blue->val, sd->red->val); - else - setexposure(gspca_dev, gspca_dev->exposure->val, - gspca_dev->gain->val, 0, 0); - } - return gspca_dev->usb_err; -} - -static void setbgain(struct gspca_dev *gspca_dev, s32 bgain) -{ - i2c_w(gspca_dev, CX0342_RAW_BGAIN_H, bgain >> 8); - i2c_w(gspca_dev, CX0342_RAW_BGAIN_L, bgain); - i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x80); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->bridge = id->driver_info; - - gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); - gspca_dev->cam.mode_framerates = sd->bridge == BRIDGE_TP6800 ? - framerates : framerates_6810; - - sd->framerate = 30; /* default: 30 fps */ - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd tp6800_preinit[] = { - {TP6800_R10_SIF_TYPE, 0x01}, /* sif */ - {TP6800_R11_SIF_CONTROL, 0x01}, - {TP6800_R15_GPIO_PU, 0x9f}, - {TP6800_R16_GPIO_PD, 0x9f}, - {TP6800_R17_GPIO_IO, 0x80}, - {TP6800_R18_GPIO_DATA, 0x40}, /* LED off */ - }; - static const struct cmd tp6810_preinit[] = { - {TP6800_R2F_TIMING_CFG, 0x2f}, - {TP6800_R15_GPIO_PU, 0x6f}, - {TP6800_R16_GPIO_PD, 0x40}, - {TP6800_R17_GPIO_IO, 0x9f}, - {TP6800_R18_GPIO_DATA, 0xc1}, /* LED off */ - }; - - if (sd->bridge == BRIDGE_TP6800) - reg_w_buf(gspca_dev, tp6800_preinit, - ARRAY_SIZE(tp6800_preinit)); - else - reg_w_buf(gspca_dev, tp6810_preinit, - ARRAY_SIZE(tp6810_preinit)); - msleep(15); - reg_r(gspca_dev, TP6800_R18_GPIO_DATA); - PDEBUG(D_PROBE, "gpio: %02x", gspca_dev->usb_buf[0]); -/* values: - * 0x80: snapshot button - * 0x40: LED - * 0x20: (bridge / sensor) reset for tp6810 ? - * 0x07: sensor type ? - */ - - /* guess the sensor type */ - if (force_sensor >= 0) { - sd->sensor = force_sensor; - } else { - if (sd->bridge == BRIDGE_TP6800) { -/*fixme: not sure this is working*/ - switch (gspca_dev->usb_buf[0] & 0x07) { - case 0: - sd->sensor = SENSOR_SOI763A; - break; - case 1: - sd->sensor = SENSOR_CX0342; - break; - } - } else { - int sensor; - - sensor = probe_6810(gspca_dev); - if (sensor < 0) { - pr_warn("Unknown sensor %d - forced to soi763a\n", - -sensor); - sensor = SENSOR_SOI763A; - } - sd->sensor = sensor; - } - } - if (sd->sensor == SENSOR_SOI763A) { - pr_info("Sensor soi763a\n"); - if (sd->bridge == BRIDGE_TP6810) { - soi763a_6810_init(gspca_dev); - } - } else { - pr_info("Sensor cx0342\n"); - if (sd->bridge == BRIDGE_TP6810) { - cx0342_6810_init(gspca_dev); - } - } - - set_dqt(gspca_dev, 0); - return 0; -} - -/* This function is called before choosing the alt setting */ -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd cx_sensor_init[] = { - {CX0342_AUTO_ADC_CALIB, 0x81}, - {CX0342_EXPO_LINE_L, 0x37}, - {CX0342_EXPO_LINE_H, 0x01}, - {CX0342_RAW_GRGAIN_L, 0x00}, - {CX0342_RAW_GBGAIN_L, 0x00}, - {CX0342_RAW_RGAIN_L, 0x00}, - {CX0342_RAW_BGAIN_L, 0x00}, - {CX0342_SYS_CTRL_0, 0x81}, - }; - static const struct cmd cx_bridge_init[] = { - {0x4d, 0x00}, - {0x4c, 0xff}, - {0x4e, 0xff}, - {0x4f, 0x00}, - }; - static const struct cmd ov_sensor_init[] = { - {0x10, 0x75}, /* exposure */ - {0x76, 0x03}, - {0x00, 0x00}, /* gain */ - }; - static const struct cmd ov_bridge_init[] = { - {0x7b, 0x90}, - {TP6800_R3F_FRAME_RATE, 0x87}, - }; - - if (sd->bridge == BRIDGE_TP6800) - return 0; - if (sd->sensor == SENSOR_CX0342) { - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x20); - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87); - i2c_w_buf(gspca_dev, cx_sensor_init, - ARRAY_SIZE(cx_sensor_init)); - reg_w_buf(gspca_dev, cx_bridge_init, - ARRAY_SIZE(cx_bridge_init)); - bulk_w(gspca_dev, 0x03, color_null, sizeof color_null); - reg_w(gspca_dev, 0x59, 0x40); - } else { - reg_w(gspca_dev, TP6800_R12_SIF_ADDR_S, 0x21); - i2c_w_buf(gspca_dev, ov_sensor_init, - ARRAY_SIZE(ov_sensor_init)); - reg_r(gspca_dev, 0x7b); - reg_w_buf(gspca_dev, ov_bridge_init, - ARRAY_SIZE(ov_bridge_init)); - } - reg_w(gspca_dev, TP6800_R78_FORMAT, - gspca_dev->curr_mode ? 0x00 : 0x01); - return gspca_dev->usb_err; -} - -static void set_led(struct gspca_dev *gspca_dev, int on) -{ - u8 data; - - reg_r(gspca_dev, TP6800_R18_GPIO_DATA); - data = gspca_dev->usb_buf[0]; - if (on) - data &= ~0x40; - else - data |= 0x40; - reg_w(gspca_dev, TP6800_R18_GPIO_DATA, data); -} - -static void cx0342_6800_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd reg_init[] = { - /* fixme: is this useful? */ - {TP6800_R17_GPIO_IO, 0x9f}, - {TP6800_R16_GPIO_PD, 0x40}, - {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */ - {TP6800_R50, 0x00}, - {TP6800_R51, 0x00}, - {TP6800_R52, 0xff}, - {TP6800_R53, 0x03}, - {TP6800_R54_DARK_CFG, 0x07}, - {TP6800_R5C_EDGE_THRLD, 0x40}, - {TP6800_R7A_BLK_THRLD, 0x40}, - {TP6800_R2F_TIMING_CFG, 0x17}, - {TP6800_R30_SENSOR_CFG, 0x18}, /* G1B..RG0 */ - {TP6800_R37_FRONT_DARK_ST, 0x00}, - {TP6800_R38_FRONT_DARK_END, 0x00}, - {TP6800_R39_REAR_DARK_ST_L, 0x00}, - {TP6800_R3A_REAR_DARK_ST_H, 0x00}, - {TP6800_R3B_REAR_DARK_END_L, 0x00}, - {TP6800_R3C_REAR_DARK_END_H, 0x00}, - {TP6800_R3D_HORIZ_DARK_LINE_L, 0x00}, - {TP6800_R3E_HORIZ_DARK_LINE_H, 0x00}, - {TP6800_R21_ENDP_1_CTL, 0x03}, - - {TP6800_R31_PIXEL_START, 0x0b}, - {TP6800_R32_PIXEL_END_L, 0x8a}, - {TP6800_R33_PIXEL_END_H, 0x02}, - {TP6800_R34_LINE_START, 0x0e}, - {TP6800_R35_LINE_END_L, 0xf4}, - {TP6800_R36_LINE_END_H, 0x01}, - {TP6800_R78_FORMAT, 0x00}, - {TP6800_R12_SIF_ADDR_S, 0x20}, /* cx0342 i2c addr */ - }; - static const struct cmd sensor_init[] = { - {CX0342_OUTPUT_CTRL, 0x07}, - {CX0342_BYPASS_MODE, 0x58}, - {CX0342_GPXLTHD_L, 0x16}, - {CX0342_RBPXLTHD_L, 0x16}, - {CX0342_PLANETHD_L, 0xc0}, - {CX0342_PLANETHD_H, 0x03}, - {CX0342_RB_GAP_L, 0xff}, - {CX0342_RB_GAP_H, 0x07}, - {CX0342_G_GAP_L, 0xff}, - {CX0342_G_GAP_H, 0x07}, - {CX0342_RST_OVERFLOW_L, 0x5c}, - {CX0342_RST_OVERFLOW_H, 0x01}, - {CX0342_DATA_OVERFLOW_L, 0xfc}, - {CX0342_DATA_OVERFLOW_H, 0x03}, - {CX0342_DATA_UNDERFLOW_L, 0x00}, - {CX0342_DATA_UNDERFLOW_H, 0x00}, - {CX0342_SYS_CTRL_0, 0x40}, - {CX0342_GLOBAL_GAIN, 0x01}, - {CX0342_CLOCK_GEN, 0x00}, - {CX0342_SYS_CTRL_0, 0x02}, - {CX0342_IDLE_CTRL, 0x05}, - {CX0342_ADCGN, 0x00}, - {CX0342_ADC_CTL, 0x00}, - {CX0342_LVRST_BLBIAS, 0x01}, - {CX0342_VTHSEL, 0x0b}, - {CX0342_RAMP_RIV, 0x0b}, - {CX0342_LDOSEL, 0x07}, - {CX0342_SPV_VALUE_L, 0x40}, - {CX0342_SPV_VALUE_H, 0x02}, - }; - - reg_w_buf(gspca_dev, reg_init, ARRAY_SIZE(reg_init)); - i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init)); - i2c_w_buf(gspca_dev, cx0342_timing_seq, ARRAY_SIZE(cx0342_timing_seq)); - reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10); - reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); - i2c_w(gspca_dev, CX0342_EXPO_LINE_H, 0x00); - i2c_w(gspca_dev, CX0342_SYS_CTRL_0, 0x01); - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), - v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - else - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); - set_led(gspca_dev, 1); - set_resolution(gspca_dev); -} - -static void cx0342_6810_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd sensor_init_2[] = { - {CX0342_EXPO_LINE_L, 0x6f}, - {CX0342_EXPO_LINE_H, 0x02}, - {CX0342_RAW_GRGAIN_L, 0x00}, - {CX0342_RAW_GBGAIN_L, 0x00}, - {CX0342_RAW_RGAIN_L, 0x00}, - {CX0342_RAW_BGAIN_L, 0x00}, - {CX0342_SYS_CTRL_0, 0x81}, - }; - static const struct cmd bridge_init_2[] = { - {0x4d, 0x00}, - {0x4c, 0xff}, - {0x4e, 0xff}, - {0x4f, 0x00}, - {TP6800_R7A_BLK_THRLD, 0x00}, - {TP6800_R79_QUALITY, 0x04}, - {TP6800_R79_QUALITY, 0x01}, - }; - static const struct cmd bridge_init_3[] = { - {TP6800_R31_PIXEL_START, 0x08}, - {TP6800_R32_PIXEL_END_L, 0x87}, - {TP6800_R33_PIXEL_END_H, 0x02}, - {TP6800_R34_LINE_START, 0x0e}, - {TP6800_R35_LINE_END_L, 0xf4}, - {TP6800_R36_LINE_END_H, 0x01}, - }; - static const struct cmd sensor_init_3[] = { - {CX0342_AUTO_ADC_CALIB, 0x81}, - {CX0342_EXPO_LINE_L, 0x6f}, - {CX0342_EXPO_LINE_H, 0x02}, - {CX0342_RAW_GRGAIN_L, 0x00}, - {CX0342_RAW_GBGAIN_L, 0x00}, - {CX0342_RAW_RGAIN_L, 0x00}, - {CX0342_RAW_BGAIN_L, 0x00}, - {CX0342_SYS_CTRL_0, 0x81}, - }; - static const struct cmd bridge_init_5[] = { - {0x4d, 0x00}, - {0x4c, 0xff}, - {0x4e, 0xff}, - {0x4f, 0x00}, - }; - static const struct cmd sensor_init_4[] = { - {CX0342_EXPO_LINE_L, 0xd3}, - {CX0342_EXPO_LINE_H, 0x01}, -/*fixme: gains, but 00..80 only*/ - {CX0342_RAW_GRGAIN_L, 0x40}, - {CX0342_RAW_GBGAIN_L, 0x40}, - {CX0342_RAW_RGAIN_L, 0x40}, - {CX0342_RAW_BGAIN_L, 0x40}, - {CX0342_SYS_CTRL_0, 0x81}, - }; - static const struct cmd sensor_init_5[] = { - {CX0342_IDLE_CTRL, 0x05}, - {CX0342_ADCGN, 0x00}, - {CX0342_ADC_CTL, 0x00}, - {CX0342_LVRST_BLBIAS, 0x01}, - {CX0342_VTHSEL, 0x0b}, - {CX0342_RAMP_RIV, 0x0b}, - {CX0342_LDOSEL, 0x07}, - {CX0342_SPV_VALUE_L, 0x40}, - {CX0342_SPV_VALUE_H, 0x02}, - {CX0342_AUTO_ADC_CALIB, 0x81}, - }; - - reg_w(gspca_dev, 0x22, gspca_dev->alt); - i2c_w_buf(gspca_dev, sensor_init_2, ARRAY_SIZE(sensor_init_2)); - reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2)); - reg_w_buf(gspca_dev, tp6810_cx_init_common, - ARRAY_SIZE(tp6810_cx_init_common)); - reg_w_buf(gspca_dev, bridge_init_3, ARRAY_SIZE(bridge_init_3)); - if (gspca_dev->curr_mode) { - reg_w(gspca_dev, 0x4a, 0x7f); - reg_w(gspca_dev, 0x07, 0x05); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ - } else { - reg_w(gspca_dev, 0x4a, 0xff); - reg_w(gspca_dev, 0x07, 0x85); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ - } - setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); - reg_w_buf(gspca_dev, tp6810_bridge_start, - ARRAY_SIZE(tp6810_bridge_start)); - setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); - bulk_w(gspca_dev, 0x03, color_gain[SENSOR_CX0342], - ARRAY_SIZE(color_gain[0])); - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x87); - i2c_w_buf(gspca_dev, sensor_init_3, ARRAY_SIZE(sensor_init_3)); - reg_w_buf(gspca_dev, bridge_init_5, ARRAY_SIZE(bridge_init_5)); - i2c_w_buf(gspca_dev, sensor_init_4, ARRAY_SIZE(sensor_init_4)); - reg_w_buf(gspca_dev, bridge_init_5, ARRAY_SIZE(bridge_init_5)); - i2c_w_buf(gspca_dev, sensor_init_5, ARRAY_SIZE(sensor_init_5)); - - set_led(gspca_dev, 1); -/* setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); */ -} - -static void soi763a_6800_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd reg_init[] = { - {TP6800_R79_QUALITY, 0x04}, - {TP6800_R79_QUALITY, 0x01}, - {TP6800_R10_SIF_TYPE, 0x00}, /* i2c 8 bits */ - - {TP6800_R50, 0x00}, - {TP6800_R51, 0x00}, - {TP6800_R52, 0xff}, - {TP6800_R53, 0x03}, - {TP6800_R54_DARK_CFG, 0x07}, - {TP6800_R5C_EDGE_THRLD, 0x40}, - - {TP6800_R79_QUALITY, 0x03}, - {TP6800_R7A_BLK_THRLD, 0x40}, - - {TP6800_R2F_TIMING_CFG, 0x46}, - {TP6800_R30_SENSOR_CFG, 0x10}, /* BG1..G0R */ - {TP6800_R37_FRONT_DARK_ST, 0x00}, - {TP6800_R38_FRONT_DARK_END, 0x00}, - {TP6800_R39_REAR_DARK_ST_L, 0x00}, - {TP6800_R3A_REAR_DARK_ST_H, 0x00}, - {TP6800_R3B_REAR_DARK_END_L, 0x00}, - {TP6800_R3C_REAR_DARK_END_H, 0x00}, - {TP6800_R3D_HORIZ_DARK_LINE_L, 0x00}, - {TP6800_R3E_HORIZ_DARK_LINE_H, 0x00}, - {TP6800_R21_ENDP_1_CTL, 0x03}, - - {TP6800_R3F_FRAME_RATE, 0x04}, /* 15 fps */ - {TP6800_R5D_DEMOSAIC_CFG, 0x0e}, /* scale down - medium edge */ - - {TP6800_R31_PIXEL_START, 0x1b}, - {TP6800_R32_PIXEL_END_L, 0x9a}, - {TP6800_R33_PIXEL_END_H, 0x02}, - {TP6800_R34_LINE_START, 0x0f}, - {TP6800_R35_LINE_END_L, 0xf4}, - {TP6800_R36_LINE_END_H, 0x01}, - {TP6800_R78_FORMAT, 0x01}, /* qvga */ - {TP6800_R12_SIF_ADDR_S, 0x21}, /* soi763a i2c addr */ - {TP6800_R1A_SIF_TX_DATA2, 0x00}, - }; - static const struct cmd sensor_init[] = { - {0x12, 0x48}, /* mirror - RGB */ - {0x13, 0xa0}, /* clock - no AGC nor AEC */ - {0x03, 0xa4}, /* saturation */ - {0x04, 0x30}, /* hue */ - {0x05, 0x88}, /* contrast */ - {0x06, 0x60}, /* brightness */ - {0x10, 0x41}, /* AEC */ - {0x11, 0x40}, /* clock rate */ - {0x13, 0xa0}, - {0x14, 0x00}, /* 640x480 */ - {0x15, 0x14}, - {0x1f, 0x41}, - {0x20, 0x80}, - {0x23, 0xee}, - {0x24, 0x50}, - {0x25, 0x7a}, - {0x26, 0x00}, - {0x27, 0xe2}, - {0x28, 0xb0}, - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2d, 0x81}, - {0x2f, 0x9d}, - {0x60, 0x80}, - {0x61, 0x00}, - {0x62, 0x88}, - {0x63, 0x11}, - {0x64, 0x89}, - {0x65, 0x00}, - {0x67, 0x94}, - {0x68, 0x7a}, - {0x69, 0x0f}, - {0x6c, 0x80}, - {0x6d, 0x80}, - {0x6e, 0x80}, - {0x6f, 0xff}, - {0x71, 0x20}, - {0x74, 0x20}, - {0x75, 0x86}, - {0x77, 0xb5}, - {0x17, 0x18}, /* H href start */ - {0x18, 0xbf}, /* H href end */ - {0x19, 0x03}, /* V start */ - {0x1a, 0xf8}, /* V end */ - {0x01, 0x80}, /* blue gain */ - {0x02, 0x80}, /* red gain */ - }; - - reg_w_buf(gspca_dev, reg_init, ARRAY_SIZE(reg_init)); - - i2c_w(gspca_dev, 0x12, 0x80); /* sensor reset */ - msleep(10); - - i2c_w_buf(gspca_dev, sensor_init, ARRAY_SIZE(sensor_init)); - - reg_w(gspca_dev, TP6800_R5C_EDGE_THRLD, 0x10); - reg_w(gspca_dev, TP6800_R54_DARK_CFG, 0x00); - - setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); - - bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], - ARRAY_SIZE(color_gain[0])); - - set_led(gspca_dev, 1); - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), - v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - else - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); - if (sd->sensor == SENSOR_SOI763A) - setquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual)); - setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); -} - -static void soi763a_6810_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const struct cmd bridge_init_2[] = { - {TP6800_R7A_BLK_THRLD, 0x00}, - {TP6800_R79_QUALITY, 0x04}, - {TP6800_R79_QUALITY, 0x01}, - }; - static const struct cmd bridge_init_3[] = { - {TP6800_R31_PIXEL_START, 0x20}, - {TP6800_R32_PIXEL_END_L, 0x9f}, - {TP6800_R33_PIXEL_END_H, 0x02}, - {TP6800_R34_LINE_START, 0x13}, - {TP6800_R35_LINE_END_L, 0xf8}, - {TP6800_R36_LINE_END_H, 0x01}, - }; - static const struct cmd bridge_init_6[] = { - {0x08, 0xff}, - {0x09, 0xff}, - {0x0a, 0x5f}, - {0x0b, 0x80}, - }; - - reg_w(gspca_dev, 0x22, gspca_dev->alt); - bulk_w(gspca_dev, 0x03, color_null, sizeof color_null); - reg_w(gspca_dev, 0x59, 0x40); - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), - v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - else - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); - reg_w_buf(gspca_dev, bridge_init_2, ARRAY_SIZE(bridge_init_2)); - reg_w_buf(gspca_dev, tp6810_ov_init_common, - ARRAY_SIZE(tp6810_ov_init_common)); - reg_w_buf(gspca_dev, bridge_init_3, ARRAY_SIZE(bridge_init_3)); - if (gspca_dev->curr_mode) { - reg_w(gspca_dev, 0x4a, 0x7f); - reg_w(gspca_dev, 0x07, 0x05); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ - } else { - reg_w(gspca_dev, 0x4a, 0xff); - reg_w(gspca_dev, 0x07, 0x85); - reg_w(gspca_dev, TP6800_R78_FORMAT, 0x01); /* qvga */ - } - setgamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); - reg_w_buf(gspca_dev, tp6810_bridge_start, - ARRAY_SIZE(tp6810_bridge_start)); - - if (gspca_dev->curr_mode) { - reg_w(gspca_dev, 0x4f, 0x00); - reg_w(gspca_dev, 0x4e, 0x7c); - } - - reg_w(gspca_dev, 0x00, 0x00); - - setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); - bulk_w(gspca_dev, 0x03, color_gain[SENSOR_SOI763A], - ARRAY_SIZE(color_gain[0])); - set_led(gspca_dev, 1); - reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0xf0); - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), - v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - else - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); - reg_w_buf(gspca_dev, bridge_init_6, ARRAY_SIZE(bridge_init_6)); -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width); - set_dqt(gspca_dev, sd->quality); - if (sd->bridge == BRIDGE_TP6800) { - if (sd->sensor == SENSOR_CX0342) - cx0342_6800_start(gspca_dev); - else - soi763a_6800_start(gspca_dev); - } else { - if (sd->sensor == SENSOR_CX0342) - cx0342_6810_start(gspca_dev); - else - soi763a_6810_start(gspca_dev); - reg_w_buf(gspca_dev, tp6810_late_start, - ARRAY_SIZE(tp6810_late_start)); - reg_w(gspca_dev, 0x80, 0x03); - reg_w(gspca_dev, 0x82, gspca_dev->curr_mode ? 0x0a : 0x0e); - - if (sd->sensor == SENSOR_CX0342) - setexposure(gspca_dev, - v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), - v4l2_ctrl_g_ctrl(sd->blue), - v4l2_ctrl_g_ctrl(sd->red)); - else - setexposure(gspca_dev, - v4l2_ctrl_g_ctrl(gspca_dev->exposure), - v4l2_ctrl_g_ctrl(gspca_dev->gain), 0, 0); - if (sd->sensor == SENSOR_SOI763A) - setquality(gspca_dev, - v4l2_ctrl_g_ctrl(sd->jpegqual)); - if (sd->bridge == BRIDGE_TP6810) - setautogain(gspca_dev, - v4l2_ctrl_g_ctrl(gspca_dev->autogain)); - } - - setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure)); - - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->bridge == BRIDGE_TP6800) - reg_w(gspca_dev, TP6800_R2F_TIMING_CFG, 0x03); - set_led(gspca_dev, 0); - reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* the start of frame contains: - * ff d8 - * ff fe - * width / 16 - * height / 8 - * quality - */ - if (sd->bridge == BRIDGE_TP6810) { - if (*data != 0x5a) { -/*fixme: don't discard the whole frame..*/ - if (*data == 0xaa || *data == 0x00) - return; - if (*data > 0xc0) { - PDEBUG(D_FRAM, "bad frame"); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - } - data++; - len--; - if (*data == 0xff && data[1] == 0xd8) { -/*fixme: there may be information in the 4 high bits*/ - if ((data[6] & 0x0f) != sd->quality) - set_dqt(gspca_dev, data[6] & 0x0f); - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 7, len - 7); - } else if (data[len - 2] == 0xff && data[len - 1] == 0xd9) { - gspca_frame_add(gspca_dev, LAST_PACKET, - data, len); - } else { - gspca_frame_add(gspca_dev, INTER_PACKET, - data, len); - } - return; - } - - switch (*data) { - case 0x55: - gspca_frame_add(gspca_dev, LAST_PACKET, data, 0); - - if (len < 8 - || data[1] != 0xff || data[2] != 0xd8 - || data[3] != 0xff || data[4] != 0xfe) { - - /* Have only seen this with corrupt frames */ - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - if (data[7] != sd->quality) - set_dqt(gspca_dev, data[7]); - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 8, len - 8); - break; - case 0xaa: - gspca_dev->last_packet_type = DISCARD_PACKET; - break; - case 0xcc: - if (data[1] != 0xff || data[2] != 0xd8) - gspca_frame_add(gspca_dev, INTER_PACKET, - data + 1, len - 1); - else - gspca_dev->last_packet_type = DISCARD_PACKET; - break; - } -} - -static void sd_dq_callback(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret, alen; - int luma, expo; - - if (sd->ag_cnt < 0) - return; - if (--sd->ag_cnt > 5) - return; - switch (sd->ag_cnt) { -/* case 5: */ - default: - reg_w(gspca_dev, 0x7d, 0x00); - break; - case 4: - reg_w(gspca_dev, 0x27, 0xb0); - break; - case 3: - reg_w(gspca_dev, 0x0c, 0x01); - break; - case 2: - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x02), - gspca_dev->usb_buf, - 32, - &alen, - 500); - if (ret < 0) { - pr_err("bulk err %d\n", ret); - break; - } - /* values not used (unknown) */ - break; - case 1: - reg_w(gspca_dev, 0x27, 0xd0); - break; - case 0: - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x02), - gspca_dev->usb_buf, - 32, - &alen, - 500); - if (ret < 0) { - pr_err("bulk err %d\n", ret); - break; - } - luma = ((gspca_dev->usb_buf[8] << 8) + gspca_dev->usb_buf[7] + - (gspca_dev->usb_buf[11] << 8) + gspca_dev->usb_buf[10] + - (gspca_dev->usb_buf[14] << 8) + gspca_dev->usb_buf[13] + - (gspca_dev->usb_buf[17] << 8) + gspca_dev->usb_buf[16] + - (gspca_dev->usb_buf[20] << 8) + gspca_dev->usb_buf[19] + - (gspca_dev->usb_buf[23] << 8) + gspca_dev->usb_buf[22] + - (gspca_dev->usb_buf[26] << 8) + gspca_dev->usb_buf[25] + - (gspca_dev->usb_buf[29] << 8) + gspca_dev->usb_buf[28]) - / 8; - if (gspca_dev->width == 640) - luma /= 4; - reg_w(gspca_dev, 0x7d, 0x00); - - expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - ret = gspca_expo_autogain(gspca_dev, luma, - 60, /* desired luma */ - 6, /* dead zone */ - 2, /* gain knee */ - 70); /* expo knee */ - sd->ag_cnt = AG_CNT_START; - if (sd->bridge == BRIDGE_TP6810) { - int new_expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - - if ((expo >= 128 && new_expo < 128) - || (expo < 128 && new_expo >= 128)) - setframerate(gspca_dev, new_expo); - } - break; - } -} - -/* get stream parameters (framerate) */ -static void sd_get_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_captureparm *cp = &parm->parm.capture; - struct v4l2_fract *tpf = &cp->timeperframe; - int fr, i; - - cp->capability |= V4L2_CAP_TIMEPERFRAME; - tpf->numerator = 1; - i = get_fr_idx(gspca_dev); - if (i & 0x80) { - if (sd->bridge == BRIDGE_TP6800) - fr = rates[6 - (i & 0x07)]; - else - fr = rates_6810[7 - (i & 0x07)]; - } else { - fr = rates[6 - i]; - } - tpf->denominator = fr; -} - -/* set stream parameters (framerate) */ -static void sd_set_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct v4l2_captureparm *cp = &parm->parm.capture; - struct v4l2_fract *tpf = &cp->timeperframe; - int fr, i; - - sd->framerate = tpf->denominator / tpf->numerator; - if (gspca_dev->streaming) - setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure)); - - /* Return the actual framerate */ - i = get_fr_idx(gspca_dev); - if (i & 0x80) - fr = rates_6810[7 - (i & 0x07)]; - else - fr = rates[6 - i]; - tpf->numerator = 1; - tpf->denominator = fr; -} - -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor != SENSOR_SOI763A) - return -ENOTTY; - v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor != SENSOR_SOI763A) - return -ENOTTY; - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAMMA: - setgamma(gspca_dev, ctrl->val); - break; - case V4L2_CID_BLUE_BALANCE: - setbgain(gspca_dev, ctrl->val); - break; - case V4L2_CID_RED_BALANCE: - setrgain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - sd_setgain(gspca_dev); - break; - case V4L2_CID_AUTOGAIN: - if (ctrl->val) - break; - sd_setgain(gspca_dev); - break; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - jpeg_set_qual(sd->jpeg_hdr, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 1, 0xdc, 1, 0x4e); - if (sd->sensor == SENSOR_CX0342) { - sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 4095, 1, 256); - sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BLUE_BALANCE, 0, 4095, 1, 256); - } - if (sd->sensor == SENSOR_SOI763A) - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 15, 1, 3); - else - gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 4095, 1, 256); - sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 3, 1, 2); - sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAMMA, 0, NGAMMA - 1, 1, - (sd->sensor == SENSOR_SOI763A && - sd->bridge == BRIDGE_TP6800) ? 0 : 1); - if (sd->bridge == BRIDGE_TP6810) - gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - if (sd->sensor == SENSOR_SOI763A) - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, - 0, 15, 1, (sd->bridge == BRIDGE_TP6810) ? 0 : 13); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (gspca_dev->autogain) - v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); - else - v4l2_ctrl_cluster(2, &gspca_dev->exposure); - return 0; -} - -static const struct sd_desc sd_desc = { - .name = KBUILD_MODNAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_isoc_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, - .dq_callback = sd_dq_callback, - .get_streamparm = sd_get_streamparm, - .set_streamparm = sd_set_streamparm, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, -}; - -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x06a2, 0x0003), .driver_info = BRIDGE_TP6800}, - {USB_DEVICE(0x06a2, 0x6810), .driver_info = BRIDGE_TP6810}, - {} /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -static int sd_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - return gspca_dev_probe(interface, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = KBUILD_MODNAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(force_sensor, int, 0644); -MODULE_PARM_DESC(force_sensor, - "Force sensor. 0: cx0342, 1: soi763a"); diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c deleted file mode 100644 index 8591324a53e1..000000000000 --- a/drivers/media/video/gspca/tv8532.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Quickcam cameras initialization data - * - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#define MODULE_NAME "tv8532" - -#include "gspca.h" - -MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); -MODULE_DESCRIPTION("TV8532 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - __u8 packet; -}; - -static const struct v4l2_pix_format sif_mode[] = { - {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* TV-8532A (ICM532A) registers (LE) */ -#define R00_PART_CONTROL 0x00 -#define LATENT_CHANGE 0x80 -#define EXPO_CHANGE 0x04 -#define R01_TIMING_CONTROL_LOW 0x01 -#define CMD_EEprom_Open 0x30 -#define CMD_EEprom_Close 0x29 -#define R03_TABLE_ADDR 0x03 -#define R04_WTRAM_DATA_L 0x04 -#define R05_WTRAM_DATA_M 0x05 -#define R06_WTRAM_DATA_H 0x06 -#define R07_TABLE_LEN 0x07 -#define R08_RAM_WRITE_ACTION 0x08 -#define R0C_AD_WIDTHL 0x0c -#define R0D_AD_WIDTHH 0x0d -#define R0E_AD_HEIGHTL 0x0e -#define R0F_AD_HEIGHTH 0x0f -#define R10_AD_COL_BEGINL 0x10 -#define R11_AD_COL_BEGINH 0x11 -#define MIRROR 0x04 /* [10] */ -#define R14_AD_ROW_BEGINL 0x14 -#define R15_AD_ROWBEGINH 0x15 -#define R1C_AD_EXPOSE_TIMEL 0x1c -#define R20_GAIN_G1L 0x20 -#define R21_GAIN_G1H 0x21 -#define R22_GAIN_RL 0x22 -#define R23_GAIN_RH 0x23 -#define R24_GAIN_BL 0x24 -#define R25_GAIN_BH 0x25 -#define R26_GAIN_G2L 0x26 -#define R27_GAIN_G2H 0x27 -#define R28_QUANT 0x28 -#define R29_LINE 0x29 -#define R2C_POLARITY 0x2c -#define R2D_POINT 0x2d -#define R2E_POINTH 0x2e -#define R2F_POINTB 0x2f -#define R30_POINTBH 0x30 -#define R31_UPD 0x31 -#define R2A_HIGH_BUDGET 0x2a -#define R2B_LOW_BUDGET 0x2b -#define R34_VID 0x34 -#define R35_VIDH 0x35 -#define R36_PID 0x36 -#define R37_PIDH 0x37 -#define R39_Test1 0x39 /* GPIO */ -#define R3B_Test3 0x3b /* GPIO */ -#define R83_AD_IDH 0x83 -#define R91_AD_SLOPEREG 0x91 -#define R94_AD_BITCONTROL 0x94 - -static const u8 eeprom_data[][3] = { -/* dataH dataM dataL */ - {0x01, 0x00, 0x01}, - {0x01, 0x80, 0x11}, - {0x05, 0x00, 0x14}, - {0x05, 0x00, 0x1c}, - {0x0d, 0x00, 0x1e}, - {0x05, 0x00, 0x1f}, - {0x05, 0x05, 0x19}, - {0x05, 0x01, 0x1b}, - {0x05, 0x09, 0x1e}, - {0x0d, 0x89, 0x2e}, - {0x05, 0x89, 0x2f}, - {0x05, 0x0d, 0xd9}, - {0x05, 0x09, 0xf1}, -}; - - -/* write 1 byte */ -static void reg_w1(struct gspca_dev *gspca_dev, - __u16 index, __u8 value) -{ - gspca_dev->usb_buf[0] = value; - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x02, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, 1, 500); -} - -/* write 2 bytes */ -static void reg_w2(struct gspca_dev *gspca_dev, - u16 index, u16 value) -{ - gspca_dev->usb_buf[0] = value; - gspca_dev->usb_buf[1] = value >> 8; - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x02, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, gspca_dev->usb_buf, 2, 500); -} - -static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) -{ - int i; - - reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open); - for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) { - reg_w1(gspca_dev, R03_TABLE_ADDR, i); - reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]); - reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]); - reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]); - reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0); - } - reg_w1(gspca_dev, R07_TABLE_LEN, i); - reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - - return 0; -} - -static void tv_8532_setReg(struct gspca_dev *gspca_dev) -{ - reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */ - /******************************************************/ - reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90); - reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01); - reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f); - reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44); - /* begin active line */ - reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00); - /* mirror and digital gain */ - reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a); - - reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02); - reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00); - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* = 0x84 */ -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - tv_8532WriteEEprom(gspca_dev); - - return 0; -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, val); - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* 0x84 */ -} - -static void setgain(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w2(gspca_dev, R20_GAIN_G1L, val); - reg_w2(gspca_dev, R22_GAIN_RL, val); - reg_w2(gspca_dev, R24_GAIN_BL, val); - reg_w2(gspca_dev, R26_GAIN_G2L, val); -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */ - reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03); - - /************************************************/ - reg_w1(gspca_dev, R28_QUANT, 0x90); - /* 0x72 compressed mode 0x28 */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { - /* 176x144 */ - reg_w1(gspca_dev, R29_LINE, 0x41); - /* CIF - 2 lines/packet */ - } else { - /* 352x288 */ - reg_w1(gspca_dev, R29_LINE, 0x81); - /* CIF - 2 lines/packet */ - } - /************************************************/ - reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */ - reg_w1(gspca_dev, R2D_POINT, 0x14); - reg_w1(gspca_dev, R2E_POINTH, 0x01); - reg_w1(gspca_dev, R2F_POINTB, 0x12); - reg_w1(gspca_dev, R30_POINTBH, 0x01); - - tv_8532_setReg(gspca_dev); - - /************************************************/ - reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ - msleep(200); - reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ - - gspca_dev->empty_packet = 0; /* check the empty packets */ - sd->packet = 0; /* ignore the first packets */ - - return 0; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - int packet_type0, packet_type1; - - packet_type0 = packet_type1 = INTER_PACKET; - if (gspca_dev->empty_packet) { - gspca_dev->empty_packet = 0; - sd->packet = gspca_dev->height / 2; - packet_type0 = FIRST_PACKET; - } else if (sd->packet == 0) - return; /* 2 more lines in 352x288 ! */ - sd->packet--; - if (sd->packet == 0) - packet_type1 = LAST_PACKET; - - /* each packet contains: - * - header 2 bytes - * - RGRG line - * - 4 bytes - * - GBGB line - * - 4 bytes - */ - gspca_frame_add(gspca_dev, packet_type0, - data + 2, gspca_dev->width); - gspca_frame_add(gspca_dev, packet_type1, - data + gspca_dev->width + 5, gspca_dev->width); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 2); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 0x18f, 1, 0x18f); - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 0x7ff, 1, 0x100); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0920)}, - {USB_DEVICE(0x046d, 0x0921)}, - {USB_DEVICE(0x0545, 0x808b)}, - {USB_DEVICE(0x0545, 0x8333)}, - {USB_DEVICE(0x0923, 0x010f)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c deleted file mode 100644 index e50079503d96..000000000000 --- a/drivers/media/video/gspca/vc032x.c +++ /dev/null @@ -1,3850 +0,0 @@ -/* - * Z-star vc0321 library - * - * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr> - * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl - * Copyright (C) 2006 Michel Xhaard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "vc032x" - -#include "gspca.h" - -MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); -MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct { /* hvflip cluster */ - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - }; - - u8 image_offset; - - u8 bridge; - u8 sensor; - u8 flags; -#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ -#define FL_HFLIP 0x02 /* mirrored by default */ -#define FL_VFLIP 0x04 /* vertical flipped by default */ -}; -enum bridges { - BRIDGE_VC0321, - BRIDGE_VC0323, -}; -enum sensors { - SENSOR_HV7131R, - SENSOR_MI0360, - SENSOR_MI1310_SOC, - SENSOR_MI1320, - SENSOR_MI1320_SOC, - SENSOR_OV7660, - SENSOR_OV7670, - SENSOR_PO1200, - SENSOR_PO3130NC, - SENSOR_POxxxx, - NSENSORS -}; - - -static const struct v4l2_pix_format vc0321_mode[] = { - {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format vc0323_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, - {1280, 960, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */ - .bytesperline = 1280, - .sizeimage = 1280 * 960 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, -}; -static const struct v4l2_pix_format bi_mode[] = { - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; -static const struct v4l2_pix_format svga_mode[] = { - {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 800, - .sizeimage = 800 * 600 * 1 / 4 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* OV7660/7670 registers */ -#define OV7660_REG_MVFP 0x1e -#define OV7660_MVFP_MIRROR 0x20 -#define OV7660_MVFP_VFLIP 0x10 - -static const u8 mi0360_matrix[9] = { - 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50 -}; - -static const u8 mi0360_initVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */ - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xb8, 0x00, 0x13, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, - {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, - {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, - {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x50, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, - {0xb8, 0x08, 0xe0, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, - {0xb8, 0x14, 0x18, 0xcc}, - {0xb8, 0xb2, 0x0a, 0xcc}, - {0xb8, 0xb4, 0x0a, 0xcc}, - {0xb8, 0xb5, 0x0a, 0xcc}, - {0xb8, 0xfe, 0x00, 0xcc}, - {0xb8, 0xff, 0x28, 0xcc}, - {0xb9, 0x00, 0x28, 0xcc}, - {0xb9, 0x01, 0x28, 0xcc}, - {0xb9, 0x02, 0x28, 0xcc}, - {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, - {0xb9, 0x05, 0x3c, 0xcc}, - {0xb9, 0x06, 0x3c, 0xcc}, - {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0x31, 0x00, 0x00, 0xbb}, - {0x09, 0x01, 0xc7, 0xbb}, - {0x34, 0x01, 0x00, 0xbb}, - {0x2b, 0x00, 0x28, 0xbb}, - {0x2c, 0x00, 0x30, 0xbb}, - {0x2d, 0x00, 0x30, 0xbb}, - {0x2e, 0x00, 0x28, 0xbb}, - {0x62, 0x04, 0x11, 0xbb}, - {0x03, 0x01, 0xe0, 0xbb}, - {0x2c, 0x00, 0x2c, 0xbb}, - {0x20, 0xd0, 0x00, 0xbb}, - {0x01, 0x00, 0x08, 0xbb}, - {0x06, 0x00, 0x10, 0xbb}, - {0x05, 0x00, 0x20, 0xbb}, - {0x20, 0x00, 0x00, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x02, 0xcc}, - {0xb6, 0x02, 0x80, 0xcc}, - {0xb6, 0x05, 0x01, 0xcc}, - {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, - {0xb6, 0x18, 0x02, 0xcc}, - {0xb6, 0x17, 0x58, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0x35, 0x00, 0x60, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi0360_initQVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xb8, 0x00, 0x13, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, - {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, - {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, - {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x50, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, - {0xb8, 0x08, 0xe0, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, - {0xb8, 0x14, 0x18, 0xcc}, - {0xb8, 0xb2, 0x0a, 0xcc}, - {0xb8, 0xb4, 0x0a, 0xcc}, - {0xb8, 0xb5, 0x0a, 0xcc}, - {0xb8, 0xfe, 0x00, 0xcc}, - {0xb8, 0xff, 0x28, 0xcc}, - {0xb9, 0x00, 0x28, 0xcc}, - {0xb9, 0x01, 0x28, 0xcc}, - {0xb9, 0x02, 0x28, 0xcc}, - {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, - {0xb9, 0x05, 0x3c, 0xcc}, - {0xb9, 0x06, 0x3c, 0xcc}, - {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0x31, 0x00, 0x00, 0xbb}, - {0x09, 0x01, 0xc7, 0xbb}, - {0x34, 0x01, 0x00, 0xbb}, - {0x2b, 0x00, 0x28, 0xbb}, - {0x2c, 0x00, 0x30, 0xbb}, - {0x2d, 0x00, 0x30, 0xbb}, - {0x2e, 0x00, 0x28, 0xbb}, - {0x62, 0x04, 0x11, 0xbb}, - {0x03, 0x01, 0xe0, 0xbb}, - {0x2c, 0x00, 0x2c, 0xbb}, - {0x20, 0xd0, 0x00, 0xbb}, - {0x01, 0x00, 0x08, 0xbb}, - {0x06, 0x00, 0x10, 0xbb}, - {0x05, 0x00, 0x20, 0xbb}, - {0x20, 0x00, 0x00, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, - {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, - {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, - {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0x35, 0x00, 0xef, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; - -static const u8 mi1310_socinitVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */ - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x03, 0xcc}, - {0xb3, 0x23, 0xc0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x5b, 0x00, 0x01, 0xbb}, - {0x2f, 0xde, 0x20, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */ - {0xf0, 0x00, 0x01, 0xbb}, - {0x05, 0x00, 0x07, 0xbb}, - {0x34, 0x00, 0x00, 0xbb}, - {0x35, 0xff, 0x00, 0xbb}, - {0xdc, 0x07, 0x02, 0xbb}, - {0xdd, 0x3c, 0x18, 0xbb}, - {0xde, 0x92, 0x6d, 0xbb}, - {0xdf, 0xcd, 0xb1, 0xbb}, - {0xe0, 0xff, 0xe7, 0xbb}, - {0x06, 0xf0, 0x0d, 0xbb}, - {0x06, 0x70, 0x0e, 0xbb}, - {0x4c, 0x00, 0x01, 0xbb}, - {0x4d, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x2e, 0x0c, 0x55, 0xbb}, - {0x21, 0xb6, 0x6e, 0xbb}, - {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc1, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x07, 0x00, 0x84, 0xbb}, - {0x08, 0x02, 0x4a, 0xbb}, - {0x05, 0x01, 0x10, 0xbb}, - {0x06, 0x00, 0x39, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x58, 0x02, 0x67, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x5a, 0x02, 0x67, 0xbb}, - {0x59, 0x02, 0x00, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x39, 0x06, 0x18, 0xbb}, - {0x3a, 0x06, 0x18, 0xbb}, - {0x3b, 0x06, 0x18, 0xbb}, - {0x3c, 0x06, 0x18, 0xbb}, - {0x64, 0x7b, 0x5b, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc0, 0xbb}, - {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, - {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x02, 0xcc}, - {0xb6, 0x02, 0x80, 0xcc}, - {0xb6, 0x05, 0x01, 0xcc}, - {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x25, 0xcc}, - {0xb6, 0x18, 0x02, 0xcc}, - {0xb6, 0x17, 0x58, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x80, 0x00, 0x03, 0xbb}, - {0x81, 0xc7, 0x14, 0xbb}, - {0x82, 0xeb, 0xe8, 0xbb}, - {0x83, 0xfe, 0xf4, 0xbb}, - {0x84, 0xcd, 0x10, 0xbb}, - {0x85, 0xf3, 0xee, 0xbb}, - {0x86, 0xff, 0xf1, 0xbb}, - {0x87, 0xcd, 0x10, 0xbb}, - {0x88, 0xf3, 0xee, 0xbb}, - {0x89, 0x01, 0xf1, 0xbb}, - {0x8a, 0xe5, 0x17, 0xbb}, - {0x8b, 0xe8, 0xe2, 0xbb}, - {0x8c, 0xf7, 0xed, 0xbb}, - {0x8d, 0x00, 0xff, 0xbb}, - {0x8e, 0xec, 0x10, 0xbb}, - {0x8f, 0xf0, 0xed, 0xbb}, - {0x90, 0xf9, 0xf2, 0xbb}, - {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xe9, 0x0d, 0xbb}, - {0x93, 0xf4, 0xf2, 0xbb}, - {0x94, 0xfb, 0xf5, 0xbb}, - {0x95, 0x00, 0xff, 0xbb}, - {0xb6, 0x0f, 0x08, 0xbb}, - {0xb7, 0x3d, 0x16, 0xbb}, - {0xb8, 0x0c, 0x04, 0xbb}, - {0xb9, 0x1c, 0x07, 0xbb}, - {0xba, 0x0a, 0x03, 0xbb}, - {0xbb, 0x1b, 0x09, 0xbb}, - {0xbc, 0x17, 0x0d, 0xbb}, - {0xbd, 0x23, 0x1d, 0xbb}, - {0xbe, 0x00, 0x28, 0xbb}, - {0xbf, 0x11, 0x09, 0xbb}, - {0xc0, 0x16, 0x15, 0xbb}, - {0xc1, 0x00, 0x1b, 0xbb}, - {0xc2, 0x0e, 0x07, 0xbb}, - {0xc3, 0x14, 0x10, 0xbb}, - {0xc4, 0x00, 0x17, 0xbb}, - {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xf4, 0x8e, 0xbb}, - {0x00, 0x00, 0x50, 0xdd}, - {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x24, 0x50, 0x20, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x34, 0x0c, 0x50, 0xbb}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x03, 0x03, 0xc0, 0xbb}, - {}, -}; -static const u8 mi1310_socinitQVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, - {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, - {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */ - {0xf0, 0x00, 0x01, 0xbb}, - {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, - {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, - {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, - {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, - {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, - {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, - {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, - {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, - {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, - {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, - {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, - {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, - {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, - {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, - {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, - {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, - {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, - {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, - {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, - {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, - {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, - {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, - {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, - {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, - {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, - {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, - {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, - {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, - {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, - {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, - {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, - {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x03, 0x03, 0xc0, 0xbb}, - {}, -}; -static const u8 mi1310_soc_InitSXGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x0d, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x03, 0xcc}, - {0xb3, 0x23, 0xc0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0x70, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x5b, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */ - {0xf0, 0x00, 0x01, 0xbb}, - {0x05, 0x00, 0x07, 0xbb}, - {0x34, 0x00, 0x00, 0xbb}, - {0x35, 0xff, 0x00, 0xbb}, - {0xdc, 0x07, 0x02, 0xbb}, - {0xdd, 0x3c, 0x18, 0xbb}, - {0xde, 0x92, 0x6d, 0xbb}, - {0xdf, 0xcd, 0xb1, 0xbb}, - {0xe0, 0xff, 0xe7, 0xbb}, - {0x06, 0xf0, 0x0d, 0xbb}, - {0x06, 0x70, 0x0e, 0xbb}, - {0x4c, 0x00, 0x01, 0xbb}, - {0x4d, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x2e, 0x0c, 0x60, 0xbb}, - {0x21, 0xb6, 0x6e, 0xbb}, - {0x37, 0x01, 0x40, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x07, 0x00, 0x84, 0xbb}, - {0x08, 0x02, 0x4a, 0xbb}, - {0x05, 0x01, 0x10, 0xbb}, - {0x06, 0x00, 0x39, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x58, 0x02, 0x67, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x5a, 0x02, 0x67, 0xbb}, - {0x59, 0x02, 0x00, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x39, 0x06, 0x18, 0xbb}, - {0x3a, 0x06, 0x18, 0xbb}, - {0x3b, 0x06, 0x18, 0xbb}, - {0x3c, 0x06, 0x18, 0xbb}, - {0x64, 0x7b, 0x5b, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x05, 0xcc}, - {0xb6, 0x02, 0x00, 0xcc}, - {0xb6, 0x05, 0x03, 0xcc}, - {0xb6, 0x04, 0xc0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x29, 0xcc}, - {0xb6, 0x18, 0x09, 0xcc}, - {0xb6, 0x17, 0x60, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0x00, 0x00, 0x80, 0xdd}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x06, 0xf0, 0x8e, 0xbb}, - {0x00, 0x00, 0x80, 0xdd}, - {0x06, 0x70, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x5e, 0x6a, 0x53, 0xbb}, - {0x5f, 0x40, 0x2c, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x58, 0x00, 0x00, 0xbb}, - {0x53, 0x09, 0x03, 0xbb}, - {0x54, 0x31, 0x18, 0xbb}, - {0x55, 0x8b, 0x5f, 0xbb}, - {0x56, 0xc0, 0xa9, 0xbb}, - {0x57, 0xe0, 0xd2, 0xbb}, - {0xe1, 0x00, 0x00, 0xbb}, - {0xdc, 0x09, 0x03, 0xbb}, - {0xdd, 0x31, 0x18, 0xbb}, - {0xde, 0x8b, 0x5f, 0xbb}, - {0xdf, 0xc0, 0xa9, 0xbb}, - {0xe0, 0xe0, 0xd2, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xf0, 0x8e, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x2f, 0xde, 0x20, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x24, 0x50, 0x20, 0xbb}, - {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, - {0xbc, 0x10, 0xc0, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x34, 0x0c, 0x50, 0xbb}, - {0xbc, 0x11, 0x03, 0xcc}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x80, 0x00, 0x03, 0xbb}, - {0x81, 0xc7, 0x14, 0xbb}, - {0x82, 0xeb, 0xe8, 0xbb}, - {0x83, 0xfe, 0xf4, 0xbb}, - {0x84, 0xcd, 0x10, 0xbb}, - {0x85, 0xf3, 0xee, 0xbb}, - {0x86, 0xff, 0xf1, 0xbb}, - {0x87, 0xcd, 0x10, 0xbb}, - {0x88, 0xf3, 0xee, 0xbb}, - {0x89, 0x01, 0xf1, 0xbb}, - {0x8a, 0xe5, 0x17, 0xbb}, - {0x8b, 0xe8, 0xe2, 0xbb}, - {0x8c, 0xf7, 0xed, 0xbb}, - {0x8d, 0x00, 0xff, 0xbb}, - {0x8e, 0xec, 0x10, 0xbb}, - {0x8f, 0xf0, 0xed, 0xbb}, - {0x90, 0xf9, 0xf2, 0xbb}, - {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xe9, 0x0d, 0xbb}, - {0x93, 0xf4, 0xf2, 0xbb}, - {0x94, 0xfb, 0xf5, 0xbb}, - {0x95, 0x00, 0xff, 0xbb}, - {0xb6, 0x0f, 0x08, 0xbb}, - {0xb7, 0x3d, 0x16, 0xbb}, - {0xb8, 0x0c, 0x04, 0xbb}, - {0xb9, 0x1c, 0x07, 0xbb}, - {0xba, 0x0a, 0x03, 0xbb}, - {0xbb, 0x1b, 0x09, 0xbb}, - {0xbc, 0x17, 0x0d, 0xbb}, - {0xbd, 0x23, 0x1d, 0xbb}, - {0xbe, 0x00, 0x28, 0xbb}, - {0xbf, 0x11, 0x09, 0xbb}, - {0xc0, 0x16, 0x15, 0xbb}, - {0xc1, 0x00, 0x1b, 0xbb}, - {0xc2, 0x0e, 0x07, 0xbb}, - {0xc3, 0x14, 0x10, 0xbb}, - {0xc4, 0x00, 0x17, 0xbb}, - {0x06, 0x74, 0x8e, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x03, 0x03, 0xc0, 0xbb}, - {} -}; - -static const u8 mi1320_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const u8 mi1320_matrix[9] = { - 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 -}; -static const u8 mi1320_initVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */ - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, - {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, - {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, - {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, - {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, - {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, - {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, - {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, - {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, - {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, - {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, - {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, - {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, - {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, - {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, - {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, - {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, - {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, - {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, - {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, - {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, - {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, - {0x08, 0x00, 0x27, 0xbb}, - {0x20, 0x01, 0x00, 0xbb}, /* h/v flips - was 03 */ - {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, - {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, - {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, - {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, - {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, - {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, - {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, - {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, - {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, - {} -}; -static const u8 mi1320_initQVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, - {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, - {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, - {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, - {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, - {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, - {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, - {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, - {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, - {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, - {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, - {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, - {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, - {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, - {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, - {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, - {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, - {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, - {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, - {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, - {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, - {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {} -}; - -static const u8 mi1320_soc_InitVGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */ - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitQVGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitSXGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x04, 0xcc}, - {0xb3, 0x23, 0x00, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x5b, 0x00, 0x01, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0x00, 0x00, 0x20, 0xdd}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x13, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x00, 0x85, 0xbb}, - {0x08, 0x00, 0x27, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */ - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0x0d, 0xbb}, - {0x3a, 0x06, 0x1b, 0xbb}, - {0x3b, 0x00, 0x95, 0xbb}, - {0x3c, 0x04, 0xdb, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x58, 0x02, 0x66, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0x5a, 0x01, 0x33, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x64, 0x5e, 0x1c, 0xbb}, - {} -}; -static const u8 po3130_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const u8 po3130_matrix[9] = { - 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 -}; - -static const u8 po3130_initVGA_data[][4] = { - {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, - {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, - {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, - {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */ - {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, - {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, - {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, - {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, - {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, - {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, - {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, - {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, - {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, - {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, - {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, - {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, - {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, - {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, - {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, - {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, - {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, - {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, - {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, - {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, - {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, - {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, - {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, - {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, - {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, - {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, - {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, - {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, - {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, - {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, - {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, - {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, - {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, - {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, - {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, - {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, - {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, - {0x00, 0x4c, 0x07, 0xaa}, - {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, - {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, -/* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, - {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */ - {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, - {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, - {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, - {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, - {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, - {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, - {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, - {} -}; -static const u8 po3130_rundata[][4] = { - {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, - {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, - {0x00, 0x44, 0x40, 0xaa}, -/* {0x00, 0xd5, 0x7c, 0xaa}, */ - {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa}, - {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa}, - {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa}, - {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa}, - {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa}, - {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa}, - {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, - {} -}; - -static const u8 po3130_initQVGA_data[][4] = { - {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, - {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, - {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, - {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, - {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, - {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, - {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, - {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, - {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, - {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, - {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, - {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, - {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, - {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, - {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, - {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, - {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, - {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, - {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, - {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, - {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, - {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, - {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, - {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, - {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, - {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, - {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, - {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, - {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, - {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, - {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, - {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, - {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, - {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, - {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, - {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, - {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, - {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, - {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, - {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, - {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa}, - {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, - {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, - {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, - {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, - {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, - {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, - {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, - {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, - {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, - {} -}; - -static const u8 hv7131r_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const u8 hv7131r_matrix[9] = { - 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 -}; -static const u8 hv7131r_initVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x20, 0xdd}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x01, 0x45, 0xcc}, - {0xb3, 0x03, 0x0b, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x02, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0x91, 0xcc}, /* i2c add: 11 */ - {0xb3, 0x00, 0x27, 0xcc}, - {0xbc, 0x00, 0x73, 0xcc}, - {0xb8, 0x00, 0x23, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, - {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, - {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, - {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x58, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x01, 0x7d, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0x00, 0x01, 0x0c, 0xaa}, - {0x00, 0x14, 0x01, 0xaa}, - {0x00, 0x15, 0xe6, 0xaa}, - {0x00, 0x16, 0x02, 0xaa}, - {0x00, 0x17, 0x86, 0xaa}, - {0x00, 0x23, 0x00, 0xaa}, - {0x00, 0x25, 0x03, 0xaa}, - {0x00, 0x26, 0xa9, 0xaa}, - {0x00, 0x27, 0x80, 0xaa}, - {0x00, 0x30, 0x18, 0xaa}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x02, 0xcc}, - {0xb6, 0x02, 0x80, 0xcc}, - {0xb6, 0x05, 0x01, 0xcc}, - {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, - {0xb6, 0x18, 0x02, 0xcc}, - {0xb6, 0x17, 0x58, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; - -static const u8 hv7131r_initQVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x20, 0xdd}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x01, 0x45, 0xcc}, - {0xb3, 0x03, 0x0b, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x02, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0x91, 0xcc}, - {0xb3, 0x00, 0x27, 0xcc}, - {0xbc, 0x00, 0xd3, 0xcc}, - {0xb8, 0x00, 0x23, 0xcc}, - {0xb8, 0x2c, 0x50, 0xcc}, - {0xb8, 0x2d, 0xf8, 0xcc}, - {0xb8, 0x2e, 0xf8, 0xcc}, - {0xb8, 0x2f, 0xf8, 0xcc}, - {0xb8, 0x30, 0x50, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf8, 0xcc}, - {0xb8, 0x33, 0xf8, 0xcc}, - {0xb8, 0x34, 0x58, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x01, 0x7d, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0x00, 0x01, 0x0c, 0xaa}, - {0x00, 0x14, 0x01, 0xaa}, - {0x00, 0x15, 0xe6, 0xaa}, - {0x00, 0x16, 0x02, 0xaa}, - {0x00, 0x17, 0x86, 0xaa}, - {0x00, 0x23, 0x00, 0xaa}, - {0x00, 0x25, 0x03, 0xaa}, - {0x00, 0x26, 0xa9, 0xaa}, - {0x00, 0x27, 0x80, 0xaa}, - {0x00, 0x30, 0x18, 0xaa}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, - {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, - {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, - {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; - -static const u8 ov7660_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const u8 ov7660_matrix[9] = { - 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 -}; -static const u8 ov7660_initVGA_data[][4] = { - {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, - {0x00, 0x00, 0x50, 0xdd}, - {0xb0, 0x03, 0x01, 0xcc}, - {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, - {0xb3, 0x1f, 0x02, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */ - {0xb3, 0x00, 0x26, 0xcc}, - {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ - {0xb8, 0x01, 0x7d, 0xcc}, - {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x8f, 0x50, 0xcc}, - {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, - {0x00, 0x12, 0x80, 0xaa}, - {0x00, 0x12, 0x05, 0xaa}, - {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */ - {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ - {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ - {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, - {0x00, 0x13, 0xa7, 0xaa}, - {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, - {0x00, 0x36, 0x00, 0xaa}, - {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, - {0x00, 0x39, 0x43, 0xaa}, - {0x00, 0x8d, 0xcf, 0xaa}, - {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, - {0x00, 0x0f, 0x62, 0xaa}, - {0x00, 0x35, 0x84, 0xaa}, - {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ - {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ - {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ - {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, - {0x00, 0x01, 0x80, 0xaa}, - {0x00, 0x02, 0x80, 0xaa}, - {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, - {0xb9, 0x00, 0x28, 0xcc}, - {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc}, - {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, - {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, - {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, - - {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, - - {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, - {} -}; -static const u8 ov7660_initQVGA_data[][4] = { - {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, - {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, - {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, - {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, - {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ - {0xb8, 0x01, 0x7d, 0xcc}, -/* sizer */ - {0xbc, 0x00, 0xd3, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, - {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, - {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, - {0x00, 0x1e, 0x01, 0xaa}, /* MVFP */ - {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ - {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ - {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, - {0x00, 0x13, 0xa7, 0xaa}, - {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, - {0x00, 0x36, 0x00, 0xaa}, - {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, - {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa}, - {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, - {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa}, - {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ - {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ - {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ - {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, - {0x00, 0x01, 0x80, 0xaa}, - {0x00, 0x02, 0x80, 0xaa}, -/* sizer filters */ - {0xbc, 0x02, 0x08, 0xcc}, - {0xbc, 0x03, 0x70, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xbc, 0x04, 0x08, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x3c, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x04, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, -/* */ - {0xb8, 0xfe, 0x00, 0xcc}, - {0xb8, 0xff, 0x28, 0xcc}, -/* */ - {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, - {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, - {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, - {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, - {0xb9, 0x08, 0x3c, 0xcc}, -/* */ - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, /* ff */ - {0x00, 0x29, 0x3c, 0xaa}, - {0xb3, 0x01, 0x45, 0xcc}, /* 45 */ - {} -}; - -static const u8 ov7660_50HZ[][4] = { - {0x00, 0x3b, 0x08, 0xaa}, - {0x00, 0x9d, 0x40, 0xaa}, - {0x00, 0x13, 0xa7, 0xaa}, - {} -}; - -static const u8 ov7660_60HZ[][4] = { - {0x00, 0x3b, 0x00, 0xaa}, - {0x00, 0x9e, 0x40, 0xaa}, - {0x00, 0x13, 0xa7, 0xaa}, - {} -}; - -static const u8 ov7660_NoFliker[][4] = { - {0x00, 0x13, 0x87, 0xaa}, - {} -}; - -static const u8 ov7670_InitVGA[][4] = { - {0xb3, 0x01, 0x05, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb3, 0x00, 0x66, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb0, 0x16, 0x01, 0xcc}, - {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */ - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xb3, 0x03, 0x1f, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xbc, 0x00, 0x41, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0x00, 0x12, 0x80, 0xaa}, - {0x00, 0x00, 0x20, 0xdd}, - {0x00, 0x12, 0x00, 0xaa}, - {0x00, 0x11, 0x40, 0xaa}, - {0x00, 0x6b, 0x0a, 0xaa}, - {0x00, 0x3a, 0x04, 0xaa}, - {0x00, 0x40, 0xc0, 0xaa}, - {0x00, 0x8c, 0x00, 0xaa}, - {0x00, 0x7a, 0x29, 0xaa}, - {0x00, 0x7b, 0x0e, 0xaa}, - {0x00, 0x7c, 0x1a, 0xaa}, - {0x00, 0x7d, 0x31, 0xaa}, - {0x00, 0x7e, 0x53, 0xaa}, - {0x00, 0x7f, 0x60, 0xaa}, - {0x00, 0x80, 0x6b, 0xaa}, - {0x00, 0x81, 0x73, 0xaa}, - {0x00, 0x82, 0x7b, 0xaa}, - {0x00, 0x83, 0x82, 0xaa}, - {0x00, 0x84, 0x89, 0xaa}, - {0x00, 0x85, 0x96, 0xaa}, - {0x00, 0x86, 0xa1, 0xaa}, - {0x00, 0x87, 0xb7, 0xaa}, - {0x00, 0x88, 0xcc, 0xaa}, - {0x00, 0x89, 0xe1, 0xaa}, - {0x00, 0x13, 0xe0, 0xaa}, - {0x00, 0x00, 0x00, 0xaa}, - {0x00, 0x10, 0x00, 0xaa}, - {0x00, 0x0d, 0x40, 0xaa}, - {0x00, 0x14, 0x28, 0xaa}, - {0x00, 0xa5, 0x05, 0xaa}, - {0x00, 0xab, 0x07, 0xaa}, - {0x00, 0x24, 0x95, 0xaa}, - {0x00, 0x25, 0x33, 0xaa}, - {0x00, 0x26, 0xe3, 0xaa}, - {0x00, 0x9f, 0x88, 0xaa}, - {0x00, 0xa0, 0x78, 0xaa}, - {0x00, 0x55, 0x90, 0xaa}, - {0x00, 0xa1, 0x03, 0xaa}, - {0x00, 0xa6, 0xe0, 0xaa}, - {0x00, 0xa7, 0xd8, 0xaa}, - {0x00, 0xa8, 0xf0, 0xaa}, - {0x00, 0xa9, 0x90, 0xaa}, - {0x00, 0xaa, 0x14, 0xaa}, - {0x00, 0x13, 0xe5, 0xaa}, - {0x00, 0x0e, 0x61, 0xaa}, - {0x00, 0x0f, 0x4b, 0xaa}, - {0x00, 0x16, 0x02, 0xaa}, - {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ - {0x00, 0x21, 0x02, 0xaa}, - {0x00, 0x22, 0x91, 0xaa}, - {0x00, 0x29, 0x07, 0xaa}, - {0x00, 0x33, 0x0b, 0xaa}, - {0x00, 0x35, 0x0b, 0xaa}, - {0x00, 0x37, 0x1d, 0xaa}, - {0x00, 0x38, 0x71, 0xaa}, - {0x00, 0x39, 0x2a, 0xaa}, - {0x00, 0x3c, 0x78, 0xaa}, - {0x00, 0x4d, 0x40, 0xaa}, - {0x00, 0x4e, 0x20, 0xaa}, - {0x00, 0x74, 0x19, 0xaa}, - {0x00, 0x8d, 0x4f, 0xaa}, - {0x00, 0x8e, 0x00, 0xaa}, - {0x00, 0x8f, 0x00, 0xaa}, - {0x00, 0x90, 0x00, 0xaa}, - {0x00, 0x91, 0x00, 0xaa}, - {0x00, 0x96, 0x00, 0xaa}, - {0x00, 0x9a, 0x80, 0xaa}, - {0x00, 0xb0, 0x84, 0xaa}, - {0x00, 0xb1, 0x0c, 0xaa}, - {0x00, 0xb2, 0x0e, 0xaa}, - {0x00, 0xb3, 0x82, 0xaa}, - {0x00, 0xb8, 0x0a, 0xaa}, - {0x00, 0x43, 0x14, 0xaa}, - {0x00, 0x44, 0xf0, 0xaa}, - {0x00, 0x45, 0x45, 0xaa}, - {0x00, 0x46, 0x63, 0xaa}, - {0x00, 0x47, 0x2d, 0xaa}, - {0x00, 0x48, 0x46, 0xaa}, - {0x00, 0x59, 0x88, 0xaa}, - {0x00, 0x5a, 0xa0, 0xaa}, - {0x00, 0x5b, 0xc6, 0xaa}, - {0x00, 0x5c, 0x7d, 0xaa}, - {0x00, 0x5d, 0x5f, 0xaa}, - {0x00, 0x5e, 0x19, 0xaa}, - {0x00, 0x6c, 0x0a, 0xaa}, - {0x00, 0x6d, 0x55, 0xaa}, - {0x00, 0x6e, 0x11, 0xaa}, - {0x00, 0x6f, 0x9e, 0xaa}, - {0x00, 0x69, 0x00, 0xaa}, - {0x00, 0x6a, 0x40, 0xaa}, - {0x00, 0x01, 0x40, 0xaa}, - {0x00, 0x02, 0x40, 0xaa}, - {0x00, 0x13, 0xe7, 0xaa}, - {0x00, 0x5f, 0xf0, 0xaa}, - {0x00, 0x60, 0xf0, 0xaa}, - {0x00, 0x61, 0xf0, 0xaa}, - {0x00, 0x27, 0xa0, 0xaa}, - {0x00, 0x28, 0x80, 0xaa}, - {0x00, 0x2c, 0x90, 0xaa}, - {0x00, 0x4f, 0x66, 0xaa}, - {0x00, 0x50, 0x66, 0xaa}, - {0x00, 0x51, 0x00, 0xaa}, - {0x00, 0x52, 0x22, 0xaa}, - {0x00, 0x53, 0x5e, 0xaa}, - {0x00, 0x54, 0x80, 0xaa}, - {0x00, 0x58, 0x9e, 0xaa}, - {0x00, 0x41, 0x08, 0xaa}, - {0x00, 0x3f, 0x00, 0xaa}, - {0x00, 0x75, 0x85, 0xaa}, - {0x00, 0x76, 0xe1, 0xaa}, - {0x00, 0x4c, 0x00, 0xaa}, - {0x00, 0x77, 0x0a, 0xaa}, - {0x00, 0x3d, 0x88, 0xaa}, - {0x00, 0x4b, 0x09, 0xaa}, - {0x00, 0xc9, 0x60, 0xaa}, - {0x00, 0x41, 0x38, 0xaa}, - {0x00, 0x62, 0x30, 0xaa}, - {0x00, 0x63, 0x30, 0xaa}, - {0x00, 0x64, 0x08, 0xaa}, - {0x00, 0x94, 0x07, 0xaa}, - {0x00, 0x95, 0x0b, 0xaa}, - {0x00, 0x65, 0x00, 0xaa}, - {0x00, 0x66, 0x05, 0xaa}, - {0x00, 0x56, 0x50, 0xaa}, - {0x00, 0x34, 0x11, 0xaa}, - {0x00, 0xa4, 0x88, 0xaa}, - {0x00, 0x96, 0x00, 0xaa}, - {0x00, 0x97, 0x30, 0xaa}, - {0x00, 0x98, 0x20, 0xaa}, - {0x00, 0x99, 0x30, 0xaa}, - {0x00, 0x9a, 0x84, 0xaa}, - {0x00, 0x9b, 0x29, 0xaa}, - {0x00, 0x9c, 0x03, 0xaa}, - {0x00, 0x78, 0x04, 0xaa}, - {0x00, 0x79, 0x01, 0xaa}, - {0x00, 0xc8, 0xf0, 0xaa}, - {0x00, 0x79, 0x0f, 0xaa}, - {0x00, 0xc8, 0x00, 0xaa}, - {0x00, 0x79, 0x10, 0xaa}, - {0x00, 0xc8, 0x7e, 0xaa}, - {0x00, 0x79, 0x0a, 0xaa}, - {0x00, 0xc8, 0x80, 0xaa}, - {0x00, 0x79, 0x0b, 0xaa}, - {0x00, 0xc8, 0x01, 0xaa}, - {0x00, 0x79, 0x0c, 0xaa}, - {0x00, 0xc8, 0x0f, 0xaa}, - {0x00, 0x79, 0x0d, 0xaa}, - {0x00, 0xc8, 0x20, 0xaa}, - {0x00, 0x79, 0x09, 0xaa}, - {0x00, 0xc8, 0x80, 0xaa}, - {0x00, 0x79, 0x02, 0xaa}, - {0x00, 0xc8, 0xc0, 0xaa}, - {0x00, 0x79, 0x03, 0xaa}, - {0x00, 0xc8, 0x40, 0xaa}, - {0x00, 0x79, 0x05, 0xaa}, - {0x00, 0xc8, 0x30, 0xaa}, - {0x00, 0x79, 0x26, 0xaa}, - {0x00, 0x11, 0x40, 0xaa}, - {0x00, 0x3a, 0x04, 0xaa}, - {0x00, 0x12, 0x00, 0xaa}, - {0x00, 0x40, 0xc0, 0xaa}, - {0x00, 0x8c, 0x00, 0xaa}, - {0x00, 0x17, 0x14, 0xaa}, - {0x00, 0x18, 0x02, 0xaa}, - {0x00, 0x32, 0x92, 0xaa}, - {0x00, 0x19, 0x02, 0xaa}, - {0x00, 0x1a, 0x7a, 0xaa}, - {0x00, 0x03, 0x0a, 0xaa}, - {0x00, 0x0c, 0x00, 0xaa}, - {0x00, 0x3e, 0x00, 0xaa}, - {0x00, 0x70, 0x3a, 0xaa}, - {0x00, 0x71, 0x35, 0xaa}, - {0x00, 0x72, 0x11, 0xaa}, - {0x00, 0x73, 0xf0, 0xaa}, - {0x00, 0xa2, 0x02, 0xaa}, - {0x00, 0xb1, 0x00, 0xaa}, - {0x00, 0xb1, 0x0c, 0xaa}, - {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ - {0x00, 0xaa, 0x14, 0xaa}, - {0x00, 0x24, 0x80, 0xaa}, - {0x00, 0x25, 0x74, 0xaa}, - {0x00, 0x26, 0xd3, 0xaa}, - {0x00, 0x0d, 0x00, 0xaa}, - {0x00, 0x14, 0x18, 0xaa}, - {0x00, 0x9d, 0x99, 0xaa}, - {0x00, 0x9e, 0x7f, 0xaa}, - {0x00, 0x64, 0x08, 0xaa}, - {0x00, 0x94, 0x07, 0xaa}, - {0x00, 0x95, 0x06, 0xaa}, - {0x00, 0x66, 0x05, 0xaa}, - {0x00, 0x41, 0x08, 0xaa}, - {0x00, 0x3f, 0x00, 0xaa}, - {0x00, 0x75, 0x07, 0xaa}, - {0x00, 0x76, 0xe1, 0xaa}, - {0x00, 0x4c, 0x00, 0xaa}, - {0x00, 0x77, 0x00, 0xaa}, - {0x00, 0x3d, 0xc2, 0xaa}, - {0x00, 0x4b, 0x09, 0xaa}, - {0x00, 0xc9, 0x60, 0xaa}, - {0x00, 0x41, 0x38, 0xaa}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x01, 0x45, 0xcc}, - {0x00, 0x77, 0x05, 0xaa}, - {}, -}; - -static const u8 ov7670_InitQVGA[][4] = { - {0xb3, 0x01, 0x05, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb3, 0x00, 0x66, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb0, 0x16, 0x01, 0xcc}, - {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */ - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xb3, 0x03, 0x1f, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0x00, 0x12, 0x80, 0xaa}, - {0x00, 0x00, 0x20, 0xdd}, - {0x00, 0x12, 0x00, 0xaa}, - {0x00, 0x11, 0x40, 0xaa}, - {0x00, 0x6b, 0x0a, 0xaa}, - {0x00, 0x3a, 0x04, 0xaa}, - {0x00, 0x40, 0xc0, 0xaa}, - {0x00, 0x8c, 0x00, 0xaa}, - {0x00, 0x7a, 0x29, 0xaa}, - {0x00, 0x7b, 0x0e, 0xaa}, - {0x00, 0x7c, 0x1a, 0xaa}, - {0x00, 0x7d, 0x31, 0xaa}, - {0x00, 0x7e, 0x53, 0xaa}, - {0x00, 0x7f, 0x60, 0xaa}, - {0x00, 0x80, 0x6b, 0xaa}, - {0x00, 0x81, 0x73, 0xaa}, - {0x00, 0x82, 0x7b, 0xaa}, - {0x00, 0x83, 0x82, 0xaa}, - {0x00, 0x84, 0x89, 0xaa}, - {0x00, 0x85, 0x96, 0xaa}, - {0x00, 0x86, 0xa1, 0xaa}, - {0x00, 0x87, 0xb7, 0xaa}, - {0x00, 0x88, 0xcc, 0xaa}, - {0x00, 0x89, 0xe1, 0xaa}, - {0x00, 0x13, 0xe0, 0xaa}, - {0x00, 0x00, 0x00, 0xaa}, - {0x00, 0x10, 0x00, 0xaa}, - {0x00, 0x0d, 0x40, 0xaa}, - {0x00, 0x14, 0x28, 0xaa}, - {0x00, 0xa5, 0x05, 0xaa}, - {0x00, 0xab, 0x07, 0xaa}, - {0x00, 0x24, 0x95, 0xaa}, - {0x00, 0x25, 0x33, 0xaa}, - {0x00, 0x26, 0xe3, 0xaa}, - {0x00, 0x9f, 0x88, 0xaa}, - {0x00, 0xa0, 0x78, 0xaa}, - {0x00, 0x55, 0x90, 0xaa}, - {0x00, 0xa1, 0x03, 0xaa}, - {0x00, 0xa6, 0xe0, 0xaa}, - {0x00, 0xa7, 0xd8, 0xaa}, - {0x00, 0xa8, 0xf0, 0xaa}, - {0x00, 0xa9, 0x90, 0xaa}, - {0x00, 0xaa, 0x14, 0xaa}, - {0x00, 0x13, 0xe5, 0xaa}, - {0x00, 0x0e, 0x61, 0xaa}, - {0x00, 0x0f, 0x4b, 0xaa}, - {0x00, 0x16, 0x02, 0xaa}, - {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ - {0x00, 0x21, 0x02, 0xaa}, - {0x00, 0x22, 0x91, 0xaa}, - {0x00, 0x29, 0x07, 0xaa}, - {0x00, 0x33, 0x0b, 0xaa}, - {0x00, 0x35, 0x0b, 0xaa}, - {0x00, 0x37, 0x1d, 0xaa}, - {0x00, 0x38, 0x71, 0xaa}, - {0x00, 0x39, 0x2a, 0xaa}, - {0x00, 0x3c, 0x78, 0xaa}, - {0x00, 0x4d, 0x40, 0xaa}, - {0x00, 0x4e, 0x20, 0xaa}, - {0x00, 0x74, 0x19, 0xaa}, - {0x00, 0x8d, 0x4f, 0xaa}, - {0x00, 0x8e, 0x00, 0xaa}, - {0x00, 0x8f, 0x00, 0xaa}, - {0x00, 0x90, 0x00, 0xaa}, - {0x00, 0x91, 0x00, 0xaa}, - {0x00, 0x96, 0x00, 0xaa}, - {0x00, 0x9a, 0x80, 0xaa}, - {0x00, 0xb0, 0x84, 0xaa}, - {0x00, 0xb1, 0x0c, 0xaa}, - {0x00, 0xb2, 0x0e, 0xaa}, - {0x00, 0xb3, 0x82, 0xaa}, - {0x00, 0xb8, 0x0a, 0xaa}, - {0x00, 0x43, 0x14, 0xaa}, - {0x00, 0x44, 0xf0, 0xaa}, - {0x00, 0x45, 0x45, 0xaa}, - {0x00, 0x46, 0x63, 0xaa}, - {0x00, 0x47, 0x2d, 0xaa}, - {0x00, 0x48, 0x46, 0xaa}, - {0x00, 0x59, 0x88, 0xaa}, - {0x00, 0x5a, 0xa0, 0xaa}, - {0x00, 0x5b, 0xc6, 0xaa}, - {0x00, 0x5c, 0x7d, 0xaa}, - {0x00, 0x5d, 0x5f, 0xaa}, - {0x00, 0x5e, 0x19, 0xaa}, - {0x00, 0x6c, 0x0a, 0xaa}, - {0x00, 0x6d, 0x55, 0xaa}, - {0x00, 0x6e, 0x11, 0xaa}, - {0x00, 0x6f, 0x9e, 0xaa}, - {0x00, 0x69, 0x00, 0xaa}, - {0x00, 0x6a, 0x40, 0xaa}, - {0x00, 0x01, 0x40, 0xaa}, - {0x00, 0x02, 0x40, 0xaa}, - {0x00, 0x13, 0xe7, 0xaa}, - {0x00, 0x5f, 0xf0, 0xaa}, - {0x00, 0x60, 0xf0, 0xaa}, - {0x00, 0x61, 0xf0, 0xaa}, - {0x00, 0x27, 0xa0, 0xaa}, - {0x00, 0x28, 0x80, 0xaa}, - {0x00, 0x2c, 0x90, 0xaa}, - {0x00, 0x4f, 0x66, 0xaa}, - {0x00, 0x50, 0x66, 0xaa}, - {0x00, 0x51, 0x00, 0xaa}, - {0x00, 0x52, 0x22, 0xaa}, - {0x00, 0x53, 0x5e, 0xaa}, - {0x00, 0x54, 0x80, 0xaa}, - {0x00, 0x58, 0x9e, 0xaa}, - {0x00, 0x41, 0x08, 0xaa}, - {0x00, 0x3f, 0x00, 0xaa}, - {0x00, 0x75, 0x85, 0xaa}, - {0x00, 0x76, 0xe1, 0xaa}, - {0x00, 0x4c, 0x00, 0xaa}, - {0x00, 0x77, 0x0a, 0xaa}, - {0x00, 0x3d, 0x88, 0xaa}, - {0x00, 0x4b, 0x09, 0xaa}, - {0x00, 0xc9, 0x60, 0xaa}, - {0x00, 0x41, 0x38, 0xaa}, - {0x00, 0x62, 0x30, 0xaa}, - {0x00, 0x63, 0x30, 0xaa}, - {0x00, 0x64, 0x08, 0xaa}, - {0x00, 0x94, 0x07, 0xaa}, - {0x00, 0x95, 0x0b, 0xaa}, - {0x00, 0x65, 0x00, 0xaa}, - {0x00, 0x66, 0x05, 0xaa}, - {0x00, 0x56, 0x50, 0xaa}, - {0x00, 0x34, 0x11, 0xaa}, - {0x00, 0xa4, 0x88, 0xaa}, - {0x00, 0x96, 0x00, 0xaa}, - {0x00, 0x97, 0x30, 0xaa}, - {0x00, 0x98, 0x20, 0xaa}, - {0x00, 0x99, 0x30, 0xaa}, - {0x00, 0x9a, 0x84, 0xaa}, - {0x00, 0x9b, 0x29, 0xaa}, - {0x00, 0x9c, 0x03, 0xaa}, - {0x00, 0x78, 0x04, 0xaa}, - {0x00, 0x79, 0x01, 0xaa}, - {0x00, 0xc8, 0xf0, 0xaa}, - {0x00, 0x79, 0x0f, 0xaa}, - {0x00, 0xc8, 0x00, 0xaa}, - {0x00, 0x79, 0x10, 0xaa}, - {0x00, 0xc8, 0x7e, 0xaa}, - {0x00, 0x79, 0x0a, 0xaa}, - {0x00, 0xc8, 0x80, 0xaa}, - {0x00, 0x79, 0x0b, 0xaa}, - {0x00, 0xc8, 0x01, 0xaa}, - {0x00, 0x79, 0x0c, 0xaa}, - {0x00, 0xc8, 0x0f, 0xaa}, - {0x00, 0x79, 0x0d, 0xaa}, - {0x00, 0xc8, 0x20, 0xaa}, - {0x00, 0x79, 0x09, 0xaa}, - {0x00, 0xc8, 0x80, 0xaa}, - {0x00, 0x79, 0x02, 0xaa}, - {0x00, 0xc8, 0xc0, 0xaa}, - {0x00, 0x79, 0x03, 0xaa}, - {0x00, 0xc8, 0x40, 0xaa}, - {0x00, 0x79, 0x05, 0xaa}, - {0x00, 0xc8, 0x30, 0xaa}, - {0x00, 0x79, 0x26, 0xaa}, - {0x00, 0x11, 0x40, 0xaa}, - {0x00, 0x3a, 0x04, 0xaa}, - {0x00, 0x12, 0x00, 0xaa}, - {0x00, 0x40, 0xc0, 0xaa}, - {0x00, 0x8c, 0x00, 0xaa}, - {0x00, 0x17, 0x14, 0xaa}, - {0x00, 0x18, 0x02, 0xaa}, - {0x00, 0x32, 0x92, 0xaa}, - {0x00, 0x19, 0x02, 0xaa}, - {0x00, 0x1a, 0x7a, 0xaa}, - {0x00, 0x03, 0x0a, 0xaa}, - {0x00, 0x0c, 0x00, 0xaa}, - {0x00, 0x3e, 0x00, 0xaa}, - {0x00, 0x70, 0x3a, 0xaa}, - {0x00, 0x71, 0x35, 0xaa}, - {0x00, 0x72, 0x11, 0xaa}, - {0x00, 0x73, 0xf0, 0xaa}, - {0x00, 0xa2, 0x02, 0xaa}, - {0x00, 0xb1, 0x00, 0xaa}, - {0x00, 0xb1, 0x0c, 0xaa}, - {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ - {0x00, 0xaa, 0x14, 0xaa}, - {0x00, 0x24, 0x80, 0xaa}, - {0x00, 0x25, 0x74, 0xaa}, - {0x00, 0x26, 0xd3, 0xaa}, - {0x00, 0x0d, 0x00, 0xaa}, - {0x00, 0x14, 0x18, 0xaa}, - {0x00, 0x9d, 0x99, 0xaa}, - {0x00, 0x9e, 0x7f, 0xaa}, - {0x00, 0x64, 0x08, 0xaa}, - {0x00, 0x94, 0x07, 0xaa}, - {0x00, 0x95, 0x06, 0xaa}, - {0x00, 0x66, 0x05, 0xaa}, - {0x00, 0x41, 0x08, 0xaa}, - {0x00, 0x3f, 0x00, 0xaa}, - {0x00, 0x75, 0x07, 0xaa}, - {0x00, 0x76, 0xe1, 0xaa}, - {0x00, 0x4c, 0x00, 0xaa}, - {0x00, 0x77, 0x00, 0xaa}, - {0x00, 0x3d, 0xc2, 0xaa}, - {0x00, 0x4b, 0x09, 0xaa}, - {0x00, 0xc9, 0x60, 0xaa}, - {0x00, 0x41, 0x38, 0xaa}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x01, 0x45, 0xcc}, - {0x00, 0x77, 0x05, 0xaa}, - {}, -}; - -/* PO1200 - values from usbvm326.inf and ms-win trace */ -static const u8 po1200_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const u8 po1200_matrix[9] = { - 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e -}; -static const u8 po1200_initVGA_data[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, /* reset? */ - {0xb0, 0x03, 0x19, 0xcc}, -/* {0x00, 0x00, 0x33, 0xdd}, */ - {0xb0, 0x04, 0x02, 0xcc}, - {0xb0, 0x02, 0x02, 0xcc}, - {0xb3, 0x5d, 0x00, 0xcc}, - {0xb3, 0x01, 0x01, 0xcc}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x02, 0xb2, 0xcc}, - {0xb3, 0x03, 0x18, 0xcc}, - {0xb3, 0x04, 0x15, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x02, 0xcc}, - {0xb3, 0x23, 0x58, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x03, 0xcc}, - {0xb3, 0x17, 0x1f, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb0, 0x54, 0x13, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0xdc, 0xcc}, /* i2c add: 5c */ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x12, 0x05, 0xaa}, - {0x00, 0x13, 0x02, 0xaa}, - {0x00, 0x1e, 0xc6, 0xaa}, /* h/v flip */ - {0x00, 0x21, 0x00, 0xaa}, - {0x00, 0x25, 0x02, 0xaa}, - {0x00, 0x3c, 0x4f, 0xaa}, - {0x00, 0x3f, 0xe0, 0xaa}, - {0x00, 0x42, 0xff, 0xaa}, - {0x00, 0x45, 0x34, 0xaa}, - {0x00, 0x55, 0xfe, 0xaa}, - {0x00, 0x59, 0xd3, 0xaa}, - {0x00, 0x5e, 0x04, 0xaa}, - {0x00, 0x61, 0xb8, 0xaa}, /* sharpness */ - {0x00, 0x62, 0x02, 0xaa}, - {0x00, 0xa7, 0x31, 0xaa}, - {0x00, 0xa9, 0x66, 0xaa}, - {0x00, 0xb0, 0x00, 0xaa}, - {0x00, 0xb1, 0x00, 0xaa}, - {0x00, 0xb3, 0x11, 0xaa}, - {0x00, 0xb6, 0x26, 0xaa}, - {0x00, 0xb7, 0x20, 0xaa}, - {0x00, 0xba, 0x04, 0xaa}, - {0x00, 0x88, 0x42, 0xaa}, - {0x00, 0x89, 0x9a, 0xaa}, - {0x00, 0x8a, 0x88, 0xaa}, - {0x00, 0x8b, 0x8e, 0xaa}, - {0x00, 0x8c, 0x3e, 0xaa}, - {0x00, 0x8d, 0x90, 0xaa}, - {0x00, 0x8e, 0x87, 0xaa}, - {0x00, 0x8f, 0x96, 0xaa}, - {0x00, 0x90, 0x3d, 0xaa}, - {0x00, 0x64, 0x00, 0xaa}, - {0x00, 0x65, 0x10, 0xaa}, - {0x00, 0x66, 0x20, 0xaa}, - {0x00, 0x67, 0x2b, 0xaa}, - {0x00, 0x68, 0x36, 0xaa}, - {0x00, 0x69, 0x49, 0xaa}, - {0x00, 0x6a, 0x5a, 0xaa}, - {0x00, 0x6b, 0x7f, 0xaa}, - {0x00, 0x6c, 0x9b, 0xaa}, - {0x00, 0x6d, 0xba, 0xaa}, - {0x00, 0x6e, 0xd4, 0xaa}, - {0x00, 0x6f, 0xea, 0xaa}, - {0x00, 0x70, 0x00, 0xaa}, - {0x00, 0x71, 0x10, 0xaa}, - {0x00, 0x72, 0x20, 0xaa}, - {0x00, 0x73, 0x2b, 0xaa}, - {0x00, 0x74, 0x36, 0xaa}, - {0x00, 0x75, 0x49, 0xaa}, - {0x00, 0x76, 0x5a, 0xaa}, - {0x00, 0x77, 0x7f, 0xaa}, - {0x00, 0x78, 0x9b, 0xaa}, - {0x00, 0x79, 0xba, 0xaa}, - {0x00, 0x7a, 0xd4, 0xaa}, - {0x00, 0x7b, 0xea, 0xaa}, - {0x00, 0x7c, 0x00, 0xaa}, - {0x00, 0x7d, 0x10, 0xaa}, - {0x00, 0x7e, 0x20, 0xaa}, - {0x00, 0x7f, 0x2b, 0xaa}, - {0x00, 0x80, 0x36, 0xaa}, - {0x00, 0x81, 0x49, 0xaa}, - {0x00, 0x82, 0x5a, 0xaa}, - {0x00, 0x83, 0x7f, 0xaa}, - {0x00, 0x84, 0x9b, 0xaa}, - {0x00, 0x85, 0xba, 0xaa}, - {0x00, 0x86, 0xd4, 0xaa}, - {0x00, 0x87, 0xea, 0xaa}, - {0x00, 0x57, 0x2a, 0xaa}, - {0x00, 0x03, 0x01, 0xaa}, - {0x00, 0x04, 0x10, 0xaa}, - {0x00, 0x05, 0x10, 0xaa}, - {0x00, 0x06, 0x10, 0xaa}, - {0x00, 0x07, 0x10, 0xaa}, - {0x00, 0x08, 0x13, 0xaa}, - {0x00, 0x0a, 0x00, 0xaa}, - {0x00, 0x0b, 0x10, 0xaa}, - {0x00, 0x0c, 0x20, 0xaa}, - {0x00, 0x0d, 0x18, 0xaa}, - {0x00, 0x22, 0x01, 0xaa}, - {0x00, 0x23, 0x60, 0xaa}, - {0x00, 0x25, 0x08, 0xaa}, - {0x00, 0x26, 0x82, 0xaa}, - {0x00, 0x2e, 0x0f, 0xaa}, - {0x00, 0x2f, 0x1e, 0xaa}, - {0x00, 0x30, 0x2d, 0xaa}, - {0x00, 0x31, 0x3c, 0xaa}, - {0x00, 0x32, 0x4b, 0xaa}, - {0x00, 0x33, 0x5a, 0xaa}, - {0x00, 0x34, 0x69, 0xaa}, - {0x00, 0x35, 0x78, 0xaa}, - {0x00, 0x36, 0x87, 0xaa}, - {0x00, 0x37, 0x96, 0xaa}, - {0x00, 0x38, 0xa5, 0xaa}, - {0x00, 0x39, 0xb4, 0xaa}, - {0x00, 0x3a, 0xc3, 0xaa}, - {0x00, 0x3b, 0xd2, 0xaa}, - {0x00, 0x3c, 0xe1, 0xaa}, - {0x00, 0x3e, 0xff, 0xaa}, - {0x00, 0x3f, 0xff, 0xaa}, - {0x00, 0x40, 0xff, 0xaa}, - {0x00, 0x41, 0xff, 0xaa}, - {0x00, 0x42, 0xff, 0xaa}, - {0x00, 0x43, 0xff, 0xaa}, - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x20, 0xc4, 0xaa}, - {0x00, 0x13, 0x03, 0xaa}, - {0x00, 0x3c, 0x50, 0xaa}, - {0x00, 0x61, 0x6a, 0xaa}, /* sharpness? */ - {0x00, 0x51, 0x5b, 0xaa}, - {0x00, 0x52, 0x91, 0xaa}, - {0x00, 0x53, 0x4c, 0xaa}, - {0x00, 0x54, 0x50, 0xaa}, - {0x00, 0x56, 0x02, 0xaa}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x03, 0xcc}, - {0xb6, 0x02, 0x20, 0xcc}, - {0xb6, 0x05, 0x02, 0xcc}, - {0xb6, 0x04, 0x58, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x21, 0xcc}, - {0xb6, 0x18, 0x03, 0xcc}, - {0xb6, 0x17, 0xa9, 0xcc}, - {0xb6, 0x16, 0x80, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xb8, 0x06, 0x20, 0xcc}, - {0xb8, 0x07, 0x03, 0xcc}, - {0xb8, 0x08, 0x58, 0xcc}, - {0xb8, 0x09, 0x02, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0xd9, 0x0f, 0xaa}, - {0x00, 0xda, 0xaa, 0xaa}, - {0x00, 0xd9, 0x10, 0xaa}, - {0x00, 0xda, 0xaa, 0xaa}, - {0x00, 0xd9, 0x11, 0xaa}, - {0x00, 0xda, 0x00, 0xaa}, - {0x00, 0xd9, 0x12, 0xaa}, - {0x00, 0xda, 0xff, 0xaa}, - {0x00, 0xd9, 0x13, 0xaa}, - {0x00, 0xda, 0xff, 0xaa}, - {0x00, 0xe8, 0x11, 0xaa}, - {0x00, 0xe9, 0x12, 0xaa}, - {0x00, 0xea, 0x5c, 0xaa}, - {0x00, 0xeb, 0xff, 0xaa}, - {0x00, 0xd8, 0x80, 0xaa}, - {0x00, 0xe6, 0x02, 0xaa}, - {0x00, 0xd6, 0x40, 0xaa}, - {0x00, 0xe3, 0x05, 0xaa}, - {0x00, 0xe0, 0x40, 0xaa}, - {0x00, 0xde, 0x03, 0xaa}, - {0x00, 0xdf, 0x03, 0xaa}, - {0x00, 0xdb, 0x02, 0xaa}, - {0x00, 0xdc, 0x00, 0xaa}, - {0x00, 0xdd, 0x03, 0xaa}, - {0x00, 0xe1, 0x08, 0xaa}, - {0x00, 0xe2, 0x01, 0xaa}, - {0x00, 0xd6, 0x40, 0xaa}, - {0x00, 0xe4, 0x40, 0xaa}, - {0x00, 0xa8, 0x8f, 0xaa}, - {0x00, 0xb4, 0x16, 0xaa}, - {0xb0, 0x02, 0x06, 0xcc}, - {0xb0, 0x18, 0x06, 0xcc}, - {0xb0, 0x19, 0x06, 0xcc}, - {0xb3, 0x5d, 0x18, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0x00, 0xb4, 0x0e, 0xaa}, - {0x00, 0xb5, 0x49, 0xaa}, - {0x00, 0xb6, 0x1c, 0xaa}, - {0x00, 0xb7, 0x96, 0xaa}, -/* end of usbvm326.inf - start of ms-win trace */ - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x3d, 0xcc}, -/*read b306*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x1a, 0x09, 0xaa}, - {0x00, 0x1b, 0x8a, 0xaa}, -/*read b827*/ - {0xb8, 0x27, 0x00, 0xcc}, - {0xb8, 0x26, 0x60, 0xcc}, - {0xb8, 0x26, 0x60, 0xcc}, -/*gamma - to do?*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0xae, 0x84, 0xaa}, -/*gamma again*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x96, 0xa0, 0xaa}, -/*matrix*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x91, 0x35, 0xaa}, - {0x00, 0x92, 0x22, 0xaa}, -/*gamma*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x95, 0x85, 0xaa}, -/*matrix*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x4d, 0x20, 0xaa}, - {0xb8, 0x22, 0x40, 0xcc}, - {0xb8, 0x23, 0x40, 0xcc}, - {0xb8, 0x24, 0x40, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0x00, 0x00, 0x64, 0xdd}, - {0x00, 0x03, 0x01, 0xaa}, -/*read 46*/ - {0x00, 0x46, 0x3c, 0xaa}, - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0x16, 0x40, 0xaa}, - {0x00, 0x17, 0x40, 0xaa}, - {0x00, 0x18, 0x40, 0xaa}, - {0x00, 0x19, 0x41, 0xaa}, - {0x00, 0x03, 0x01, 0xaa}, - {0x00, 0x46, 0x3c, 0xaa}, - {0x00, 0x00, 0x18, 0xdd}, -/*read bfff*/ - {0x00, 0x03, 0x00, 0xaa}, - {0x00, 0xb4, 0x1c, 0xaa}, - {0x00, 0xb5, 0x92, 0xaa}, - {0x00, 0xb6, 0x39, 0xaa}, - {0x00, 0xb7, 0x24, 0xaa}, -/*write 89 0400 1415*/ - {} -}; - -static const u8 poxxxx_init_common[][4] = { - {0xb3, 0x00, 0x04, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb3, 0x00, 0x65, 0xcc}, - {0x00, 0x00, 0x10, 0xdd}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb0, 0x03, 0x09, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x01, 0xcc}, - {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */ - {0xb3, 0x02, 0xb0, 0xcc}, - {0xb3, 0x03, 0x18, 0xcc}, - {0xb3, 0x04, 0x15, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x04, 0xcc}, /* sensor height = 1024 */ - {0xb3, 0x23, 0x00, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, /* sensor width = 1280 */ - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x2c, 0x03, 0xcc}, - {0xb3, 0x2d, 0x56, 0xcc}, - {0xb3, 0x2e, 0x02, 0xcc}, - {0xb3, 0x2f, 0x0a, 0xcc}, - {0xb3, 0x40, 0x00, 0xcc}, - {0xb3, 0x41, 0x34, 0xcc}, - {0xb3, 0x42, 0x01, 0xcc}, - {0xb3, 0x43, 0xe0, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb3, 0x4d, 0x00, 0xcc}, - {0x00, 0x0b, 0x2a, 0xaa}, - {0x00, 0x0e, 0x03, 0xaa}, - {0x00, 0x0f, 0xea, 0xaa}, - {0x00, 0x12, 0x08, 0xaa}, - {0x00, 0x1e, 0x06, 0xaa}, - {0x00, 0x21, 0x00, 0xaa}, - {0x00, 0x31, 0x1f, 0xaa}, - {0x00, 0x33, 0x38, 0xaa}, - {0x00, 0x36, 0xc0, 0xaa}, - {0x00, 0x37, 0xc8, 0xaa}, - {0x00, 0x3b, 0x36, 0xaa}, - {0x00, 0x4b, 0xfe, 0xaa}, - {0x00, 0x4d, 0x2e, 0xaa}, - {0x00, 0x51, 0x1c, 0xaa}, - {0x00, 0x52, 0x01, 0xaa}, - {0x00, 0x55, 0x0a, 0xaa}, - {0x00, 0x56, 0x0a, 0xaa}, - {0x00, 0x57, 0x07, 0xaa}, - {0x00, 0x58, 0x07, 0xaa}, - {0x00, 0x59, 0x04, 0xaa}, - {0x00, 0x70, 0x68, 0xaa}, - {0x00, 0x71, 0x04, 0xaa}, - {0x00, 0x72, 0x10, 0xaa}, - {0x00, 0x80, 0x71, 0xaa}, - {0x00, 0x81, 0x08, 0xaa}, - {0x00, 0x82, 0x00, 0xaa}, - {0x00, 0x83, 0x55, 0xaa}, - {0x00, 0x84, 0x06, 0xaa}, - {0x00, 0x85, 0x06, 0xaa}, - {0x00, 0x8b, 0x25, 0xaa}, - {0x00, 0x8c, 0x00, 0xaa}, - {0x00, 0x8d, 0x86, 0xaa}, - {0x00, 0x8e, 0x82, 0xaa}, - {0x00, 0x8f, 0x2d, 0xaa}, - {0x00, 0x90, 0x8b, 0xaa}, - {0x00, 0x91, 0x81, 0xaa}, - {0x00, 0x92, 0x81, 0xaa}, - {0x00, 0x93, 0x23, 0xaa}, - {0x00, 0xa3, 0x2a, 0xaa}, - {0x00, 0xa4, 0x03, 0xaa}, - {0x00, 0xa5, 0xea, 0xaa}, - {0x00, 0xb0, 0x68, 0xaa}, - {0x00, 0xbc, 0x04, 0xaa}, - {0x00, 0xbe, 0x3b, 0xaa}, - {0x00, 0x4e, 0x40, 0xaa}, - {0x00, 0x06, 0x04, 0xaa}, - {0x00, 0x07, 0x03, 0xaa}, - {0x00, 0xcd, 0x18, 0xaa}, - {0x00, 0x28, 0x03, 0xaa}, - {0x00, 0x29, 0xef, 0xaa}, -/* reinit on alt 2 (qvga) or alt7 (vga) */ - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb8, 0x00, 0x01, 0xcc}, - - {0x00, 0x1d, 0x85, 0xaa}, - {0x00, 0x1e, 0xc6, 0xaa}, - {0x00, 0x00, 0x40, 0xdd}, - {0x00, 0x1d, 0x05, 0xaa}, - {} -}; -static const u8 poxxxx_gamma[][4] = { - {0x00, 0xd6, 0x22, 0xaa}, /* gamma 0 */ - {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x0a, 0xaa}, - {0x00, 0x75, 0x16, 0xaa}, - {0x00, 0x76, 0x25, 0xaa}, - {0x00, 0x77, 0x34, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, - {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, - {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, - {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, - - {0x00, 0xd6, 0x62, 0xaa}, /* gamma 1 */ - {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x0a, 0xaa}, - {0x00, 0x75, 0x16, 0xaa}, - {0x00, 0x76, 0x25, 0xaa}, - {0x00, 0x77, 0x34, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, - {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, - {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, - {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, - - {0x00, 0xd6, 0xa2, 0xaa}, /* gamma 2 */ - {0x00, 0x73, 0x00, 0xaa}, - {0x00, 0x74, 0x0a, 0xaa}, - {0x00, 0x75, 0x16, 0xaa}, - {0x00, 0x76, 0x25, 0xaa}, - {0x00, 0x77, 0x34, 0xaa}, - {0x00, 0x78, 0x49, 0xaa}, - {0x00, 0x79, 0x5a, 0xaa}, - {0x00, 0x7a, 0x7f, 0xaa}, - {0x00, 0x7b, 0x9b, 0xaa}, - {0x00, 0x7c, 0xba, 0xaa}, - {0x00, 0x7d, 0xd4, 0xaa}, - {0x00, 0x7e, 0xea, 0xaa}, - {} -}; -static const u8 poxxxx_init_start_3[][4] = { - {0x00, 0xb8, 0x28, 0xaa}, - {0x00, 0xb9, 0x1e, 0xaa}, - {0x00, 0xb6, 0x14, 0xaa}, - {0x00, 0xb7, 0x0f, 0xaa}, - {0x00, 0x5c, 0x10, 0xaa}, - {0x00, 0x5d, 0x18, 0xaa}, - {0x00, 0x5e, 0x24, 0xaa}, - {0x00, 0x5f, 0x24, 0xaa}, - {0x00, 0x86, 0x1a, 0xaa}, - {0x00, 0x60, 0x00, 0xaa}, - {0x00, 0x61, 0x1b, 0xaa}, - {0x00, 0x62, 0x30, 0xaa}, - {0x00, 0x63, 0x40, 0xaa}, - {0x00, 0x87, 0x1a, 0xaa}, - {0x00, 0x64, 0x00, 0xaa}, - {0x00, 0x65, 0x08, 0xaa}, - {0x00, 0x66, 0x10, 0xaa}, - {0x00, 0x67, 0x20, 0xaa}, - {0x00, 0x88, 0x10, 0xaa}, - {0x00, 0x68, 0x00, 0xaa}, - {0x00, 0x69, 0x08, 0xaa}, - {0x00, 0x6a, 0x0f, 0xaa}, - {0x00, 0x6b, 0x0f, 0xaa}, - {0x00, 0x89, 0x07, 0xaa}, - {0x00, 0xd5, 0x4c, 0xaa}, - {0x00, 0x0a, 0x00, 0xaa}, - {0x00, 0x0b, 0x2a, 0xaa}, - {0x00, 0x0e, 0x03, 0xaa}, - {0x00, 0x0f, 0xea, 0xaa}, - {0x00, 0xa2, 0x00, 0xaa}, - {0x00, 0xa3, 0x2a, 0xaa}, - {0x00, 0xa4, 0x03, 0xaa}, - {0x00, 0xa5, 0xea, 0xaa}, - {} -}; -static const u8 poxxxx_initVGA[][4] = { - {0x00, 0x20, 0x11, 0xaa}, - {0x00, 0x33, 0x38, 0xaa}, - {0x00, 0xbb, 0x0d, 0xaa}, - {0xb3, 0x22, 0x01, 0xcc}, /* change to 640x480 */ - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x02, 0xb0, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0x00, 0x04, 0x06, 0xaa}, - {0x00, 0x05, 0x3f, 0xaa}, - {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */ - {} -}; -static const u8 poxxxx_initQVGA[][4] = { - {0x00, 0x20, 0x33, 0xaa}, - {0x00, 0x33, 0x38, 0xaa}, - {0x00, 0xbb, 0x0d, 0xaa}, - {0xb3, 0x22, 0x00, 0xcc}, /* change to 320x240 */ - {0xb3, 0x23, 0xf0, 0xcc}, - {0xb3, 0x16, 0x01, 0xcc}, - {0xb3, 0x17, 0x3f, 0xcc}, - {0xb3, 0x02, 0xb0, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x5c, 0x00, 0xcc}, - {0x00, 0x04, 0x06, 0xaa}, - {0x00, 0x05, 0x3f, 0xaa}, - {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */ - {} -}; -static const u8 poxxxx_init_end_1[][4] = { - {0x00, 0x47, 0x25, 0xaa}, - {0x00, 0x48, 0x80, 0xaa}, - {0x00, 0x49, 0x1f, 0xaa}, - {0x00, 0x4a, 0x40, 0xaa}, - {0x00, 0x44, 0x40, 0xaa}, - {0x00, 0xab, 0x4a, 0xaa}, - {0x00, 0xb1, 0x00, 0xaa}, - {0x00, 0xb2, 0x04, 0xaa}, - {0x00, 0xb3, 0x08, 0xaa}, - {0x00, 0xb4, 0x0b, 0xaa}, - {0x00, 0xb5, 0x0d, 0xaa}, - {} -}; -static const u8 poxxxx_init_end_2[][4] = { - {0x00, 0x1d, 0x85, 0xaa}, - {0x00, 0x1e, 0x06, 0xaa}, - {0x00, 0x1d, 0x05, 0xaa}, - {} -}; - -struct sensor_info { - s8 sensorId; - u8 I2cAdd; - u8 IdAdd; - u16 VpId; - u8 m1; - u8 m2; - u8 op; -}; - -/* probe values */ -static const struct sensor_info vc0321_probe_data[] = { -/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ -/* 0 OV9640 */ - {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, -/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */ - {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01}, -/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/ - {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 3 MI1310 */ - {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 4 MI360 - tested in vc032x_probe_sensor */ -/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */ -/* 5 7131R */ - {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, -/* 6 OV7649 */ - {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05}, -/* 7 PAS302BCW */ - {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05}, -/* 8 OV7660 */ - {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, -/* 9 PO3130NC - (tested in vc032x_probe_sensor) */ -/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */ -/* 10 PO1030KC */ - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 11 MI1310_SOC */ - {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, -/* 12 OV9650 */ - {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, -/* 13 S5K532 */ - {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01}, -/* 14 MI360_SOC - ??? */ -/* 15 PO1200N */ - {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01}, -/* 16 PO3030K */ - {-1, 0x80 | 0x18, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 17 PO2030 */ - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* ?? */ - {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01}, - {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01}, -}; -static const struct sensor_info vc0323_probe_data[] = { -/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ -/* 0 OV9640 */ - {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, -/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */ - {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01}, -/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/ - {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 3 MI1310 */ - {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 4 MI360 - tested in vc032x_probe_sensor */ -/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */ -/* 5 7131R */ - {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, -/* 6 OV7649 */ - {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05}, -/* 7 PAS302BCW */ - {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05}, -/* 8 OV7660 */ - {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, -/* 9 PO3130NC - (tested in vc032x_probe_sensor) */ -/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */ -/* 10 PO1030KC */ - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* 11 MI1310_SOC */ - {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, -/* 12 OV9650 */ - {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, -/* 13 S5K532 */ - {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01}, -/* 14 MI360_SOC - ??? */ -/* 15 PO1200N */ - {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01}, -/* 16 ?? */ - {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01}, -/* 17 PO2030 */ - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* ?? */ - {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01}, - {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01}, -/*fixme: not in the ms-win probe - may be found before? */ - {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, -}; - -/* read 'len' bytes in gspca_dev->usb_buf */ -static void reg_r_i(struct gspca_dev *gspca_dev, - u16 req, - u16 index, - u16 len) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, /* value */ - index, gspca_dev->usb_buf, len, - 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - } -} -static void reg_r(struct gspca_dev *gspca_dev, - u16 req, - u16 index, - u16 len) -{ - reg_r_i(gspca_dev, req, index, len); -#ifdef GSPCA_DEBUG - if (gspca_dev->usb_err < 0) - return; - if (len == 1) - PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index, - gspca_dev->usb_buf[0]); - else - PDEBUG(D_USBI, "GET %02x 0001 %04x %*ph", - req, index, 3, gspca_dev->usb_buf); -#endif -} - -static void reg_w_i(struct gspca_dev *gspca_dev, - u16 req, - u16 value, - u16 index) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, - 500); - if (ret < 0) { - pr_err("reg_w err %d\n", ret); - gspca_dev->usb_err = ret; - } -} -static void reg_w(struct gspca_dev *gspca_dev, - u16 req, - u16 value, - u16 index) -{ -#ifdef GSPCA_DEBUG - if (gspca_dev->usb_err < 0) - return; - PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index); -#endif - reg_w_i(gspca_dev, req, value, index); -} - -static u16 read_sensor_register(struct gspca_dev *gspca_dev, - u16 address) -{ - u8 ldata, mdata, hdata; - int retry = 50; - - reg_r(gspca_dev, 0xa1, 0xb33f, 1); - if (!(gspca_dev->usb_buf[0] & 0x02)) { - pr_err("I2c Bus Busy Wait %02x\n", gspca_dev->usb_buf[0]); - return 0; - } - reg_w(gspca_dev, 0xa0, address, 0xb33a); - reg_w(gspca_dev, 0xa0, 0x02, 0xb339); - - do { - reg_r(gspca_dev, 0xa1, 0xb33b, 1); - if (gspca_dev->usb_buf[0] == 0x00) - break; - msleep(40); - } while (--retry >= 0); - - reg_r(gspca_dev, 0xa1, 0xb33e, 1); - ldata = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0xa1, 0xb33d, 1); - mdata = gspca_dev->usb_buf[0]; - reg_r(gspca_dev, 0xa1, 0xb33c, 1); - hdata = gspca_dev->usb_buf[0]; - if (hdata != 0 && mdata != 0 && ldata != 0) - PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x", - hdata, mdata, ldata); - reg_r(gspca_dev, 0xa1, 0xb334, 1); - if (gspca_dev->usb_buf[0] == 0x02) - return (hdata << 8) + mdata; - return hdata; -} - -static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, n; - u16 value; - const struct sensor_info *ptsensor_info; - -/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/ - if (sd->flags & FL_SAMSUNG) { - reg_w(gspca_dev, 0xa0, 0x01, 0xb301); - reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff); - /* select the back sensor */ - } - - reg_r(gspca_dev, 0xa1, 0xbfcf, 1); - PDEBUG(D_PROBE, "vc032%d check sensor header %02x", - sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]); - if (sd->bridge == BRIDGE_VC0321) { - ptsensor_info = vc0321_probe_data; - n = ARRAY_SIZE(vc0321_probe_data); - } else { - ptsensor_info = vc0323_probe_data; - n = ARRAY_SIZE(vc0323_probe_data); - } - for (i = 0; i < n; i++) { - reg_w(gspca_dev, 0xa0, 0x02, 0xb334); - reg_w(gspca_dev, 0xa0, ptsensor_info->m1, 0xb300); - reg_w(gspca_dev, 0xa0, ptsensor_info->m2, 0xb300); - reg_w(gspca_dev, 0xa0, 0x01, 0xb308); - reg_w(gspca_dev, 0xa0, 0x0c, 0xb309); - reg_w(gspca_dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); - reg_w(gspca_dev, 0xa0, ptsensor_info->op, 0xb301); - value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd); - if (value == 0 && ptsensor_info->IdAdd == 0x82) - value = read_sensor_register(gspca_dev, 0x83); - if (value != 0) { - PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)", - value, i); - if (value == ptsensor_info->VpId) - return ptsensor_info->sensorId; - - switch (value) { - case 0x3130: - return SENSOR_PO3130NC; - case 0x7673: - return SENSOR_OV7670; - case 0x8243: - return SENSOR_MI0360; - } - } - ptsensor_info++; - } - return -1; -} - -static void i2c_write(struct gspca_dev *gspca_dev, - u8 reg, const u8 *val, - u8 size) /* 1 or 2 */ -{ - int retry; - -#ifdef GSPCA_DEBUG - if (gspca_dev->usb_err < 0) - return; - if (size == 1) - PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val); - else - PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]); -#endif - reg_r_i(gspca_dev, 0xa1, 0xb33f, 1); -/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/ - reg_w_i(gspca_dev, 0xa0, size, 0xb334); - reg_w_i(gspca_dev, 0xa0, reg, 0xb33a); - reg_w_i(gspca_dev, 0xa0, val[0], 0xb336); - if (size > 1) - reg_w_i(gspca_dev, 0xa0, val[1], 0xb337); - reg_w_i(gspca_dev, 0xa0, 0x01, 0xb339); - retry = 4; - do { - reg_r_i(gspca_dev, 0xa1, 0xb33b, 1); - if (gspca_dev->usb_buf[0] == 0) - break; - msleep(20); - } while (--retry > 0); - if (retry <= 0) - pr_err("i2c_write timeout\n"); -} - -static void put_tab_to_reg(struct gspca_dev *gspca_dev, - const u8 *tab, u8 tabsize, u16 addr) -{ - int j; - u16 ad = addr; - - for (j = 0; j < tabsize; j++) - reg_w(gspca_dev, 0xa0, tab[j], ad++); -} - -static void usb_exchange(struct gspca_dev *gspca_dev, - const u8 data[][4]) -{ - int i = 0; - - for (;;) { - switch (data[i][3]) { - default: - return; - case 0xcc: /* normal write */ - reg_w(gspca_dev, 0xa0, data[i][2], - (data[i][0]) << 8 | data[i][1]); - break; - case 0xaa: /* i2c op */ - i2c_write(gspca_dev, data[i][1], &data[i][2], 1); - break; - case 0xbb: /* i2c op */ - i2c_write(gspca_dev, data[i][0], &data[i][1], 2); - break; - case 0xdd: - msleep(data[i][1] * 256 + data[i][2] + 10); - break; - } - i++; - } - /*not reached*/ -} - - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->bridge = id->driver_info >> 8; - sd->flags = id->driver_info & 0xff; - - if (id->idVendor == 0x046d && - (id->idProduct == 0x0892 || id->idProduct == 0x0896)) - sd->sensor = SENSOR_POxxxx; /* no probe */ - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int sensor; - /* number of packets per ISOC message */ - static u8 npkt[NSENSORS] = { - [SENSOR_HV7131R] = 64, - [SENSOR_MI0360] = 32, - [SENSOR_MI1310_SOC] = 32, - [SENSOR_MI1320] = 64, - [SENSOR_MI1320_SOC] = 128, - [SENSOR_OV7660] = 32, - [SENSOR_OV7670] = 64, - [SENSOR_PO1200] = 128, - [SENSOR_PO3130NC] = 128, - [SENSOR_POxxxx] = 128, - }; - - if (sd->sensor != SENSOR_POxxxx) - sensor = vc032x_probe_sensor(gspca_dev); - else - sensor = sd->sensor; - - switch (sensor) { - case -1: - pr_err("Unknown sensor...\n"); - return -EINVAL; - case SENSOR_HV7131R: - PDEBUG(D_PROBE, "Find Sensor HV7131R"); - break; - case SENSOR_MI0360: - PDEBUG(D_PROBE, "Find Sensor MI0360"); - sd->bridge = BRIDGE_VC0323; - break; - case SENSOR_MI1310_SOC: - PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); - break; - case SENSOR_MI1320: - PDEBUG(D_PROBE, "Find Sensor MI1320"); - break; - case SENSOR_MI1320_SOC: - PDEBUG(D_PROBE, "Find Sensor MI1320_SOC"); - break; - case SENSOR_OV7660: - PDEBUG(D_PROBE, "Find Sensor OV7660"); - break; - case SENSOR_OV7670: - PDEBUG(D_PROBE, "Find Sensor OV7670"); - break; - case SENSOR_PO1200: - PDEBUG(D_PROBE, "Find Sensor PO1200"); - break; - case SENSOR_PO3130NC: - PDEBUG(D_PROBE, "Find Sensor PO3130NC"); - break; - case SENSOR_POxxxx: - PDEBUG(D_PROBE, "Sensor POxxxx"); - break; - } - sd->sensor = sensor; - - cam = &gspca_dev->cam; - if (sd->bridge == BRIDGE_VC0321) { - cam->cam_mode = vc0321_mode; - cam->nmodes = ARRAY_SIZE(vc0321_mode); - } else { - switch (sensor) { - case SENSOR_PO1200: - cam->cam_mode = svga_mode; - cam->nmodes = ARRAY_SIZE(svga_mode); - break; - case SENSOR_MI1310_SOC: - cam->cam_mode = vc0323_mode; - cam->nmodes = ARRAY_SIZE(vc0323_mode); - break; - case SENSOR_MI1320_SOC: - cam->cam_mode = bi_mode; - cam->nmodes = ARRAY_SIZE(bi_mode); - break; - case SENSOR_OV7670: - cam->cam_mode = bi_mode; - cam->nmodes = ARRAY_SIZE(bi_mode) - 1; - break; - default: - cam->cam_mode = vc0323_mode; - cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1; - break; - } - } - cam->npkt = npkt[sd->sensor]; - - if (sd->sensor == SENSOR_OV7670) - sd->flags |= FL_HFLIP | FL_VFLIP; - - if (sd->bridge == BRIDGE_VC0321) { - reg_r(gspca_dev, 0x8a, 0, 3); - reg_w(gspca_dev, 0x87, 0x00, 0x0f0f); - reg_r(gspca_dev, 0x8b, 0, 3); - reg_w(gspca_dev, 0x88, 0x00, 0x0202); - if (sd->sensor == SENSOR_POxxxx) { - reg_r(gspca_dev, 0xa1, 0xb300, 1); - if (gspca_dev->usb_buf[0] != 0) { - reg_w(gspca_dev, 0xa0, 0x26, 0xb300); - reg_w(gspca_dev, 0xa0, 0x04, 0xb300); - } - reg_w(gspca_dev, 0xa0, 0x00, 0xb300); - } - } - return gspca_dev->usb_err; -} - -static void setbrightness(struct gspca_dev *gspca_dev, s32 val) -{ - u8 data; - - data = val; - if (data >= 0x80) - data &= 0x7f; - else - data = 0xff ^ data; - i2c_write(gspca_dev, 0x98, &data, 1); -} - -static void setcontrast(struct gspca_dev *gspca_dev, u8 val) -{ - i2c_write(gspca_dev, 0x99, &val, 1); -} - -static void setcolors(struct gspca_dev *gspca_dev, u8 val) -{ - u8 data; - - data = val - (val >> 3) - 1; - i2c_write(gspca_dev, 0x94, &data, 1); - i2c_write(gspca_dev, 0x95, &val, 1); -} - -static void sethvflip(struct gspca_dev *gspca_dev, bool hflip, bool vflip) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data[2]; - - if (sd->flags & FL_HFLIP) - hflip = !hflip; - if (sd->flags & FL_VFLIP) - vflip = !vflip; - switch (sd->sensor) { - case SENSOR_MI1310_SOC: - case SENSOR_MI1320: - case SENSOR_MI1320_SOC: - data[0] = data[1] = 0; /* select page 0 */ - i2c_write(gspca_dev, 0xf0, data, 2); - data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01; - data[1] = 0x02 * hflip - | 0x01 * vflip; - i2c_write(gspca_dev, 0x20, data, 2); - break; - case SENSOR_OV7660: - case SENSOR_OV7670: - data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07; - data[0] |= OV7660_MVFP_MIRROR * hflip - | OV7660_MVFP_VFLIP * vflip; - i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1); - break; - case SENSOR_PO1200: - data[0] = 0; - i2c_write(gspca_dev, 0x03, data, 1); - data[0] = 0x80 * hflip - | 0x40 * vflip - | 0x06; - i2c_write(gspca_dev, 0x1e, data, 1); - break; - } -} - -static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - static const u8 (*ov7660_freq_tb[3])[4] = - {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; - - if (sd->sensor != SENSOR_OV7660) - return; - usb_exchange(gspca_dev, ov7660_freq_tb[val]); -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data; - - switch (sd->sensor) { - case SENSOR_PO1200: - data = 0; - i2c_write(gspca_dev, 0x03, &data, 1); - if (val < 0) - data = 0x6a; - else - data = 0xb5 + val * 3; - i2c_write(gspca_dev, 0x61, &data, 1); - break; - case SENSOR_POxxxx: - if (val < 0) - data = 0x7e; /* def = max */ - else - data = 0x60 + val * 0x0f; - i2c_write(gspca_dev, 0x59, &data, 1); - break; - } -} -static void setgain(struct gspca_dev *gspca_dev, u8 val) -{ - i2c_write(gspca_dev, 0x15, &val, 1); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - u8 data; - - data = val >> 8; - i2c_write(gspca_dev, 0x1a, &data, 1); - data = val; - i2c_write(gspca_dev, 0x1b, &data, 1); -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - static const u8 data[2] = {0x28, 0x3c}; - - i2c_write(gspca_dev, 0xd1, &data[val], 1); -} - -static void setgamma(struct gspca_dev *gspca_dev) -{ -/*fixme:to do */ - usb_exchange(gspca_dev, poxxxx_gamma); -} - -static void setbacklight(struct gspca_dev *gspca_dev, s32 val) -{ - u16 v; - u8 data; - - data = (val << 4) | 0x0f; - i2c_write(gspca_dev, 0xaa, &data, 1); - v = 613 + 12 * val; - data = v >> 8; - i2c_write(gspca_dev, 0xc4, &data, 1); - data = v; - i2c_write(gspca_dev, 0xc5, &data, 1); - v = 1093 - 12 * val; - data = v >> 8; - i2c_write(gspca_dev, 0xc6, &data, 1); - data = v; - i2c_write(gspca_dev, 0xc7, &data, 1); - v = 342 + 9 * val; - data = v >> 8; - i2c_write(gspca_dev, 0xc8, &data, 1); - data = v; - i2c_write(gspca_dev, 0xc9, &data, 1); - v = 702 - 9 * val; - data = v >> 8; - i2c_write(gspca_dev, 0xca, &data, 1); - data = v; - i2c_write(gspca_dev, 0xcb, &data, 1); -} - -static void setwb(struct gspca_dev *gspca_dev) -{ -/*fixme:to do - valid when reg d1 = 0x1c - (reg16 + reg15 = 0xa3)*/ - static const u8 data[2] = {0x00, 0x00}; - - i2c_write(gspca_dev, 0x16, &data[0], 1); - i2c_write(gspca_dev, 0x18, &data[1], 1); -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - const u8 (*init)[4]; - const u8 *GammaT = NULL; - const u8 *MatrixT = NULL; - int mode; - static const u8 (*mi1320_soc_init[])[4] = { - mi1320_soc_InitSXGA, - mi1320_soc_InitVGA, - mi1320_soc_InitQVGA, - }; - -/*fixme: back sensor only*/ - if (sd->flags & FL_SAMSUNG) { - reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff); - reg_w(gspca_dev, 0xa9, 0x8348, 0x000e); - reg_w(gspca_dev, 0xa9, 0x0000, 0x001a); - } - - /* Assume start use the good resolution from gspca_dev->mode */ - if (sd->bridge == BRIDGE_VC0321) { - reg_w(gspca_dev, 0xa0, 0xff, 0xbfec); - reg_w(gspca_dev, 0xa0, 0xff, 0xbfed); - reg_w(gspca_dev, 0xa0, 0xff, 0xbfee); - reg_w(gspca_dev, 0xa0, 0xff, 0xbfef); - sd->image_offset = 46; - } else { - if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat - == V4L2_PIX_FMT_JPEG) - sd->image_offset = 0; - else - sd->image_offset = 32; - } - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - switch (sd->sensor) { - case SENSOR_HV7131R: - GammaT = hv7131r_gamma; - MatrixT = hv7131r_matrix; - if (mode) - init = hv7131r_initQVGA_data; /* 320x240 */ - else - init = hv7131r_initVGA_data; /* 640x480 */ - break; - case SENSOR_OV7660: - GammaT = ov7660_gamma; - MatrixT = ov7660_matrix; - if (mode) - init = ov7660_initQVGA_data; /* 320x240 */ - else - init = ov7660_initVGA_data; /* 640x480 */ - break; - case SENSOR_MI0360: - GammaT = mi1320_gamma; - MatrixT = mi0360_matrix; - if (mode) - init = mi0360_initQVGA_JPG; /* 320x240 */ - else - init = mi0360_initVGA_JPG; /* 640x480 */ - break; - case SENSOR_MI1310_SOC: - GammaT = mi1320_gamma; - MatrixT = mi1320_matrix; - switch (mode) { - case 1: - init = mi1310_socinitQVGA_JPG; /* 320x240 */ - break; - case 0: - init = mi1310_socinitVGA_JPG; /* 640x480 */ - break; - default: - init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */ - break; - } - break; - case SENSOR_MI1320: - GammaT = mi1320_gamma; - MatrixT = mi1320_matrix; - if (mode) - init = mi1320_initQVGA_data; /* 320x240 */ - else - init = mi1320_initVGA_data; /* 640x480 */ - break; - case SENSOR_MI1320_SOC: - GammaT = mi1320_gamma; - MatrixT = mi1320_matrix; - init = mi1320_soc_init[mode]; - break; - case SENSOR_OV7670: - init = mode == 1 ? ov7670_InitVGA : ov7670_InitQVGA; - break; - case SENSOR_PO3130NC: - GammaT = po3130_gamma; - MatrixT = po3130_matrix; - if (mode) - init = po3130_initQVGA_data; /* 320x240 */ - else - init = po3130_initVGA_data; /* 640x480 */ - usb_exchange(gspca_dev, init); - init = po3130_rundata; - break; - case SENSOR_PO1200: - GammaT = po1200_gamma; - MatrixT = po1200_matrix; - init = po1200_initVGA_data; - break; - default: -/* case SENSOR_POxxxx: */ - usb_exchange(gspca_dev, poxxxx_init_common); - setgamma(gspca_dev); - usb_exchange(gspca_dev, poxxxx_init_start_3); - if (mode) - init = poxxxx_initQVGA; - else - init = poxxxx_initVGA; - usb_exchange(gspca_dev, init); - reg_r(gspca_dev, 0x8c, 0x0000, 3); - reg_w(gspca_dev, 0xa0, - gspca_dev->usb_buf[2] & 1 ? 0 : 1, - 0xb35c); - msleep(300); -/*fixme: i2c read 04 and 05*/ - init = poxxxx_init_end_1; - break; - } - usb_exchange(gspca_dev, init); - if (GammaT && MatrixT) { - put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); - put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); - put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); - put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); - - switch (sd->sensor) { - case SENSOR_PO1200: - case SENSOR_HV7131R: - reg_w(gspca_dev, 0x89, 0x0400, 0x1415); - break; - case SENSOR_MI1310_SOC: - reg_w(gspca_dev, 0x89, 0x058c, 0x0000); - break; - } - msleep(100); - } - switch (sd->sensor) { - case SENSOR_OV7670: - reg_w(gspca_dev, 0x87, 0xffff, 0xffff); - reg_w(gspca_dev, 0x88, 0xff00, 0xf0f1); - reg_w(gspca_dev, 0xa0, 0x0000, 0xbfff); - break; - case SENSOR_POxxxx: - usb_exchange(gspca_dev, poxxxx_init_end_2); - setwb(gspca_dev); - msleep(80); /* led on */ - reg_w(gspca_dev, 0x89, 0xffff, 0xfdff); - break; - } - return gspca_dev->usb_err; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { - case SENSOR_MI1310_SOC: - reg_w(gspca_dev, 0x89, 0x058c, 0x00ff); - break; - case SENSOR_POxxxx: - return; - default: - if (!(sd->flags & FL_SAMSUNG)) - reg_w(gspca_dev, 0x89, 0xffff, 0xffff); - break; - } - reg_w(gspca_dev, 0xa0, 0x01, 0xb301); - reg_w(gspca_dev, 0xa0, 0x09, 0xb003); -} - -/* called on streamoff with alt 0 and on disconnect */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (!gspca_dev->present) - return; -/*fixme: is this useful?*/ - if (sd->sensor == SENSOR_MI1310_SOC) - reg_w(gspca_dev, 0x89, 0x058c, 0x00ff); - else if (!(sd->flags & FL_SAMSUNG)) - reg_w(gspca_dev, 0x89, 0xffff, 0xffff); - - if (sd->sensor == SENSOR_POxxxx) { - reg_w(gspca_dev, 0xa0, 0x26, 0xb300); - reg_w(gspca_dev, 0xa0, 0x04, 0xb300); - reg_w(gspca_dev, 0xa0, 0x00, 0xb300); - } -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso pkt length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (data[0] == 0xff && data[1] == 0xd8) { - PDEBUG(D_PACK, - "vc032x header packet found len %d", len); - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - data += sd->image_offset; - len -= sd->image_offset; - gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); - return; - } - - /* The vc0321 sends some additional data after sending the complete - * frame, we ignore this. */ - if (sd->bridge == BRIDGE_VC0321) { - int size, l; - - l = gspca_dev->image_len; - size = gspca_dev->frsz; - if (len > size - l) - len = size - l; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) - return 0; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - setbrightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - setcontrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_SATURATION: - setcolors(gspca_dev, ctrl->val); - break; - case V4L2_CID_HFLIP: - sethvflip(gspca_dev, sd->hflip->val, sd->vflip->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_AUTOGAIN: - setautogain(gspca_dev, ctrl->val); - break; - case V4L2_CID_GAIN: - setgain(gspca_dev, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - setexposure(gspca_dev, ctrl->val); - break; - case V4L2_CID_BACKLIGHT_COMPENSATION: - setbacklight(gspca_dev, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setlightfreq(gspca_dev, ctrl->val); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - bool has_brightness = false; - bool has_contrast = false; - bool has_sat = false; - bool has_hvflip = false; - bool has_freq = false; - bool has_backlight = false; - bool has_exposure = false; - bool has_autogain = false; - bool has_gain = false; - bool has_sharpness = false; - - switch (sd->sensor) { - case SENSOR_HV7131R: - case SENSOR_MI0360: - case SENSOR_PO3130NC: - break; - case SENSOR_MI1310_SOC: - case SENSOR_MI1320: - case SENSOR_MI1320_SOC: - case SENSOR_OV7660: - has_hvflip = true; - break; - case SENSOR_OV7670: - has_hvflip = has_freq = true; - break; - case SENSOR_PO1200: - has_hvflip = has_sharpness = true; - break; - case SENSOR_POxxxx: - has_brightness = has_contrast = has_sat = has_backlight = - has_exposure = has_autogain = has_gain = - has_sharpness = true; - break; - } - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 8); - if (has_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - if (has_contrast) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 127); - if (has_sat) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SATURATION, 1, 127, 1, 63); - if (has_hvflip) { - sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - } - if (has_sharpness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, -1, 2, 1, -1); - if (has_freq) - v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ); - if (has_autogain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - if (has_gain) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_GAIN, 0, 78, 1, 0); - if (has_exposure) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 4095, 1, 450); - if (has_backlight) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BACKLIGHT_COMPENSATION, 0, 15, 1, 15); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - if (sd->hflip) - v4l2_ctrl_cluster(2, &sd->hflip); - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .init_controls = sd_init_controls, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -#define BF(bridge, flags) \ - .driver_info = (BRIDGE_ ## bridge << 8) \ - | (flags) -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)}, - {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)}, - {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)}, - {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)}, - {USB_DEVICE(0x0ac8, 0x0321), BF(VC0321, 0)}, - {USB_DEVICE(0x0ac8, 0x0323), BF(VC0323, 0)}, - {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)}, - {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)}, - {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)}, - {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)}, - {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)}, - {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)}, - {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c deleted file mode 100644 index b1a64b912666..000000000000 --- a/drivers/media/video/gspca/vicam.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * gspca ViCam subdriver - * - * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com> - * - * Based on the usbvideo vicam driver, which is: - * - * Copyright (c) 2002 Joe Burks (jburks@wavicle.org), - * Christopher L Cheney (ccheney@cheney.cx), - * Pavel Machek (pavel@ucw.cz), - * John Tyner (jtyner@cs.ucr.edu), - * Monroe Williams (monroe@pobox.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "vicam" -#define HEADER_SIZE 64 - -#include <linux/workqueue.h> -#include <linux/slab.h> -#include <linux/firmware.h> -#include <linux/ihex.h> -#include "gspca.h" - -#define VICAM_FIRMWARE "vicam/firmware.fw" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(VICAM_FIRMWARE); - -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -/* The vicam sensor has a resolution of 512 x 244, with I believe square - pixels, but this is forced to a 4:3 ratio by optics. So it has - non square pixels :( */ -static struct v4l2_pix_format vicam_mode[] = { - { 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 256, - .sizeimage = 256 * 122, - .colorspace = V4L2_COLORSPACE_SRGB,}, - /* 2 modes with somewhat more square pixels */ - { 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 256, - .sizeimage = 256 * 200, - .colorspace = V4L2_COLORSPACE_SRGB,}, - { 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 256, - .sizeimage = 256 * 240, - .colorspace = V4L2_COLORSPACE_SRGB,}, -#if 0 /* This mode has extremely non square pixels, testing use only */ - { 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 512, - .sizeimage = 512 * 122, - .colorspace = V4L2_COLORSPACE_SRGB,}, -#endif - { 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 512, - .sizeimage = 512 * 244, - .colorspace = V4L2_COLORSPACE_SRGB,}, -}; - -static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request, - u16 value, u16 index, u8 *data, u16 len) -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - request, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, len, 1000); - if (ret < 0) - pr_err("control msg req %02X error %d\n", request, ret); - - return ret; -} - -static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state) -{ - int ret; - - ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0); - if (ret < 0) - return ret; - - if (state) - ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0); - - return ret; -} - -/* - * request and read a block of data - see warning on vicam_command. - */ -static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) -{ - int ret, unscaled_height, act_len = 0; - u8 *req_data = gspca_dev->usb_buf; - s32 expo = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - s32 gain = v4l2_ctrl_g_ctrl(gspca_dev->gain); - - memset(req_data, 0, 16); - req_data[0] = gain; - if (gspca_dev->width == 256) - req_data[1] |= 0x01; /* low nibble x-scale */ - if (gspca_dev->height <= 122) { - req_data[1] |= 0x10; /* high nibble y-scale */ - unscaled_height = gspca_dev->height * 2; - } else - unscaled_height = gspca_dev->height; - req_data[2] = 0x90; /* unknown, does not seem to do anything */ - if (unscaled_height <= 200) - req_data[3] = 0x06; /* vend? */ - else if (unscaled_height <= 242) /* Yes 242 not 240 */ - req_data[3] = 0x07; /* vend? */ - else /* Up to 244 lines with req_data[3] == 0x08 */ - req_data[3] = 0x08; /* vend? */ - - if (expo < 256) { - /* Frame rate maxed out, use partial frame expo time */ - req_data[4] = 255 - expo; - req_data[5] = 0x00; - req_data[6] = 0x00; - req_data[7] = 0x01; - } else { - /* Modify frame rate */ - req_data[4] = 0x00; - req_data[5] = 0x00; - req_data[6] = expo & 0xFF; - req_data[7] = expo >> 8; - } - req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */ - /* bytes 9-15 do not seem to affect exposure or image quality */ - - mutex_lock(&gspca_dev->usb_lock); - ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16); - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) - return ret; - - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - data, size, &act_len, 10000); - /* successful, it returns 0, otherwise negative */ - if (ret < 0 || act_len != size) { - pr_err("bulk read fail (%d) len %d/%d\n", - ret, act_len, size); - return -EIO; - } - return 0; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface we take the gspca - * usb_lock when performing USB operations. In practice the only thing we need - * to protect against is the usb_set_interface call that gspca makes during - * stream_off as the camera doesn't provide any controls that the user could try - * to change. - */ -static void vicam_dostream(struct work_struct *work) -{ - struct sd *sd = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - int ret, frame_sz; - u8 *buffer; - - frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage + - HEADER_SIZE; - buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA); - if (!buffer) { - pr_err("Couldn't allocate USB buffer\n"); - goto exit; - } - - while (gspca_dev->dev && gspca_dev->streaming) { -#ifdef CONFIG_PM - if (gspca_dev->frozen) - break; -#endif - ret = vicam_read_frame(gspca_dev, buffer, frame_sz); - if (ret < 0) - break; - - /* Note the frame header contents seem to be completely - constant, they do not change with either image, or - settings. So we simply discard it. The frames have - a very similar 64 byte footer, which we don't even - bother reading from the cam */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - buffer + HEADER_SIZE, - frame_sz - HEADER_SIZE); - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - } -exit: - kfree(buffer); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *sd = (struct sd *)gspca_dev; - - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk = 1; - cam->bulk_size = 64; - cam->cam_mode = vicam_mode; - cam->nmodes = ARRAY_SIZE(vicam_mode); - - INIT_WORK(&sd->work_struct, vicam_dostream); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - int ret; - const struct ihex_binrec *rec; - const struct firmware *uninitialized_var(fw); - u8 *firmware_buf; - - ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, - &gspca_dev->dev->dev); - if (ret) { - pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret); - return ret; - } - - firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!firmware_buf) { - ret = -ENOMEM; - goto exit; - } - for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { - memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len)); - ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf, - be16_to_cpu(rec->len)); - if (ret < 0) - break; - } - - kfree(firmware_buf); -exit: - release_firmware(fw); - return ret; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - int ret; - - ret = vicam_set_camera_power(gspca_dev, 1); - if (ret < 0) - return ret; - - /* Start the workqueue function to do the streaming */ - sd->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(sd->work_thread, &sd->work_struct); - - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *)gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for vicam_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); - - if (gspca_dev->dev) - vicam_set_camera_power(gspca_dev, 0); -} - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 2); - gspca_dev->exposure = v4l2_ctrl_new_std(hdl, NULL, - V4L2_CID_EXPOSURE, 0, 2047, 1, 256); - gspca_dev->gain = v4l2_ctrl_new_std(hdl, NULL, - V4L2_CID_GAIN, 0, 255, 1, 200); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* Table of supported USB devices */ -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x04c1, 0x009d)}, - {USB_DEVICE(0x0602, 0x1001)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c deleted file mode 100644 index 9e3a909e0a00..000000000000 --- a/drivers/media/video/gspca/w996Xcf.c +++ /dev/null @@ -1,567 +0,0 @@ -/** - * - * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip. - * - * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> - * - * This module is adapted from the in kernel v4l1 w9968cf driver: - * - * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* Note this is not a stand alone driver, it gets included in ov519.c, this - is a bit of a hack, but it needs the driver code for a lot of different - ov sensors which is already present in ov519.c (the old v4l1 driver used - the ovchipcam framework). When we have the time we really should move - the sensor drivers to v4l2 sub drivers, and properly split of this - driver from ov519.c */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */ - -#define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET]) -#define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET]) - -static const struct v4l2_pix_format w9968cf_vga_mode[] = { - {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, - {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_JPEG}, -}; - -static void reg_w(struct sd *sd, u16 index, u16 value); - -/*-------------------------------------------------------------------------- - Write 64-bit data to the fast serial bus registers. - Return 0 on success, -1 otherwise. - --------------------------------------------------------------------------*/ -static void w9968cf_write_fsb(struct sd *sd, u16* data) -{ - struct usb_device *udev = sd->gspca_dev.dev; - u16 value; - int ret; - - if (sd->gspca_dev.usb_err < 0) - return; - - value = *data++; - memcpy(sd->gspca_dev.usb_buf, data, 6); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - value, 0x06, sd->gspca_dev.usb_buf, 6, 500); - if (ret < 0) { - pr_err("Write FSB registers failed (%d)\n", ret); - sd->gspca_dev.usb_err = ret; - } -} - -/*-------------------------------------------------------------------------- - Write data to the serial bus control register. - Return 0 on success, a negative number otherwise. - --------------------------------------------------------------------------*/ -static void w9968cf_write_sb(struct sd *sd, u16 value) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return; - - /* We don't use reg_w here, as that would cause all writes when - bitbanging i2c to be logged, making the logs impossible to read */ - ret = usb_control_msg(sd->gspca_dev.dev, - usb_sndctrlpipe(sd->gspca_dev.dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0x01, NULL, 0, 500); - - udelay(W9968CF_I2C_BUS_DELAY); - - if (ret < 0) { - pr_err("Write SB reg [01] %04x failed\n", value); - sd->gspca_dev.usb_err = ret; - } -} - -/*-------------------------------------------------------------------------- - Read data from the serial bus control register. - Return 0 on success, a negative number otherwise. - --------------------------------------------------------------------------*/ -static int w9968cf_read_sb(struct sd *sd) -{ - int ret; - - if (sd->gspca_dev.usb_err < 0) - return -1; - - /* We don't use reg_r here, as the w9968cf is special and has 16 - bit registers instead of 8 bit */ - ret = usb_control_msg(sd->gspca_dev.dev, - usb_rcvctrlpipe(sd->gspca_dev.dev, 0), - 1, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); - if (ret >= 0) { - ret = sd->gspca_dev.usb_buf[0] | - (sd->gspca_dev.usb_buf[1] << 8); - } else { - pr_err("Read SB reg [01] failed\n"); - sd->gspca_dev.usb_err = ret; - } - - udelay(W9968CF_I2C_BUS_DELAY); - - return ret; -} - -/*-------------------------------------------------------------------------- - Upload quantization tables for the JPEG compression. - This function is called by w9968cf_start_transfer(). - Return 0 on success, a negative number otherwise. - --------------------------------------------------------------------------*/ -static void w9968cf_upload_quantizationtables(struct sd *sd) -{ - u16 a, b; - int i, j; - - reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */ - - for (i = 0, j = 0; i < 32; i++, j += 2) { - a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8); - b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8); - reg_w(sd, 0x40 + i, a); - reg_w(sd, 0x60 + i, b); - } - reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */ -} - -/**************************************************************************** - * Low-level I2C I/O functions. * - * The adapter supports the following I2C transfer functions: * - * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) * - * i2c_adap_read_byte_data() * - * i2c_adap_read_byte() * - ****************************************************************************/ - -static void w9968cf_smbus_start(struct sd *sd) -{ - w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ - w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ -} - -static void w9968cf_smbus_stop(struct sd *sd) -{ - w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */ - w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */ - w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ -} - -static void w9968cf_smbus_write_byte(struct sd *sd, u8 v) -{ - u8 bit; - int sda; - - for (bit = 0 ; bit < 8 ; bit++) { - sda = (v & 0x80) ? 2 : 0; - v <<= 1; - /* SDE=1, SDA=sda, SCL=0 */ - w9968cf_write_sb(sd, 0x10 | sda); - /* SDE=1, SDA=sda, SCL=1 */ - w9968cf_write_sb(sd, 0x11 | sda); - /* SDE=1, SDA=sda, SCL=0 */ - w9968cf_write_sb(sd, 0x10 | sda); - } -} - -static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v) -{ - u8 bit; - - /* No need to ensure SDA is high as we are always called after - read_ack which ends with SDA high */ - *v = 0; - for (bit = 0 ; bit < 8 ; bit++) { - *v <<= 1; - /* SDE=1, SDA=1, SCL=1 */ - w9968cf_write_sb(sd, 0x0013); - *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; - /* SDE=1, SDA=1, SCL=0 */ - w9968cf_write_sb(sd, 0x0012); - } -} - -static void w9968cf_smbus_write_nack(struct sd *sd) -{ - /* No need to ensure SDA is high as we are always called after - read_byte which ends with SDA high */ - w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ - w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ -} - -static void w9968cf_smbus_read_ack(struct sd *sd) -{ - int sda; - - /* Ensure SDA is high before raising clock to avoid a spurious stop */ - w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ - w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */ - sda = w9968cf_read_sb(sd); - w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */ - if (sda >= 0 && (sda & 0x08)) { - PDEBUG(D_USBI, "Did not receive i2c ACK"); - sd->gspca_dev.usb_err = -EIO; - } -} - -/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ -static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value) -{ - u16* data = (u16 *)sd->gspca_dev.usb_buf; - - data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0); - data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0; - data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0); - data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0; - data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0; - data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0); - data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0; - data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0; - data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0); - data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0; - - w9968cf_write_fsb(sd, data); - - data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0); - data[0] |= (reg & 0x40) ? 0x0540 : 0x0; - data[0] |= (reg & 0x20) ? 0x5000 : 0x0; - data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0); - data[1] |= (reg & 0x10) ? 0x0054 : 0x0; - data[1] |= (reg & 0x08) ? 0x1500 : 0x0; - data[1] |= (reg & 0x04) ? 0x4000 : 0x0; - data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0); - data[2] |= (reg & 0x02) ? 0x0150 : 0x0; - data[2] |= (reg & 0x01) ? 0x5400 : 0x0; - data[3] = 0x001d; - - w9968cf_write_fsb(sd, data); - - data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0); - data[0] |= (value & 0x40) ? 0x0540 : 0x0; - data[0] |= (value & 0x20) ? 0x5000 : 0x0; - data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0); - data[1] |= (value & 0x10) ? 0x0054 : 0x0; - data[1] |= (value & 0x08) ? 0x1500 : 0x0; - data[1] |= (value & 0x04) ? 0x4000 : 0x0; - data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0); - data[2] |= (value & 0x02) ? 0x0150 : 0x0; - data[2] |= (value & 0x01) ? 0x5400 : 0x0; - data[3] = 0xfe1d; - - w9968cf_write_fsb(sd, data); - - PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); -} - -/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ -static int w9968cf_i2c_r(struct sd *sd, u8 reg) -{ - int ret = 0; - u8 value; - - /* Fast serial bus data control disable */ - w9968cf_write_sb(sd, 0x0013); /* don't change ! */ - - w9968cf_smbus_start(sd); - w9968cf_smbus_write_byte(sd, sd->sensor_addr); - w9968cf_smbus_read_ack(sd); - w9968cf_smbus_write_byte(sd, reg); - w9968cf_smbus_read_ack(sd); - w9968cf_smbus_stop(sd); - w9968cf_smbus_start(sd); - w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1); - w9968cf_smbus_read_ack(sd); - w9968cf_smbus_read_byte(sd, &value); - /* signal we don't want to read anymore, the v4l1 driver used to - send an ack here which is very wrong! (and then fixed - the issues this gave by retrying reads) */ - w9968cf_smbus_write_nack(sd); - w9968cf_smbus_stop(sd); - - /* Fast serial bus data control re-enable */ - w9968cf_write_sb(sd, 0x0030); - - if (sd->gspca_dev.usb_err >= 0) { - ret = value; - PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); - } else - PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); - - return ret; -} - -/*-------------------------------------------------------------------------- - Turn on the LED on some webcams. A beep should be heard too. - Return 0 on success, a negative number otherwise. - --------------------------------------------------------------------------*/ -static void w9968cf_configure(struct sd *sd) -{ - reg_w(sd, 0x00, 0xff00); /* power-down */ - reg_w(sd, 0x00, 0xbf17); /* reset everything */ - reg_w(sd, 0x00, 0xbf10); /* normal operation */ - reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */ - reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */ - reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */ - reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */ - - sd->stopped = 1; -} - -static void w9968cf_init(struct sd *sd) -{ - unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2), - y0 = 0x0000, - u0 = y0 + hw_bufsize / 2, - v0 = u0 + hw_bufsize / 4, - y1 = v0 + hw_bufsize / 4, - u1 = y1 + hw_bufsize / 2, - v1 = u1 + hw_bufsize / 4; - - reg_w(sd, 0x00, 0xff00); /* power off */ - reg_w(sd, 0x00, 0xbf10); /* power on */ - - reg_w(sd, 0x03, 0x405d); /* DRAM timings */ - reg_w(sd, 0x04, 0x0030); /* SDRAM timings */ - - reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */ - reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */ - reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */ - reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */ - reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */ - reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */ - - reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */ - reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */ - reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */ - reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */ - reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */ - reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */ - - reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */ - reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */ - - reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */ - reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */ - - reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */ - reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/ - reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */ - reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */ -} - -static void w9968cf_set_crop_window(struct sd *sd) -{ - int start_cropx, start_cropy, x, y, fw, fh, cw, ch, - max_width, max_height; - - if (sd->sif) { - max_width = 352; - max_height = 288; - } else { - max_width = 640; - max_height = 480; - } - - if (sd->sensor == SEN_OV7620) { - /* - * Sigh, this is dependend on the clock / framerate changes - * made by the frequency control, sick. - * - * Note we cannot use v4l2_ctrl_g_ctrl here, as we get called - * from ov519.c:setfreq() with the ctrl lock held! - */ - if (sd->freq->val == 1) { - start_cropx = 277; - start_cropy = 37; - } else { - start_cropx = 105; - start_cropy = 37; - } - } else { - start_cropx = 320; - start_cropy = 35; - } - - /* Work around to avoid FP arithmetics */ - #define SC(x) ((x) << 10) - - /* Scaling factors */ - fw = SC(sd->gspca_dev.width) / max_width; - fh = SC(sd->gspca_dev.height) / max_height; - - cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh; - ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height; - - sd->sensor_width = max_width; - sd->sensor_height = max_height; - - x = (max_width - cw) / 2; - y = (max_height - ch) / 2; - - reg_w(sd, 0x10, start_cropx + x); - reg_w(sd, 0x11, start_cropy + y); - reg_w(sd, 0x12, start_cropx + x + cw); - reg_w(sd, 0x13, start_cropy + y + ch); -} - -static void w9968cf_mode_init_regs(struct sd *sd) -{ - int val, vs_polarity, hs_polarity; - - w9968cf_set_crop_window(sd); - - reg_w(sd, 0x14, sd->gspca_dev.width); - reg_w(sd, 0x15, sd->gspca_dev.height); - - /* JPEG width & height */ - reg_w(sd, 0x30, sd->gspca_dev.width); - reg_w(sd, 0x31, sd->gspca_dev.height); - - /* Y & UV frame buffer strides (in WORD) */ - if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == - V4L2_PIX_FMT_JPEG) { - reg_w(sd, 0x2c, sd->gspca_dev.width / 2); - reg_w(sd, 0x2d, sd->gspca_dev.width / 4); - } else - reg_w(sd, 0x2c, sd->gspca_dev.width); - - reg_w(sd, 0x00, 0xbf17); /* reset everything */ - reg_w(sd, 0x00, 0xbf10); /* normal operation */ - - /* Transfer size in WORDS (for UYVY format only) */ - val = sd->gspca_dev.width * sd->gspca_dev.height; - reg_w(sd, 0x3d, val & 0xffff); /* low bits */ - reg_w(sd, 0x3e, val >> 16); /* high bits */ - - if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == - V4L2_PIX_FMT_JPEG) { - /* We may get called multiple times (usb isoc bw negotiat.) */ - jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, - sd->gspca_dev.width, 0x22); /* JPEG 420 */ - jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); - w9968cf_upload_quantizationtables(sd); - v4l2_ctrl_grab(sd->jpegqual, true); - } - - /* Video Capture Control Register */ - if (sd->sensor == SEN_OV7620) { - /* Seems to work around a bug in the image sensor */ - vs_polarity = 1; - hs_polarity = 1; - } else { - vs_polarity = 1; - hs_polarity = 0; - } - - val = (vs_polarity << 12) | (hs_polarity << 11); - - /* NOTE: We may not have enough memory to do double buffering while - doing compression (amount of memory differs per model cam). - So we use the second image buffer also as jpeg stream buffer - (see w9968cf_init), and disable double buffering. */ - if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == - V4L2_PIX_FMT_JPEG) { - /* val |= 0x0002; YUV422P */ - val |= 0x0003; /* YUV420P */ - } else - val |= 0x0080; /* Enable HW double buffering */ - - /* val |= 0x0020; enable clamping */ - /* val |= 0x0008; enable (1-2-1) filter */ - /* val |= 0x000c; enable (2-3-6-3-2) filter */ - - val |= 0x8000; /* capt. enable */ - - reg_w(sd, 0x16, val); - - sd->gspca_dev.empty_packet = 0; -} - -static void w9968cf_stop0(struct sd *sd) -{ - v4l2_ctrl_grab(sd->jpegqual, false); - reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ - reg_w(sd, 0x16, 0x0000); /* stop video capture */ -} - -/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF - for the next frame). This seems to simply not be true when operating - in JPEG mode, in this case there may be empty packets within the - frame. So in JPEG mode use the JPEG SOI marker to detect SOF. - - Note to make things even more interesting the w9968cf sends *PLANAR* jpeg, - to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS, - V-data, EOI. */ -static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat == - V4L2_PIX_FMT_JPEG) { - if (len >= 2 && - data[0] == 0xff && - data[1] == 0xd8) { - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - /* Strip the ff d8, our own header (which adds - huffman and quantization tables) already has this */ - len -= 2; - data += 2; - } - } else { - /* In UYVY mode an empty packet signals EOF */ - if (gspca_dev->empty_packet) { - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); - gspca_frame_add(gspca_dev, FIRST_PACKET, - NULL, 0); - gspca_dev->empty_packet = 0; - } - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c deleted file mode 100644 index 13b8d395d210..000000000000 --- a/drivers/media/video/gspca/xirlink_cit.c +++ /dev/null @@ -1,3145 +0,0 @@ -/* - * USB IBM C-It Video Camera driver - * - * Supports Xirlink C-It Video Camera, IBM PC Camera, - * IBM NetCamera and Veo Stingray. - * - * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> - * - * This driver is based on earlier work of: - * - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define MODULE_NAME "xirlink-cit" - -#include <linux/input.h> -#include "gspca.h" - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Xirlink C-IT"); -MODULE_LICENSE("GPL"); - -/* FIXME we should autodetect this */ -static int ibm_netcam_pro; -module_param(ibm_netcam_pro, int, 0); -MODULE_PARM_DESC(ibm_netcam_pro, - "Use IBM Netcamera Pro init sequences for Model 3 cams"); - -/* FIXME this should be handled through the V4L2 input selection API */ -static int rca_input; -module_param(rca_input, int, 0644); -MODULE_PARM_DESC(rca_input, - "Use rca input instead of ccd sensor on Model 3 cams"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - struct v4l2_ctrl *lighting; - u8 model; -#define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */ -#define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */ -#define CIT_MODEL2 2 /* ibmcam driver */ -#define CIT_MODEL3 3 -#define CIT_MODEL4 4 -#define CIT_IBM_NETCAM_PRO 5 - u8 input_index; - u8 button_state; - u8 stop_on_control_change; - u8 sof_read; - u8 sof_len; -}; - -static void sd_stop0(struct gspca_dev *gspca_dev); - -static const struct v4l2_pix_format cif_yuv_mode[] = { - {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; - -static const struct v4l2_pix_format vga_yuv_mode[] = { - {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; - -static const struct v4l2_pix_format model0_mode[] = { - {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; - -static const struct v4l2_pix_format model2_mode[] = { - {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 2 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, - {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 + 4, - .colorspace = V4L2_COLORSPACE_SRGB}, -}; - -/* - * 01.01.08 - Added for RCA video in support -LO - * This struct is used to init the Model3 cam to use the RCA video in port - * instead of the CCD sensor. - */ -static const u16 rca_initdata[][3] = { - {0, 0x0000, 0x010c}, - {0, 0x0006, 0x012c}, - {0, 0x0078, 0x012d}, - {0, 0x0046, 0x012f}, - {0, 0xd141, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfea8, 0x0124}, - {1, 0x0000, 0x0116}, - {0, 0x0064, 0x0116}, - {1, 0x0000, 0x0115}, - {0, 0x0003, 0x0115}, - {0, 0x0008, 0x0123}, - {0, 0x0000, 0x0117}, - {0, 0x0000, 0x0112}, - {0, 0x0080, 0x0100}, - {0, 0x0000, 0x0100}, - {1, 0x0000, 0x0116}, - {0, 0x0060, 0x0116}, - {0, 0x0002, 0x0112}, - {0, 0x0000, 0x0123}, - {0, 0x0001, 0x0117}, - {0, 0x0040, 0x0108}, - {0, 0x0019, 0x012c}, - {0, 0x0040, 0x0116}, - {0, 0x000a, 0x0115}, - {0, 0x000b, 0x0115}, - {0, 0x0078, 0x012d}, - {0, 0x0046, 0x012f}, - {0, 0xd141, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfea8, 0x0124}, - {0, 0x0064, 0x0116}, - {0, 0x0000, 0x0115}, - {0, 0x0001, 0x0115}, - {0, 0xffff, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00aa, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xffff, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00f2, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x000f, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xffff, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00f8, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00fc, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xffff, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00f9, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x003c, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xffff, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0027, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0019, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0021, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0006, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0045, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002a, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x000e, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002b, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00f4, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002c, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0004, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002d, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0014, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002e, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0003, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x002f, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0003, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0014, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0053, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0x0000, 0x0101}, - {0, 0x00a0, 0x0103}, - {0, 0x0078, 0x0105}, - {0, 0x0000, 0x010a}, - {0, 0x0024, 0x010b}, - {0, 0x0028, 0x0119}, - {0, 0x0088, 0x011b}, - {0, 0x0002, 0x011d}, - {0, 0x0003, 0x011e}, - {0, 0x0000, 0x0129}, - {0, 0x00fc, 0x012b}, - {0, 0x0008, 0x0102}, - {0, 0x0000, 0x0104}, - {0, 0x0008, 0x011a}, - {0, 0x0028, 0x011c}, - {0, 0x0021, 0x012a}, - {0, 0x0000, 0x0118}, - {0, 0x0000, 0x0132}, - {0, 0x0000, 0x0109}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0031, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x00dc, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0032, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0020, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0001, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0040, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0037, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0030, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0xfff9, 0x0124}, - {0, 0x0086, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0038, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0008, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0x0000, 0x0127}, - {0, 0xfff8, 0x0124}, - {0, 0xfffd, 0x0124}, - {0, 0xfffa, 0x0124}, - {0, 0x0003, 0x0111}, -}; - -/* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we - do the same for now (testing needed to see if this is really necessary) */ -static const int cit_model1_ntries = 5; -static const int cit_model1_ntries2 = 2; - -static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index) -{ - struct usb_device *udev = gspca_dev->dev; - int err; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, - value, index, NULL, 0, 1000); - if (err < 0) - pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n", - index, value, err); - - return 0; -} - -static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose) -{ - struct usb_device *udev = gspca_dev->dev; - __u8 *buf = gspca_dev->usb_buf; - int res; - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, - 0x00, index, buf, 8, 1000); - if (res < 0) { - pr_err("Failed to read a register (index 0x%04X, error %d)\n", - index, res); - return res; - } - - if (verbose) - PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]); - - return 0; -} - -/* - * cit_send_FF_04_02() - * - * This procedure sends magic 3-command prefix to the camera. - * The purpose of this prefix is not known. - * - * History: - * 1/2/00 Created. - */ -static void cit_send_FF_04_02(struct gspca_dev *gspca_dev) -{ - cit_write_reg(gspca_dev, 0x00FF, 0x0127); - cit_write_reg(gspca_dev, 0x0004, 0x0124); - cit_write_reg(gspca_dev, 0x0002, 0x0124); -} - -static void cit_send_00_04_06(struct gspca_dev *gspca_dev) -{ - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0x0004, 0x0124); - cit_write_reg(gspca_dev, 0x0006, 0x0124); -} - -static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x) -{ - cit_write_reg(gspca_dev, x, 0x0127); - cit_write_reg(gspca_dev, 0x0000, 0x0124); -} - -static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x) -{ - cit_send_x_00(gspca_dev, x); - cit_write_reg(gspca_dev, 0x0005, 0x0124); -} - -static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x) -{ - cit_write_reg(gspca_dev, x, 0x0127); - cit_write_reg(gspca_dev, 0x0000, 0x0124); - cit_write_reg(gspca_dev, 0x0005, 0x0124); - cit_write_reg(gspca_dev, 0x0002, 0x0124); -} - -static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x) -{ - cit_write_reg(gspca_dev, x, 0x0127); - cit_write_reg(gspca_dev, 0x0001, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0124); - cit_write_reg(gspca_dev, 0x0005, 0x0124); -} - -static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x) -{ - cit_write_reg(gspca_dev, x, 0x0127); - cit_write_reg(gspca_dev, 0x0000, 0x0124); - cit_write_reg(gspca_dev, 0x0005, 0x0124); - cit_write_reg(gspca_dev, 0x0002, 0x0124); - cit_write_reg(gspca_dev, 0x0001, 0x0124); -} - -static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x) -{ - cit_write_reg(gspca_dev, x, 0x0127); - cit_write_reg(gspca_dev, 0x0000, 0x0124); - cit_write_reg(gspca_dev, 0x0005, 0x0124); - cit_write_reg(gspca_dev, 0x0002, 0x0124); - cit_write_reg(gspca_dev, 0x0008, 0x0124); - cit_write_reg(gspca_dev, 0x0001, 0x0124); -} - -static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val) -{ - cit_send_x_01_00_05(gspca_dev, 0x0088); - cit_send_x_00_05(gspca_dev, fkey); - cit_send_x_00_05_02_08_01(gspca_dev, val); - cit_send_x_00_05(gspca_dev, 0x0088); - cit_send_x_00_05_02_01(gspca_dev, fkey); - cit_send_x_00_05(gspca_dev, 0x0089); - cit_send_x_00(gspca_dev, fkey); - cit_send_00_04_06(gspca_dev); - cit_read_reg(gspca_dev, 0x0126, 0); - cit_send_FF_04_02(gspca_dev); -} - -static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val) -{ - cit_send_x_01_00_05(gspca_dev, 0x0088); - cit_send_x_00_05(gspca_dev, fkey); - cit_send_x_00_05_02(gspca_dev, val); -} - -static void cit_model2_Packet2(struct gspca_dev *gspca_dev) -{ - cit_write_reg(gspca_dev, 0x00ff, 0x012d); - cit_write_reg(gspca_dev, 0xfea3, 0x0124); -} - -static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) -{ - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x00ff, 0x012e); - cit_write_reg(gspca_dev, v1, 0x012f); - cit_write_reg(gspca_dev, 0x00ff, 0x0130); - cit_write_reg(gspca_dev, 0xc719, 0x0124); - cit_write_reg(gspca_dev, v2, 0x0127); - - cit_model2_Packet2(gspca_dev); -} - -/* - * cit_model3_Packet1() - * - * 00_0078_012d - * 00_0097_012f - * 00_d141_0124 - * 00_0096_0127 - * 00_fea8_0124 -*/ -static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) -{ - cit_write_reg(gspca_dev, 0x0078, 0x012d); - cit_write_reg(gspca_dev, v1, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, v2, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); -} - -static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2) -{ - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, v1, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, v2, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); -} - -static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val) -{ - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0026, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, val, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0038, 0x012d); - cit_write_reg(gspca_dev, 0x0004, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - - sd->model = id->driver_info; - if (sd->model == CIT_MODEL3 && ibm_netcam_pro) - sd->model = CIT_IBM_NETCAM_PRO; - - cam = &gspca_dev->cam; - switch (sd->model) { - case CIT_MODEL0: - cam->cam_mode = model0_mode; - cam->nmodes = ARRAY_SIZE(model0_mode); - sd->sof_len = 4; - break; - case CIT_MODEL1: - cam->cam_mode = cif_yuv_mode; - cam->nmodes = ARRAY_SIZE(cif_yuv_mode); - sd->sof_len = 4; - break; - case CIT_MODEL2: - cam->cam_mode = model2_mode + 1; /* no 160x120 */ - cam->nmodes = 3; - break; - case CIT_MODEL3: - cam->cam_mode = vga_yuv_mode; - cam->nmodes = ARRAY_SIZE(vga_yuv_mode); - sd->stop_on_control_change = 1; - sd->sof_len = 4; - break; - case CIT_MODEL4: - cam->cam_mode = model2_mode; - cam->nmodes = ARRAY_SIZE(model2_mode); - break; - case CIT_IBM_NETCAM_PRO: - cam->cam_mode = vga_yuv_mode; - cam->nmodes = 2; /* no 640 x 480 */ - cam->input_flags = V4L2_IN_ST_VFLIP; - sd->stop_on_control_change = 1; - sd->sof_len = 4; - break; - } - - return 0; -} - -static int cit_init_model0(struct gspca_dev *gspca_dev) -{ - cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ - cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */ - cit_write_reg(gspca_dev, 0x0000, 0x0400); - cit_write_reg(gspca_dev, 0x0001, 0x0400); - cit_write_reg(gspca_dev, 0x0000, 0x0420); - cit_write_reg(gspca_dev, 0x0001, 0x0420); - cit_write_reg(gspca_dev, 0x000d, 0x0409); - cit_write_reg(gspca_dev, 0x0002, 0x040a); - cit_write_reg(gspca_dev, 0x0018, 0x0405); - cit_write_reg(gspca_dev, 0x0008, 0x0435); - cit_write_reg(gspca_dev, 0x0026, 0x040b); - cit_write_reg(gspca_dev, 0x0007, 0x0437); - cit_write_reg(gspca_dev, 0x0015, 0x042f); - cit_write_reg(gspca_dev, 0x002b, 0x0439); - cit_write_reg(gspca_dev, 0x0026, 0x043a); - cit_write_reg(gspca_dev, 0x0008, 0x0438); - cit_write_reg(gspca_dev, 0x001e, 0x042b); - cit_write_reg(gspca_dev, 0x0041, 0x042c); - - return 0; -} - -static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev) -{ - cit_read_reg(gspca_dev, 0x128, 1); - cit_write_reg(gspca_dev, 0x0003, 0x0133); - cit_write_reg(gspca_dev, 0x0000, 0x0117); - cit_write_reg(gspca_dev, 0x0008, 0x0123); - cit_write_reg(gspca_dev, 0x0000, 0x0100); - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - cit_write_reg(gspca_dev, 0x0002, 0x0112); - cit_write_reg(gspca_dev, 0x0000, 0x0133); - cit_write_reg(gspca_dev, 0x0000, 0x0123); - cit_write_reg(gspca_dev, 0x0001, 0x0117); - cit_write_reg(gspca_dev, 0x0040, 0x0108); - cit_write_reg(gspca_dev, 0x0019, 0x012c); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - cit_write_reg(gspca_dev, 0x0002, 0x0115); - cit_write_reg(gspca_dev, 0x000b, 0x0115); - - cit_write_reg(gspca_dev, 0x0078, 0x012d); - cit_write_reg(gspca_dev, 0x0001, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0079, 0x012d); - cit_write_reg(gspca_dev, 0x00ff, 0x0130); - cit_write_reg(gspca_dev, 0xcd41, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_read_reg(gspca_dev, 0x0126, 1); - - cit_model3_Packet1(gspca_dev, 0x0000, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0000, 0x0001); - cit_model3_Packet1(gspca_dev, 0x000b, 0x0000); - cit_model3_Packet1(gspca_dev, 0x000c, 0x0008); - cit_model3_Packet1(gspca_dev, 0x000d, 0x003a); - cit_model3_Packet1(gspca_dev, 0x000e, 0x0060); - cit_model3_Packet1(gspca_dev, 0x000f, 0x0060); - cit_model3_Packet1(gspca_dev, 0x0010, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0011, 0x0004); - cit_model3_Packet1(gspca_dev, 0x0012, 0x0028); - cit_model3_Packet1(gspca_dev, 0x0013, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0014, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb); - cit_model3_Packet1(gspca_dev, 0x0016, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0017, 0x0037); - cit_model3_Packet1(gspca_dev, 0x0018, 0x0036); - cit_model3_Packet1(gspca_dev, 0x001e, 0x0000); - cit_model3_Packet1(gspca_dev, 0x001f, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1); - cit_model3_Packet1(gspca_dev, 0x0021, 0x0034); - cit_model3_Packet1(gspca_dev, 0x0022, 0x0034); - cit_model3_Packet1(gspca_dev, 0x0025, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0028, 0x0022); - cit_model3_Packet1(gspca_dev, 0x0029, 0x000a); - cit_model3_Packet1(gspca_dev, 0x002b, 0x0000); - cit_model3_Packet1(gspca_dev, 0x002c, 0x0000); - cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x0032, 0x0007); - cit_model3_Packet1(gspca_dev, 0x0033, 0x0005); - cit_model3_Packet1(gspca_dev, 0x0037, 0x0040); - cit_model3_Packet1(gspca_dev, 0x0039, 0x0000); - cit_model3_Packet1(gspca_dev, 0x003a, 0x0000); - cit_model3_Packet1(gspca_dev, 0x003b, 0x0001); - cit_model3_Packet1(gspca_dev, 0x003c, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0040, 0x000c); - cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb); - cit_model3_Packet1(gspca_dev, 0x0042, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0043, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0045, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0047, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0048, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0049, 0x0000); - cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff); - cit_model3_Packet1(gspca_dev, 0x004f, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0050, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0051, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0055, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0056, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0057, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0058, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0059, 0x0000); - cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); - cit_model3_Packet1(gspca_dev, 0x005d, 0x0022); - cit_model3_Packet1(gspca_dev, 0x005e, 0x003c); - cit_model3_Packet1(gspca_dev, 0x005f, 0x0050); - cit_model3_Packet1(gspca_dev, 0x0060, 0x0044); - cit_model3_Packet1(gspca_dev, 0x0061, 0x0005); - cit_model3_Packet1(gspca_dev, 0x006a, 0x007e); - cit_model3_Packet1(gspca_dev, 0x006f, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0072, 0x001b); - cit_model3_Packet1(gspca_dev, 0x0073, 0x0005); - cit_model3_Packet1(gspca_dev, 0x0074, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0075, 0x001b); - cit_model3_Packet1(gspca_dev, 0x0076, 0x002a); - cit_model3_Packet1(gspca_dev, 0x0077, 0x003c); - cit_model3_Packet1(gspca_dev, 0x0078, 0x0050); - cit_model3_Packet1(gspca_dev, 0x007b, 0x0000); - cit_model3_Packet1(gspca_dev, 0x007c, 0x0011); - cit_model3_Packet1(gspca_dev, 0x007d, 0x0024); - cit_model3_Packet1(gspca_dev, 0x007e, 0x0043); - cit_model3_Packet1(gspca_dev, 0x007f, 0x005a); - cit_model3_Packet1(gspca_dev, 0x0084, 0x0020); - cit_model3_Packet1(gspca_dev, 0x0085, 0x0033); - cit_model3_Packet1(gspca_dev, 0x0086, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0087, 0x0030); - cit_model3_Packet1(gspca_dev, 0x0088, 0x0070); - cit_model3_Packet1(gspca_dev, 0x008b, 0x0008); - cit_model3_Packet1(gspca_dev, 0x008f, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0090, 0x0006); - cit_model3_Packet1(gspca_dev, 0x0091, 0x0028); - cit_model3_Packet1(gspca_dev, 0x0092, 0x005a); - cit_model3_Packet1(gspca_dev, 0x0093, 0x0082); - cit_model3_Packet1(gspca_dev, 0x0096, 0x0014); - cit_model3_Packet1(gspca_dev, 0x0097, 0x0020); - cit_model3_Packet1(gspca_dev, 0x0098, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046); - cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004); - cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007); - cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002); - cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004); - cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8); - cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014); - cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004); - cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020); - cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040); - cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf); - cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008); - cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8); - cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022); - cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028); - cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002); - cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000); - - cit_model3_Packet1(gspca_dev, 0x00be, 0x0003); - cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020); - cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040); - cit_model3_Packet1(gspca_dev, 0x0053, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0082, 0x000e); - cit_model3_Packet1(gspca_dev, 0x0083, 0x0020); - cit_model3_Packet1(gspca_dev, 0x0034, 0x003c); - cit_model3_Packet1(gspca_dev, 0x006e, 0x0055); - cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); - cit_model3_Packet1(gspca_dev, 0x0063, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0066, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0067, 0x0006); - cit_model3_Packet1(gspca_dev, 0x006b, 0x0010); - cit_model3_Packet1(gspca_dev, 0x005a, 0x0001); - cit_model3_Packet1(gspca_dev, 0x005b, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0023, 0x0006); - cit_model3_Packet1(gspca_dev, 0x0026, 0x0004); - cit_model3_Packet1(gspca_dev, 0x0036, 0x0069); - cit_model3_Packet1(gspca_dev, 0x0038, 0x0064); - cit_model3_Packet1(gspca_dev, 0x003d, 0x0003); - cit_model3_Packet1(gspca_dev, 0x003e, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014); - cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014); - cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004); - cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001); - - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - cit_init_model0(gspca_dev); - sd_stop0(gspca_dev); - break; - case CIT_MODEL1: - case CIT_MODEL2: - case CIT_MODEL3: - case CIT_MODEL4: - break; /* All is done in sd_start */ - case CIT_IBM_NETCAM_PRO: - cit_init_ibm_netcam_pro(gspca_dev); - sd_stop0(gspca_dev); - break; - } - return 0; -} - -static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_IBM_NETCAM_PRO: - /* No (known) brightness control for these */ - break; - case CIT_MODEL1: - /* Model 1: Brightness range 0 - 63 */ - cit_Packet_Format1(gspca_dev, 0x0031, val); - cit_Packet_Format1(gspca_dev, 0x0032, val); - cit_Packet_Format1(gspca_dev, 0x0033, val); - break; - case CIT_MODEL2: - /* Model 2: Brightness range 0x60 - 0xee */ - /* Scale 0 - 63 to 0x60 - 0xee */ - i = 0x60 + val * 2254 / 1000; - cit_model2_Packet1(gspca_dev, 0x001a, i); - break; - case CIT_MODEL3: - /* Model 3: Brightness range 'i' in [0x0C..0x3F] */ - i = val; - if (i < 0x0c) - i = 0x0c; - cit_model3_Packet1(gspca_dev, 0x0036, i); - break; - case CIT_MODEL4: - /* Model 4: Brightness range 'i' in [0x04..0xb4] */ - /* Scale 0 - 63 to 0x04 - 0xb4 */ - i = 0x04 + val * 2794 / 1000; - cit_model4_BrightnessPacket(gspca_dev, i); - break; - } - - return 0; -} - -static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: { - int i; - /* gain 0-15, 0-20 -> 0-15 */ - i = val * 1000 / 1333; - cit_write_reg(gspca_dev, i, 0x0422); - /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */ - i = val * 2000 / 1333; - cit_write_reg(gspca_dev, i, 0x0423); - /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */ - i = val * 4000 / 1333; - cit_write_reg(gspca_dev, i, 0x0424); - /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */ - i = val * 8000 / 1333; - cit_write_reg(gspca_dev, i, 0x0425); - break; - } - case CIT_MODEL2: - case CIT_MODEL4: - /* These models do not have this control. */ - break; - case CIT_MODEL1: - { - /* Scale 0 - 20 to 15 - 0 */ - int i, new_contrast = (20 - val) * 1000 / 1333; - for (i = 0; i < cit_model1_ntries; i++) { - cit_Packet_Format1(gspca_dev, 0x0014, new_contrast); - cit_send_FF_04_02(gspca_dev); - } - break; - } - case CIT_MODEL3: - { /* Preset hardware values */ - static const struct { - unsigned short cv1; - unsigned short cv2; - unsigned short cv3; - } cv[7] = { - { 0x05, 0x05, 0x0f }, /* Minimum */ - { 0x04, 0x04, 0x16 }, - { 0x02, 0x03, 0x16 }, - { 0x02, 0x08, 0x16 }, - { 0x01, 0x0c, 0x16 }, - { 0x01, 0x0e, 0x16 }, - { 0x01, 0x10, 0x16 } /* Maximum */ - }; - int i = val / 3; - cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1); - cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2); - cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3); - break; - } - case CIT_IBM_NETCAM_PRO: - cit_model3_Packet1(gspca_dev, 0x005b, val + 1); - break; - } - return 0; -} - -static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_MODEL1: - case CIT_IBM_NETCAM_PRO: - /* No hue control for these models */ - break; - case CIT_MODEL2: - cit_model2_Packet1(gspca_dev, 0x0024, val); - /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */ - break; - case CIT_MODEL3: { - /* Model 3: Brightness range 'i' in [0x05..0x37] */ - /* TESTME according to the ibmcam driver this does not work */ - if (0) { - /* Scale 0 - 127 to 0x05 - 0x37 */ - int i = 0x05 + val * 1000 / 2540; - cit_model3_Packet1(gspca_dev, 0x007e, i); - } - break; - } - case CIT_MODEL4: - /* HDG: taken from ibmcam, setting the color gains does not - * really belong here. - * - * I am not sure r/g/b_gain variables exactly control gain - * of those channels. Most likely they subtly change some - * very internal image processing settings in the camera. - * In any case, here is what they do, and feel free to tweak: - * - * r_gain: seriously affects red gain - * g_gain: seriously affects green gain - * b_gain: seriously affects blue gain - * hue: changes average color from violet (0) to red (0xFF) - */ - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 160, 0x0127); /* Green gain */ - cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */ - cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */ - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, val, 0x012d); /* Hue */ - cit_write_reg(gspca_dev, 0xf545, 0x0124); - break; - } - return 0; -} - -static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_MODEL2: - case CIT_MODEL4: - case CIT_IBM_NETCAM_PRO: - /* These models do not have this control */ - break; - case CIT_MODEL1: { - int i; - const unsigned short sa[] = { - 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; - - for (i = 0; i < cit_model1_ntries; i++) - cit_PacketFormat2(gspca_dev, 0x0013, sa[val]); - break; - } - case CIT_MODEL3: - { /* - * "Use a table of magic numbers. - * This setting doesn't really change much. - * But that's how Windows does it." - */ - static const struct { - unsigned short sv1; - unsigned short sv2; - unsigned short sv3; - unsigned short sv4; - } sv[7] = { - { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */ - { 0x01, 0x04, 0x05, 0x14 }, - { 0x02, 0x04, 0x05, 0x14 }, - { 0x03, 0x04, 0x05, 0x14 }, - { 0x03, 0x05, 0x05, 0x14 }, - { 0x03, 0x06, 0x05, 0x14 }, - { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */ - }; - cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1); - cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2); - cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3); - cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4); - break; - } - } - return 0; -} - -/* - * cit_set_lighting() - * - * Camera model 1: - * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low. - * - * Camera model 2: - * We have 16 levels of lighting, 0 for bright light and up to 15 for - * low light. But values above 5 or so are useless because camera is - * not really capable to produce anything worth viewing at such light. - * This setting may be altered only in certain camera state. - * - * Low lighting forces slower FPS. - * - * History: - * 1/5/00 Created. - * 2/20/00 Added support for Model 2 cameras. - */ -static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_MODEL2: - case CIT_MODEL3: - case CIT_MODEL4: - case CIT_IBM_NETCAM_PRO: - break; - case CIT_MODEL1: { - int i; - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x0027, val); - break; - } - } -} - -static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - if (val) - cit_write_reg(gspca_dev, 0x0020, 0x0115); - else - cit_write_reg(gspca_dev, 0x0040, 0x0115); - break; - case CIT_MODEL1: - case CIT_MODEL2: - case CIT_MODEL3: - case CIT_MODEL4: - case CIT_IBM_NETCAM_PRO: - break; - } -} - -static int cit_restart_stream(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_MODEL1: - cit_write_reg(gspca_dev, 0x0001, 0x0114); - /* Fall through */ - case CIT_MODEL2: - case CIT_MODEL4: - cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ - usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); - break; - case CIT_MODEL3: - case CIT_IBM_NETCAM_PRO: - cit_write_reg(gspca_dev, 0x0001, 0x0114); - cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */ - usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); - /* Clear button events from while we were not streaming */ - cit_write_reg(gspca_dev, 0x0001, 0x0113); - break; - } - - sd->sof_read = 0; - - return 0; -} - -static int cit_get_packet_size(struct gspca_dev *gspca_dev) -{ - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - alt = usb_altnum_to_altsetting(intf, gspca_dev->alt); - if (!alt) { - pr_err("Couldn't get altsetting\n"); - return -EIO; - } - - return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); -} - -/* Calculate the clockdiv giving us max fps given the available bandwidth */ -static int cit_get_clock_div(struct gspca_dev *gspca_dev) -{ - int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */ - int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 }; - int packet_size; - - packet_size = cit_get_packet_size(gspca_dev); - if (packet_size < 0) - return packet_size; - - while (clock_div > 3 && - 1000 * packet_size > - gspca_dev->width * gspca_dev->height * - fps[clock_div - 1] * 3 / 2) - clock_div--; - - PDEBUG(D_PROBE, - "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)", - packet_size, gspca_dev->width, gspca_dev->height, clock_div, - fps[clock_div]); - - return clock_div; -} - -static int cit_start_model0(struct gspca_dev *gspca_dev) -{ - const unsigned short compression = 0; /* 0=none, 7=best frame rate */ - int clock_div; - - clock_div = cit_get_clock_div(gspca_dev); - if (clock_div < 0) - return clock_div; - - cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ - cit_write_reg(gspca_dev, 0x0003, 0x0438); - cit_write_reg(gspca_dev, 0x001e, 0x042b); - cit_write_reg(gspca_dev, 0x0041, 0x042c); - cit_write_reg(gspca_dev, 0x0008, 0x0436); - cit_write_reg(gspca_dev, 0x0024, 0x0403); - cit_write_reg(gspca_dev, 0x002c, 0x0404); - cit_write_reg(gspca_dev, 0x0002, 0x0426); - cit_write_reg(gspca_dev, 0x0014, 0x0427); - - switch (gspca_dev->width) { - case 160: /* 160x120 */ - cit_write_reg(gspca_dev, 0x0004, 0x010b); - cit_write_reg(gspca_dev, 0x0001, 0x010a); - cit_write_reg(gspca_dev, 0x0010, 0x0102); - cit_write_reg(gspca_dev, 0x00a0, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x0078, 0x0105); - break; - - case 176: /* 176x144 */ - cit_write_reg(gspca_dev, 0x0006, 0x010b); - cit_write_reg(gspca_dev, 0x0000, 0x010a); - cit_write_reg(gspca_dev, 0x0005, 0x0102); - cit_write_reg(gspca_dev, 0x00b0, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x0090, 0x0105); - break; - - case 320: /* 320x240 */ - cit_write_reg(gspca_dev, 0x0008, 0x010b); - cit_write_reg(gspca_dev, 0x0004, 0x010a); - cit_write_reg(gspca_dev, 0x0005, 0x0102); - cit_write_reg(gspca_dev, 0x00a0, 0x0103); - cit_write_reg(gspca_dev, 0x0010, 0x0104); - cit_write_reg(gspca_dev, 0x0078, 0x0105); - break; - } - - cit_write_reg(gspca_dev, compression, 0x0109); - cit_write_reg(gspca_dev, clock_div, 0x0111); - - return 0; -} - -static int cit_start_model1(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, clock_div; - - clock_div = cit_get_clock_div(gspca_dev); - if (clock_div < 0) - return clock_div; - - cit_read_reg(gspca_dev, 0x0128, 1); - cit_read_reg(gspca_dev, 0x0100, 0); - cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ - cit_read_reg(gspca_dev, 0x0100, 0); - cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ - cit_read_reg(gspca_dev, 0x0100, 0); - cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ - cit_write_reg(gspca_dev, 0x01, 0x0108); - - cit_write_reg(gspca_dev, 0x03, 0x0112); - cit_read_reg(gspca_dev, 0x0115, 0); - cit_write_reg(gspca_dev, 0x06, 0x0115); - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x44, 0x0116); - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x40, 0x0116); - cit_read_reg(gspca_dev, 0x0115, 0); - cit_write_reg(gspca_dev, 0x0e, 0x0115); - cit_write_reg(gspca_dev, 0x19, 0x012c); - - cit_Packet_Format1(gspca_dev, 0x00, 0x1e); - cit_Packet_Format1(gspca_dev, 0x39, 0x0d); - cit_Packet_Format1(gspca_dev, 0x39, 0x09); - cit_Packet_Format1(gspca_dev, 0x3b, 0x00); - cit_Packet_Format1(gspca_dev, 0x28, 0x22); - cit_Packet_Format1(gspca_dev, 0x27, 0x00); - cit_Packet_Format1(gspca_dev, 0x2b, 0x1f); - cit_Packet_Format1(gspca_dev, 0x39, 0x08); - - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x2c, 0x00); - - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x30, 0x14); - - cit_PacketFormat2(gspca_dev, 0x39, 0x02); - cit_PacketFormat2(gspca_dev, 0x01, 0xe1); - cit_PacketFormat2(gspca_dev, 0x02, 0xcd); - cit_PacketFormat2(gspca_dev, 0x03, 0xcd); - cit_PacketFormat2(gspca_dev, 0x04, 0xfa); - cit_PacketFormat2(gspca_dev, 0x3f, 0xff); - cit_PacketFormat2(gspca_dev, 0x39, 0x00); - - cit_PacketFormat2(gspca_dev, 0x39, 0x02); - cit_PacketFormat2(gspca_dev, 0x0a, 0x37); - cit_PacketFormat2(gspca_dev, 0x0b, 0xb8); - cit_PacketFormat2(gspca_dev, 0x0c, 0xf3); - cit_PacketFormat2(gspca_dev, 0x0d, 0xe3); - cit_PacketFormat2(gspca_dev, 0x0e, 0x0d); - cit_PacketFormat2(gspca_dev, 0x0f, 0xf2); - cit_PacketFormat2(gspca_dev, 0x10, 0xd5); - cit_PacketFormat2(gspca_dev, 0x11, 0xba); - cit_PacketFormat2(gspca_dev, 0x12, 0x53); - cit_PacketFormat2(gspca_dev, 0x3f, 0xff); - cit_PacketFormat2(gspca_dev, 0x39, 0x00); - - cit_PacketFormat2(gspca_dev, 0x39, 0x02); - cit_PacketFormat2(gspca_dev, 0x16, 0x00); - cit_PacketFormat2(gspca_dev, 0x17, 0x28); - cit_PacketFormat2(gspca_dev, 0x18, 0x7d); - cit_PacketFormat2(gspca_dev, 0x19, 0xbe); - cit_PacketFormat2(gspca_dev, 0x3f, 0xff); - cit_PacketFormat2(gspca_dev, 0x39, 0x00); - - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x00, 0x18); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x13, 0x18); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x14, 0x06); - - /* TESTME These are handled through controls - KEEP until someone can test leaving this out is ok */ - if (0) { - /* This is default brightness */ - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x31, 0x37); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x32, 0x46); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x33, 0x55); - } - - cit_Packet_Format1(gspca_dev, 0x2e, 0x04); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x2d, 0x04); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x29, 0x80); - cit_Packet_Format1(gspca_dev, 0x2c, 0x01); - cit_Packet_Format1(gspca_dev, 0x30, 0x17); - cit_Packet_Format1(gspca_dev, 0x39, 0x08); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x34, 0x00); - - cit_write_reg(gspca_dev, 0x00, 0x0101); - cit_write_reg(gspca_dev, 0x00, 0x010a); - - switch (gspca_dev->width) { - case 128: /* 128x96 */ - cit_write_reg(gspca_dev, 0x80, 0x0103); - cit_write_reg(gspca_dev, 0x60, 0x0105); - cit_write_reg(gspca_dev, 0x0c, 0x010b); - cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x0b, 0x011d); - cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x00, 0x0129); - break; - case 176: /* 176x144 */ - cit_write_reg(gspca_dev, 0xb0, 0x0103); - cit_write_reg(gspca_dev, 0x8f, 0x0105); - cit_write_reg(gspca_dev, 0x06, 0x010b); - cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x0d, 0x011d); - cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x03, 0x0129); - break; - case 352: /* 352x288 */ - cit_write_reg(gspca_dev, 0xb0, 0x0103); - cit_write_reg(gspca_dev, 0x90, 0x0105); - cit_write_reg(gspca_dev, 0x02, 0x010b); - cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x05, 0x011d); - cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x00, 0x0129); - break; - } - - cit_write_reg(gspca_dev, 0xff, 0x012b); - - /* TESTME These are handled through controls - KEEP until someone can test leaving this out is ok */ - if (0) { - /* This is another brightness - don't know why */ - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x31, 0xc3); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x32, 0xd2); - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x33, 0xe1); - - /* Default contrast */ - for (i = 0; i < cit_model1_ntries; i++) - cit_Packet_Format1(gspca_dev, 0x14, 0x0a); - - /* Default sharpness */ - for (i = 0; i < cit_model1_ntries2; i++) - cit_PacketFormat2(gspca_dev, 0x13, 0x1a); - - /* Default lighting conditions */ - cit_Packet_Format1(gspca_dev, 0x0027, - v4l2_ctrl_g_ctrl(sd->lighting)); - } - - /* Assorted init */ - switch (gspca_dev->width) { - case 128: /* 128x96 */ - cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); - cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x36, 0x0102); - cit_write_reg(gspca_dev, 0x1a, 0x0104); - cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x2b, 0x011c); - cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ - break; - case 176: /* 176x144 */ - cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); - cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x04, 0x0102); - cit_write_reg(gspca_dev, 0x02, 0x0104); - cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x2b, 0x011c); - cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ - break; - case 352: /* 352x288 */ - cit_Packet_Format1(gspca_dev, 0x2b, 0x1f); - cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x08, 0x0102); - cit_write_reg(gspca_dev, 0x01, 0x0104); - cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */ - cit_write_reg(gspca_dev, 0x2f, 0x011c); - cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */ - break; - } - - cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ - cit_write_reg(gspca_dev, clock_div, 0x0111); - - return 0; -} - -static int cit_start_model2(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int clock_div = 0; - - cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - cit_write_reg(gspca_dev, 0x0002, 0x0112); - cit_write_reg(gspca_dev, 0x00bc, 0x012c); - cit_write_reg(gspca_dev, 0x0008, 0x012b); - cit_write_reg(gspca_dev, 0x0000, 0x0108); - cit_write_reg(gspca_dev, 0x0001, 0x0133); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - switch (gspca_dev->width) { - case 176: /* 176x144 */ - cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ - cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */ - cit_write_reg(gspca_dev, 0x00b9, 0x010a); /* Unique to this mode */ - cit_write_reg(gspca_dev, 0x0038, 0x0119); /* Unique to this mode */ - /* TESTME HDG: this does not seem right - (it is 2 for all other resolutions) */ - sd->sof_len = 10; - break; - case 320: /* 320x240 */ - cit_write_reg(gspca_dev, 0x0028, 0x0103); /* Unique to this mode */ - cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ - cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */ - cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ - sd->sof_len = 2; - break; - /* case VIDEOSIZE_352x240: */ - cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ - cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */ - cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ - sd->sof_len = 2; - break; - case 352: /* 352x288 */ - cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ - cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */ - cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ - sd->sof_len = 2; - break; - } - - cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ - - switch (gspca_dev->width) { - case 176: /* 176x144 */ - cit_write_reg(gspca_dev, 0x0050, 0x0111); - cit_write_reg(gspca_dev, 0x00d0, 0x0111); - break; - case 320: /* 320x240 */ - case 352: /* 352x288 */ - cit_write_reg(gspca_dev, 0x0040, 0x0111); - cit_write_reg(gspca_dev, 0x00c0, 0x0111); - break; - } - cit_write_reg(gspca_dev, 0x009b, 0x010f); - cit_write_reg(gspca_dev, 0x00bb, 0x010f); - - /* - * Hardware settings, may affect CMOS sensor; not user controls! - * ------------------------------------------------------------- - * 0x0004: no effect - * 0x0006: hardware effect - * 0x0008: no effect - * 0x000a: stops video stream, probably important h/w setting - * 0x000c: changes color in hardware manner (not user setting) - * 0x0012: changes number of colors (does not affect speed) - * 0x002a: no effect - * 0x002c: hardware setting (related to scan lines) - * 0x002e: stops video stream, probably important h/w setting - */ - cit_model2_Packet1(gspca_dev, 0x000a, 0x005c); - cit_model2_Packet1(gspca_dev, 0x0004, 0x0000); - cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb); - cit_model2_Packet1(gspca_dev, 0x0008, 0x0000); - cit_model2_Packet1(gspca_dev, 0x000c, 0x0009); - cit_model2_Packet1(gspca_dev, 0x0012, 0x000a); - cit_model2_Packet1(gspca_dev, 0x002a, 0x0000); - cit_model2_Packet1(gspca_dev, 0x002c, 0x0000); - cit_model2_Packet1(gspca_dev, 0x002e, 0x0008); - - /* - * Function 0x0030 pops up all over the place. Apparently - * it is a hardware control register, with every bit assigned to - * do something. - */ - cit_model2_Packet1(gspca_dev, 0x0030, 0x0000); - - /* - * Magic control of CMOS sensor. Only lower values like - * 0-3 work, and picture shifts left or right. Don't change. - */ - switch (gspca_dev->width) { - case 176: /* 176x144 */ - cit_model2_Packet1(gspca_dev, 0x0014, 0x0002); - cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ - cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */ - clock_div = 6; - break; - case 320: /* 320x240 */ - cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); - cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */ - cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */ - clock_div = 8; - break; - /* case VIDEOSIZE_352x240: */ - /* This mode doesn't work as Windows programs it; changed to work */ - cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */ - cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */ - cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ - clock_div = 10; - break; - case 352: /* 352x288 */ - cit_model2_Packet1(gspca_dev, 0x0014, 0x0003); - cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ - cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */ - clock_div = 16; - break; - } - - /* TESTME These are handled through controls - KEEP until someone can test leaving this out is ok */ - if (0) - cit_model2_Packet1(gspca_dev, 0x001a, 0x005a); - - /* - * We have our own frame rate setting varying from 0 (slowest) to 6 - * (fastest). The camera model 2 allows frame rate in range [0..0x1F] - # where 0 is also the slowest setting. However for all practical - # reasons high settings make no sense because USB is not fast enough - # to support high FPS. Be aware that the picture datastream will be - # severely disrupted if you ask for frame rate faster than allowed - # for the video size - see below: - * - * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz): - * ----------------------------------------------------------------- - * 176x144: [6..31] - * 320x240: [8..31] - * 352x240: [10..31] - * 352x288: [16..31] I have to raise lower threshold for stability... - * - * As usual, slower FPS provides better sensitivity. - */ - cit_model2_Packet1(gspca_dev, 0x001c, clock_div); - - /* - * This setting does not visibly affect pictures; left it here - * because it was present in Windows USB data stream. This function - * does not allow arbitrary values and apparently is a bit mask, to - * be activated only at appropriate time. Don't change it randomly! - */ - switch (gspca_dev->width) { - case 176: /* 176x144 */ - cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2); - break; - case 320: /* 320x240 */ - cit_model2_Packet1(gspca_dev, 0x0026, 0x0044); - break; - /* case VIDEOSIZE_352x240: */ - cit_model2_Packet1(gspca_dev, 0x0026, 0x0046); - break; - case 352: /* 352x288 */ - cit_model2_Packet1(gspca_dev, 0x0026, 0x0048); - break; - } - - cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting)); - /* model2 cannot change the backlight compensation while streaming */ - v4l2_ctrl_grab(sd->lighting, true); - - /* color balance rg2 */ - cit_model2_Packet1(gspca_dev, 0x001e, 0x002f); - /* saturation */ - cit_model2_Packet1(gspca_dev, 0x0020, 0x0034); - /* color balance yb */ - cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0); - - /* Hardware control command */ - cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); - - return 0; -} - -static int cit_start_model3(struct gspca_dev *gspca_dev) -{ - const unsigned short compression = 0; /* 0=none, 7=best frame rate */ - int i, clock_div = 0; - - /* HDG not in ibmcam driver, added to see if it helps with - auto-detecting between model3 and ibm netcamera pro */ - cit_read_reg(gspca_dev, 0x128, 1); - - cit_write_reg(gspca_dev, 0x0000, 0x0100); - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - cit_write_reg(gspca_dev, 0x0002, 0x0112); - cit_write_reg(gspca_dev, 0x0000, 0x0123); - cit_write_reg(gspca_dev, 0x0001, 0x0117); - cit_write_reg(gspca_dev, 0x0040, 0x0108); - cit_write_reg(gspca_dev, 0x0019, 0x012c); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - cit_write_reg(gspca_dev, 0x0002, 0x0115); - cit_write_reg(gspca_dev, 0x0003, 0x0115); - cit_read_reg(gspca_dev, 0x0115, 0); - cit_write_reg(gspca_dev, 0x000b, 0x0115); - - /* TESTME HDG not in ibmcam driver, added to see if it helps with - auto-detecting between model3 and ibm netcamera pro */ - if (0) { - cit_write_reg(gspca_dev, 0x0078, 0x012d); - cit_write_reg(gspca_dev, 0x0001, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0079, 0x012d); - cit_write_reg(gspca_dev, 0x00ff, 0x0130); - cit_write_reg(gspca_dev, 0xcd41, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_read_reg(gspca_dev, 0x0126, 1); - } - - cit_model3_Packet1(gspca_dev, 0x000a, 0x0040); - cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6); - cit_model3_Packet1(gspca_dev, 0x000c, 0x0002); - cit_model3_Packet1(gspca_dev, 0x000d, 0x0020); - cit_model3_Packet1(gspca_dev, 0x000e, 0x0033); - cit_model3_Packet1(gspca_dev, 0x000f, 0x0007); - cit_model3_Packet1(gspca_dev, 0x0010, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0011, 0x0070); - cit_model3_Packet1(gspca_dev, 0x0012, 0x0030); - cit_model3_Packet1(gspca_dev, 0x0013, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0014, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0015, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0016, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0017, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0018, 0x0000); - cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3); - cit_model3_Packet1(gspca_dev, 0x0020, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0028, 0x0010); - cit_model3_Packet1(gspca_dev, 0x0029, 0x0054); - cit_model3_Packet1(gspca_dev, 0x002a, 0x0013); - cit_model3_Packet1(gspca_dev, 0x002b, 0x0007); - cit_model3_Packet1(gspca_dev, 0x002d, 0x0028); - cit_model3_Packet1(gspca_dev, 0x002e, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0031, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0032, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0033, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0034, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0035, 0x0038); - cit_model3_Packet1(gspca_dev, 0x003a, 0x0001); - cit_model3_Packet1(gspca_dev, 0x003c, 0x001e); - cit_model3_Packet1(gspca_dev, 0x003f, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0041, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0046, 0x003f); - cit_model3_Packet1(gspca_dev, 0x0047, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0050, 0x0005); - cit_model3_Packet1(gspca_dev, 0x0052, 0x001a); - cit_model3_Packet1(gspca_dev, 0x0053, 0x0003); - cit_model3_Packet1(gspca_dev, 0x005a, 0x006b); - cit_model3_Packet1(gspca_dev, 0x005d, 0x001e); - cit_model3_Packet1(gspca_dev, 0x005e, 0x0030); - cit_model3_Packet1(gspca_dev, 0x005f, 0x0041); - cit_model3_Packet1(gspca_dev, 0x0064, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0065, 0x0015); - cit_model3_Packet1(gspca_dev, 0x0068, 0x000f); - cit_model3_Packet1(gspca_dev, 0x0079, 0x0000); - cit_model3_Packet1(gspca_dev, 0x007a, 0x0000); - cit_model3_Packet1(gspca_dev, 0x007c, 0x003f); - cit_model3_Packet1(gspca_dev, 0x0082, 0x000f); - cit_model3_Packet1(gspca_dev, 0x0085, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0099, 0x0000); - cit_model3_Packet1(gspca_dev, 0x009b, 0x0023); - cit_model3_Packet1(gspca_dev, 0x009c, 0x0022); - cit_model3_Packet1(gspca_dev, 0x009d, 0x0096); - cit_model3_Packet1(gspca_dev, 0x009e, 0x0096); - cit_model3_Packet1(gspca_dev, 0x009f, 0x000a); - - switch (gspca_dev->width) { - case 160: - cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ - cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */ - cit_write_reg(gspca_dev, 0x00a9, 0x0119); - cit_write_reg(gspca_dev, 0x0016, 0x011b); - cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */ - cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ - cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ - cit_write_reg(gspca_dev, 0x0018, 0x0102); - cit_write_reg(gspca_dev, 0x0004, 0x0104); - cit_write_reg(gspca_dev, 0x0004, 0x011a); - cit_write_reg(gspca_dev, 0x0028, 0x011c); - cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ - cit_write_reg(gspca_dev, 0x0000, 0x0118); - cit_write_reg(gspca_dev, 0x0000, 0x0132); - cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ - cit_write_reg(gspca_dev, compression, 0x0109); - clock_div = 3; - break; - case 320: - cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ - cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */ - cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */ - cit_write_reg(gspca_dev, 0x0000, 0x011e); - cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ - cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ - /* 4 commands from 160x120 skipped */ - cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ - cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ - cit_write_reg(gspca_dev, compression, 0x0109); - cit_write_reg(gspca_dev, 0x00d9, 0x0119); - cit_write_reg(gspca_dev, 0x0006, 0x011b); - cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x0010, 0x0104); - cit_write_reg(gspca_dev, 0x0004, 0x011a); - cit_write_reg(gspca_dev, 0x003f, 0x011c); - cit_write_reg(gspca_dev, 0x001c, 0x0118); - cit_write_reg(gspca_dev, 0x0000, 0x0132); - clock_div = 5; - break; - case 640: - cit_write_reg(gspca_dev, 0x00f0, 0x0105); - cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ - cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */ - cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */ - cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */ - cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ - cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ - cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */ - cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */ - cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ - cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */ - cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */ - cit_write_reg(gspca_dev, compression, 0x0109); - cit_write_reg(gspca_dev, 0x0040, 0x0101); - cit_write_reg(gspca_dev, 0x0040, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */ - clock_div = 7; - break; - } - - cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); /* Hue */ - cit_model3_Packet1(gspca_dev, 0x0036, 0x0011); /* Brightness */ - cit_model3_Packet1(gspca_dev, 0x0060, 0x0002); /* Sharpness */ - cit_model3_Packet1(gspca_dev, 0x0061, 0x0004); /* Sharpness */ - cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); /* Sharpness */ - cit_model3_Packet1(gspca_dev, 0x0063, 0x0014); /* Sharpness */ - cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */ - cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */ - cit_model3_Packet1(gspca_dev, 0x0067, 0x0001); /* Contrast */ - cit_model3_Packet1(gspca_dev, 0x005b, 0x000c); /* Contrast */ - cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); /* Contrast */ - cit_model3_Packet1(gspca_dev, 0x0098, 0x000b); - cit_model3_Packet1(gspca_dev, 0x002c, 0x0003); /* Was 1, broke 640x480 */ - cit_model3_Packet1(gspca_dev, 0x002f, 0x002a); - cit_model3_Packet1(gspca_dev, 0x0030, 0x0029); - cit_model3_Packet1(gspca_dev, 0x0037, 0x0002); - cit_model3_Packet1(gspca_dev, 0x0038, 0x0059); - cit_model3_Packet1(gspca_dev, 0x003d, 0x002e); - cit_model3_Packet1(gspca_dev, 0x003e, 0x0028); - cit_model3_Packet1(gspca_dev, 0x0078, 0x0005); - cit_model3_Packet1(gspca_dev, 0x007b, 0x0011); - cit_model3_Packet1(gspca_dev, 0x007d, 0x004b); - cit_model3_Packet1(gspca_dev, 0x007f, 0x0022); - cit_model3_Packet1(gspca_dev, 0x0080, 0x000c); - cit_model3_Packet1(gspca_dev, 0x0081, 0x000b); - cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd); - cit_model3_Packet1(gspca_dev, 0x0086, 0x000b); - cit_model3_Packet1(gspca_dev, 0x0087, 0x000b); - cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); - cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */ - cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */ - cit_model3_Packet1(gspca_dev, 0x0098, 0x000b); - - /* FIXME we should probably use cit_get_clock_div() here (in - combination with isoc negotiation using the programmable isoc size) - like with the IBM netcam pro). */ - cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */ - - switch (gspca_dev->width) { - case 160: - cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ - cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ - cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */ - cit_model3_Packet1(gspca_dev, 0x0040, 0x000a); - cit_model3_Packet1(gspca_dev, 0x0051, 0x000a); - break; - case 320: - cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ - cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ - cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */ - cit_model3_Packet1(gspca_dev, 0x0040, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0051, 0x000b); - break; - case 640: - cit_model3_Packet1(gspca_dev, 0x001f, 0x0002); /* !Same */ - cit_model3_Packet1(gspca_dev, 0x0039, 0x003e); /* !Same */ - cit_model3_Packet1(gspca_dev, 0x0040, 0x0008); - cit_model3_Packet1(gspca_dev, 0x0051, 0x000a); - break; - } - -/* if (sd->input_index) { */ - if (rca_input) { - for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { - if (rca_initdata[i][0]) - cit_read_reg(gspca_dev, rca_initdata[i][2], 0); - else - cit_write_reg(gspca_dev, rca_initdata[i][1], - rca_initdata[i][2]); - } - } - - return 0; -} - -static int cit_start_model4(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - cit_write_reg(gspca_dev, 0x0000, 0x0100); - cit_write_reg(gspca_dev, 0x00c0, 0x0111); - cit_write_reg(gspca_dev, 0x00bc, 0x012c); - cit_write_reg(gspca_dev, 0x0080, 0x012b); - cit_write_reg(gspca_dev, 0x0000, 0x0108); - cit_write_reg(gspca_dev, 0x0001, 0x0133); - cit_write_reg(gspca_dev, 0x009b, 0x010f); - cit_write_reg(gspca_dev, 0x00bb, 0x010f); - cit_model4_Packet1(gspca_dev, 0x0038, 0x0000); - cit_model4_Packet1(gspca_dev, 0x000a, 0x005c); - - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0004, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0x00fb, 0x012e); - cit_write_reg(gspca_dev, 0x0000, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x000c, 0x0127); - cit_write_reg(gspca_dev, 0x0009, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0012, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0008, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x002a, 0x012d); - cit_write_reg(gspca_dev, 0x0000, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_model4_Packet1(gspca_dev, 0x0034, 0x0000); - - switch (gspca_dev->width) { - case 128: /* 128x96 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); - cit_write_reg(gspca_dev, 0x00d0, 0x0111); - cit_write_reg(gspca_dev, 0x0039, 0x010a); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - cit_write_reg(gspca_dev, 0x0028, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x001e, 0x0105); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0016, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x000a, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0014, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012e); - cit_write_reg(gspca_dev, 0x001a, 0x0130); - cit_write_reg(gspca_dev, 0x8a0a, 0x0124); - cit_write_reg(gspca_dev, 0x005a, 0x012d); - cit_write_reg(gspca_dev, 0x9545, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x0127); - cit_write_reg(gspca_dev, 0x0018, 0x012e); - cit_write_reg(gspca_dev, 0x0043, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x001c, 0x0127); - cit_write_reg(gspca_dev, 0x00eb, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0032, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0036, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0017, 0x0127); - cit_write_reg(gspca_dev, 0x0013, 0x012e); - cit_write_reg(gspca_dev, 0x0031, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x0017, 0x012d); - cit_write_reg(gspca_dev, 0x0078, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); - sd->sof_len = 2; - break; - case 160: /* 160x120 */ - cit_write_reg(gspca_dev, 0x0038, 0x0119); - cit_write_reg(gspca_dev, 0x00d0, 0x0111); - cit_write_reg(gspca_dev, 0x00b9, 0x010a); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - cit_write_reg(gspca_dev, 0x0028, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x001e, 0x0105); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0016, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x000b, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0014, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012e); - cit_write_reg(gspca_dev, 0x001a, 0x0130); - cit_write_reg(gspca_dev, 0x8a0a, 0x0124); - cit_write_reg(gspca_dev, 0x005a, 0x012d); - cit_write_reg(gspca_dev, 0x9545, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x0127); - cit_write_reg(gspca_dev, 0x0018, 0x012e); - cit_write_reg(gspca_dev, 0x0043, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x001c, 0x0127); - cit_write_reg(gspca_dev, 0x00c7, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0032, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0025, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0036, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0048, 0x0127); - cit_write_reg(gspca_dev, 0x0035, 0x012e); - cit_write_reg(gspca_dev, 0x00d0, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x0048, 0x012d); - cit_write_reg(gspca_dev, 0x0090, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x0001, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); - sd->sof_len = 2; - break; - case 176: /* 176x144 */ - cit_write_reg(gspca_dev, 0x0038, 0x0119); - cit_write_reg(gspca_dev, 0x00d0, 0x0111); - cit_write_reg(gspca_dev, 0x00b9, 0x010a); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - cit_write_reg(gspca_dev, 0x002c, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x0024, 0x0105); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0016, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0007, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0014, 0x012d); - cit_write_reg(gspca_dev, 0x0001, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012e); - cit_write_reg(gspca_dev, 0x001a, 0x0130); - cit_write_reg(gspca_dev, 0x8a0a, 0x0124); - cit_write_reg(gspca_dev, 0x005e, 0x012d); - cit_write_reg(gspca_dev, 0x9545, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x0127); - cit_write_reg(gspca_dev, 0x0018, 0x012e); - cit_write_reg(gspca_dev, 0x0049, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x001c, 0x0127); - cit_write_reg(gspca_dev, 0x00c7, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0032, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0028, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0036, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0010, 0x0127); - cit_write_reg(gspca_dev, 0x0013, 0x012e); - cit_write_reg(gspca_dev, 0x002a, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x0010, 0x012d); - cit_write_reg(gspca_dev, 0x006d, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x0001, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); - /* TESTME HDG: this does not seem right - (it is 2 for all other resolutions) */ - sd->sof_len = 10; - break; - case 320: /* 320x240 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); - cit_write_reg(gspca_dev, 0x00d0, 0x0111); - cit_write_reg(gspca_dev, 0x0039, 0x010a); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - cit_write_reg(gspca_dev, 0x0028, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x001e, 0x0105); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0016, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x000a, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0014, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012e); - cit_write_reg(gspca_dev, 0x001a, 0x0130); - cit_write_reg(gspca_dev, 0x8a0a, 0x0124); - cit_write_reg(gspca_dev, 0x005a, 0x012d); - cit_write_reg(gspca_dev, 0x9545, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x0127); - cit_write_reg(gspca_dev, 0x0018, 0x012e); - cit_write_reg(gspca_dev, 0x0043, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x001c, 0x0127); - cit_write_reg(gspca_dev, 0x00eb, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0032, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0036, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0017, 0x0127); - cit_write_reg(gspca_dev, 0x0013, 0x012e); - cit_write_reg(gspca_dev, 0x0031, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x0017, 0x012d); - cit_write_reg(gspca_dev, 0x0078, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); - sd->sof_len = 2; - break; - case 352: /* 352x288 */ - cit_write_reg(gspca_dev, 0x0070, 0x0119); - cit_write_reg(gspca_dev, 0x00c0, 0x0111); - cit_write_reg(gspca_dev, 0x0039, 0x010a); - cit_write_reg(gspca_dev, 0x0001, 0x0102); - cit_write_reg(gspca_dev, 0x002c, 0x0103); - cit_write_reg(gspca_dev, 0x0000, 0x0104); - cit_write_reg(gspca_dev, 0x0024, 0x0105); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0016, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0006, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0014, 0x012d); - cit_write_reg(gspca_dev, 0x0002, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012e); - cit_write_reg(gspca_dev, 0x001a, 0x0130); - cit_write_reg(gspca_dev, 0x8a0a, 0x0124); - cit_write_reg(gspca_dev, 0x005e, 0x012d); - cit_write_reg(gspca_dev, 0x9545, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x0127); - cit_write_reg(gspca_dev, 0x0018, 0x012e); - cit_write_reg(gspca_dev, 0x0049, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012f); - cit_write_reg(gspca_dev, 0xd055, 0x0124); - cit_write_reg(gspca_dev, 0x001c, 0x0127); - cit_write_reg(gspca_dev, 0x00cf, 0x012e); - cit_write_reg(gspca_dev, 0xaa28, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x0032, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0x00aa, 0x0130); - cit_write_reg(gspca_dev, 0x82a8, 0x0124); - cit_write_reg(gspca_dev, 0x0036, 0x012d); - cit_write_reg(gspca_dev, 0x0008, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0xfffa, 0x0124); - cit_write_reg(gspca_dev, 0x00aa, 0x012d); - cit_write_reg(gspca_dev, 0x001e, 0x012f); - cit_write_reg(gspca_dev, 0xd141, 0x0124); - cit_write_reg(gspca_dev, 0x0010, 0x0127); - cit_write_reg(gspca_dev, 0x0013, 0x012e); - cit_write_reg(gspca_dev, 0x0025, 0x0130); - cit_write_reg(gspca_dev, 0x8a28, 0x0124); - cit_write_reg(gspca_dev, 0x0010, 0x012d); - cit_write_reg(gspca_dev, 0x0048, 0x012f); - cit_write_reg(gspca_dev, 0xd145, 0x0124); - cit_write_reg(gspca_dev, 0x0000, 0x0127); - cit_write_reg(gspca_dev, 0xfea8, 0x0124); - sd->sof_len = 2; - break; - } - - cit_model4_Packet1(gspca_dev, 0x0038, 0x0004); - - return 0; -} - -static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) -{ - const unsigned short compression = 0; /* 0=none, 7=best frame rate */ - int i, clock_div; - - clock_div = cit_get_clock_div(gspca_dev); - if (clock_div < 0) - return clock_div; - - cit_write_reg(gspca_dev, 0x0003, 0x0133); - cit_write_reg(gspca_dev, 0x0000, 0x0117); - cit_write_reg(gspca_dev, 0x0008, 0x0123); - cit_write_reg(gspca_dev, 0x0000, 0x0100); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - /* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */ - cit_write_reg(gspca_dev, 0x0000, 0x0133); - cit_write_reg(gspca_dev, 0x0000, 0x0123); - cit_write_reg(gspca_dev, 0x0001, 0x0117); - cit_write_reg(gspca_dev, 0x0040, 0x0108); - cit_write_reg(gspca_dev, 0x0019, 0x012c); - cit_write_reg(gspca_dev, 0x0060, 0x0116); - /* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */ - - cit_model3_Packet1(gspca_dev, 0x0049, 0x0000); - - cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */ - cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */ - cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */ - cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */ - cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ - cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ - - switch (gspca_dev->width) { - case 160: /* 160x120 */ - cit_write_reg(gspca_dev, 0x0024, 0x010b); - cit_write_reg(gspca_dev, 0x0089, 0x0119); - cit_write_reg(gspca_dev, 0x000a, 0x011b); - cit_write_reg(gspca_dev, 0x0003, 0x011e); - cit_write_reg(gspca_dev, 0x0007, 0x0104); - cit_write_reg(gspca_dev, 0x0009, 0x011a); - cit_write_reg(gspca_dev, 0x008b, 0x011c); - cit_write_reg(gspca_dev, 0x0008, 0x0118); - cit_write_reg(gspca_dev, 0x0000, 0x0132); - break; - case 320: /* 320x240 */ - cit_write_reg(gspca_dev, 0x0028, 0x010b); - cit_write_reg(gspca_dev, 0x00d9, 0x0119); - cit_write_reg(gspca_dev, 0x0006, 0x011b); - cit_write_reg(gspca_dev, 0x0000, 0x011e); - cit_write_reg(gspca_dev, 0x000e, 0x0104); - cit_write_reg(gspca_dev, 0x0004, 0x011a); - cit_write_reg(gspca_dev, 0x003f, 0x011c); - cit_write_reg(gspca_dev, 0x000c, 0x0118); - cit_write_reg(gspca_dev, 0x0000, 0x0132); - break; - } - - cit_model3_Packet1(gspca_dev, 0x0019, 0x0031); - cit_model3_Packet1(gspca_dev, 0x001a, 0x0003); - cit_model3_Packet1(gspca_dev, 0x001b, 0x0038); - cit_model3_Packet1(gspca_dev, 0x001c, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0024, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0027, 0x0001); - cit_model3_Packet1(gspca_dev, 0x002a, 0x0004); - cit_model3_Packet1(gspca_dev, 0x0035, 0x000b); - cit_model3_Packet1(gspca_dev, 0x003f, 0x0001); - cit_model3_Packet1(gspca_dev, 0x0044, 0x0000); - cit_model3_Packet1(gspca_dev, 0x0054, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001); - cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000); - cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0); - - cit_write_reg(gspca_dev, compression, 0x0109); - cit_write_reg(gspca_dev, clock_div, 0x0111); - -/* if (sd->input_index) { */ - if (rca_input) { - for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) { - if (rca_initdata[i][0]) - cit_read_reg(gspca_dev, rca_initdata[i][2], 0); - else - cit_write_reg(gspca_dev, rca_initdata[i][1], - rca_initdata[i][2]); - } - } - - return 0; -} - -/* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int packet_size; - - packet_size = cit_get_packet_size(gspca_dev); - if (packet_size < 0) - return packet_size; - - switch (sd->model) { - case CIT_MODEL0: - cit_start_model0(gspca_dev); - break; - case CIT_MODEL1: - cit_start_model1(gspca_dev); - break; - case CIT_MODEL2: - cit_start_model2(gspca_dev); - break; - case CIT_MODEL3: - cit_start_model3(gspca_dev); - break; - case CIT_MODEL4: - cit_start_model4(gspca_dev); - break; - case CIT_IBM_NETCAM_PRO: - cit_start_ibm_netcam_pro(gspca_dev); - break; - } - - /* Program max isoc packet size */ - cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); - cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); - - cit_restart_stream(gspca_dev); - - return 0; -} - -static int sd_isoc_init(struct gspca_dev *gspca_dev) -{ - struct usb_host_interface *alt; - int max_packet_size; - - switch (gspca_dev->width) { - case 160: - max_packet_size = 450; - break; - case 176: - max_packet_size = 600; - break; - default: - max_packet_size = 1022; - break; - } - - /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size); - - return 0; -} - -static int sd_isoc_nego(struct gspca_dev *gspca_dev) -{ - int ret, packet_size, min_packet_size; - struct usb_host_interface *alt; - - switch (gspca_dev->width) { - case 160: - min_packet_size = 200; - break; - case 176: - min_packet_size = 266; - break; - default: - min_packet_size = 400; - break; - } - - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - if (packet_size <= min_packet_size) - return -EIO; - - packet_size -= 100; - if (packet_size < min_packet_size) - packet_size = min_packet_size; - alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); - - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - if (ret < 0) - pr_err("set alt 1 err %d\n", ret); - - return ret; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - cit_write_reg(gspca_dev, 0x0000, 0x010c); -} - -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* We cannot use gspca_dev->present here as that is not set when - sd_init gets called and we get called from sd_init */ - if (!gspca_dev->dev) - return; - - switch (sd->model) { - case CIT_MODEL0: - /* HDG windows does this, but it causes the cams autogain to - restart from a gain of 0, which does not look good when - changing resolutions. */ - /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ - cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */ - break; - case CIT_MODEL1: - cit_send_FF_04_02(gspca_dev); - cit_read_reg(gspca_dev, 0x0100, 0); - cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */ - break; - case CIT_MODEL2: - v4l2_ctrl_grab(sd->lighting, false); - /* Fall through! */ - case CIT_MODEL4: - cit_model2_Packet1(gspca_dev, 0x0030, 0x0004); - - cit_write_reg(gspca_dev, 0x0080, 0x0100); /* LED Off */ - cit_write_reg(gspca_dev, 0x0020, 0x0111); - cit_write_reg(gspca_dev, 0x00a0, 0x0111); - - cit_model2_Packet1(gspca_dev, 0x0030, 0x0002); - - cit_write_reg(gspca_dev, 0x0020, 0x0111); - cit_write_reg(gspca_dev, 0x0000, 0x0112); - break; - case CIT_MODEL3: - cit_write_reg(gspca_dev, 0x0006, 0x012c); - cit_model3_Packet1(gspca_dev, 0x0046, 0x0000); - cit_read_reg(gspca_dev, 0x0116, 0); - cit_write_reg(gspca_dev, 0x0064, 0x0116); - cit_read_reg(gspca_dev, 0x0115, 0); - cit_write_reg(gspca_dev, 0x0003, 0x0115); - cit_write_reg(gspca_dev, 0x0008, 0x0123); - cit_write_reg(gspca_dev, 0x0000, 0x0117); - cit_write_reg(gspca_dev, 0x0000, 0x0112); - cit_write_reg(gspca_dev, 0x0080, 0x0100); - break; - case CIT_IBM_NETCAM_PRO: - cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff); - cit_write_reg(gspca_dev, 0x0006, 0x012c); - cit_write_reg(gspca_dev, 0x0000, 0x0116); - /* HDG windows does this, but I cannot get the camera - to restart with this without redoing the entire init - sequence which makes switching modes really slow */ - /* cit_write_reg(gspca_dev, 0x0006, 0x0115); */ - cit_write_reg(gspca_dev, 0x0008, 0x0123); - cit_write_reg(gspca_dev, 0x0000, 0x0117); - cit_write_reg(gspca_dev, 0x0003, 0x0133); - cit_write_reg(gspca_dev, 0x0000, 0x0111); - /* HDG windows does this, but I get a green picture when - restarting the stream after this */ - /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ - cit_write_reg(gspca_dev, 0x00c0, 0x0100); - break; - } - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - /* If the last button state is pressed, release it now! */ - if (sd->button_state) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - sd->button_state = 0; - } -#endif -} - -static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 byte3 = 0, byte4 = 0; - int i; - - switch (sd->model) { - case CIT_MODEL0: - case CIT_MODEL1: - case CIT_MODEL3: - case CIT_IBM_NETCAM_PRO: - switch (gspca_dev->width) { - case 160: /* 160x120 */ - byte3 = 0x02; - byte4 = 0x0a; - break; - case 176: /* 176x144 */ - byte3 = 0x02; - byte4 = 0x0e; - break; - case 320: /* 320x240 */ - byte3 = 0x02; - byte4 = 0x08; - break; - case 352: /* 352x288 */ - byte3 = 0x02; - byte4 = 0x00; - break; - case 640: - byte3 = 0x03; - byte4 = 0x08; - break; - } - - /* These have a different byte3 */ - if (sd->model <= CIT_MODEL1) - byte3 = 0x00; - - for (i = 0; i < len; i++) { - /* For this model the SOF always starts at offset 0 - so no need to search the entire frame */ - if (sd->model == CIT_MODEL0 && sd->sof_read != i) - break; - - switch (sd->sof_read) { - case 0: - if (data[i] == 0x00) - sd->sof_read++; - break; - case 1: - if (data[i] == 0xff) - sd->sof_read++; - else if (data[i] == 0x00) - sd->sof_read = 1; - else - sd->sof_read = 0; - break; - case 2: - if (data[i] == byte3) - sd->sof_read++; - else if (data[i] == 0x00) - sd->sof_read = 1; - else - sd->sof_read = 0; - break; - case 3: - if (data[i] == byte4) { - sd->sof_read = 0; - return data + i + (sd->sof_len - 3); - } - if (byte3 == 0x00 && data[i] == 0xff) - sd->sof_read = 2; - else if (data[i] == 0x00) - sd->sof_read = 1; - else - sd->sof_read = 0; - break; - } - } - break; - case CIT_MODEL2: - case CIT_MODEL4: - /* TESTME we need to find a longer sof signature to avoid - false positives */ - for (i = 0; i < len; i++) { - switch (sd->sof_read) { - case 0: - if (data[i] == 0x00) - sd->sof_read++; - break; - case 1: - sd->sof_read = 0; - if (data[i] == 0xff) { - if (i >= 4) - PDEBUG(D_FRAM, - "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n", - i - 1, - data[i - 4], - data[i - 3], - data[i], - data[i + 1], - data[i + 2]); - else - PDEBUG(D_FRAM, - "header found at offset: %d: 00 %02x %02x %02x\n", - i - 1, - data[i], - data[i + 1], - data[i + 2]); - return data + i + (sd->sof_len - 1); - } - break; - } - } - break; - } - return NULL; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - unsigned char *sof; - - sof = cit_find_sof(gspca_dev, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sd->sof_len) - n -= sd->sof_len; - else - n = 0; - gspca_frame_add(gspca_dev, LAST_PACKET, - data, n); - gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); - len -= sof - data; - data = sof; - } - - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static void cit_check_button(struct gspca_dev *gspca_dev) -{ - int new_button_state; - struct sd *sd = (struct sd *)gspca_dev; - - switch (sd->model) { - case CIT_MODEL3: - case CIT_IBM_NETCAM_PRO: - break; - default: /* TEST ME unknown if this works on other models too */ - return; - } - - /* Read the button state */ - cit_read_reg(gspca_dev, 0x0113, 0); - new_button_state = !gspca_dev->usb_buf[0]; - - /* Tell the cam we've seen the button press, notice that this - is a nop (iow the cam keeps reporting pressed) until the - button is actually released. */ - if (new_button_state) - cit_write_reg(gspca_dev, 0x01, 0x0113); - - if (sd->button_state != new_button_state) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, - new_button_state); - input_sync(gspca_dev->input_dev); - sd->button_state = new_button_state; - } -} -#endif - -static int sd_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - gspca_dev->usb_err = 0; - - if (!gspca_dev->streaming) - return 0; - - if (sd->stop_on_control_change) - sd_stopN(gspca_dev); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - cit_set_brightness(gspca_dev, ctrl->val); - break; - case V4L2_CID_CONTRAST: - cit_set_contrast(gspca_dev, ctrl->val); - break; - case V4L2_CID_HUE: - cit_set_hue(gspca_dev, ctrl->val); - break; - case V4L2_CID_HFLIP: - cit_set_hflip(gspca_dev, ctrl->val); - break; - case V4L2_CID_SHARPNESS: - cit_set_sharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_BACKLIGHT_COMPENSATION: - cit_set_lighting(gspca_dev, ctrl->val); - break; - } - if (sd->stop_on_control_change) - cit_restart_stream(gspca_dev); - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops sd_ctrl_ops = { - .s_ctrl = sd_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - bool has_brightness; - bool has_contrast; - bool has_hue; - bool has_sharpness; - bool has_lighting; - bool has_hflip; - - has_brightness = has_contrast = has_hue = - has_sharpness = has_hflip = has_lighting = false; - switch (sd->model) { - case CIT_MODEL0: - has_contrast = has_hflip = true; - break; - case CIT_MODEL1: - has_brightness = has_contrast = - has_sharpness = has_lighting = true; - break; - case CIT_MODEL2: - has_brightness = has_hue = has_lighting = true; - break; - case CIT_MODEL3: - has_brightness = has_contrast = has_sharpness = true; - break; - case CIT_MODEL4: - has_brightness = has_hue = true; - break; - case CIT_IBM_NETCAM_PRO: - has_brightness = has_hue = - has_sharpness = has_hflip = has_lighting = true; - break; - } - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 5); - if (has_brightness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 63, 1, 32); - if (has_contrast) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_CONTRAST, 0, 20, 1, 10); - if (has_hue) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HUE, 0, 127, 1, 63); - if (has_sharpness) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 6, 1, 3); - if (has_lighting) - sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1); - if (has_hflip) - v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - return 0; -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .dq_callback = cit_check_button, - .other_input = 1, -#endif -}; - -static const struct sd_desc sd_desc_isoc_nego = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .start = sd_start, - .isoc_init = sd_isoc_init, - .isoc_nego = sd_isoc_nego, - .stopN = sd_stopN, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .dq_callback = cit_check_button, - .other_input = 1, -#endif -}; - -/* -- module initialisation -- */ -static const struct usb_device_id device_table[] = { - { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 }, - { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 }, - { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, - { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 }, - { USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 }, - { USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, - { USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 }, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - const struct sd_desc *desc = &sd_desc; - - switch (id->driver_info) { - case CIT_MODEL0: - case CIT_MODEL1: - if (intf->cur_altsetting->desc.bInterfaceNumber != 2) - return -ENODEV; - break; - case CIT_MODEL2: - case CIT_MODEL4: - if (intf->cur_altsetting->desc.bInterfaceNumber != 0) - return -ENODEV; - break; - case CIT_MODEL3: - if (intf->cur_altsetting->desc.bInterfaceNumber != 0) - return -ENODEV; - /* FIXME this likely applies to all model3 cams and probably - to other models too. */ - if (ibm_netcam_pro) - desc = &sd_desc_isoc_nego; - break; - } - - return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h deleted file mode 100644 index a1bd94e8ce52..000000000000 --- a/drivers/media/video/gspca/zc3xx-reg.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * zc030x registers - * - * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * The register aliases used here came from this driver: - * http://zc0302.sourceforge.net/zc0302.php - * - * This code is placed under the terms of the GNU General Public License v2 - */ - -/* Define the register map */ -#define ZC3XX_R000_SYSTEMCONTROL 0x0000 -#define ZC3XX_R001_SYSTEMOPERATING 0x0001 - -/* Picture size */ -#define ZC3XX_R002_CLOCKSELECT 0x0002 -#define ZC3XX_R003_FRAMEWIDTHHIGH 0x0003 -#define ZC3XX_R004_FRAMEWIDTHLOW 0x0004 -#define ZC3XX_R005_FRAMEHEIGHTHIGH 0x0005 -#define ZC3XX_R006_FRAMEHEIGHTLOW 0x0006 - -/* JPEG control */ -#define ZC3XX_R008_CLOCKSETTING 0x0008 - -/* Test mode */ -#define ZC3XX_R00B_TESTMODECONTROL 0x000b - -/* Frame retreiving */ -#define ZC3XX_R00C_LASTACQTIME 0x000c -#define ZC3XX_R00D_MONITORRES 0x000d -#define ZC3XX_R00E_TIMESTAMPHIGH 0x000e -#define ZC3XX_R00F_TIMESTAMPLOW 0x000f -#define ZC3XX_R018_FRAMELOST 0x0018 -#define ZC3XX_R019_AUTOADJUSTFPS 0x0019 -#define ZC3XX_R01A_LASTFRAMESTATE 0x001a -#define ZC3XX_R025_DATACOUNTER 0x0025 - -/* Stream and sensor specific */ -#define ZC3XX_R010_CMOSSENSORSELECT 0x0010 -#define ZC3XX_R011_VIDEOSTATUS 0x0011 -#define ZC3XX_R012_VIDEOCONTROLFUNC 0x0012 - -/* Horizontal and vertical synchros */ -#define ZC3XX_R01D_HSYNC_0 0x001d -#define ZC3XX_R01E_HSYNC_1 0x001e -#define ZC3XX_R01F_HSYNC_2 0x001f -#define ZC3XX_R020_HSYNC_3 0x0020 - -/* Target picture size in byte */ -#define ZC3XX_R022_TARGETPICTSIZE_0 0x0022 -#define ZC3XX_R023_TARGETPICTSIZE_1 0x0023 -#define ZC3XX_R024_TARGETPICTSIZE_2 0x0024 - -/* Audio registers */ -#define ZC3XX_R030_AUDIOADC 0x0030 -#define ZC3XX_R031_AUDIOSTREAMSTATUS 0x0031 -#define ZC3XX_R032_AUDIOSTATUS 0x0032 - -/* Sensor interface */ -#define ZC3XX_R080_HBLANKHIGH 0x0080 -#define ZC3XX_R081_HBLANKLOW 0x0081 -#define ZC3XX_R082_RESETLEVELADDR 0x0082 -#define ZC3XX_R083_RGAINADDR 0x0083 -#define ZC3XX_R084_GGAINADDR 0x0084 -#define ZC3XX_R085_BGAINADDR 0x0085 -#define ZC3XX_R086_EXPTIMEHIGH 0x0086 -#define ZC3XX_R087_EXPTIMEMID 0x0087 -#define ZC3XX_R088_EXPTIMELOW 0x0088 -#define ZC3XX_R089_RESETBLACKHIGH 0x0089 -#define ZC3XX_R08A_RESETWHITEHIGH 0x008a -#define ZC3XX_R08B_I2CDEVICEADDR 0x008b -#define ZC3XX_R08C_I2CIDLEANDNACK 0x008c -#define ZC3XX_R08D_COMPABILITYMODE 0x008d -#define ZC3XX_R08E_COMPABILITYMODE2 0x008e - -/* I2C control */ -#define ZC3XX_R090_I2CCOMMAND 0x0090 -#define ZC3XX_R091_I2CSTATUS 0x0091 -#define ZC3XX_R092_I2CADDRESSSELECT 0x0092 -#define ZC3XX_R093_I2CSETVALUE 0x0093 -#define ZC3XX_R094_I2CWRITEACK 0x0094 -#define ZC3XX_R095_I2CREAD 0x0095 -#define ZC3XX_R096_I2CREADACK 0x0096 - -/* Window inside the sensor array */ -#define ZC3XX_R097_WINYSTARTHIGH 0x0097 -#define ZC3XX_R098_WINYSTARTLOW 0x0098 -#define ZC3XX_R099_WINXSTARTHIGH 0x0099 -#define ZC3XX_R09A_WINXSTARTLOW 0x009a -#define ZC3XX_R09B_WINHEIGHTHIGH 0x009b -#define ZC3XX_R09C_WINHEIGHTLOW 0x009c -#define ZC3XX_R09D_WINWIDTHHIGH 0x009d -#define ZC3XX_R09E_WINWIDTHLOW 0x009e -#define ZC3XX_R119_FIRSTYHIGH 0x0119 -#define ZC3XX_R11A_FIRSTYLOW 0x011a -#define ZC3XX_R11B_FIRSTXHIGH 0x011b -#define ZC3XX_R11C_FIRSTXLOW 0x011c - -/* Max sensor array size */ -#define ZC3XX_R09F_MAXXHIGH 0x009f -#define ZC3XX_R0A0_MAXXLOW 0x00a0 -#define ZC3XX_R0A1_MAXYHIGH 0x00a1 -#define ZC3XX_R0A2_MAXYLOW 0x00a2 -#define ZC3XX_R0A3_EXPOSURETIMEHIGH 0x00a3 -#define ZC3XX_R0A4_EXPOSURETIMELOW 0x00a4 -#define ZC3XX_R0A5_EXPOSUREGAIN 0x00a5 -#define ZC3XX_R0A6_EXPOSUREBLACKLVL 0x00a6 - -/* Other registers */ -#define ZC3XX_R100_OPERATIONMODE 0x0100 -#define ZC3XX_R101_SENSORCORRECTION 0x0101 - -/* Gains */ -#define ZC3XX_R116_RGAIN 0x0116 -#define ZC3XX_R117_GGAIN 0x0117 -#define ZC3XX_R118_BGAIN 0x0118 -#define ZC3XX_R11D_GLOBALGAIN 0x011d -#define ZC3XX_R1A8_DIGITALGAIN 0x01a8 -#define ZC3XX_R1A9_DIGITALLIMITDIFF 0x01a9 -#define ZC3XX_R1AA_DIGITALGAINSTEP 0x01aa - -/* Auto correction */ -#define ZC3XX_R180_AUTOCORRECTENABLE 0x0180 -#define ZC3XX_R181_WINXSTART 0x0181 -#define ZC3XX_R182_WINXWIDTH 0x0182 -#define ZC3XX_R183_WINXCENTER 0x0183 -#define ZC3XX_R184_WINYSTART 0x0184 -#define ZC3XX_R185_WINYWIDTH 0x0185 -#define ZC3XX_R186_WINYCENTER 0x0186 - -/* Gain range */ -#define ZC3XX_R187_MAXGAIN 0x0187 -#define ZC3XX_R188_MINGAIN 0x0188 - -/* Auto exposure and white balance */ -#define ZC3XX_R189_AWBSTATUS 0x0189 -#define ZC3XX_R18A_AWBFREEZE 0x018a -#define ZC3XX_R18B_AESTATUS 0x018b -#define ZC3XX_R18C_AEFREEZE 0x018c -#define ZC3XX_R18F_AEUNFREEZE 0x018f -#define ZC3XX_R190_EXPOSURELIMITHIGH 0x0190 -#define ZC3XX_R191_EXPOSURELIMITMID 0x0191 -#define ZC3XX_R192_EXPOSURELIMITLOW 0x0192 -#define ZC3XX_R195_ANTIFLICKERHIGH 0x0195 -#define ZC3XX_R196_ANTIFLICKERMID 0x0196 -#define ZC3XX_R197_ANTIFLICKERLOW 0x0197 - -/* What is this ? */ -#define ZC3XX_R18D_YTARGET 0x018d -#define ZC3XX_R18E_RESETLVL 0x018e - -/* Color */ -#define ZC3XX_R1A0_REDMEANAFTERAGC 0x01a0 -#define ZC3XX_R1A1_GREENMEANAFTERAGC 0x01a1 -#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2 -#define ZC3XX_R1A3_REDMEANAFTERAWB 0x01a3 -#define ZC3XX_R1A4_GREENMEANAFTERAWB 0x01a4 -#define ZC3XX_R1A5_BLUEMEANAFTERAWB 0x01a5 -#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6 -#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7 - -/* Matrixes */ - -/* Color matrix is like : - R' = R * RGB00 + G * RGB01 + B * RGB02 + RGB03 - G' = R * RGB10 + G * RGB11 + B * RGB22 + RGB13 - B' = R * RGB20 + G * RGB21 + B * RGB12 + RGB23 - */ -#define ZC3XX_R10A_RGB00 0x010a -#define ZC3XX_R10B_RGB01 0x010b -#define ZC3XX_R10C_RGB02 0x010c -#define ZC3XX_R113_RGB03 0x0113 -#define ZC3XX_R10D_RGB10 0x010d -#define ZC3XX_R10E_RGB11 0x010e -#define ZC3XX_R10F_RGB12 0x010f -#define ZC3XX_R114_RGB13 0x0114 -#define ZC3XX_R110_RGB20 0x0110 -#define ZC3XX_R111_RGB21 0x0111 -#define ZC3XX_R112_RGB22 0x0112 -#define ZC3XX_R115_RGB23 0x0115 - -/* Gamma matrix */ -#define ZC3XX_R120_GAMMA00 0x0120 -#define ZC3XX_R121_GAMMA01 0x0121 -#define ZC3XX_R122_GAMMA02 0x0122 -#define ZC3XX_R123_GAMMA03 0x0123 -#define ZC3XX_R124_GAMMA04 0x0124 -#define ZC3XX_R125_GAMMA05 0x0125 -#define ZC3XX_R126_GAMMA06 0x0126 -#define ZC3XX_R127_GAMMA07 0x0127 -#define ZC3XX_R128_GAMMA08 0x0128 -#define ZC3XX_R129_GAMMA09 0x0129 -#define ZC3XX_R12A_GAMMA0A 0x012a -#define ZC3XX_R12B_GAMMA0B 0x012b -#define ZC3XX_R12C_GAMMA0C 0x012c -#define ZC3XX_R12D_GAMMA0D 0x012d -#define ZC3XX_R12E_GAMMA0E 0x012e -#define ZC3XX_R12F_GAMMA0F 0x012f -#define ZC3XX_R130_GAMMA10 0x0130 -#define ZC3XX_R131_GAMMA11 0x0131 -#define ZC3XX_R132_GAMMA12 0x0132 -#define ZC3XX_R133_GAMMA13 0x0133 -#define ZC3XX_R134_GAMMA14 0x0134 -#define ZC3XX_R135_GAMMA15 0x0135 -#define ZC3XX_R136_GAMMA16 0x0136 -#define ZC3XX_R137_GAMMA17 0x0137 -#define ZC3XX_R138_GAMMA18 0x0138 -#define ZC3XX_R139_GAMMA19 0x0139 -#define ZC3XX_R13A_GAMMA1A 0x013a -#define ZC3XX_R13B_GAMMA1B 0x013b -#define ZC3XX_R13C_GAMMA1C 0x013c -#define ZC3XX_R13D_GAMMA1D 0x013d -#define ZC3XX_R13E_GAMMA1E 0x013e -#define ZC3XX_R13F_GAMMA1F 0x013f - -/* Luminance gamma */ -#define ZC3XX_R140_YGAMMA00 0x0140 -#define ZC3XX_R141_YGAMMA01 0x0141 -#define ZC3XX_R142_YGAMMA02 0x0142 -#define ZC3XX_R143_YGAMMA03 0x0143 -#define ZC3XX_R144_YGAMMA04 0x0144 -#define ZC3XX_R145_YGAMMA05 0x0145 -#define ZC3XX_R146_YGAMMA06 0x0146 -#define ZC3XX_R147_YGAMMA07 0x0147 -#define ZC3XX_R148_YGAMMA08 0x0148 -#define ZC3XX_R149_YGAMMA09 0x0149 -#define ZC3XX_R14A_YGAMMA0A 0x014a -#define ZC3XX_R14B_YGAMMA0B 0x014b -#define ZC3XX_R14C_YGAMMA0C 0x014c -#define ZC3XX_R14D_YGAMMA0D 0x014d -#define ZC3XX_R14E_YGAMMA0E 0x014e -#define ZC3XX_R14F_YGAMMA0F 0x014f -#define ZC3XX_R150_YGAMMA10 0x0150 -#define ZC3XX_R151_YGAMMA11 0x0151 - -#define ZC3XX_R1C5_SHARPNESSMODE 0x01c5 -#define ZC3XX_R1C6_SHARPNESS00 0x01c6 -#define ZC3XX_R1C7_SHARPNESS01 0x01c7 -#define ZC3XX_R1C8_SHARPNESS02 0x01c8 -#define ZC3XX_R1C9_SHARPNESS03 0x01c9 -#define ZC3XX_R1CA_SHARPNESS04 0x01ca -#define ZC3XX_R1CB_SHARPNESS05 0x01cb - -/* Dead pixels */ -#define ZC3XX_R250_DEADPIXELSMODE 0x0250 - -/* EEPROM */ -#define ZC3XX_R300_EEPROMCONFIG 0x0300 -#define ZC3XX_R301_EEPROMACCESS 0x0301 -#define ZC3XX_R302_EEPROMSTATUS 0x0302 diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c deleted file mode 100644 index f0bacee33ef9..000000000000 --- a/drivers/media/video/gspca/zc3xx.c +++ /dev/null @@ -1,7024 +0,0 @@ -/* - * Z-Star/Vimicro zc301/zc302p/vc30x driver - * - * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr> - * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/input.h> -#include "gspca.h" -#include "jpeg.h" - -MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " - "Serge A. Suchkov <Serge.A.S@tochka.ru>"); -MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); -MODULE_LICENSE("GPL"); - -static int force_sensor = -1; - -#define REG08_DEF 3 /* default JPEG compression (75%) */ -#include "zc3xx-reg.h" - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - struct { /* gamma/brightness/contrast control cluster */ - struct v4l2_ctrl *gamma; - struct v4l2_ctrl *brightness; - struct v4l2_ctrl *contrast; - }; - struct { /* autogain/exposure control cluster */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *exposure; - }; - struct v4l2_ctrl *plfreq; - struct v4l2_ctrl *sharpness; - struct v4l2_ctrl *jpegqual; - - struct work_struct work; - struct workqueue_struct *work_thread; - - u8 reg08; /* webcam compression quality */ - - u8 bridge; - u8 sensor; /* Type of image sensor chip */ - u16 chip_revision; - - u8 jpeg_hdr[JPEG_HDR_SZ]; -}; -enum bridges { - BRIDGE_ZC301, - BRIDGE_ZC303, -}; -enum sensors { - SENSOR_ADCM2700, - SENSOR_CS2102, - SENSOR_CS2102K, - SENSOR_GC0303, - SENSOR_GC0305, - SENSOR_HDCS2020, - SENSOR_HV7131B, - SENSOR_HV7131R, - SENSOR_ICM105A, - SENSOR_MC501CB, - SENSOR_MT9V111_1, /* (mi360soc) zc301 */ - SENSOR_MT9V111_3, /* (mi360soc) zc303 */ - SENSOR_OV7620, /* OV7648 - same values */ - SENSOR_OV7630C, - SENSOR_PAS106, - SENSOR_PAS202B, - SENSOR_PB0330, - SENSOR_PO2030, - SENSOR_TAS5130C, - SENSOR_MAX -}; - -static const struct v4l2_pix_format vga_mode[] = { - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const struct v4l2_pix_format broken_vga_mode[] = { - {320, 232, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 232 * 4 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 472, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 472 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -static const struct v4l2_pix_format sif_mode[] = { - {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; - -/* - * Bridge reg08 bits 1-2 -> JPEG quality conversion table. Note the highest - * quality setting is not usable as USB 1 does not have enough bandwidth. - */ -static u8 jpeg_qual[] = {50, 75, 87, /* 94 */}; - -/* usb exchanges */ -struct usb_action { - u8 req; - u8 val; - u16 idx; -}; - -static const struct usb_action adcm2700_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ - {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ - {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ - {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ - {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ - {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ - {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ - {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ - {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */ - {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ - {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */ - {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ -/*mswin+*/ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, - {0xaa, 0xfe, 0x0002}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xaa, 0xb4, 0xcd37}, - {0xaa, 0xa4, 0x0004}, - {0xaa, 0xa8, 0x0007}, - {0xaa, 0xac, 0x0004}, -/*mswin-*/ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ - {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; -static const struct usb_action adcm2700_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ - {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ - {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ - {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ - {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ - {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ - {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ - {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ - {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */ - {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ - {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */ - {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ - /*******/ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ - {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; -static const struct usb_action adcm2700_50HZ[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */ - {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */ - {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; -static const struct usb_action adcm2700_60HZ[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */ - {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; -static const struct usb_action adcm2700_NoFliker[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */ - {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; -static const struct usb_action cs2102_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, - {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, - {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, - {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, - {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, - {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, - {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xaa, 0x02, 0x0008}, - {0xaa, 0x03, 0x0000}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x12, 0x0089}, - {0xaa, 0x13, 0x0000}, - {0xaa, 0x14, 0x00e9}, - {0xaa, 0x20, 0x0000}, - {0xaa, 0x22, 0x0000}, - {0xaa, 0x0b, 0x0004}, - {0xaa, 0x30, 0x0030}, - {0xaa, 0x31, 0x0030}, - {0xaa, 0x32, 0x0030}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x10, 0x01ae}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x68, ZC3XX_R18D_YTARGET}, - {0xa0, 0x00, 0x01ad}, - {} -}; - -static const struct usb_action cs2102_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, - {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, - {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, - {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, - {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, - {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, - {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xaa, 0x02, 0x0008}, - {0xaa, 0x03, 0x0000}, - {0xaa, 0x11, 0x0001}, - {0xaa, 0x12, 0x0087}, - {0xaa, 0x13, 0x0001}, - {0xaa, 0x14, 0x00e7}, - {0xaa, 0x20, 0x0000}, - {0xaa, 0x22, 0x0000}, - {0xaa, 0x0b, 0x0004}, - {0xaa, 0x30, 0x0030}, - {0xaa, 0x31, 0x0030}, - {0xaa, 0x32, 0x0030}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x68, ZC3XX_R18D_YTARGET}, - {0xa0, 0x00, 0x01ad}, - {} -}; -static const struct usb_action cs2102_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0001}, - {0xaa, 0x24, 0x005f}, - {0xaa, 0x25, 0x0090}, - {0xaa, 0x21, 0x00dd}, - {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xdd, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xe4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action cs2102_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0000}, - {0xaa, 0x24, 0x00af}, - {0xaa, 0x25, 0x00c8}, - {0xaa, 0x21, 0x0068}, - {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xe3, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action cs2102_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0001}, - {0xaa, 0x24, 0x0055}, - {0xaa, 0x25, 0x00cc}, - {0xaa, 0x21, 0x003f}, - {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x39, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x70, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action cs2102_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0000}, - {0xaa, 0x24, 0x00aa}, - {0xaa, 0x25, 0x00e6}, - {0xaa, 0x21, 0x003f}, - {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x55, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xcc, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x18, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x6a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x3f, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action cs2102_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0001}, - {0xaa, 0x24, 0x005f}, - {0xaa, 0x25, 0x0000}, - {0xaa, 0x21, 0x0001}, - {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x01, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action cs2102_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x23, 0x0000}, - {0xaa, 0x24, 0x00af}, - {0xaa, 0x25, 0x0080}, - {0xaa, 0x21, 0x0001}, - {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x01, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xa0, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; - -/* CS2102_KOCOM */ -static const struct usb_action cs2102K_InitialScale[] = { - {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x7c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {} -}; - -static const struct usb_action cs2102K_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, -/*fixme: next sequence = i2c exchanges*/ - {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x4c, ZC3XX_R118_BGAIN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, -/*fixme:what does the next sequence?*/ - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {} -}; - -static const struct usb_action gc0305_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ - {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */ - {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */ - {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ - {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ - {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ - {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ - {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ - {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ - {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ - {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ - {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ - {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ - {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ - {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ - {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ - {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ - {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ - {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ - {0xaa, 0x17, 0x00e6}, /* 00,17,e6,aa */ - {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ - {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ - {0xa0, 0x85, ZC3XX_R18D_YTARGET}, /* 01,8d,85,cc */ - {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ - {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ - {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ - {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ - {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ - {} -}; -static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ - {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ - {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */ - {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ - {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ - {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ - {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ - {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ - {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ - {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ - {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ - {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ - {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ - {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ - {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ - {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ - {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ - {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ - {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ - {0xaa, 0x17, 0x00e8}, /* 00,17,e8,aa */ - {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ - {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ - {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ - {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ - {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ - {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ - {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ - {} -}; -static const struct usb_action gc0305_50HZ[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ - {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ - {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ - /* win: 01,92,10 */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc */ - /* win: 01,97,ec */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ -/* {0xa0, 0x85, ZC3XX_R18D_YTARGET}, * 01,8d,85,cc * - * if 640x480 */ - {} -}; -static const struct usb_action gc0305_60HZ[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ - {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ - {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0xec, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,ec,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ - {} -}; - -static const struct usb_action gc0305_NoFliker[] = { - {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */ - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ - {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,00,cc */ - {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,48,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ - {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ - {} -}; - -static const struct usb_action hdcs2020_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ - {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xaa, 0x1c, 0x0000}, - {0xaa, 0x0a, 0x0001}, - {0xaa, 0x0b, 0x0006}, - {0xaa, 0x0c, 0x007b}, - {0xaa, 0x0d, 0x00a7}, - {0xaa, 0x03, 0x00fb}, - {0xaa, 0x05, 0x0000}, - {0xaa, 0x06, 0x0003}, - {0xaa, 0x09, 0x0008}, - - {0xaa, 0x0f, 0x0018}, /* set sensor gain */ - {0xaa, 0x10, 0x0018}, - {0xaa, 0x11, 0x0018}, - {0xaa, 0x12, 0x0018}, - - {0xaa, 0x15, 0x004e}, - {0xaa, 0x1c, 0x0004}, - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - - {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xed, ZC3XX_R10B_RGB01}, - {0xa0, 0xed, ZC3XX_R10C_RGB02}, - {0xa0, 0xed, ZC3XX_R10D_RGB10}, - {0xa0, 0x66, ZC3XX_R10E_RGB11}, - {0xa0, 0xed, ZC3XX_R10F_RGB12}, - {0xa0, 0xed, ZC3XX_R110_RGB20}, - {0xa0, 0xed, ZC3XX_R111_RGB21}, - {0xa0, 0x66, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x13, 0x0031}, - {0xaa, 0x14, 0x0001}, - {0xaa, 0x0e, 0x0004}, - {0xaa, 0x19, 0x00cd}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 0x14 */ - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action hdcs2020_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xaa, 0x1c, 0x0000}, - {0xaa, 0x0a, 0x0001}, - {0xaa, 0x0b, 0x0006}, - {0xaa, 0x0c, 0x007a}, - {0xaa, 0x0d, 0x00a7}, - {0xaa, 0x03, 0x00fb}, - {0xaa, 0x05, 0x0000}, - {0xaa, 0x06, 0x0003}, - {0xaa, 0x09, 0x0008}, - {0xaa, 0x0f, 0x0018}, /* original setting */ - {0xaa, 0x10, 0x0018}, - {0xaa, 0x11, 0x0018}, - {0xaa, 0x12, 0x0018}, - {0xaa, 0x15, 0x004e}, - {0xaa, 0x1c, 0x0004}, - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ - {0xa0, 0x38, ZC3XX_R121_GAMMA01}, - {0xa0, 0x59, ZC3XX_R122_GAMMA02}, - {0xa0, 0x79, ZC3XX_R123_GAMMA03}, - {0xa0, 0x92, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, - {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, - {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, - {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, - {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x26, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xed, ZC3XX_R10B_RGB01}, - {0xa0, 0xed, ZC3XX_R10C_RGB02}, - {0xa0, 0xed, ZC3XX_R10D_RGB10}, - {0xa0, 0x66, ZC3XX_R10E_RGB11}, - {0xa0, 0xed, ZC3XX_R10F_RGB12}, - {0xa0, 0xed, ZC3XX_R110_RGB20}, - {0xa0, 0xed, ZC3XX_R111_RGB21}, - {0xa0, 0x66, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - /**** set exposure ***/ - {0xaa, 0x13, 0x0031}, - {0xaa, 0x14, 0x0001}, - {0xaa, 0x0e, 0x0004}, - {0xaa, 0x19, 0x00cd}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action hdcs2020_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ - {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ - {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ - {0xa0, 0x05, ZC3XX_R01D_HSYNC_0}, /* 00,1d,05,cc */ - {0xa0, 0x1a, ZC3XX_R01E_HSYNC_1}, /* 00,1e,1a,cc */ - {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */ - {} -}; -static const struct usb_action hdcs2020_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ - {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ - {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ - {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ - {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, /* 00,1e,18,cc */ - {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */ - {} -}; -static const struct usb_action hdcs2020_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ - {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ - {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ - {0xa0, 0x17, ZC3XX_R01E_HSYNC_1}, /* 00,1e,17,cc */ - {0xa0, 0x2a, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2a,cc */ - {} -}; - -static const struct usb_action hv7131b_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xaa, 0x30, 0x002d}, - {0xaa, 0x01, 0x0005}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x13, 0x0001}, /* {0xaa, 0x13, 0x0000}, */ - {0xaa, 0x14, 0x0001}, - {0xaa, 0x15, 0x00e8}, - {0xaa, 0x16, 0x0002}, - {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */ - {0xaa, 0x31, 0x0038}, - {0xaa, 0x32, 0x0038}, - {0xaa, 0x33, 0x0038}, - {0xaa, 0x5b, 0x0001}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x68, ZC3XX_R18D_YTARGET}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0xc0, 0x019b}, - {0xa0, 0xa0, 0x019c}, - {0xa0, 0x02, ZC3XX_R188_MINGAIN}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ - {} -}; - -static const struct usb_action hv7131b_Initial[] = { /* 640x480*/ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xaa, 0x30, 0x002d}, - {0xaa, 0x01, 0x0005}, - {0xaa, 0x11, 0x0001}, - {0xaa, 0x13, 0x0000}, /* {0xaa, 0x13, 0x0001}; */ - {0xaa, 0x14, 0x0001}, - {0xaa, 0x15, 0x00e6}, - {0xaa, 0x16, 0x0002}, - {0xaa, 0x17, 0x0086}, - {0xaa, 0x31, 0x0038}, - {0xaa, 0x32, 0x0038}, - {0xaa, 0x33, 0x0038}, - {0xaa, 0x5b, 0x0001}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0xc0, 0x019b}, - {0xa0, 0xa0, 0x019c}, - {0xa0, 0x02, ZC3XX_R188_MINGAIN}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ - {} -}; -static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */ - {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */ - {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */ - {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */ - {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */ - {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,ea,cc */ - {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,60,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ - {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ - {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */ - {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */ - {} -}; -static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */ - {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */ - {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */ - {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */ - {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0x9b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,9b,cc */ - {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */ - {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */ - {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,d4,cc */ - {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,c0,cc */ - {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */ - {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */ - {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ - {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */ - {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */ - {} -}; -static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */ - {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */ - {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */ - {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */ - {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */ - {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,c3,cc */ - {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,50,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ - {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ - {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */ - {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */ - {} -}; -static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */ - {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */ - {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */ - {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */ - {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0x4d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,4d,cc */ - {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,60,cc */ - {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,01,cc */ - {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,86,cc */ - {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,a0,cc */ - {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */ - {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */ - {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */ - {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */ - {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */ - {} -}; -static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */ - {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */ - {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */ - {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ - {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */ - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */ - {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */ - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */ - {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */ - {} -}; -static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */ - {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */ - {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */ - {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ - {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */ - {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */ - {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */ - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,2f,cc */ - {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,f8,cc */ - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,00,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,02,cc */ - {0xa0, 0x00, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,00,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */ - {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */ - {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */ - {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */ - {} -}; - -/* from lPEPI264v.inf (hv7131b!) */ -static const struct usb_action hv7131r_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x000c}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x13, 0x0000}, - {0xaa, 0x14, 0x0001}, - {0xaa, 0x15, 0x00e8}, - {0xaa, 0x16, 0x0002}, - {0xaa, 0x17, 0x0088}, - {0xaa, 0x30, 0x000b}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0xc0, 0x019b}, - {0xa0, 0xa0, 0x019c}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {} -}; -static const struct usb_action hv7131r_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x000c}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x13, 0x0000}, - {0xaa, 0x14, 0x0001}, - {0xaa, 0x15, 0x00e6}, - {0xaa, 0x16, 0x0002}, - {0xaa, 0x17, 0x0086}, - {0xaa, 0x30, 0x000b}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0xc0, 0x019b}, - {0xa0, 0xa0, 0x019c}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {} -}; -static const struct usb_action hv7131r_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x06, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x68, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0xea, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x60, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x18, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action hv7131r_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x0c, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xd1, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x40, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x18, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action hv7131r_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x06, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x1a, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x18, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action hv7131r_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x0c, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x18, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action hv7131r_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x02, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action hv7131r_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x04, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0xb0, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0x08, ZC3XX_R020_HSYNC_3}, - {} -}; - -static const struct usb_action icm105a_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, - {0xa0, 0x01, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, - {0xa0, 0x01, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x01, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x01, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xaa, 0x01, 0x0010}, - {0xaa, 0x03, 0x0000}, - {0xaa, 0x04, 0x0001}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0001}, - {0xaa, 0x04, 0x0011}, - {0xaa, 0x05, 0x00a0}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0002}, - {0xaa, 0x04, 0x0013}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0003}, - {0xaa, 0x04, 0x0015}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0004}, - {0xaa, 0x04, 0x0017}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x000d}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0005}, - {0xaa, 0x04, 0x0019}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0006}, - {0xaa, 0x04, 0x0017}, - {0xaa, 0x05, 0x0026}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0007}, - {0xaa, 0x04, 0x0019}, - {0xaa, 0x05, 0x0022}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0008}, - {0xaa, 0x04, 0x0021}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0009}, - {0xaa, 0x04, 0x0023}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x000d}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000a}, - {0xaa, 0x04, 0x0025}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000b}, - {0xaa, 0x04, 0x00ec}, - {0xaa, 0x05, 0x002e}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000c}, - {0xaa, 0x04, 0x00fa}, - {0xaa, 0x05, 0x002a}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x07, 0x000d}, - {0xaa, 0x01, 0x0005}, - {0xaa, 0x94, 0x0002}, - {0xaa, 0x90, 0x0000}, - {0xaa, 0x91, 0x001f}, - {0xaa, 0x10, 0x0064}, - {0xaa, 0x9b, 0x00f0}, - {0xaa, 0x9c, 0x0002}, - {0xaa, 0x14, 0x001a}, - {0xaa, 0x20, 0x0080}, - {0xaa, 0x22, 0x0080}, - {0xaa, 0x24, 0x0080}, - {0xaa, 0x26, 0x0080}, - {0xaa, 0x00, 0x0084}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xaa, 0xa8, 0x00c0}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {0xa1, 0x01, 0x0008}, - - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf7, ZC3XX_R10B_RGB01}, - {0xa0, 0xf7, ZC3XX_R10C_RGB02}, - {0xa0, 0xf7, ZC3XX_R10D_RGB10}, - {0xa0, 0x52, ZC3XX_R10E_RGB11}, - {0xa0, 0xf7, ZC3XX_R10F_RGB12}, - {0xa0, 0xf7, ZC3XX_R110_RGB20}, - {0xa0, 0xf7, ZC3XX_R111_RGB21}, - {0xa0, 0x52, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x0d, 0x0003}, - {0xaa, 0x0c, 0x008c}, - {0xaa, 0x0e, 0x0095}, - {0xaa, 0x0f, 0x0002}, - {0xaa, 0x1c, 0x0094}, - {0xaa, 0x1d, 0x0002}, - {0xaa, 0x20, 0x0080}, - {0xaa, 0x22, 0x0080}, - {0xaa, 0x24, 0x0080}, - {0xaa, 0x26, 0x0080}, - {0xaa, 0x00, 0x0084}, - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0xc0, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; - -static const struct usb_action icm105a_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, - {0xa0, 0x02, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, - {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x02, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xaa, 0x01, 0x0010}, - {0xaa, 0x03, 0x0000}, - {0xaa, 0x04, 0x0001}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0001}, - {0xaa, 0x04, 0x0011}, - {0xaa, 0x05, 0x00a0}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0002}, - {0xaa, 0x04, 0x0013}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0001}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0003}, - {0xaa, 0x04, 0x0015}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0004}, - {0xaa, 0x04, 0x0017}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x000d}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0005}, - {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, - {0xa0, 0x19, ZC3XX_R093_I2CSETVALUE}, - {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, - {0xa1, 0x01, 0x0091}, - {0xaa, 0x05, 0x0020}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0006}, - {0xaa, 0x04, 0x0017}, - {0xaa, 0x05, 0x0026}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0007}, - {0xaa, 0x04, 0x0019}, - {0xaa, 0x05, 0x0022}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0008}, - {0xaa, 0x04, 0x0021}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x0009}, - {0xaa, 0x04, 0x0023}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x000d}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000a}, - {0xaa, 0x04, 0x0025}, - {0xaa, 0x05, 0x00aa}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000b}, - {0xaa, 0x04, 0x00ec}, - {0xaa, 0x05, 0x002e}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x03, 0x000c}, - {0xaa, 0x04, 0x00fa}, - {0xaa, 0x05, 0x002a}, - {0xaa, 0x06, 0x0005}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x07, 0x000d}, - {0xaa, 0x01, 0x0005}, - {0xaa, 0x94, 0x0002}, - {0xaa, 0x90, 0x0000}, - {0xaa, 0x91, 0x0010}, - {0xaa, 0x10, 0x0064}, - {0xaa, 0x9b, 0x00f0}, - {0xaa, 0x9c, 0x0002}, - {0xaa, 0x14, 0x001a}, - {0xaa, 0x20, 0x0080}, - {0xaa, 0x22, 0x0080}, - {0xaa, 0x24, 0x0080}, - {0xaa, 0x26, 0x0080}, - {0xaa, 0x00, 0x0084}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xaa, 0xa8, 0x0080}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, - {0xa1, 0x01, 0x0002}, - {0xa1, 0x01, 0x0008}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {0xa1, 0x01, 0x0008}, - - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - - {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf7, ZC3XX_R10B_RGB01}, - {0xa0, 0xf7, ZC3XX_R10C_RGB02}, - {0xa0, 0xf7, ZC3XX_R10D_RGB10}, - {0xa0, 0x52, ZC3XX_R10E_RGB11}, - {0xa0, 0xf7, ZC3XX_R10F_RGB12}, - {0xa0, 0xf7, ZC3XX_R110_RGB20}, - {0xa0, 0xf7, ZC3XX_R111_RGB21}, - {0xa0, 0x52, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x0d, 0x0003}, - {0xaa, 0x0c, 0x0020}, - {0xaa, 0x0e, 0x000e}, - {0xaa, 0x0f, 0x0002}, - {0xaa, 0x1c, 0x000d}, - {0xaa, 0x1d, 0x0002}, - {0xaa, 0x20, 0x0080}, - {0xaa, 0x22, 0x0080}, - {0xaa, 0x24, 0x0080}, - {0xaa, 0x26, 0x0080}, - {0xaa, 0x00, 0x0084}, - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, - {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action icm105a_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ - {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x000d}, /* 00,1c,0d,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,0d,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,1a,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4b,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ - {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ - {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d8,cc */ - {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {} -}; -static const struct usb_action icm105a_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ - {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x0094}, /* 00,1c,94,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,94,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,84,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ - {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e3,cc */ - {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, /* 00,1e,ec,cc */ - {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f5,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ - {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ - {} -}; -static const struct usb_action icm105a_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ - {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x0008}, /* 00,1c,08,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x08, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,08,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x41, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,41,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ - {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {} -}; -static const struct usb_action icm105a_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ - {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x0085}, /* 00,1c,85,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x85, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,85,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,08,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ - {0xa0, 0xc2, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c2,cc */ - {0xa0, 0xd6, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d6,cc */ - {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ - {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ - {} -}; -static const struct usb_action icm105a_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ - {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x0000}, /* 00,1c,00,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x00, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,00,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {} -}; -static const struct usb_action icm105a_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ - {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ - {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */ - {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ - {0xaa, 0x1c, 0x0080}, /* 00,1c,80,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ - {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ - {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ - {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ - {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ - {0xa0, 0x80, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,80,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ - {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ - {} -}; - -static const struct usb_action mc501cb_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ - {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ - {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ - {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ - {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ - {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ - {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ - {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ - {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ - {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ - {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ - {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ - {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ - {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ - {0xaa, 0x18, 0x00de}, /* 00,18,de,aa */ - {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ - {0xaa, 0x1a, 0x0086}, /* 00,1a,86,aa */ - {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ - {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ - {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ - {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ - {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ - {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ - {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ - {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ - {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ - {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ - {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ - {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ - {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ - {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ - {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ - {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ - {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ - {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ - {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ - {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ - {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ - {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ - {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ - {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ - {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ - {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ - {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ - {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ - {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ - {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ - {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ - {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ - {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ - {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ - {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ - {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ - {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ - {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ - {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ - {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ - {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x1c, 0x0050}, /* 00,1C,50,aa */ - {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ - {0xaa, 0x3b, 0x001d}, /* 00,3b,1D,aa */ - {0xaa, 0x3c, 0x004c}, /* 00,3c,4C,aa */ - {0xaa, 0x3d, 0x0018}, /* 00,3d,18,aa */ - {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */ - {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ - {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ - {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */ - {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */ - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ - {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ - {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ - {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ - {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ - {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ - - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ - {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ - {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ - {} -}; - -static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ - {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ - {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ - {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ - {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ - {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ - {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ - {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ - {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ - {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ - {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ - {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ - {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ - {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ - {0xaa, 0x18, 0x00d8}, /* 00,18,d8,aa */ - {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ - {0xaa, 0x1a, 0x0088}, /* 00,1a,88,aa */ - {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ - {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ - {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ - {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ - {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ - {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ - {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ - {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ - {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ - {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ - {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ - {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ - {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ - {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ - {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ - {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ - {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ - {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ - {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ - {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ - {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ - {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ - {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ - {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ - {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ - {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ - {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ - {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ - {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ - {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ - {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ - {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ - {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ - {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ - {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ - {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ - {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ - {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ - {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ - {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ - {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x1c, 0x0050}, /* 00,1c,50,aa */ - {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ - {0xaa, 0x3b, 0x003a}, /* 00,3b,3A,aa */ - {0xaa, 0x3c, 0x0098}, /* 00,3c,98,aa */ - {0xaa, 0x3d, 0x0030}, /* 00,3d,30,aa */ - {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ - {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ - {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ - {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */ - {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */ - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ - {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ - {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ - {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ - {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ - {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ - {} -}; - -static const struct usb_action mc501cb_50HZ[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ - {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ - {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ - {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */ - {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */ - {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */ - {} -}; - -static const struct usb_action mc501cb_50HZScale[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ - {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ - {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ - {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */ - {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */ - {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */ - {} -}; - -static const struct usb_action mc501cb_60HZ[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ - {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ - {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ - {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ - {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ - {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ - {} -}; - -static const struct usb_action mc501cb_60HZScale[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ - {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ - {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ - {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ - {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ - {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ - {} -}; - -static const struct usb_action mc501cb_NoFliker[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ - {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ - {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ - {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ - {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ - {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ - {} -}; - -static const struct usb_action mc501cb_NoFlikerScale[] = { - {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ - {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ - {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ - {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ - {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ - {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ - {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ - {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ - {} -}; - -/* from zs211.inf */ -static const struct usb_action ov7620_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */ - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ - {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ - {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ - {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ - {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ - {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ - {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ - {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ - {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ - {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ - {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ - {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ - {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ - {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ - {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ - {0xaa, 0x1a, 0x00f1}, /* 00,1a,f1,aa */ - {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ - {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ - {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ - {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ - {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ - {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ - {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ - {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ - {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ - {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ - {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ - {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ - {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ - {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ - {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ - {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ - {0xa0, 0x40, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,40,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ - {} -}; -static const struct usb_action ov7620_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ - /* mx change? */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ - {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ - {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ - {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ - {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ - {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xd6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d6,cc */ - /* OV7648 00,9c,d8,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ - {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ - {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ - {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ - {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ - {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ - {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ - {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ - {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ - {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ - {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ - {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ - {0xaa, 0x1a, 0x00f2}, /* 00,1a,f2,aa */ - {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ - {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ - {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ - {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ - {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ - {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ - {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ - {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ - {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ - {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ - {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ - {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ - {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ - {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,50,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ - {} -}; -static const struct usb_action ov7620_50HZ[] = { - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ - {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ - {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ - {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ - {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ -/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc - * if mode0 (640x480) */ - {} -}; -static const struct usb_action ov7620_60HZ[] = { - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ - /* (bug in zs211.inf) */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ - {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ - {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ - {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */ - {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ -/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc - * if mode0 (640x480) */ -/* ?? in gspca v1, it was - {0xa0, 0x00, 0x0039}, * 00,00,00,dd * - {0xa1, 0x01, 0x0037}, */ - {} -}; -static const struct usb_action ov7620_NoFliker[] = { - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ - /* (bug in zs211.inf) */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ - {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */ - {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ - {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,01,cc */ -/* {0xa0, 0x44, ZC3XX_R002_CLOCKSELECT}, * 00,02,44,cc - * if mode1 (320x240) */ -/* ?? was - {0xa0, 0x00, 0x0039}, * 00,00,00,dd * - {0xa1, 0x01, 0x0037}, */ - {} -}; - -static const struct usb_action ov7630c_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x12, 0x0080}, - {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, - {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, - {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, - {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xaa, 0x12, 0x0069}, - {0xaa, 0x04, 0x0020}, - {0xaa, 0x06, 0x0050}, - {0xaa, 0x13, 0x0083}, - {0xaa, 0x14, 0x0000}, - {0xaa, 0x15, 0x0024}, - {0xaa, 0x17, 0x0018}, - {0xaa, 0x18, 0x00ba}, - {0xaa, 0x19, 0x0002}, - {0xaa, 0x1a, 0x00f6}, - {0xaa, 0x1b, 0x0002}, - {0xaa, 0x20, 0x00c2}, - {0xaa, 0x24, 0x0060}, - {0xaa, 0x25, 0x0040}, - {0xaa, 0x26, 0x0030}, - {0xaa, 0x27, 0x00ea}, - {0xaa, 0x28, 0x00a0}, - {0xaa, 0x21, 0x0000}, - {0xaa, 0x2a, 0x0081}, - {0xaa, 0x2b, 0x0096}, - {0xaa, 0x2d, 0x0094}, - {0xaa, 0x2f, 0x003d}, - {0xaa, 0x30, 0x0024}, - {0xaa, 0x60, 0x0000}, - {0xaa, 0x61, 0x0040}, - {0xaa, 0x68, 0x007c}, - {0xaa, 0x6f, 0x0015}, - {0xaa, 0x75, 0x0088}, - {0xaa, 0x77, 0x00b5}, - {0xaa, 0x01, 0x0060}, - {0xaa, 0x02, 0x0060}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x46, ZC3XX_R118_BGAIN}, - {0xa0, 0x04, ZC3XX_R113_RGB03}, -/* 0x10, */ - {0xa1, 0x01, 0x0002}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x01, ZC3XX_R120_GAMMA00}, /* gamma 2 ?*/ - {0xa0, 0x0c, ZC3XX_R121_GAMMA01}, - {0xa0, 0x1f, ZC3XX_R122_GAMMA02}, - {0xa0, 0x3a, ZC3XX_R123_GAMMA03}, - {0xa0, 0x53, ZC3XX_R124_GAMMA04}, - {0xa0, 0x6d, ZC3XX_R125_GAMMA05}, - {0xa0, 0x85, ZC3XX_R126_GAMMA06}, - {0xa0, 0x9c, ZC3XX_R127_GAMMA07}, - {0xa0, 0xb0, ZC3XX_R128_GAMMA08}, - {0xa0, 0xc2, ZC3XX_R129_GAMMA09}, - {0xa0, 0xd1, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xde, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xe9, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xf2, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xf9, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x05, ZC3XX_R130_GAMMA10}, - {0xa0, 0x0f, ZC3XX_R131_GAMMA11}, - {0xa0, 0x16, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, - {0xa0, 0x19, ZC3XX_R134_GAMMA14}, - {0xa0, 0x19, ZC3XX_R135_GAMMA15}, - {0xa0, 0x17, ZC3XX_R136_GAMMA16}, - {0xa0, 0x15, ZC3XX_R137_GAMMA17}, - {0xa0, 0x12, ZC3XX_R138_GAMMA18}, - {0xa0, 0x10, ZC3XX_R139_GAMMA19}, - {0xa0, 0x0e, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x0b, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x09, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x08, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x06, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x03, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf8, ZC3XX_R10B_RGB01}, - {0xa0, 0xf8, ZC3XX_R10C_RGB02}, - {0xa0, 0xf8, ZC3XX_R10D_RGB10}, - {0xa0, 0x50, ZC3XX_R10E_RGB11}, - {0xa0, 0xf8, ZC3XX_R10F_RGB12}, - {0xa0, 0xf8, ZC3XX_R110_RGB20}, - {0xa0, 0xf8, ZC3XX_R111_RGB21}, - {0xa0, 0x50, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xaa, 0x10, 0x001b}, - {0xaa, 0x76, 0x0002}, - {0xaa, 0x2a, 0x0081}, - {0xaa, 0x2b, 0x0000}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xb8, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x37, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xaa, 0x13, 0x0083}, /* 40 */ - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; - -static const struct usb_action ov7630c_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - - {0xaa, 0x12, 0x0080}, - {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, - {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, - {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, - {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, - {0xaa, 0x12, 0x0069}, /* i2c */ - {0xaa, 0x04, 0x0020}, - {0xaa, 0x06, 0x0050}, - {0xaa, 0x13, 0x00c3}, - {0xaa, 0x14, 0x0000}, - {0xaa, 0x15, 0x0024}, - {0xaa, 0x19, 0x0003}, - {0xaa, 0x1a, 0x00f6}, - {0xaa, 0x1b, 0x0002}, - {0xaa, 0x20, 0x00c2}, - {0xaa, 0x24, 0x0060}, - {0xaa, 0x25, 0x0040}, - {0xaa, 0x26, 0x0030}, - {0xaa, 0x27, 0x00ea}, - {0xaa, 0x28, 0x00a0}, - {0xaa, 0x21, 0x0000}, - {0xaa, 0x2a, 0x0081}, - {0xaa, 0x2b, 0x0096}, - {0xaa, 0x2d, 0x0084}, - {0xaa, 0x2f, 0x003d}, - {0xaa, 0x30, 0x0024}, - {0xaa, 0x60, 0x0000}, - {0xaa, 0x61, 0x0040}, - {0xaa, 0x68, 0x007c}, - {0xaa, 0x6f, 0x0015}, - {0xaa, 0x75, 0x0088}, - {0xaa, 0x77, 0x00b5}, - {0xaa, 0x01, 0x0060}, - {0xaa, 0x02, 0x0060}, - {0xaa, 0x17, 0x0018}, - {0xaa, 0x18, 0x00ba}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R116_RGAIN}, - {0xa0, 0x46, ZC3XX_R118_BGAIN}, - {0xa0, 0x04, ZC3XX_R113_RGB03}, - - {0xa1, 0x01, 0x0002}, - {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xfe, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf7, ZC3XX_R10D_RGB10}, - {0xa0, 0x4d, ZC3XX_R10E_RGB11}, - {0xa0, 0xfc, ZC3XX_R10F_RGB12}, - {0xa0, 0x00, ZC3XX_R110_RGB20}, - {0xa0, 0xf6, ZC3XX_R111_RGB21}, - {0xa0, 0x4a, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ - {0xa0, 0x16, ZC3XX_R120_GAMMA00}, /* gamma ~4 */ - {0xa0, 0x3a, ZC3XX_R121_GAMMA01}, - {0xa0, 0x5b, ZC3XX_R122_GAMMA02}, - {0xa0, 0x7c, ZC3XX_R123_GAMMA03}, - {0xa0, 0x94, ZC3XX_R124_GAMMA04}, - {0xa0, 0xa9, ZC3XX_R125_GAMMA05}, - {0xa0, 0xbb, ZC3XX_R126_GAMMA06}, - {0xa0, 0xca, ZC3XX_R127_GAMMA07}, - {0xa0, 0xd7, ZC3XX_R128_GAMMA08}, - {0xa0, 0xe1, ZC3XX_R129_GAMMA09}, - {0xa0, 0xea, ZC3XX_R12A_GAMMA0A}, - {0xa0, 0xf1, ZC3XX_R12B_GAMMA0B}, - {0xa0, 0xf7, ZC3XX_R12C_GAMMA0C}, - {0xa0, 0xfc, ZC3XX_R12D_GAMMA0D}, - {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, - {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, - {0xa0, 0x20, ZC3XX_R130_GAMMA10}, - {0xa0, 0x22, ZC3XX_R131_GAMMA11}, - {0xa0, 0x20, ZC3XX_R132_GAMMA12}, - {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, - {0xa0, 0x16, ZC3XX_R134_GAMMA14}, - {0xa0, 0x13, ZC3XX_R135_GAMMA15}, - {0xa0, 0x10, ZC3XX_R136_GAMMA16}, - {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, - {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, - {0xa0, 0x09, ZC3XX_R139_GAMMA19}, - {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, - {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, - {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, - {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, - {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, - {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, - {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xfe, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf7, ZC3XX_R10D_RGB10}, - {0xa0, 0x4d, ZC3XX_R10E_RGB11}, - {0xa0, 0xfc, ZC3XX_R10F_RGB12}, - {0xa0, 0x00, ZC3XX_R110_RGB20}, - {0xa0, 0xf6, ZC3XX_R111_RGB21}, - {0xa0, 0x4a, ZC3XX_R112_RGB22}, - - {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xaa, 0x10, 0x000d}, - {0xaa, 0x76, 0x0002}, - {0xaa, 0x2a, 0x0081}, - {0xaa, 0x2b, 0x0000}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xd8, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x1b, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xaa, 0x13, 0x00c3}, - - {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; - -static const struct usb_action pas106b_Initial_com[] = { -/* Sream and Sensor specific */ - {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */ -/* System */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ -/* Picture size */ - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* ClockSelect */ - {0xa0, 0x03, 0x003a}, - {0xa0, 0x0c, 0x003b}, - {0xa0, 0x04, 0x0038}, - {} -}; - -static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */ -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, -/* Sream and Sensor specific */ - {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, -/* Picture size */ - {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, -/* System */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, -/* Sream and Sensor specific */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, -/* Sensor Interface */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, -/* Window inside sensor array */ - {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, -/* Init the sensor */ - {0xaa, 0x02, 0x0004}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x09, 0x0005}, - {0xaa, 0x0a, 0x0002}, - {0xaa, 0x0b, 0x0002}, - {0xaa, 0x0c, 0x0005}, - {0xaa, 0x0d, 0x0000}, - {0xaa, 0x0e, 0x0002}, - {0xaa, 0x14, 0x0081}, -/* Other registers */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, -/* Frame retreiving */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, -/* Gains */ - {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, -/* Unknown */ - {0xa0, 0x00, 0x01ad}, -/* Sharpness */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, -/* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, -/* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, -/*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, -/* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, -/* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, -/* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, -/*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, -/* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, - - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, -/* Auto correction */ - {0xa0, 0x03, ZC3XX_R181_WINXSTART}, - {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, - {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, - {0xa0, 0x03, ZC3XX_R184_WINYSTART}, - {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, - {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, -/* Auto exposure and white balance */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, -/* sensor on */ - {0xaa, 0x07, 0x00b1}, - {0xaa, 0x05, 0x0003}, - {0xaa, 0x04, 0x0001}, - {0xaa, 0x03, 0x003b}, -/* Gains */ - {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, -/* Auto correction */ - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, -/* Gains */ - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - {} -}; - -static const struct usb_action pas106b_Initial[] = { /* 352x288 */ -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, -/* Sream and Sensor specific */ - {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, -/* Picture size */ - {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, -/* System */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, -/* Sream and Sensor specific */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, -/* Sensor Interface */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, -/* Window inside sensor array */ - {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, -/* Init the sensor */ - {0xaa, 0x02, 0x0004}, - {0xaa, 0x08, 0x0000}, - {0xaa, 0x09, 0x0005}, - {0xaa, 0x0a, 0x0002}, - {0xaa, 0x0b, 0x0002}, - {0xaa, 0x0c, 0x0005}, - {0xaa, 0x0d, 0x0000}, - {0xaa, 0x0e, 0x0002}, - {0xaa, 0x14, 0x0081}, -/* Other registers */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, -/* Frame retreiving */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, -/* Gains */ - {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, -/* Unknown */ - {0xa0, 0x00, 0x01ad}, -/* Sharpness */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, -/* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, -/* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, -/*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, -/* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, -/* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, -/* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, -/*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, -/* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, -/* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, - - {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ - {0xa0, 0xf4, ZC3XX_R10B_RGB01}, - {0xa0, 0xf4, ZC3XX_R10C_RGB02}, - {0xa0, 0xf4, ZC3XX_R10D_RGB10}, - {0xa0, 0x58, ZC3XX_R10E_RGB11}, - {0xa0, 0xf4, ZC3XX_R10F_RGB12}, - {0xa0, 0xf4, ZC3XX_R110_RGB20}, - {0xa0, 0xf4, ZC3XX_R111_RGB21}, - {0xa0, 0x58, ZC3XX_R112_RGB22}, -/* Auto correction */ - {0xa0, 0x03, ZC3XX_R181_WINXSTART}, - {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, - {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, - {0xa0, 0x03, ZC3XX_R184_WINYSTART}, - {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, - {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - -/* Auto exposure and white balance */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, - - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, - - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, -/* sensor on */ - {0xaa, 0x07, 0x00b1}, - {0xaa, 0x05, 0x0003}, - {0xaa, 0x04, 0x0001}, - {0xaa, 0x03, 0x003b}, -/* Gains */ - {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, -/* Auto correction */ - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, -/* Gains */ - {0xa0, 0x40, ZC3XX_R116_RGAIN}, - {0xa0, 0x40, ZC3XX_R117_GGAIN}, - {0xa0, 0x40, ZC3XX_R118_BGAIN}, - - {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ - {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */ - {} -}; -static const struct usb_action pas106b_50HZ[] = { - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ - {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,54,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,87,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ - {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */ - {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */ - {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ - {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ - {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ - {} -}; -static const struct usb_action pas106b_60HZ[] = { - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ - {0xa0, 0x2e, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,2e,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x71, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,71,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ - {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */ - {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */ - {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ - {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ - {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ - {} -}; -static const struct usb_action pas106b_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ - {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */ - {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ - {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ - {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {} -}; - -/* from lvWIMv.inf 046d:08a2/:08aa 2007/06/03 */ -static const struct usb_action pas202b_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,03,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,03,cc */ - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xaa, 0x02, 0x0002}, /* 00,02,04,aa --> 02 */ - {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */ - {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */ - {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ - {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ - {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ - {0xaa, 0x0c, 0x0006}, - {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ - {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */ - {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */ - {} -}; -static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ - {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,08,cc */ - {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,02,cc */ - {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */ - {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */ - {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */ - {0xaa, 0x07, 0x0006}, /* 00,07,06,aa */ - {0xaa, 0x08, 0x0002}, /* 00,08,02,aa */ - {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ - {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ - {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ - {0xaa, 0x0c, 0x0006}, - {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ - {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ - {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ - {0xaa, 0x13, 0x0063}, /* 00,13,63,aa */ - {0xaa, 0x15, 0x0070}, /* 00,15,70,aa */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */ - {0xa0, 0xff, ZC3XX_R097_WINYSTARTHIGH}, - {0xa0, 0xfe, ZC3XX_R098_WINYSTARTLOW}, - {} -}; -static const struct usb_action pas202b_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ - {0xaa, 0x21, 0x001b}, - {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */ - {0xaa, 0x04, 0x0008}, - {0xaa, 0x05, 0x001b}, - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */ - {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ - {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ - {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, /* 00,20,eb,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; -static const struct usb_action pas202b_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0004}, - {0xaa, 0x21, 0x003d}, - {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */ - {0xaa, 0x04, 0x0010}, - {0xaa, 0x05, 0x003d}, - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ - {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ - {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; -static const struct usb_action pas202b_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ - {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ - {0xaa, 0x03, 0x0045}, /* 00,03,45,aa */ - {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ - {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */ - {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */ - {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */ - {0xa0, 0xf5, ZC3XX_R020_HSYNC_3}, /* 00,20,f5,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; -static const struct usb_action pas202b_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0004}, - {0xaa, 0x21, 0x0008}, - {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */ - {0xaa, 0x04, 0x0010}, - {0xaa, 0x05, 0x0008}, - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */ - {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ - {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; -static const struct usb_action pas202b_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ - {0xaa, 0x21, 0x0006}, - {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ - {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ - {0xaa, 0x05, 0x0006}, - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x06, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; -static const struct usb_action pas202b_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ - {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ - {0xaa, 0x20, 0x0004}, - {0xaa, 0x21, 0x000c}, - {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ - {0xaa, 0x04, 0x0010}, - {0xaa, 0x05, 0x000c}, - {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ - {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x0c, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */ - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, /* 00,87,0f,cc */ - {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */ - {} -}; - -/* mt9v111 (mi0360soc) and pb0330 from vm30x.inf 0ac8:301b 07/02/13 */ -static const struct usb_action mt9v111_1_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0001}, - {0xaa, 0x06, 0x0000}, - {0xaa, 0x08, 0x0483}, - {0xaa, 0x01, 0x0004}, - {0xaa, 0x08, 0x0006}, - {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e5}, /*jfm: was 01e7*/ - {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/ - {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x5100}, - {0xaa, 0x35, 0x507f}, - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xaa, 0x2b, 0x007f}, - {0xaa, 0x2c, 0x007f}, /*jfm: was 0030*/ - {0xaa, 0x2d, 0x007f}, /*jfm: was 0030*/ - {0xaa, 0x2e, 0x007f}, /*jfm: was 0030*/ - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, - {0xa0, 0x65, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action mt9v111_1_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0001}, - {0xaa, 0x06, 0x0000}, - {0xaa, 0x08, 0x0483}, - {0xaa, 0x01, 0x0004}, - {0xaa, 0x08, 0x0006}, - {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e7}, - {0xaa, 0x04, 0x0287}, - {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x5100}, - {0xaa, 0x35, 0x007f}, /*jfm: was 0050*/ - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xaa, 0x2b, 0x007f}, /*jfm: was 28*/ - {0xaa, 0x2c, 0x007f}, /*jfm: was 30*/ - {0xaa, 0x2d, 0x007f}, /*jfm: was 30*/ - {0xaa, 0x2e, 0x007f}, /*jfm: was 28*/ - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x09, 0x01ad}, /*jfm: was 00*/ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, - {0xa0, 0x65, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action mt9v111_1_AE50HZ[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0562}, - {0xbb, 0x01, 0x09aa}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_1_AE50HZScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0509}, - {0xbb, 0x01, 0x0934}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_1_AE60HZ[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x003d}, - {0xaa, 0x09, 0x016e}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_1_AE60HZScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0509}, - {0xbb, 0x01, 0x0983}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_1_AENoFliker[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0509}, - {0xbb, 0x01, 0x0960}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_1_AENoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0534}, - {0xbb, 0x02, 0x0960}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x34, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -/* from usbvm303.inf 0ac8:303b 07/03/25 (3 - tas5130c) */ -static const struct usb_action mt9v111_3_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0001}, /* select IFP/SOC registers */ - {0xaa, 0x06, 0x0000}, /* operating mode control */ - {0xaa, 0x08, 0x0483}, /* output format control */ - /* H red first, V red or blue first, - * raw Bayer, auto flicker */ - {0xaa, 0x01, 0x0004}, /* select sensor core registers */ - {0xaa, 0x08, 0x0006}, /* row start */ - {0xaa, 0x02, 0x0011}, /* column start */ - {0xaa, 0x03, 0x01e5}, /* window height - 1 */ - {0xaa, 0x04, 0x0285}, /* window width - 1 */ - {0xaa, 0x07, 0x3002}, /* output control */ - {0xaa, 0x20, 0x1100}, /* read mode: bits 8 & 12 (?) */ - {0xaa, 0x35, 0x007f}, /* global gain */ - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xaa, 0x2b, 0x007f}, /* green1 gain */ - {0xaa, 0x2c, 0x007f}, /* blue gain */ - {0xaa, 0x2d, 0x007f}, /* red gain */ - {0xaa, 0x2e, 0x007f}, /* green2 gain */ - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, - {0xa0, 0x65, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action mt9v111_3_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0001}, - {0xaa, 0x06, 0x0000}, - {0xaa, 0x08, 0x0483}, - {0xaa, 0x01, 0x0004}, - {0xaa, 0x08, 0x0006}, - {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e7}, - {0xaa, 0x04, 0x0287}, - {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x1100}, - {0xaa, 0x35, 0x007f}, - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xaa, 0x2b, 0x007f}, - {0xaa, 0x2c, 0x007f}, - {0xaa, 0x2d, 0x007f}, - {0xaa, 0x2e, 0x007f}, - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, - {0xa0, 0x65, ZC3XX_R118_BGAIN}, - {} -}; -static const struct usb_action mt9v111_3_AE50HZ[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, /* horizontal blanking */ - {0xaa, 0x09, 0x01ce}, /* shutter width */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_3_AE50HZScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, - {0xaa, 0x09, 0x01ce}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_3_AE60HZ[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, - {0xaa, 0x09, 0x0083}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_3_AE60HZScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0009}, - {0xaa, 0x09, 0x0083}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_3_AENoFliker[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0034}, - {0xaa, 0x09, 0x0260}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x34, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; -static const struct usb_action mt9v111_3_AENoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xaa, 0x05, 0x0034}, - {0xaa, 0x09, 0x0260}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x34, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, - {} -}; - -static const struct usb_action pb0330_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0006}, - {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e5}, /*jfm: was 1e7*/ - {0xaa, 0x04, 0x0285}, /*jfm: was 0287*/ - {0xaa, 0x06, 0x0003}, - {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x1100}, - {0xaa, 0x2f, 0xf7b0}, - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x34, 0x0100}, - {0xaa, 0x35, 0x0060}, - {0xaa, 0x3d, 0x068f}, - {0xaa, 0x40, 0x01e0}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x09, 0x01ad}, /*jfm: was 00 */ - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/ - {} -}; -static const struct usb_action pb0330_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, - {0xdd, 0x00, 0x0200}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xaa, 0x01, 0x0006}, - {0xaa, 0x02, 0x0011}, - {0xaa, 0x03, 0x01e7}, - {0xaa, 0x04, 0x0287}, - {0xaa, 0x06, 0x0003}, - {0xaa, 0x07, 0x3002}, - {0xaa, 0x20, 0x1100}, - {0xaa, 0x2f, 0xf7b0}, - {0xaa, 0x30, 0x0005}, - {0xaa, 0x31, 0x0000}, - {0xaa, 0x34, 0x0100}, - {0xaa, 0x35, 0x0060}, - {0xaa, 0x3d, 0x068f}, - {0xaa, 0x40, 0x01e0}, - {0xaa, 0x58, 0x0078}, - {0xaa, 0x62, 0x0411}, - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x09, 0x01ad}, - {0xa0, 0x15, 0x01ae}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /*jfm: was 6c*/ - {} -}; -static const struct usb_action pb0330_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x055c}, - {0xbb, 0x01, 0x09aa}, - {0xbb, 0x00, 0x1001}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x5c, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action pb0330_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0566}, - {0xbb, 0x02, 0x09b2}, - {0xbb, 0x00, 0x1002}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action pb0330_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0535}, - {0xbb, 0x01, 0x0974}, - {0xbb, 0x00, 0x1001}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xd0, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action pb0330_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0535}, - {0xbb, 0x02, 0x096c}, - {0xbb, 0x00, 0x1002}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xd0, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action pb0330_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0509}, - {0xbb, 0x02, 0x0940}, - {0xbb, 0x00, 0x1002}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {} -}; -static const struct usb_action pb0330_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, - {0xbb, 0x00, 0x0535}, - {0xbb, 0x01, 0x0980}, - {0xbb, 0x00, 0x1001}, - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x35, ZC3XX_R01D_HSYNC_0}, - {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, - {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, - {0xa0, 0xe0, ZC3XX_R020_HSYNC_3}, - {} -}; - -/* from oem9.inf */ -static const struct usb_action po2030_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ - {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ - {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ - {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ - {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ - {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ - {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ - {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */ - {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ - {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */ - {0xaa, 0x0f, 0x00eb}, /* 00,0f,eb,aa */ - {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ - {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ - {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ - {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ - {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ - {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ - {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ - {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ - {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ - {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ - {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ - {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ - {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ - {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ - {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ - {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ - {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ - {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ - {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ - {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ - {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ - {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ - {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ - {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ - {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ - {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ - {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ - {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ - {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ - {} -}; - -/* from oem9.inf */ -static const struct usb_action po2030_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ - {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ - {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ - {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ - {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ - {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ - {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ - {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */ - {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ - {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */ - {0xaa, 0x0f, 0x00ed}, /* 00,0f,ed,aa */ - {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ - {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ - {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ - {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ - {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ - {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ - {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ - {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ - {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ - {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ - {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ - {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ - {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ - {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ - {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ - {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ - {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ - {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ - {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ - {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ - {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ - {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ - {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ - {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ - {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ - {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ - {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ - {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ - {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ - {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ - {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ - {} -}; - -static const struct usb_action po2030_50HZ[] = { - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ - {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ - {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */ - {0xa0, 0x05, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,05,cc */ - {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,35,cc */ - {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x85, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,85,cc */ - {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,58,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ - {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ - {} -}; - -static const struct usb_action po2030_60HZ[] = { - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ - {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ - {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */ - {0xa0, 0x08, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,08,cc */ - {0xa0, 0xae, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,ae,cc */ - {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x6f, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,6f,cc */ - {0xa0, 0x20, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,20,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ - {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ - {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ - {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ - /* win: 01,8d,80 */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ - {} -}; - -static const struct usb_action po2030_NoFliker[] = { - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ - {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */ - {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ - {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ - {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ - {} -}; - -static const struct usb_action tas5130c_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - - {0xa0, 0x04, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x04, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, - {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, - {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, - {} -}; -static const struct usb_action tas5130c_Initial[] = { /* 640x480 */ - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, - {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, - {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, - {0xa0, 0x05, ZC3XX_R098_WINYSTARTLOW}, - {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, - {0xa0, 0x05, ZC3XX_R11A_FIRSTYLOW}, - {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, - {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, - {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, - {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, - {0xa0, 0x70, ZC3XX_R18D_YTARGET}, - {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, - {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, - {} -}; -static const struct usb_action tas5130c_50HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ - {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ - {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ - {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; -static const struct usb_action tas5130c_50HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ - {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ - {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ - {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; -static const struct usb_action tas5130c_60HZ[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ - {0xa0, 0x28, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; -static const struct usb_action tas5130c_60HZScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ - {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ - {0xa0, 0x20, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; -static const struct usb_action tas5130c_NoFliker[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ - {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; - -static const struct usb_action tas5130c_NoFlikerScale[] = { - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ - {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */ - {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ - {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ - {0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, - {0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, - {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ - {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ - {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ - {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ - {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ - {0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW}, - {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, - {} -}; - -/* from usbvm305.inf 0ac8:305b 07/06/15 (3 - tas5130c) */ -static const struct usb_action gc0303_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ - {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ - {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc, - * 6<->8 */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc, - * 6<->8 */ - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xaa, 0x01, 0x0000}, - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ - {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ - {0xaa, 0x1b, 0x0000}, - {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ - {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ - {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ - {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ - {0xaa, 0x0a, 0x0002}, - {0xaa, 0x0b, 0x0000}, - {0xaa, 0x0c, 0x0002}, - {0xaa, 0x0d, 0x0000}, - {0xaa, 0x0e, 0x0002}, - {0xaa, 0x0f, 0x0000}, - {0xaa, 0x10, 0x0002}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ - {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ - {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ - {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */ - {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ - {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ - {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ - {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ - {0xaa, 0x1b, 0x0000}, - {} -}; - -static const struct usb_action gc0303_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ - {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ - {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ - {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc, - * 8<->6 */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc, - * 8<->6 */ - {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ - {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ - {0xaa, 0x01, 0x0000}, - {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ - {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ - {0xaa, 0x1b, 0x0000}, - {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ - {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ - {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ - {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ - {0xaa, 0x0a, 0x0001}, - {0xaa, 0x0b, 0x0000}, - {0xaa, 0x0c, 0x0001}, - {0xaa, 0x0d, 0x0000}, - {0xaa, 0x0e, 0x0001}, - {0xaa, 0x0f, 0x0000}, - {0xaa, 0x10, 0x0001}, - {0xaa, 0x11, 0x0000}, - {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ - {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ - {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ - {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ - {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ - {0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN}, - {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ - {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ - {0xaa, 0x1b, 0x0000}, - {} -}; -static const struct usb_action gc0303_50HZ[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ - {0xaa, 0x84, 0x0063}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ - {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ - {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, - {} -}; - -static const struct usb_action gc0303_50HZScale[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ - {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x0d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ - {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ - {0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x7f, ZC3XX_R18D_YTARGET}, - {} -}; - -static const struct usb_action gc0303_60HZ[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, - {0xaa, 0x84, 0x003b}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ - {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x3b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3b,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, - {} -}; - -static const struct usb_action gc0303_60HZScale[] = { - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, - {0xaa, 0x84, 0x0076}, - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ - {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,5,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,6,00,cc, */ - {0xa0, 0x76, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,7,76,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,f,15,cc, */ - {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,9,10,cc, */ - {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,a,24,cc, */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, - {} -}; - -static const struct usb_action gc0303_NoFliker[] = { - {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ - {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ - {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ - {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ - {} -}; - -static const struct usb_action gc0303_NoFlikerScale[] = { - {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ - {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ - {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ - {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ - {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, - {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ - {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ - {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ - {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ - {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ - {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ - {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ - {} -}; - -static u8 reg_r(struct gspca_dev *gspca_dev, - u16 index) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return 0; - ret = usb_control_msg(gspca_dev->dev, - usb_rcvctrlpipe(gspca_dev->dev, 0), - 0xa1, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x01, /* value */ - index, gspca_dev->usb_buf, 1, - 500); - if (ret < 0) { - pr_err("reg_r err %d\n", ret); - gspca_dev->usb_err = ret; - return 0; - } - return gspca_dev->usb_buf[0]; -} - -static void reg_w(struct gspca_dev *gspca_dev, - u8 value, - u16 index) -{ - int ret; - - if (gspca_dev->usb_err < 0) - return; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0xa0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, - 500); - if (ret < 0) { - pr_err("reg_w_i err %d\n", ret); - gspca_dev->usb_err = ret; - } -} - -static u16 i2c_read(struct gspca_dev *gspca_dev, - u8 reg) -{ - u8 retbyte; - u16 retval; - - if (gspca_dev->usb_err < 0) - return 0; - reg_w(gspca_dev, reg, 0x0092); - reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */ - msleep(20); - retbyte = reg_r(gspca_dev, 0x0091); /* read status */ - if (retbyte != 0x00) - pr_err("i2c_r status error %02x\n", retbyte); - retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */ - retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */ - return retval; -} - -static u8 i2c_write(struct gspca_dev *gspca_dev, - u8 reg, - u8 valL, - u8 valH) -{ - u8 retbyte; - - if (gspca_dev->usb_err < 0) - return 0; - reg_w(gspca_dev, reg, 0x92); - reg_w(gspca_dev, valL, 0x93); - reg_w(gspca_dev, valH, 0x94); - reg_w(gspca_dev, 0x01, 0x90); /* <- write command */ - msleep(1); - retbyte = reg_r(gspca_dev, 0x0091); /* read status */ - if (retbyte != 0x00) - pr_err("i2c_w status error %02x\n", retbyte); - return retbyte; -} - -static void usb_exchange(struct gspca_dev *gspca_dev, - const struct usb_action *action) -{ - while (action->req) { - switch (action->req) { - case 0xa0: /* write register */ - reg_w(gspca_dev, action->val, action->idx); - break; - case 0xa1: /* read status */ - reg_r(gspca_dev, action->idx); - break; - case 0xaa: - i2c_write(gspca_dev, - action->val, /* reg */ - action->idx & 0xff, /* valL */ - action->idx >> 8); /* valH */ - break; - case 0xbb: - i2c_write(gspca_dev, - action->idx >> 8, /* reg */ - action->idx & 0xff, /* valL */ - action->val); /* valH */ - break; - default: -/* case 0xdd: * delay */ - msleep(action->idx); - break; - } - action++; - msleep(1); - } -} - -static void setmatrix(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - const u8 *matrix; - static const u8 adcm2700_matrix[9] = -/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */ -/*ms-win*/ - {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74}; - static const u8 gc0305_matrix[9] = - {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; - static const u8 ov7620_matrix[9] = - {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; - static const u8 pas202b_matrix[9] = - {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; - static const u8 po2030_matrix[9] = - {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; - static const u8 tas5130c_matrix[9] = - {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; - static const u8 gc0303_matrix[9] = - {0x6c, 0xea, 0xea, 0xea, 0x6c, 0xea, 0xea, 0xea, 0x6c}; - static const u8 *matrix_tb[SENSOR_MAX] = { - [SENSOR_ADCM2700] = adcm2700_matrix, - [SENSOR_CS2102] = ov7620_matrix, - [SENSOR_CS2102K] = NULL, - [SENSOR_GC0303] = gc0303_matrix, - [SENSOR_GC0305] = gc0305_matrix, - [SENSOR_HDCS2020] = NULL, - [SENSOR_HV7131B] = NULL, - [SENSOR_HV7131R] = po2030_matrix, - [SENSOR_ICM105A] = po2030_matrix, - [SENSOR_MC501CB] = NULL, - [SENSOR_MT9V111_1] = gc0305_matrix, - [SENSOR_MT9V111_3] = gc0305_matrix, - [SENSOR_OV7620] = ov7620_matrix, - [SENSOR_OV7630C] = NULL, - [SENSOR_PAS106] = NULL, - [SENSOR_PAS202B] = pas202b_matrix, - [SENSOR_PB0330] = gc0305_matrix, - [SENSOR_PO2030] = po2030_matrix, - [SENSOR_TAS5130C] = tas5130c_matrix, - }; - - matrix = matrix_tb[sd->sensor]; - if (matrix == NULL) - return; /* matrix already loaded */ - for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++) - reg_w(gspca_dev, matrix[i], 0x010a + i); -} - -static void setsharpness(struct gspca_dev *gspca_dev, s32 val) -{ - static const u8 sharpness_tb[][2] = { - {0x02, 0x03}, - {0x04, 0x07}, - {0x08, 0x0f}, - {0x10, 0x1e} - }; - - reg_w(gspca_dev, sharpness_tb[val][0], 0x01c6); - reg_r(gspca_dev, 0x01c8); - reg_r(gspca_dev, 0x01c9); - reg_r(gspca_dev, 0x01ca); - reg_w(gspca_dev, sharpness_tb[val][1], 0x01cb); -} - -static void setcontrast(struct gspca_dev *gspca_dev, - s32 gamma, s32 brightness, s32 contrast) -{ - const u8 *Tgamma; - int g, i, adj, gp1, gp2; - u8 gr[16]; - static const u8 delta_b[16] = /* delta for brightness */ - {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d, - 0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18}; - static const u8 delta_c[16] = /* delta for contrast */ - {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06, - 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02}; - static const u8 gamma_tb[6][16] = { - {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, - 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}, - {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, - 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}, - {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, - 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}, - {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}, - {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, - 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}, - {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, - 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}, - }; - - Tgamma = gamma_tb[gamma - 1]; - - contrast -= 128; /* -128 / 127 */ - brightness -= 128; /* -128 / 92 */ - adj = 0; - gp1 = gp2 = 0; - for (i = 0; i < 16; i++) { - g = Tgamma[i] + delta_b[i] * brightness / 256 - - delta_c[i] * contrast / 256 - adj / 2; - if (g > 0xff) - g = 0xff; - else if (g < 0) - g = 0; - reg_w(gspca_dev, g, 0x0120 + i); /* gamma */ - if (contrast > 0) - adj--; - else if (contrast < 0) - adj++; - if (i > 1) - gr[i - 1] = (g - gp2) / 2; - else if (i != 0) - gr[0] = gp1 == 0 ? 0 : (g - gp1); - gp2 = gp1; - gp1 = g; - } - gr[15] = (0xff - gp2) / 2; - for (i = 0; i < 16; i++) - reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */ -} - -static s32 getexposure(struct gspca_dev *gspca_dev) -{ - return (i2c_read(gspca_dev, 0x25) << 9) - | (i2c_read(gspca_dev, 0x26) << 1) - | (i2c_read(gspca_dev, 0x27) >> 7); -} - -static void setexposure(struct gspca_dev *gspca_dev, s32 val) -{ - i2c_write(gspca_dev, 0x25, val >> 9, 0x00); - i2c_write(gspca_dev, 0x26, val >> 1, 0x00); - i2c_write(gspca_dev, 0x27, val << 7, 0x00); -} - -static void setquality(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08 >> 1]); - reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); -} - -/* Matches the sensor's internal frame rate to the lighting frequency. - * Valid frequencies are: - * 50Hz, for European and Asian lighting (default) - * 60Hz, for American lighting - * 0 = No Fliker (for outdoore usage) - */ -static void setlightfreq(struct gspca_dev *gspca_dev, s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, mode; - const struct usb_action *zc3_freq; - static const struct usb_action *freq_tb[SENSOR_MAX][6] = { - [SENSOR_ADCM2700] = - {adcm2700_NoFliker, adcm2700_NoFliker, - adcm2700_50HZ, adcm2700_50HZ, - adcm2700_60HZ, adcm2700_60HZ}, - [SENSOR_CS2102] = - {cs2102_NoFliker, cs2102_NoFlikerScale, - cs2102_50HZ, cs2102_50HZScale, - cs2102_60HZ, cs2102_60HZScale}, - [SENSOR_CS2102K] = - {cs2102_NoFliker, cs2102_NoFlikerScale, - NULL, NULL, /* currently disabled */ - NULL, NULL}, - [SENSOR_GC0303] = - {gc0303_NoFliker, gc0303_NoFlikerScale, - gc0303_50HZ, gc0303_50HZScale, - gc0303_60HZ, gc0303_60HZScale}, - [SENSOR_GC0305] = - {gc0305_NoFliker, gc0305_NoFliker, - gc0305_50HZ, gc0305_50HZ, - gc0305_60HZ, gc0305_60HZ}, - [SENSOR_HDCS2020] = - {hdcs2020_NoFliker, hdcs2020_NoFliker, - hdcs2020_50HZ, hdcs2020_50HZ, - hdcs2020_60HZ, hdcs2020_60HZ}, - [SENSOR_HV7131B] = - {hv7131b_NoFliker, hv7131b_NoFlikerScale, - hv7131b_50HZ, hv7131b_50HZScale, - hv7131b_60HZ, hv7131b_60HZScale}, - [SENSOR_HV7131R] = - {hv7131r_NoFliker, hv7131r_NoFlikerScale, - hv7131r_50HZ, hv7131r_50HZScale, - hv7131r_60HZ, hv7131r_60HZScale}, - [SENSOR_ICM105A] = - {icm105a_NoFliker, icm105a_NoFlikerScale, - icm105a_50HZ, icm105a_50HZScale, - icm105a_60HZ, icm105a_60HZScale}, - [SENSOR_MC501CB] = - {mc501cb_NoFliker, mc501cb_NoFlikerScale, - mc501cb_50HZ, mc501cb_50HZScale, - mc501cb_60HZ, mc501cb_60HZScale}, - [SENSOR_MT9V111_1] = - {mt9v111_1_AENoFliker, mt9v111_1_AENoFlikerScale, - mt9v111_1_AE50HZ, mt9v111_1_AE50HZScale, - mt9v111_1_AE60HZ, mt9v111_1_AE60HZScale}, - [SENSOR_MT9V111_3] = - {mt9v111_3_AENoFliker, mt9v111_3_AENoFlikerScale, - mt9v111_3_AE50HZ, mt9v111_3_AE50HZScale, - mt9v111_3_AE60HZ, mt9v111_3_AE60HZScale}, - [SENSOR_OV7620] = - {ov7620_NoFliker, ov7620_NoFliker, - ov7620_50HZ, ov7620_50HZ, - ov7620_60HZ, ov7620_60HZ}, - [SENSOR_OV7630C] = - {NULL, NULL, - NULL, NULL, - NULL, NULL}, - [SENSOR_PAS106] = - {pas106b_NoFliker, pas106b_NoFliker, - pas106b_50HZ, pas106b_50HZ, - pas106b_60HZ, pas106b_60HZ}, - [SENSOR_PAS202B] = - {pas202b_NoFliker, pas202b_NoFlikerScale, - pas202b_50HZ, pas202b_50HZScale, - pas202b_60HZ, pas202b_60HZScale}, - [SENSOR_PB0330] = - {pb0330_NoFliker, pb0330_NoFlikerScale, - pb0330_50HZ, pb0330_50HZScale, - pb0330_60HZ, pb0330_60HZScale}, - [SENSOR_PO2030] = - {po2030_NoFliker, po2030_NoFliker, - po2030_50HZ, po2030_50HZ, - po2030_60HZ, po2030_60HZ}, - [SENSOR_TAS5130C] = - {tas5130c_NoFliker, tas5130c_NoFlikerScale, - tas5130c_50HZ, tas5130c_50HZScale, - tas5130c_60HZ, tas5130c_60HZScale}, - }; - - i = val * 2; - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - if (mode) - i++; /* 320x240 */ - zc3_freq = freq_tb[sd->sensor][i]; - if (zc3_freq == NULL) - return; - usb_exchange(gspca_dev, zc3_freq); - switch (sd->sensor) { - case SENSOR_GC0305: - if (mode /* if 320x240 */ - && val == 1) /* and 50Hz */ - reg_w(gspca_dev, 0x85, 0x018d); - /* win: 0x80, 0x018d */ - break; - case SENSOR_OV7620: - if (!mode) { /* if 640x480 */ - if (val != 0) /* and filter */ - reg_w(gspca_dev, 0x40, 0x0002); - else - reg_w(gspca_dev, 0x44, 0x0002); - } - break; - case SENSOR_PAS202B: - reg_w(gspca_dev, 0x00, 0x01a7); - break; - } -} - -static void setautogain(struct gspca_dev *gspca_dev, s32 val) -{ - reg_w(gspca_dev, val ? 0x42 : 0x02, 0x0180); -} - -/* - * Update the transfer parameters. - * This function is executed from a work queue. - */ -static void transfer_update(struct work_struct *work) -{ - struct sd *sd = container_of(work, struct sd, work); - struct gspca_dev *gspca_dev = &sd->gspca_dev; - int change, good; - u8 reg07, reg11; - - /* reg07 gets set to 0 by sd_start before starting us */ - reg07 = 0; - - good = 0; - for (;;) { - msleep(100); - - mutex_lock(&gspca_dev->usb_lock); -#ifdef CONFIG_PM - if (gspca_dev->frozen) - goto err; -#endif - if (!gspca_dev->dev || !gspca_dev->streaming) - goto err; - - /* Bit 0 of register 11 indicates FIFO overflow */ - gspca_dev->usb_err = 0; - reg11 = reg_r(gspca_dev, 0x0011); - if (gspca_dev->usb_err) - goto err; - - change = reg11 & 0x01; - if (change) { /* overflow */ - good = 0; - - if (reg07 == 0) /* Bit Rate Control not enabled? */ - reg07 = 0x32; /* Allow 98 bytes / unit */ - else if (reg07 > 2) - reg07 -= 2; /* Decrease allowed bytes / unit */ - else - change = 0; - } else { /* no overflow */ - good++; - if (good >= 10) { - good = 0; - if (reg07) { /* BRC enabled? */ - change = 1; - if (reg07 < 0x32) - reg07 += 2; - else - reg07 = 0; - } - } - } - if (change) { - gspca_dev->usb_err = 0; - reg_w(gspca_dev, reg07, 0x0007); - if (gspca_dev->usb_err) - goto err; - } - mutex_unlock(&gspca_dev->usb_lock); - } - return; -err: - mutex_unlock(&gspca_dev->usb_lock); -} - -static void send_unknown(struct gspca_dev *gspca_dev, int sensor) -{ - reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */ - switch (sensor) { - case SENSOR_PAS106: - reg_w(gspca_dev, 0x03, 0x003a); - reg_w(gspca_dev, 0x0c, 0x003b); - reg_w(gspca_dev, 0x08, 0x0038); - break; - case SENSOR_ADCM2700: - case SENSOR_GC0305: - case SENSOR_OV7620: - case SENSOR_MT9V111_1: - case SENSOR_MT9V111_3: - case SENSOR_PB0330: - case SENSOR_PO2030: - reg_w(gspca_dev, 0x0d, 0x003a); - reg_w(gspca_dev, 0x02, 0x003b); - reg_w(gspca_dev, 0x00, 0x0038); - break; - case SENSOR_HV7131R: - case SENSOR_PAS202B: - reg_w(gspca_dev, 0x03, 0x003b); - reg_w(gspca_dev, 0x0c, 0x003a); - reg_w(gspca_dev, 0x0b, 0x0039); - if (sensor == SENSOR_PAS202B) - reg_w(gspca_dev, 0x0b, 0x0038); - break; - } -} - -/* start probe 2 wires */ -static void start_2wr_probe(struct gspca_dev *gspca_dev, int sensor) -{ - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, sensor, 0x0010); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0x03, 0x0012); - reg_w(gspca_dev, 0x01, 0x0012); -/* msleep(2); */ -} - -static int sif_probe(struct gspca_dev *gspca_dev) -{ - u16 checkword; - - start_2wr_probe(gspca_dev, 0x0f); /* PAS106 */ - reg_w(gspca_dev, 0x08, 0x008d); - msleep(150); - checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4) - | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4); - PDEBUG(D_PROBE, "probe sif 0x%04x", checkword); - if (checkword == 0x0007) { - send_unknown(gspca_dev, SENSOR_PAS106); - return 0x0f; /* PAS106 */ - } - return -1; -} - -static int vga_2wr_probe(struct gspca_dev *gspca_dev) -{ - u16 retword; - - start_2wr_probe(gspca_dev, 0x00); /* HV7131B */ - i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) - return 0x00; /* HV7131B */ - - start_2wr_probe(gspca_dev, 0x04); /* CS2102 */ - i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) - return 0x04; /* CS2102 */ - - start_2wr_probe(gspca_dev, 0x06); /* OmniVision */ - reg_w(gspca_dev, 0x08, 0x008d); - i2c_write(gspca_dev, 0x11, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x11); - if (retword != 0) { - /* (should have returned 0xaa) --> Omnivision? */ - /* reg_r 0x10 -> 0x06 --> */ - goto ov_check; - } - - start_2wr_probe(gspca_dev, 0x08); /* HDCS2020 */ - i2c_write(gspca_dev, 0x1c, 0x00, 0x00); - i2c_write(gspca_dev, 0x15, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x15); - if (retword != 0) - return 0x08; /* HDCS2020 */ - - start_2wr_probe(gspca_dev, 0x0a); /* PB0330 */ - i2c_write(gspca_dev, 0x07, 0xaa, 0xaa); - retword = i2c_read(gspca_dev, 0x07); - if (retword != 0) - return 0x0a; /* PB0330 */ - retword = i2c_read(gspca_dev, 0x03); - if (retword != 0) - return 0x0a; /* PB0330 ?? */ - retword = i2c_read(gspca_dev, 0x04); - if (retword != 0) - return 0x0a; /* PB0330 ?? */ - - start_2wr_probe(gspca_dev, 0x0c); /* ICM105A */ - i2c_write(gspca_dev, 0x01, 0x11, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) - return 0x0c; /* ICM105A */ - - start_2wr_probe(gspca_dev, 0x0e); /* PAS202BCB */ - reg_w(gspca_dev, 0x08, 0x008d); - i2c_write(gspca_dev, 0x03, 0xaa, 0x00); - msleep(50); - retword = i2c_read(gspca_dev, 0x03); - if (retword != 0) { - send_unknown(gspca_dev, SENSOR_PAS202B); - return 0x0e; /* PAS202BCB */ - } - - start_2wr_probe(gspca_dev, 0x02); /* TAS5130C */ - i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) - return 0x02; /* TAS5130C */ -ov_check: - reg_r(gspca_dev, 0x0010); /* ?? */ - reg_r(gspca_dev, 0x0010); - - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0x06, 0x0010); /* OmniVision */ - reg_w(gspca_dev, 0xa1, 0x008b); - reg_w(gspca_dev, 0x08, 0x008d); - msleep(500); - reg_w(gspca_dev, 0x01, 0x0012); - i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */ - retword = i2c_read(gspca_dev, 0x0a) << 8; - retword |= i2c_read(gspca_dev, 0x0b); - PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword); - switch (retword) { - case 0x7631: /* OV7630C */ - reg_w(gspca_dev, 0x06, 0x0010); - break; - case 0x7620: /* OV7620 */ - case 0x7648: /* OV7648 */ - break; - default: - return -1; /* not OmniVision */ - } - return retword; -} - -struct sensor_by_chipset_revision { - u16 revision; - u8 internal_sensor_id; -}; -static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { - {0xc000, 0x12}, /* TAS5130C */ - {0xc001, 0x13}, /* MT9V111 */ - {0xe001, 0x13}, - {0x8001, 0x13}, - {0x8000, 0x14}, /* CS2102K */ - {0x8400, 0x15}, /* MT9V111 */ - {0xe400, 0x15}, -}; - -static int vga_3wr_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - u16 retword; - -/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ - reg_w(gspca_dev, 0x02, 0x0010); - reg_r(gspca_dev, 0x0010); - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, 0x00, 0x0010); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0x91, 0x008b); - reg_w(gspca_dev, 0x03, 0x0012); - reg_w(gspca_dev, 0x01, 0x0012); - reg_w(gspca_dev, 0x05, 0x0012); - retword = i2c_read(gspca_dev, 0x14); - if (retword != 0) - return 0x11; /* HV7131R */ - retword = i2c_read(gspca_dev, 0x15); - if (retword != 0) - return 0x11; /* HV7131R */ - retword = i2c_read(gspca_dev, 0x16); - if (retword != 0) - return 0x11; /* HV7131R */ - - reg_w(gspca_dev, 0x02, 0x0010); - retword = reg_r(gspca_dev, 0x000b) << 8; - retword |= reg_r(gspca_dev, 0x000a); - PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); - reg_r(gspca_dev, 0x0010); - if ((retword & 0xff00) == 0x6400) - return 0x02; /* TAS5130C */ - for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { - if (chipset_revision_sensor[i].revision == retword) { - sd->chip_revision = retword; - send_unknown(gspca_dev, SENSOR_PB0330); - return chipset_revision_sensor[i].internal_sensor_id; - } - } - - reg_w(gspca_dev, 0x01, 0x0000); /* check PB0330 */ - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0xdd, 0x008b); - reg_w(gspca_dev, 0x0a, 0x0010); - reg_w(gspca_dev, 0x03, 0x0012); - reg_w(gspca_dev, 0x01, 0x0012); - retword = i2c_read(gspca_dev, 0x00); - if (retword != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type 0a"); - return 0x0a; /* PB0330 */ - } - - /* probe gc0303 / gc0305 */ - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0x98, 0x008b); - reg_w(gspca_dev, 0x01, 0x0010); - reg_w(gspca_dev, 0x03, 0x0012); - msleep(2); - reg_w(gspca_dev, 0x01, 0x0012); - retword = i2c_read(gspca_dev, 0x00); - if (retword != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword); - if (retword == 0x0011) /* gc0303 */ - return 0x0303; - if (retword == 0x0029) /* gc0305 */ - send_unknown(gspca_dev, SENSOR_GC0305); - return retword; - } - - reg_w(gspca_dev, 0x01, 0x0000); /* check OmniVision */ - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0xa1, 0x008b); - reg_w(gspca_dev, 0x08, 0x008d); - reg_w(gspca_dev, 0x06, 0x0010); - reg_w(gspca_dev, 0x01, 0x0012); - reg_w(gspca_dev, 0x05, 0x0012); - if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */ - && i2c_read(gspca_dev, 0x1d) == 0x00a2) { - send_unknown(gspca_dev, SENSOR_OV7620); - return 0x06; /* OmniVision confirm ? */ - } - - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, 0x00, 0x0002); - reg_w(gspca_dev, 0x01, 0x0010); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0xee, 0x008b); - reg_w(gspca_dev, 0x03, 0x0012); - reg_w(gspca_dev, 0x01, 0x0012); - reg_w(gspca_dev, 0x05, 0x0012); - retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ - retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ - PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); - if (retword == 0x2030) { -#ifdef GSPCA_DEBUG - u8 retbyte; - - retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ - PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); -#endif - send_unknown(gspca_dev, SENSOR_PO2030); - return retword; - } - - reg_w(gspca_dev, 0x01, 0x0000); - reg_w(gspca_dev, 0x0a, 0x0010); - reg_w(gspca_dev, 0xd3, 0x008b); - reg_w(gspca_dev, 0x01, 0x0001); - reg_w(gspca_dev, 0x03, 0x0012); - reg_w(gspca_dev, 0x01, 0x0012); - reg_w(gspca_dev, 0x05, 0x0012); - reg_w(gspca_dev, 0xd3, 0x008b); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); - return 0x16; /* adcm2700 (6100/6200) */ - } - return -1; -} - -static int zcxx_probeSensor(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int sensor; - - switch (sd->sensor) { - case SENSOR_MC501CB: - return -1; /* don't probe */ - case SENSOR_GC0303: - /* may probe but with no write in reg 0x0010 */ - return -1; /* don't probe */ - case SENSOR_PAS106: - sensor = sif_probe(gspca_dev); - if (sensor >= 0) - return sensor; - break; - } - sensor = vga_2wr_probe(gspca_dev); - if (sensor >= 0) - return sensor; - return vga_3wr_probe(gspca_dev); -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (id->idProduct == 0x301b) - sd->bridge = BRIDGE_ZC301; - else - sd->bridge = BRIDGE_ZC303; - - /* define some sensors from the vendor/product */ - sd->sensor = id->driver_info; - - sd->reg08 = REG08_DEF; - - INIT_WORK(&sd->work, transfer_update); - - return 0; -} - -static int zcxx_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - gspca_dev->usb_err = 0; - if (ctrl->val && sd->exposure && gspca_dev->streaming) - sd->exposure->val = getexposure(gspca_dev); - return gspca_dev->usb_err; - } - return -EINVAL; -} - -static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gspca_dev *gspca_dev = - container_of(ctrl->handler, struct gspca_dev, ctrl_handler); - struct sd *sd = (struct sd *)gspca_dev; - int i, qual; - - gspca_dev->usb_err = 0; - - if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) { - qual = sd->reg08 >> 1; - - for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) { - if (ctrl->val <= jpeg_qual[i]) - break; - } - if (i > 0 && i == qual && ctrl->val < jpeg_qual[i]) - i--; - - /* With high quality settings we need max bandwidth */ - if (i >= 2 && gspca_dev->streaming && - !gspca_dev->cam.needs_full_bandwidth) - return -EBUSY; - - sd->reg08 = (i << 1) | 1; - ctrl->val = jpeg_qual[i]; - } - - if (!gspca_dev->streaming) - return 0; - - switch (ctrl->id) { - /* gamma/brightness/contrast cluster */ - case V4L2_CID_GAMMA: - setcontrast(gspca_dev, sd->gamma->val, - sd->brightness->val, sd->contrast->val); - break; - /* autogain/exposure cluster */ - case V4L2_CID_AUTOGAIN: - setautogain(gspca_dev, ctrl->val); - if (!gspca_dev->usb_err && !ctrl->val && sd->exposure) - setexposure(gspca_dev, sd->exposure->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - setlightfreq(gspca_dev, ctrl->val); - break; - case V4L2_CID_SHARPNESS: - setsharpness(gspca_dev, ctrl->val); - break; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: - setquality(gspca_dev); - break; - } - return gspca_dev->usb_err; -} - -static const struct v4l2_ctrl_ops zcxx_ctrl_ops = { - .g_volatile_ctrl = zcxx_g_volatile_ctrl, - .s_ctrl = zcxx_s_ctrl, -}; - -static int sd_init_controls(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *)gspca_dev; - struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; - static const u8 gamma[SENSOR_MAX] = { - [SENSOR_ADCM2700] = 4, - [SENSOR_CS2102] = 4, - [SENSOR_CS2102K] = 5, - [SENSOR_GC0303] = 3, - [SENSOR_GC0305] = 4, - [SENSOR_HDCS2020] = 4, - [SENSOR_HV7131B] = 4, - [SENSOR_HV7131R] = 4, - [SENSOR_ICM105A] = 4, - [SENSOR_MC501CB] = 4, - [SENSOR_MT9V111_1] = 4, - [SENSOR_MT9V111_3] = 4, - [SENSOR_OV7620] = 3, - [SENSOR_OV7630C] = 4, - [SENSOR_PAS106] = 4, - [SENSOR_PAS202B] = 4, - [SENSOR_PB0330] = 4, - [SENSOR_PO2030] = 4, - [SENSOR_TAS5130C] = 3, - }; - - gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 8); - sd->brightness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - sd->contrast = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, 128); - sd->gamma = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_GAMMA, 1, 6, 1, gamma[sd->sensor]); - if (sd->sensor == SENSOR_HV7131R) - sd->exposure = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_EXPOSURE, 0x30d, 0x493e, 1, 0x927); - sd->autogain = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - if (sd->sensor != SENSOR_OV7630C) - sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &zcxx_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, - V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); - sd->sharpness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_SHARPNESS, 0, 3, 1, - sd->sensor == SENSOR_PO2030 ? 0 : 2); - sd->jpegqual = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, - jpeg_qual[0], jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1], 1, - jpeg_qual[REG08_DEF >> 1]); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } - v4l2_ctrl_cluster(3, &sd->gamma); - if (sd->sensor == SENSOR_HV7131R) - v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int sensor; - static const u8 mode_tb[SENSOR_MAX] = { - [SENSOR_ADCM2700] = 2, - [SENSOR_CS2102] = 1, - [SENSOR_CS2102K] = 1, - [SENSOR_GC0303] = 1, - [SENSOR_GC0305] = 1, - [SENSOR_HDCS2020] = 1, - [SENSOR_HV7131B] = 1, - [SENSOR_HV7131R] = 1, - [SENSOR_ICM105A] = 1, - [SENSOR_MC501CB] = 2, - [SENSOR_MT9V111_1] = 1, - [SENSOR_MT9V111_3] = 1, - [SENSOR_OV7620] = 2, - [SENSOR_OV7630C] = 1, - [SENSOR_PAS106] = 0, - [SENSOR_PAS202B] = 1, - [SENSOR_PB0330] = 1, - [SENSOR_PO2030] = 1, - [SENSOR_TAS5130C] = 1, - }; - - sensor = zcxx_probeSensor(gspca_dev); - if (sensor >= 0) - PDEBUG(D_PROBE, "probe sensor -> %04x", sensor); - if ((unsigned) force_sensor < SENSOR_MAX) { - sd->sensor = force_sensor; - PDEBUG(D_PROBE, "sensor forced to %d", force_sensor); - } else { - switch (sensor) { - case -1: - switch (sd->sensor) { - case SENSOR_MC501CB: - PDEBUG(D_PROBE, "Sensor MC501CB"); - break; - case SENSOR_GC0303: - PDEBUG(D_PROBE, "Sensor GC0303"); - break; - default: - pr_warn("Unknown sensor - set to TAS5130C\n"); - sd->sensor = SENSOR_TAS5130C; - } - break; - case 0: - /* check the sensor type */ - sensor = i2c_read(gspca_dev, 0x00); - PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor); - switch (sensor) { - case 0: /* hv7131b */ - case 1: /* hv7131e */ - PDEBUG(D_PROBE, "Find Sensor HV7131B"); - sd->sensor = SENSOR_HV7131B; - break; - default: -/* case 2: * hv7131r */ - PDEBUG(D_PROBE, "Find Sensor HV7131R"); - sd->sensor = SENSOR_HV7131R; - break; - } - break; - case 0x02: - PDEBUG(D_PROBE, "Sensor TAS5130C"); - sd->sensor = SENSOR_TAS5130C; - break; - case 0x04: - PDEBUG(D_PROBE, "Find Sensor CS2102"); - sd->sensor = SENSOR_CS2102; - break; - case 0x08: - PDEBUG(D_PROBE, "Find Sensor HDCS2020"); - sd->sensor = SENSOR_HDCS2020; - break; - case 0x0a: - PDEBUG(D_PROBE, - "Find Sensor PB0330. Chip revision %x", - sd->chip_revision); - sd->sensor = SENSOR_PB0330; - break; - case 0x0c: - PDEBUG(D_PROBE, "Find Sensor ICM105A"); - sd->sensor = SENSOR_ICM105A; - break; - case 0x0e: - PDEBUG(D_PROBE, "Find Sensor PAS202B"); - sd->sensor = SENSOR_PAS202B; - break; - case 0x0f: - PDEBUG(D_PROBE, "Find Sensor PAS106"); - sd->sensor = SENSOR_PAS106; - break; - case 0x10: - case 0x12: - PDEBUG(D_PROBE, "Find Sensor TAS5130C"); - sd->sensor = SENSOR_TAS5130C; - break; - case 0x11: - PDEBUG(D_PROBE, "Find Sensor HV7131R"); - sd->sensor = SENSOR_HV7131R; - break; - case 0x13: - case 0x15: - PDEBUG(D_PROBE, - "Sensor MT9V111. Chip revision %04x", - sd->chip_revision); - sd->sensor = sd->bridge == BRIDGE_ZC301 - ? SENSOR_MT9V111_1 - : SENSOR_MT9V111_3; - break; - case 0x14: - PDEBUG(D_PROBE, - "Find Sensor CS2102K?. Chip revision %x", - sd->chip_revision); - sd->sensor = SENSOR_CS2102K; - break; - case 0x16: - PDEBUG(D_PROBE, "Find Sensor ADCM2700"); - sd->sensor = SENSOR_ADCM2700; - break; - case 0x29: - PDEBUG(D_PROBE, "Find Sensor GC0305"); - sd->sensor = SENSOR_GC0305; - break; - case 0x0303: - PDEBUG(D_PROBE, "Sensor GC0303"); - sd->sensor = SENSOR_GC0303; - break; - case 0x2030: - PDEBUG(D_PROBE, "Find Sensor PO2030"); - sd->sensor = SENSOR_PO2030; - break; - case 0x7620: - PDEBUG(D_PROBE, "Find Sensor OV7620"); - sd->sensor = SENSOR_OV7620; - break; - case 0x7631: - PDEBUG(D_PROBE, "Find Sensor OV7630C"); - sd->sensor = SENSOR_OV7630C; - break; - case 0x7648: - PDEBUG(D_PROBE, "Find Sensor OV7648"); - sd->sensor = SENSOR_OV7620; /* same sensor (?) */ - break; - default: - pr_err("Unknown sensor %04x\n", sensor); - return -EINVAL; - } - } - if (sensor < 0x20) { - if (sensor == -1 || sensor == 0x10 || sensor == 0x12) - reg_w(gspca_dev, 0x02, 0x0010); - reg_r(gspca_dev, 0x0010); - } - - cam = &gspca_dev->cam; - switch (mode_tb[sd->sensor]) { - case 0: - cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); - break; - case 1: - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - break; - default: -/* case 2: */ - cam->cam_mode = broken_vga_mode; - cam->nmodes = ARRAY_SIZE(broken_vga_mode); - break; - } - - /* switch off the led */ - reg_w(gspca_dev, 0x01, 0x0000); - return gspca_dev->usb_err; -} - -static int sd_pre_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - gspca_dev->cam.needs_full_bandwidth = (sd->reg08 >= 4) ? 1 : 0; - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int mode; - static const struct usb_action *init_tb[SENSOR_MAX][2] = { - [SENSOR_ADCM2700] = - {adcm2700_Initial, adcm2700_InitialScale}, - [SENSOR_CS2102] = - {cs2102_Initial, cs2102_InitialScale}, - [SENSOR_CS2102K] = - {cs2102K_Initial, cs2102K_InitialScale}, - [SENSOR_GC0303] = - {gc0303_Initial, gc0303_InitialScale}, - [SENSOR_GC0305] = - {gc0305_Initial, gc0305_InitialScale}, - [SENSOR_HDCS2020] = - {hdcs2020_Initial, hdcs2020_InitialScale}, - [SENSOR_HV7131B] = - {hv7131b_Initial, hv7131b_InitialScale}, - [SENSOR_HV7131R] = - {hv7131r_Initial, hv7131r_InitialScale}, - [SENSOR_ICM105A] = - {icm105a_Initial, icm105a_InitialScale}, - [SENSOR_MC501CB] = - {mc501cb_Initial, mc501cb_InitialScale}, - [SENSOR_MT9V111_1] = - {mt9v111_1_Initial, mt9v111_1_InitialScale}, - [SENSOR_MT9V111_3] = - {mt9v111_3_Initial, mt9v111_3_InitialScale}, - [SENSOR_OV7620] = - {ov7620_Initial, ov7620_InitialScale}, - [SENSOR_OV7630C] = - {ov7630c_Initial, ov7630c_InitialScale}, - [SENSOR_PAS106] = - {pas106b_Initial, pas106b_InitialScale}, - [SENSOR_PAS202B] = - {pas202b_Initial, pas202b_InitialScale}, - [SENSOR_PB0330] = - {pb0330_Initial, pb0330_InitialScale}, - [SENSOR_PO2030] = - {po2030_Initial, po2030_InitialScale}, - [SENSOR_TAS5130C] = - {tas5130c_Initial, tas5130c_InitialScale}, - }; - - /* create the JPEG header */ - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - - mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; - switch (sd->sensor) { - case SENSOR_HV7131R: - zcxx_probeSensor(gspca_dev); - break; - case SENSOR_PAS106: - usb_exchange(gspca_dev, pas106b_Initial_com); - break; - } - usb_exchange(gspca_dev, init_tb[sd->sensor][mode]); - - switch (sd->sensor) { - case SENSOR_ADCM2700: - case SENSOR_GC0305: - case SENSOR_OV7620: - case SENSOR_PO2030: - case SENSOR_TAS5130C: - case SENSOR_GC0303: -/* msleep(100); * ?? */ - reg_r(gspca_dev, 0x0002); /* --> 0x40 */ - reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */ - reg_w(gspca_dev, 0x15, 0x01ae); - if (sd->sensor == SENSOR_TAS5130C) - break; - reg_w(gspca_dev, 0x0d, 0x003a); - reg_w(gspca_dev, 0x02, 0x003b); - reg_w(gspca_dev, 0x00, 0x0038); - break; - case SENSOR_HV7131R: - case SENSOR_PAS202B: - reg_w(gspca_dev, 0x03, 0x003b); - reg_w(gspca_dev, 0x0c, 0x003a); - reg_w(gspca_dev, 0x0b, 0x0039); - if (sd->sensor == SENSOR_HV7131R) - reg_w(gspca_dev, 0x50, ZC3XX_R11D_GLOBALGAIN); - break; - } - - setmatrix(gspca_dev); - switch (sd->sensor) { - case SENSOR_ADCM2700: - case SENSOR_OV7620: - reg_r(gspca_dev, 0x0008); - reg_w(gspca_dev, 0x00, 0x0008); - break; - case SENSOR_PAS202B: - case SENSOR_GC0305: - case SENSOR_HV7131R: - case SENSOR_TAS5130C: - reg_r(gspca_dev, 0x0008); - /* fall thru */ - case SENSOR_PO2030: - reg_w(gspca_dev, 0x03, 0x0008); - break; - } - setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); - - /* set the gamma tables when not set */ - switch (sd->sensor) { - case SENSOR_CS2102K: /* gamma set in xxx_Initial */ - case SENSOR_HDCS2020: - case SENSOR_OV7630C: - break; - default: - setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma), - v4l2_ctrl_g_ctrl(sd->brightness), - v4l2_ctrl_g_ctrl(sd->contrast)); - break; - } - setmatrix(gspca_dev); /* one more time? */ - switch (sd->sensor) { - case SENSOR_OV7620: - case SENSOR_PAS202B: - reg_r(gspca_dev, 0x0180); /* from win */ - reg_w(gspca_dev, 0x00, 0x0180); - break; - } - setquality(gspca_dev); - /* Start with BRC disabled, transfer_update will enable it if needed */ - reg_w(gspca_dev, 0x00, 0x0007); - if (sd->plfreq) - setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq)); - - switch (sd->sensor) { - case SENSOR_ADCM2700: - reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */ - reg_w(gspca_dev, 0x15, 0x01ae); - reg_w(gspca_dev, 0x02, 0x0180); - /* ms-win + */ - reg_w(gspca_dev, 0x40, 0x0117); - break; - case SENSOR_HV7131R: - setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); - reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); - break; - case SENSOR_GC0305: - case SENSOR_TAS5130C: - reg_w(gspca_dev, 0x09, 0x01ad); /* (from win traces) */ - reg_w(gspca_dev, 0x15, 0x01ae); - /* fall thru */ - case SENSOR_PAS202B: - case SENSOR_PO2030: -/* reg_w(gspca_dev, 0x40, ZC3XX_R117_GGAIN); in win traces */ - reg_r(gspca_dev, 0x0180); - break; - case SENSOR_OV7620: - reg_w(gspca_dev, 0x09, 0x01ad); - reg_w(gspca_dev, 0x15, 0x01ae); - i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ - i2c_write(gspca_dev, 0x13, 0xa3, 0x00); - /*fixme: returned value to send? */ - reg_w(gspca_dev, 0x40, 0x0117); - reg_r(gspca_dev, 0x0180); - break; - } - - setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); - - if (gspca_dev->usb_err < 0) - return gspca_dev->usb_err; - - /* Start the transfer parameters update thread */ - sd->work_thread = create_singlethread_workqueue(KBUILD_MODNAME); - queue_work(sd->work_thread, &sd->work); - - return 0; -} - -/* called on streamoff with alt 0 and on disconnect */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->work_thread != NULL) { - mutex_unlock(&gspca_dev->usb_lock); - destroy_workqueue(sd->work_thread); - mutex_lock(&gspca_dev->usb_lock); - sd->work_thread = NULL; - } - if (!gspca_dev->dev) - return; - send_unknown(gspca_dev, sd->sensor); -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* check the JPEG end of frame */ - if (len >= 3 - && data[len - 3] == 0xff && data[len - 2] == 0xd9) { -/*fixme: what does the last byte mean?*/ - gspca_frame_add(gspca_dev, LAST_PACKET, - data, len - 1); - return; - } - - /* check the JPEG start of a frame */ - if (data[0] == 0xff && data[1] == 0xd8) { - /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, - sd->jpeg_hdr, JPEG_HDR_SZ); - - /* remove the webcam's header: - * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp - * - 'ss ss' is the frame sequence number (BE) - * - 'ww ww' and 'hh hh' are the window dimensions (BE) - * - 'pp pp' is the packet sequence number (BE) - */ - data += 18; - len -= 18; - } - gspca_frame_add(gspca_dev, INTER_PACKET, data, len); -} - -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - int ret; - - ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); - if (ret) - return ret; - jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) -static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, - u8 *data, /* interrupt packet data */ - int len) /* interrput packet length */ -{ - if (len == 8 && data[4] == 1) { - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); - input_sync(gspca_dev->input_dev); - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); - input_sync(gspca_dev->input_dev); - } - - return 0; -} -#endif - -static const struct sd_desc sd_desc = { - .name = KBUILD_MODNAME, - .config = sd_config, - .init = sd_init, - .init_controls = sd_init_controls, - .isoc_init = sd_pre_start, - .start = sd_start, - .stop0 = sd_stop0, - .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) - .int_pkt_scan = sd_int_pkt_scan, -#endif -}; - -static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x03f0, 0x1b07)}, - {USB_DEVICE(0x041e, 0x041e)}, - {USB_DEVICE(0x041e, 0x4017)}, - {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x041e, 0x401e)}, - {USB_DEVICE(0x041e, 0x401f)}, - {USB_DEVICE(0x041e, 0x4022)}, - {USB_DEVICE(0x041e, 0x4029)}, - {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x041e, 0x4036)}, - {USB_DEVICE(0x041e, 0x403a)}, - {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_GC0303}, - {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_GC0303}, - {USB_DEVICE(0x0458, 0x7007)}, - {USB_DEVICE(0x0458, 0x700c)}, - {USB_DEVICE(0x0458, 0x700f)}, - {USB_DEVICE(0x0461, 0x0a00)}, - {USB_DEVICE(0x046d, 0x089d), .driver_info = SENSOR_MC501CB}, - {USB_DEVICE(0x046d, 0x08a0)}, - {USB_DEVICE(0x046d, 0x08a1)}, - {USB_DEVICE(0x046d, 0x08a2)}, - {USB_DEVICE(0x046d, 0x08a3)}, - {USB_DEVICE(0x046d, 0x08a6)}, - {USB_DEVICE(0x046d, 0x08a7)}, - {USB_DEVICE(0x046d, 0x08a9)}, - {USB_DEVICE(0x046d, 0x08aa)}, - {USB_DEVICE(0x046d, 0x08ac)}, - {USB_DEVICE(0x046d, 0x08ad)}, - {USB_DEVICE(0x046d, 0x08ae)}, - {USB_DEVICE(0x046d, 0x08af)}, - {USB_DEVICE(0x046d, 0x08b9)}, - {USB_DEVICE(0x046d, 0x08d7)}, - {USB_DEVICE(0x046d, 0x08d8)}, - {USB_DEVICE(0x046d, 0x08d9)}, - {USB_DEVICE(0x046d, 0x08da)}, - {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, - {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x055f, 0xc005)}, - {USB_DEVICE(0x055f, 0xd003)}, - {USB_DEVICE(0x055f, 0xd004)}, - {USB_DEVICE(0x0698, 0x2003)}, - {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0ac8, 0x301b)}, - {USB_DEVICE(0x0ac8, 0x303b)}, - {USB_DEVICE(0x0ac8, 0x305b)}, - {USB_DEVICE(0x0ac8, 0x307b)}, - {USB_DEVICE(0x10fd, 0x0128)}, - {USB_DEVICE(0x10fd, 0x804d)}, - {USB_DEVICE(0x10fd, 0x8050)}, - {} /* end of entry */ -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -/* USB driver */ -static struct usb_driver sd_driver = { - .name = KBUILD_MODNAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, - .reset_resume = gspca_resume, -#endif -}; - -module_usb_driver(sd_driver); - -module_param(force_sensor, int, 0644); -MODULE_PARM_DESC(force_sensor, - "Force sensor. Only for experts!!!"); |