diff --git a/Kbuild b/Kbuild new file mode 100644 index 0000000..6097934 --- /dev/null +++ b/Kbuild @@ -0,0 +1,17 @@ + +EXTRA_CFLAGS = -Idrivers/media/video/usbvideo/ + +obj-m := stk11xx.o + +stk11xx-objs := stk11xx-usb.o stk11xx-v4l.o stk11xx-sysfs.o stk11xx-dev.o stk11xx-buf.o stk11xx-bayer.o + +stk11xx-objs += stk11xx-dev-0408.o +stk11xx-objs += stk11xx-dev-0500.o +stk11xx-objs += stk11xx-dev-a311.o +stk11xx-objs += stk11xx-dev-a821.o +stk11xx-objs += stk11xx-dev-6a31.o +stk11xx-objs += stk11xx-dev-6a33.o +stk11xx-objs += stk11xx-dev-6a51.o +stk11xx-objs += stk11xx-dev-6a54.o +stk11xx-objs += stk11xx-dev-6d51.o + diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..a6090b1 --- /dev/null +++ b/Kconfig @@ -0,0 +1,43 @@ +config STK11XX + tristate "Syntek USB 2.0 1.3M WebCam" + depends on VIDEO_V4L2 && (VIDEO_V4L1 || VIDEO_V4L1_COMPAT) + ---help--- + Say Y or M here if you want to use a Syntek video camera. + + For the Syntek video camera, the lsusb output is : + * 174f:a311 + * 174f:a821 + * 174f:6a31 + * 174f:6a33 + * 174f:6a51 + * 174f:6a54 + * 174f:6d51 + * 05e1:0408 + * 05e1:0500 + * 05e1:0501 + + These webcams are often embedded in the laptops (Asus, Acer, HP...). + All have the same name : Syntek USB2.0 - STK-1125 / STK-1135. + + To compile this driver as a module, choose M here: the + module will be called stk11xx. + + +config STK11XX_DEBUG + bool "Syntek USB 2.0 1.3M WebCam verbose debug" + depends on STK11XX + ---help--- + Say Y here in order to have the syntek driver generate verbose debugging + messages. + + +config STK11XX_DEBUG_STREAM + bool "Syntek USB 2.0 1.3M WebCam verbose stream debug (only debug !)" + depends on STK11XX + ---help--- + Say Y here in order to have the syntek driver generate verbose stream + debugging messages. + + WARNING : this option slowes your computer ! + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a6b3e98 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ + +stk11xx-objs := stk11xx-usb.o stk11xx-v4l.o stk11xx-sysfs.o stk11xx-dev.o stk11xx-buf.o stk11xx-bayer.o + +stk11xx-objs += stk11xx-dev-0408.o +stk11xx-objs += stk11xx-dev-0500.o +stk11xx-objs += stk11xx-dev-0501.o +stk11xx-objs += stk11xx-dev-a311.o +stk11xx-objs += stk11xx-dev-a821.o +stk11xx-objs += stk11xx-dev-6a31.o +stk11xx-objs += stk11xx-dev-6a33.o +stk11xx-objs += stk11xx-dev-6a51.o +stk11xx-objs += stk11xx-dev-6a54.o + +obj-$(CONFIG_STK11XX) += stk11xx.o + diff --git a/Makefile-syntecdriver b/Makefile-syntecdriver new file mode 100644 index 0000000..4ef41a8 --- /dev/null +++ b/Makefile-syntecdriver @@ -0,0 +1,26 @@ +ifneq ($(KERNELRELEASE),) +obj-m := stk11xx.o +stk11xx-objs := stk11xx-bayer.c stk11xx-buf.c stk11xx-dev.c stk11xx-sysfs.c stk11xx-usb.c stk11xx-v4l.c +else +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +VERSION = 0.42 +DISTFILES = stk11xx.h stk11xx-bayer.c stk11xx-buf.c stk11xx-dev.c stk11xx-sysfs.c stk11xx-usb.c stk11xx-v4l.c Makefile README COPYING INSTALL +DISTNAME = stk11xx-$(VERSION) +all: +$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules +clean: +rm -f *.o *.ko .*.o.d *~ .stk11xx*.cmd *.mod.c +rm -rf $(DISTNAME) .tmp_versions +rm -f $(DISTNAME).tar.bz2 +install: +mkdir -p $(DESTDIR)/lib/modules/$(shell uname -r)/kernel/drivers/usb/media +install -m 644 -o 0 -g 0 stk11xx.ko $(DESTDIR)/lib/modules/$(shell uname -r)/kernel/drivers/usb/media +depmod -a +dist: +[ -d $(DISTNAME) ] && rm -rf $(DISTNAME) || true +mkdir $(DISTNAME) +cp -aR $(DISTFILES) $(DISTNAME) +tar cjvf $(DISTNAME).tar.bz2 $(DISTNAME) +rm -rf $(DISTNAME) +endif diff --git a/Makefile.standalone b/Makefile.standalone new file mode 100644 index 0000000..4fc446d --- /dev/null +++ b/Makefile.standalone @@ -0,0 +1,26 @@ +# run make -f Makefile.standalone KVER=x.y.z to build for a specific version +KVER=$(shell uname -r) +KSRC=/lib/modules/$(KVER)/build + + +all: driver + +doc: + @echo "Generating document with Doxygen..." + @doxygen doxygen.cfg + +driver: + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules + @ctags -R + +install: driver + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules_install + +clean: + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) clean + @rm -f Module.symvers + +cleandoc: + @echo "Removing documentation generated by Doxygen..." + @rm -Rf ../doxygen + diff --git a/README b/README new file mode 100644 index 0000000..bdbfb0a --- /dev/null +++ b/README @@ -0,0 +1,192 @@ +Syntek USB 2.0 Video Camera +=========================== + +Note : The syntek USB 2.0 video camera driver for DC-1125 ans STK-1135 is currently being developed +on Linux. This driver can do damages. Use this driver only if you know what you are doing. + +--------------------------------------------------------------------------------------------------- + +Table of contents : + +1. Requirements + +2. Compilation + 2.1 Documentation + 2.2 Kernel module + +3. Installation + +4. Usage + 4.1 Option "fps" module + 4.2 Options "hflip" and "vflip" module + 4.3 Options "contrast", "colour", "whiteness" and "brightness" + 4.4 Use the "sysfs" + +5. Status of project + +6. Test experimental + +7. Debug + 7.1. 'lsusb' output + 7.2. USB logs from Windows + 7.3. USB logs from Linux + 7.4. Enable module traces + +8. Licence + +--------------------------------------------------------------------------------------------------- + +1. Requirements + +Kernel 2.6.18 or higher +Doxygen to compile the documentation + +--------------------------------------------------------------------------------------------------- + +2. Compilation + + 2.1 Documentation + + To build documentation : + $ make -f Makefile.standalone doc + $ make -f Makefile.standalone cleandoc + + 2.2 Kernel module + + To build the kernel module : + $ make -f Makefile.standalone + or + $ make -f Makefile.standalone driver + + $ make -f Makefile.standalone clean + +--------------------------------------------------------------------------------------------------- + +3. Installation + +TODO... + +--------------------------------------------------------------------------------------------------- + +4. Usage + + 4.1 Option "fps" module + + The syntek module waits the option "fps" (10, 15, 20, 25, 30) : + $ modprobe stk11xx fps=30 + + By default, the fps is set to '25'. + + 4.2 Options "hflip" and "vflip" module + + The syntek module waits the options "hflip" and "vflip" (values are 0 or 1): + $ modprobe stk11xx hflip=0 vflip=1 + + By default, the hflip and vflip are set to '1'. + + 4.3 Options "contrast", "colour", "brightness" and "whiteness" + + The syntek module waits the options "contrast", "colour", "brightness" and "whiteness" : + $ modprobe stk11xx contrast=0x7F00 colour=0x7F00 + + By default, the value of these options is set to '0x7F00'. + + 4.4 Use the "sysfs" + + In the directory : /sys/class/video4linux/videoX (by sample video0), you + can read and write some parameters : + $ cat hflip + $ echo 0 > hflip + + To display informations about driver : + $ cat informations + +--------------------------------------------------------------------------------------------------- + +5. Status + +The kernel module is currently being developped. + +The driver supports several webcam models : +- 0x174F:0xA311 : Quiet good supported (developper's model) +- 0x174F:0xA821 : Supported (only the video stream) +- 0x174F:0x6A31 : Supported (only the video stream) +- 0x174F:0x6A33 : Supported (only the video stream) +- 0x174F:0x6A51 : Supported (only the video stream) +- 0x174F:0x6A54 : Supported (only the video stream) +- 0x174F:0x6D51 : Supported (only the video stream) +- 0x05E1:0x0500 : +- 0x05E1:0x0501 : Like '0x174F:0xA311' (it's the same model) + +To increase the support, I need some help... Or somebody gives me the webcam ! + +--------------------------------------------------------------------------------------------------- + +6. Test experimental + +To build and load the driver, follow the steps : + +$ make -f Makefile.standalone clean +$ make -f Makefile.standalone +$ modprobe videodev +$ insmod stk11xx.ko + +To test the driver with the V4L v1 API (map methode) : + +$ camorama -D --width=640 --height=480 + +To test the driver with the V4L v1 API (read methode) : + +$ camorama -D -R --width=640 --height=480 + +To test the driver with the V4L v2 : + +$ xawtv + +To use mplayer / mencoder : + +$ mplayer tv:// -tv driver=v4l:width=640:height=480 +$ mplayer tv:// -tv driver=v4l2:width=320:height=240:fps=25:outfmt=rgb24:device=/dev/video0 +$ mplayer tv:// -tv driver=v4l2:width=320:height=240:fps=25:outfmt=yuy2:device=/dev/video0 +$ mplayer tv:// -tv driver=v4l2:width=320:height=240:fps=25:outfmt=uyvy:device=/dev/video0 +$ mplayer tv:// -tv driver=v4l2:width=720:height=576:outfmt=yuy2:device=/dev/video0:input=1 + +$ mencoder tv:// -tv driver=v4l:width=640:height=480:outfmt=rgb24:device=/dev/video0 -nosound -ovc lavc -o out.avi +$ mencoder tv:// -tv driver=v4l2:width=320:height=240:fps=25:outfmt=rgb24:device=/dev/video0 -nosound -ovc lavc -o out.avi + +--------------------------------------------------------------------------------------------------- + +7. Debug + + 7.1. 'lsusb' output + + [root@Dahlia driver]$ lsusb + Bus 002 Device 002: ID 046d:c047 Logitech, Inc. + Bus 002 Device 001: ID 0000:0000 + Bus 005 Device 001: ID 0000:0000 + Bus 004 Device 002: ID 0b05:1712 ASUSTek Computer, Inc. + Bus 004 Device 001: ID 0000:0000 + Bus 003 Device 001: ID 0000:0000 + Bus 001 Device 004: ID 174f:a311 <== Our Webcam + Bus 001 Device 001: ID 0000:0000 + + [root@Dahlia driver]$ lsusb -d 174f:a311 -vvv > lsusb.txt + + 7.2. USB logs from Windows + There is 3 USB logs useful : + - Log 1 : when you plug your webcam + - Log 2 : when you run VideoView.exe (with the default settings) + - Log 3 : when you run VideoView.exe, then change the resolution to 1280x1024 + + 7.3. USB logs from Linux + Use the kernel module usbmon (enable option debugfs in the kernel) + + 7.4. Enable module traces + You can enable : CONFIG_STK11XX_DEBUG and CONFIG_STK11XX_DEBUG_STREAM + +--------------------------------------------------------------------------------------------------- + +8. Licence + +The kernel module is distributed under the licence GPL. + diff --git a/doxygen.cfg b/doxygen.cfg new file mode 100644 index 0000000..1bb5847 --- /dev/null +++ b/doxygen.cfg @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Syntek USB Video Camera + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ../doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.h *.c *.txt + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = *.mod.c + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/stk11xx-bayer.c b/stk11xx-bayer.c new file mode 100644 index 0000000..1bbf3b8 --- /dev/null +++ b/stk11xx-bayer.c @@ -0,0 +1,1292 @@ +/** + * @file stk11xx-bayer.c + * @author Martin ROOS + * @date 2006-01-14 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date: $ + * $Revision: $ + * $Author: $ + * $HeadURL: $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "stk11xx.h" + + +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define CLIP(a,low,high) MAX((low),MIN((high),(a))) + + +void stk11xx_b2rgb24(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); +void stk11xx_b2rgb32(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); +void stk11xx_b2bgr24(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); +void stk11xx_b2bgr32(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); + +void stk11xx_b2uyvy(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); +void stk11xx_b2yuyv(uint8_t *, uint8_t *, + struct stk11xx_coord *, struct stk11xx_coord *, + const int, const int, const int); + + +void stk11xx_correct_brightness(uint8_t *, const int, const int, + const int, int, int); + + +static signed short stk11xx_yuv_interp[256][8] = { + {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,-1,0}, + {1,2,0,0,-1,2,-1,0},{1,2,0,0,-1,2,-2,0},{1,3,0,-1,-1,3,-2,0},{2,3,0,-1,-2,3,-2,0}, + {2,4,0,-1,-2,4,-3,0},{2,5,1,-1,-2,4,-3,0},{2,5,1,-1,-3,5,-4,0},{3,6,1,-1,-3,5,-4,0}, + {3,6,1,-2,-3,6,-5,0},{3,7,1,-2,-4,6,-5,-1},{4,7,1,-2,-4,7,-5,-1},{4,8,1,-2,-4,7,-6,-1}, + {4,9,1,-2,-5,8,-6,-1},{5,9,1,-2,-5,8,-7,-1},{5,10,2,-3,-5,9,-7,-1},{5,10,2,-3,-6,9,-7,-1}, + {5,11,2,-3,-6,10,-8,-1},{6,11,2,-3,-6,10,-8,-1},{6,12,2,-3,-7,11,-9,-1},{6,13,2,-3,-7,11,-9,-1}, + {7,13,2,-4,-7,12,-10,-1},{7,14,2,-4,-8,12,-10,-2},{7,14,2,-4,-8,13,-10,-2},{8,15,3,-4,-8,13,-11,-2}, + {8,15,3,-4,-9,14,-11,-2},{8,16,3,-4,-9,14,-12,-2},{8,17,3,-5,-9,15,-12,-2},{9,17,3,-5,-10,15,-12,-2}, + {9,18,3,-5,-10,16,-13,-2},{9,18,3,-5,-10,16,-13,-2},{10,19,3,-5,-11,17,-14,-2},{10,19,3,-5,-11,17,-14,-2}, + {10,20,4,-6,-11,18,-15,-2},{11,20,4,-6,-12,18,-15,-3},{11,21,4,-6,-12,19,-15,-3},{11,22,4,-6,-12,19,-16,-3}, + {11,22,4,-6,-13,20,-16,-3},{12,23,4,-6,-13,20,-17,-3},{12,23,4,-7,-13,21,-17,-3},{12,24,4,-7,-14,21,-18,-3}, + {13,24,5,-7,-14,22,-18,-3},{13,25,5,-7,-14,22,-18,-3},{13,26,5,-7,-15,23,-19,-3},{14,26,5,-7,-15,23,-19,-3}, + {14,27,5,-8,-15,24,-20,-3},{14,27,5,-8,-16,24,-20,-3},{14,28,5,-8,-16,25,-20,-4},{15,28,5,-8,-16,25,-21,-4}, + {15,29,5,-8,-17,26,-21,-4},{15,30,6,-8,-17,26,-22,-4},{16,30,6,-9,-17,27,-22,-4},{16,31,6,-9,-18,27,-23,-4}, + {16,31,6,-9,-18,28,-23,-4},{17,32,6,-9,-18,28,-23,-4},{17,32,6,-9,-19,29,-24,-4},{17,33,6,-9,-19,29,-24,-4}, + {17,34,6,-10,-19,30,-25,-4},{18,34,6,-10,-20,30,-25,-4},{18,35,7,-10,-20,31,-25,-5},{18,35,7,-10,-20,31,-26,-5}, + {19,36,7,-10,-21,32,-26,-5},{19,36,7,-10,-21,32,-27,-5},{19,37,7,-11,-21,33,-27,-5},{20,37,7,-11,-22,33,-28,-5}, + {20,38,7,-11,-22,34,-28,-5},{20,39,7,-11,-22,34,-28,-5},{20,39,7,-11,-23,35,-29,-5},{21,40,8,-11,-23,35,-29,-5}, + {21,40,8,-12,-23,36,-30,-5},{21,41,8,-12,-24,36,-30,-5},{22,41,8,-12,-24,37,-30,-6},{22,42,8,-12,-24,37,-31,-6}, + {22,43,8,-12,-25,38,-31,-6},{23,43,8,-12,-25,38,-32,-6},{23,44,8,-13,-25,39,-32,-6},{23,44,9,-13,-26,39,-33,-6}, + {23,45,9,-13,-26,40,-33,-6},{24,45,9,-13,-26,40,-33,-6},{24,46,9,-13,-27,41,-34,-6},{24,47,9,-14,-27,41,-34,-6}, + {25,47,9,-14,-27,42,-35,-6},{25,48,9,-14,-28,42,-35,-6},{25,48,9,-14,-28,43,-36,-6},{26,49,9,-14,-28,43,-36,-7}, + {26,49,10,-14,-29,44,-36,-7},{26,50,10,-15,-29,44,-37,-7},{26,51,10,-15,-29,45,-37,-7},{27,51,10,-15,-30,45,-38,-7}, + {27,52,10,-15,-30,46,-38,-7},{27,52,10,-15,-30,46,-38,-7},{28,53,10,-15,-31,47,-39,-7},{28,53,10,-16,-31,47,-39,-7}, + {28,54,10,-16,-31,48,-40,-7},{29,54,11,-16,-32,48,-40,-7},{29,55,11,-16,-32,49,-41,-7},{29,56,11,-16,-32,49,-41,-8}, + {29,56,11,-16,-33,50,-41,-8},{30,57,11,-17,-33,50,-42,-8},{30,57,11,-17,-33,51,-42,-8},{30,58,11,-17,-34,51,-43,-8}, + {31,58,11,-17,-34,52,-43,-8},{31,59,11,-17,-34,52,-43,-8},{31,60,12,-17,-35,53,-44,-8},{31,60,12,-18,-35,53,-44,-8}, + {32,61,12,-18,-35,54,-45,-8},{32,61,12,-18,-36,54,-45,-8},{32,62,12,-18,-36,55,-46,-8},{33,62,12,-18,-36,55,-46,-9}, + {33,63,12,-18,-37,56,-46,-9},{33,64,12,-19,-37,56,-47,-9},{34,64,12,-19,-37,57,-47,-9},{34,65,13,-19,-38,57,-48,-9}, + {34,65,13,-19,-38,58,-48,-9},{34,66,13,-19,-38,58,-48,-9},{35,66,13,-19,-39,59,-49,-9},{35,67,13,-20,-39,59,-49,-9}, + {35,68,13,-20,-39,60,-50,-9},{36,68,13,-20,-40,60,-50,-9},{36,69,13,-20,-40,61,-51,-9},{36,69,14,-20,-40,61,-51,-9}, + {37,70,14,-20,-41,62,-51,-10},{37,70,14,-21,-41,62,-52,-10},{37,71,14,-21,-41,63,-52,-10},{37,72,14,-21,-42,63,-53,-10}, + {38,72,14,-21,-42,64,-53,-10},{38,73,14,-21,-42,64,-54,-10},{38,73,14,-21,-43,65,-54,-10},{39,74,14,-22,-43,65,-54,-10}, + {39,74,15,-22,-43,66,-55,-10},{39,75,15,-22,-44,66,-55,-10},{40,75,15,-22,-44,67,-56,-10},{40,76,15,-22,-44,67,-56,-10}, + {40,77,15,-22,-45,68,-56,-11},{40,77,15,-23,-45,68,-57,-11},{41,78,15,-23,-45,69,-57,-11},{41,78,15,-23,-46,69,-58,-11}, + {41,79,15,-23,-46,70,-58,-11},{42,79,16,-23,-46,70,-59,-11},{42,80,16,-23,-47,71,-59,-11},{42,81,16,-24,-47,71,-59,-11}, + {43,81,16,-24,-47,72,-60,-11},{43,82,16,-24,-48,72,-60,-11},{43,82,16,-24,-48,73,-61,-11},{43,83,16,-24,-48,73,-61,-11}, + {44,83,16,-24,-49,74,-61,-12},{44,84,16,-25,-49,74,-62,-12},{44,85,17,-25,-49,75,-62,-12},{45,85,17,-25,-50,75,-63,-12}, + {45,86,17,-25,-50,76,-63,-12},{45,86,17,-25,-50,76,-64,-12},{46,87,17,-25,-51,77,-64,-12},{46,87,17,-26,-51,77,-64,-12}, + {46,88,17,-26,-51,78,-65,-12},{46,89,17,-26,-52,78,-65,-12},{47,89,18,-26,-52,79,-66,-12},{47,90,18,-26,-52,79,-66,-12}, + {47,90,18,-26,-53,80,-66,-13},{48,91,18,-27,-53,80,-67,-13},{48,91,18,-27,-53,81,-67,-13},{48,92,18,-27,-54,81,-68,-13}, + {49,92,18,-27,-54,82,-68,-13},{49,93,18,-27,-54,82,-69,-13},{49,94,18,-28,-54,83,-69,-13},{49,94,19,-28,-55,83,-69,-13}, + {50,95,19,-28,-55,84,-70,-13},{50,95,19,-28,-55,84,-70,-13},{50,96,19,-28,-56,85,-71,-13},{51,96,19,-28,-56,85,-71,-13}, + {51,97,19,-29,-56,86,-72,-13},{51,98,19,-29,-57,86,-72,-14},{52,98,19,-29,-57,87,-72,-14},{52,99,19,-29,-57,87,-73,-14}, + {52,99,20,-29,-58,88,-73,-14},{52,100,20,-29,-58,88,-74,-14},{53,100,20,-30,-58,89,-74,-14},{53,101,20,-30,-59,89,-74,-14}, + {53,102,20,-30,-59,90,-75,-14},{54,102,20,-30,-59,90,-75,-14},{54,103,20,-30,-60,91,-76,-14},{54,103,20,-30,-60,91,-76,-14}, + {55,104,20,-31,-60,92,-77,-14},{55,104,21,-31,-61,92,-77,-15},{55,105,21,-31,-61,93,-77,-15},{55,106,21,-31,-61,93,-78,-15}, + {56,106,21,-31,-62,94,-78,-15},{56,107,21,-31,-62,94,-79,-15},{56,107,21,-32,-62,95,-79,-15},{57,108,21,-32,-63,95,-79,-15}, + {57,108,21,-32,-63,96,-80,-15},{57,109,22,-32,-63,96,-80,-15},{58,109,22,-32,-64,97,-81,-15},{58,110,22,-32,-64,97,-81,-15}, + {58,111,22,-33,-64,98,-82,-15},{58,111,22,-33,-65,98,-82,-16},{59,112,22,-33,-65,99,-82,-16},{59,112,22,-33,-65,99,-83,-16}, + {59,113,22,-33,-66,100,-83,-16},{60,113,22,-33,-66,100,-84,-16},{60,114,23,-34,-66,101,-84,-16},{60,115,23,-34,-67,101,-84,-16}, + {60,115,23,-34,-67,102,-85,-16},{61,116,23,-34,-67,102,-85,-16},{61,116,23,-34,-68,103,-86,-16},{61,117,23,-34,-68,103,-86,-16}, + {62,117,23,-35,-68,104,-87,-16},{62,118,23,-35,-69,104,-87,-16},{62,119,23,-35,-69,105,-87,-17},{63,119,24,-35,-69,105,-88,-17}, + {63,120,24,-35,-70,106,-88,-17},{63,120,24,-35,-70,106,-89,-17},{63,121,24,-36,-70,107,-89,-17},{64,121,24,-36,-71,107,-90,-17}, + {64,122,24,-36,-71,108,-90,-17},{64,123,24,-36,-71,108,-90,-17},{65,123,24,-36,-72,109,-91,-17},{65,124,24,-36,-72,109,-91,-17}, + {65,124,25,-37,-72,110,-92,-17},{66,125,25,-37,-73,110,-92,-17},{66,125,25,-37,-73,111,-92,-18},{66,126,25,-37,-73,111,-93,-18}, + {66,127,25,-37,-74,112,-93,-18},{67,127,25,-37,-74,112,-94,-18},{67,128,25,-38,-74,113,-94,-18},{67,128,25,-38,-75,113,-95,-18}, + {68,129,25,-38,-75,114,-95,-18},{68,129,26,-38,-75,114,-95,-18},{68,130,26,-38,-76,115,-96,-18},{69,130,26,-38,-76,115,-96,-18}, + {69,131,26,-39,-76,116,-97,-18},{69,132,26,-39,-77,116,-97,-18},{69,132,26,-39,-77,117,-97,-19},{70,133,26,-39,-77,117,-98,-19}, + {70,133,26,-39,-78,118,-98,-19},{70,134,27,-39,-78,118,-99,-19},{71,134,27,-40,-78,119,-99,-19},{71,135,27,-40,-79,119,-100,-19}, + {71,136,27,-40,-79,120,-100,-19},{72,136,27,-40,-79,120,-100,-19},{72,137,27,-40,-80,121,-101,-19},{72,137,27,-40,-80,121,-101,-19}, + {72,138,27,-41,-80,122,-102,-19},{73,138,27,-41,-81,122,-102,-19},{73,139,28,-41,-81,123,-103,-19},{73,140,28,-41,-81,123,-103,-20}, + {74,140,28,-41,-82,124,-103,-20},{74,141,28,-42,-82,124,-104,-20},{74,141,28,-42,-82,125,-104,-20},{75,142,28,-42,-83,125,-105,-20}, + {75,142,28,-42,-83,126,-105,-20},{75,143,28,-42,-83,126,-105,-20},{75,144,28,-42,-84,127,-106,-20},{76,144,29,-43,-84,127,-106,-20} +}; + + +/** + * @brief Decompress a frame + * + * This function permits to decompress a frame from the video stream. + * + * @param dev Device structure + * + * @returns 0 if all is OK + */ +int stk11xx_decompress(struct usb_stk11xx *dev) +{ + int factor; + + void *data; + void *image; + struct stk11xx_frame_buf *framebuf; + + if (dev == NULL) + return -EFAULT; + + framebuf = dev->read_frame; + + if (framebuf == NULL) + return -EFAULT; + + image = dev->image_data; + image += dev->images[dev->fill_image].offset; + + data = framebuf->data; + + switch (dev->resolution) { + case STK11XX_80x60: + factor = 8; + break; + + case STK11XX_128x96: + factor = 5; + break; + + case STK11XX_160x120: + factor = 4; + break; + + case STK11XX_213x160: + factor = 3; + break; + + case STK11XX_320x240: + factor = 2; + break; + + case STK11XX_640x480: + factor = 1; + break; + + case STK11XX_720x576: + case STK11XX_800x600: + factor = 2; + break; + + case STK11XX_1024x768: + factor = 2; + break; + + case STK11XX_1280x1024: + factor = 1; + break; + + default: + return -EFAULT; + } + + + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_RGB24: + stk11xx_b2rgb24(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + + case STK11XX_PALETTE_RGB32: + stk11xx_b2rgb32(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + + case STK11XX_PALETTE_BGR24: + stk11xx_b2bgr24(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + + case STK11XX_PALETTE_BGR32: + stk11xx_b2bgr32(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + + case STK11XX_PALETTE_UYVY: + stk11xx_b2uyvy(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + + case STK11XX_PALETTE_YUYV: + stk11xx_b2yuyv(data, image, &dev->image, &dev->view, + dev->vsettings.hflip, dev->vsettings.vflip, factor); + break; + } + + stk11xx_correct_brightness(image, dev->view.x, dev->view.y, + dev->vsettings.brightness, dev->vsettings.palette, dev->vsettings.depth); + + return 0; +} + + +/** + * @brief Correct the brightness of an image. + * + * This function permits to correct the brightness of an image. + * + * @param img Buffer to RGB/YUV data + * @param width Width of frame + * @param height Height of frame + * @param brightness Brightness correction + * @param depth Color depth + * + * @retval rgb Buffer to RGB/YUV data + */ +void stk11xx_correct_brightness(uint8_t *img, const int width, const int height, + const int brightness, int palette, int depth) +{ + int i; + int x; + + + switch (palette) { + case STK11XX_PALETTE_RGB24: + case STK11XX_PALETTE_BGR24: + case STK11XX_PALETTE_RGB32: + case STK11XX_PALETTE_BGR32: + depth = (depth == 24) ? 3 : 4; + + if (brightness >= 32767) { + x = (brightness - 32767) / 256; + + for (i = 0; i < (width * height * depth); i++) { + if ((*(img + i) + (unsigned char) x) > 255) + *(img + i) = 255; + else + *(img + i) += (unsigned char) x; + } + } + else { + x = (32767 - brightness) / 256; + + for (i = 0; i < (width * height * depth); i++) { + if ((unsigned char) x > *(img + i)) + *(img + i) = 0; + else + *(img + i) -= (unsigned char) x; + } + } + + break; + + case STK11XX_PALETTE_UYVY: + depth = 2; + + if (brightness >= 32767) { + x = (brightness - 32767) / 256; + + for (i = 1; i < (width * height * depth); i=i+depth) { + if ((*(img + i) + (unsigned char) x) > 255) + *(img + i) = 255; + else + *(img + i) += (unsigned char) x; + } + } + else { + x = (32767 - brightness) / 256; + + for (i = 1; i < (width * height * depth); i=i+depth) { + if ((unsigned char) x > *(img + i)) + *(img + i) = 0; + else + *(img + i) -= (unsigned char) x; + } + } + + break; + + case STK11XX_PALETTE_YUYV: + depth = 2; + + if (brightness >= 32767) { + x = (brightness - 32767) / 256; + + for (i = 0; i < (width * height * depth); i=i+depth) { + if ((*(img + i) + (unsigned char) x) > 255) + *(img + i) = 255; + else + *(img + i) += (unsigned char) x; + } + } + else { + x = (32767 - brightness) / 256; + + for (i = 0; i < (width * height * depth); i=i+depth) { + if ((unsigned char) x > *(img + i)) + *(img + i) = 0; + else + *(img + i) -= (unsigned char) x; + } + } + + break; + } +} + + +/** + * @brief This function permits to convert an image from bayer to RGB24 + * + * @param bayer Buffer with the bayer data + * @param image Size of image + * @param view Size of view + * @param hflip Horizontal flip + * @param vflip Vertical flip + * @param factor Factor of redimensioning + * + * @retval rgb Buffer with the RGB data + */ +void stk11xx_b2rgb24(uint8_t *bayer, uint8_t *rgb, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int factor) { + uint8_t *b; + + int x, y; // Position in bayer image + int i, j; // Position in rgb image + + int width = image->x; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + + // Skip the first line + bayer += width; + + // To center vertically the image in the view + rgb += ((view->y - nheight) / 2) * view->x * 3; + + // To center horizontally the image in the view + rgb += ((view->x - nwidth) / 2) * 3; + + // Clean the first line + memset(rgb, 0, nwidth * 3); + rgb += nwidth * 3; + + + // For each rgb line without the borders (first and last line) + for (j=0, y=starty; jx - nwidth) * 3; + + if (y & 0x1) { + // Skip the first pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *rgb++ = *b; + } + else { + *rgb++ = (*(b-width) + *(b+width)) >> 1; + *rgb++ = *b; + *rgb++ = (*(b-1) + *(b+1)) >> 1; + } + + b += stepx; + } + + // Skip the last pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + } + else { + // Skip the first pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + *rgb++ = *b; + *rgb++ = (*(b-width) + *(b+width)) >> 1; + } + else { + *rgb++ = *b; + *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + } + + b += stepx; + } + + // Skip the last pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + } + } + + // Clean the last line + memset(rgb, 0, nwidth * 3); +} + + +/** + * @brief This function permits to convert an image from bayer to RGB32 + * + * @param bayer Buffer with the bayer data + * @param image Size of image + * @param view Size of view + * @param hflip Horizontal flip + * @param vflip Vertical flip + * @param factor Factor of redimensioning + * + * @retval rgb Buffer with the RGB data + */ +void stk11xx_b2rgb32(uint8_t *bayer, uint8_t *rgb, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int factor) { + uint8_t *b; + + int x, y; // Position in bayer image + int i, j; // Position in rgb image + + int width = image->x; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + + // Skip the first line + bayer += width; + + // To center vertically the image in the view + rgb += ((view->y - nheight) / 2) * view->x * 4; + + // To center horizontally the image in the view + rgb += ((view->x - nwidth) / 2) * 4; + + // Clean the first line + memset(rgb, 0, nwidth * 4); + rgb += nwidth * 4; + + + // For each rgb line without the borders (first and last line) + for (j=0, y=starty; jx - nwidth) * 4; + + if (y & 0x1) { + // Skip the first pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *rgb++ = *b; + *rgb++ = 0; + } + else { + *rgb++ = (*(b-width) + *(b+width)) >> 1; + *rgb++ = *b; + *rgb++ = (*(b-1) + *(b+1)) >> 1; + *rgb++ = 0; + } + + b += stepx; + } + + // Skip the last pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + } + else { + // Skip the first pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + *rgb++ = *b; + *rgb++ = (*(b-width) + *(b+width)) >> 1; + *rgb++ = 0; + } + else { + *rgb++ = *b; + *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + *rgb++ = 0; + } + + b += stepx; + } + + // Skip the last pixel + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + *rgb++ = 0; + } + } + + // Clean the last line + memset(rgb, 0, nwidth * 4); +} + + +/** + * @brief This function permits to convert an image from bayer to BGR24 + * + * @param bayer Buffer with the bayer data + * @param image Size of image + * @param view Size of view + * @param hflip Horizontal flip + * @param vflip Vertical flip + * @param factor Factor of redimensioning + * + * @retval bgr Buffer with the BGR data + */ +void stk11xx_b2bgr24(uint8_t *bayer, uint8_t *bgr, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int factor) { + uint8_t *b; + + int x, y; // Position in bayer image + int i, j; // Position in bgr image + + int width = image->x; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + + // Skip the first line + bayer += width; + + // To center vertically the image in the view + bgr += ((view->y - nheight) / 2) * view->x * 3; + + // To center horizontally the image in the view + bgr += ((view->x - nwidth) / 2) * 3; + + // Clean the first line + memset(bgr, 0, nwidth * 3); + bgr += nwidth * 3; + + + // For each bgr line without the borders (first and last line) + for (j=0, y=starty; jx - nwidth) * 3; + + if (y & 0x1) { + // Skip the first pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + } + else { + *bgr++ = (*(b-1) + *(b+1)) >> 1; + *bgr++ = *b; + *bgr++ = (*(b-width) + *(b+width)) >> 1; + } + + b += stepx; + } + + // Skip the last pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + } + else { + // Skip the first pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + *bgr++ = *b; + *bgr++ = (*(b-1) + *(b+1)) >> 1; + } + else { + *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *bgr++ = *b; + } + + b += stepx; + } + + // Skip the last pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + } + } + + // Clean the last line + memset(bgr, 0, nwidth * 3); +} + + +/** + * @brief This function permits to convert an image from bayer to BGR32 + * + * @param bayer Buffer with the bayer data + * @param image Size of image + * @param view Size of view + * @param hflip Horizontal flip + * @param vflip Vertical flip + * @param factor Factor of redimensioning + * + * @retval bgr Buffer with the BGR data + */ +void stk11xx_b2bgr32(uint8_t *bayer, uint8_t *bgr, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int factor) { + uint8_t *b; + + int x, y; // Position in bayer image + int i, j; // Position in bgr image + + int width = image->x; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + + // Skip the first line + bayer += width; + + // To center vertically the image in the view + bgr += ((view->y - nheight) / 2) * view->x * 4; + + // To center horizontally the image in the view + bgr += ((view->x - nwidth) / 2) * 4; + + // Clean the first line + memset(bgr, 0, nwidth * 4); + bgr += nwidth * 4; + + + // For each bgr line without the borders (first and last line) + for (j=0, y=starty; jx - nwidth) * 4; + + if (y & 0x1) { + // Skip the first pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + *bgr++ = 0; + } + else { + *bgr++ = (*(b-1) + *(b+1)) >> 1; + *bgr++ = *b; + *bgr++ = (*(b-width) + *(b+width)) >> 1; + *bgr++ = 0; + } + + b += stepx; + } + + // Skip the last pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + } + else { + // Skip the first pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + *bgr++ = *b; + *bgr++ = (*(b-1) + *(b+1)) >> 1; + *bgr++ = 0; + } + else { + *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + *bgr++ = *b; + *bgr++ = 0; + } + + b += stepx; + } + + // Skip the last pixel + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + *bgr++ = 0; + } + } + + // Clean the last line + memset(bgr, 0, nwidth * 4); +} + + +/** + * @brief This function permits to convert an image from bayer to YUV (UYVY) + * + * @param bayer Buffer with the bayer data + * @param image Size of image + * @param view Size of view + * @param hflip Horizontal flip + * @param vflip Vertical flip + * @param factor Factor of redimensioning + * + * @retval yuv Buffer with the YUV data + */ +void stk11xx_b2uyvy(uint8_t *bayer, uint8_t *yuv, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int factor) { + uint8_t *b; + + int x, y; // Position in bayer image + int i, j; // Position in yuv image + + int pR, pG, pB; + int pY, pU, pV; + + int width = image->x; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + // Background color... + memset(yuv, 16, width * 2); + for (i=0; iy - nheight) / 2) * view->x * 2; + + // To center horizontally the image in the view + yuv += ((view->x - nwidth) / 2) * 2; + + // Clean the first line + memset(yuv, 16, nwidth * 2); + for (i=0; ix - nwidth) * 2; + + if (y & 0x1) { + // Skip the first pixel + *yuv++ = 128; + *yuv++ = 16; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + pB = *b; + } + else { + pR = (*(b-width) + *(b+width)) >> 1; + pG = *b; + pB = (*(b-1) + *(b+1)) >> 1; + } + + pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2]; + pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5]; + pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7]; + + pY = CLIP(pY, 0,255); + pU = CLIP(pU, -127,127); + pV = CLIP(pV, -127,127); + + if (i % 2){ + *yuv++ = (112 * pU)/127 + 128; // U + *yuv++ = (219 * pY)/255 + 16; // Y + } + else { + *yuv++ = (112 * pV)/127 + 128; // V + *yuv++ = (219 * pY)/255 + 16; // Y + } + + b += stepx; + } + + // Skip the last pixel + *yuv++ = 128; + *yuv++ = 16; + } + else { + // Skip the first pixel + *yuv++ = 128; + *yuv++ = 16; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + pG = *b; + pB = (*(b-width) + *(b+width)) >> 1; + } + else { + pR = *b; + pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + } + + pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2]; + pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5]; + pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7]; + + pY = CLIP(pY, 0,255); + pU = CLIP(pU, -127,127); + pV = CLIP(pV, -127,127); + + if (i % 2){ + *yuv++ = (112 * pU)/127 + 128; // U + *yuv++ = (219 * pY)/255 + 16; // Y + } + else { + *yuv++ = (112 * pV)/127 + 128; // V + *yuv++ = (219 * pY)/255 + 16; // Y + } + + b += stepx; + } + + // Skip the last pixel + *yuv++ = 128; + *yuv++ = 16; + } + } + + // Clean the last line + memset(yuv, 16, nwidth * 2); + for (i=0; ix; + int height = image->y; + + int nwidth = width / factor; + int nheight = height / factor; + + int offset; + int startx, stepx; + int starty, stepy; + + + // Calculate the initial position (on Y axis) + if (vflip) { + starty = height - 2; + stepy = -factor; + } + else { + starty = 0; + stepy = factor; + } + + // Calculate the initial position (on X axis) + if (hflip) { + startx = width - 1; + stepx = -factor; + offset = width - 2; + } + else { + startx = 0; + stepx = factor; + offset = 1; + } + + // Background color... + memset(yuv, 128, width * 2); + for (i=0; iy - nheight) / 2) * view->x * 2; + + // To center horizontally the image in the view + yuv += ((view->x - nwidth) / 2) * 2; + + // Clean the first line + memset(yuv, 128, nwidth * 2); + for (i=0; ix - nwidth) * 2; + + if (y & 0x1) { + // Skip the first pixel + *yuv++ = 16; + *yuv++ = 128; + + // GBGBGB : Line process... + for (i=0, x=startx; i> 2; + pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + pB = *b; + } + else { + pR = (*(b-width) + *(b+width)) >> 1; + pG = *b; + pB = (*(b-1) + *(b+1)) >> 1; + } + + pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2]; + pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5]; + pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7]; + + pY = CLIP(pY, 0,255); + pU = CLIP(pU, -127,127); + pV = CLIP(pV, -127,127); + + if (i % 2){ + *yuv++ = (219 * pY)/255 + 16; // Y + *yuv++ = (112 * pU)/127 + 128; // U + } + else { + *yuv++ = (219 * pY)/255 + 16; // Y + *yuv++ = (112 * pV)/127 + 128; // V + } + + b += stepx; + } + + // Skip the last pixel + *yuv++ = 16; + *yuv++ = 128; + } + else { + // Skip the first pixel + *yuv++ = 16; + *yuv++ = 128; + + // RGRGRG : Line process... + for (i=0, x=startx; i> 1; + pG = *b; + pB = (*(b-width) + *(b+width)) >> 1; + } + else { + pR = *b; + pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2; + pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2; + } + + pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2]; + pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5]; + pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7]; + + pY = CLIP(pY, 0,255); + pU = CLIP(pU, -127,127); + pV = CLIP(pV, -127,127); + + if (i % 2){ + *yuv++ = (219 * pY)/255 + 16; // Y + *yuv++ = (112 * pU)/127 + 128; // U + } + else { + *yuv++ = (219 * pY)/255 + 16; // Y + *yuv++ = (112 * pV)/127 + 128; // V + } + + b += stepx; + } + + // Skip the last pixel + *yuv++ = 16; + *yuv++ = 128; + } + } + + // Clean the last line + memset(yuv, 128, nwidth * 2); + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" + + +/** + * @var default_nbrframebuf + * Number of frame buffer by default + */ +static int default_nbrframebuf = 3; + + +/** + * @param size Size of memory + * + * @returns Address on the allocated memory + * + * @brief Allocate a buffer. + * + * This function permits to allocate a buffer in memory. + */ +void * stk11xx_rvmalloc(unsigned long size) +{ + void *mem; + unsigned long addr; + + size = PAGE_ALIGN(size); + mem = vmalloc_32(size); + + if (!mem) + return NULL; + + memset(mem, 0, size); + + addr = (unsigned long) mem; + + while (size > 0) { + SetPageReserved(vmalloc_to_page((void *) addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return mem; +} + + +/** + * @param mem Memory address + * @param size Size of allocated memory + * + * @brief Free a buffer + * + * This function permits to free a buffer. + */ +void stk11xx_rvfree(void *mem, unsigned long size) +{ + unsigned long addr; + + if (!mem) + return; + + addr = (unsigned long) mem; + + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *) addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + vfree(mem); +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Allocate all ISOC buffers. + * + * This function permits to reserved the memory for each ISOC buffer. + */ +int stk11xx_allocate_buffers(struct usb_stk11xx *dev) +{ + int i; + void *kbuf; + + STK_DEBUG("Allocate video buffers\n"); + + if (dev == NULL) + return -ENXIO; + + // Allocate isochronous pipe buffers + for (i=0; iisobuf[i].data == NULL) { + kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL); + + if (kbuf == NULL) { + STK_ERROR("Failed to allocate iso buffer %d\n", i); + return -ENOMEM; + } + + STK_DEBUG("Allocated iso buffer at %p\n", kbuf); + + dev->isobuf[i].data = kbuf; + } + } + + // Allocate frame buffer structure + if (dev->framebuf == NULL) { + kbuf = kzalloc(default_nbrframebuf * sizeof(struct stk11xx_frame_buf), GFP_KERNEL); + + if (kbuf == NULL) { + STK_ERROR("Failed to allocate frame buffer structure\n"); + return -ENOMEM; + } + + STK_DEBUG("Allocated frame buffer structure at %p\n", kbuf); + + dev->framebuf = kbuf; + } + + // Create frame buffers and make circular ring + for (i=0; iframebuf[i].data == NULL) { + kbuf = vmalloc(STK11XX_FRAME_SIZE); + + if (kbuf == NULL) { + STK_ERROR("Failed to allocate frame buffer %d\n", i); + return -ENOMEM; + } + + STK_DEBUG("Allocated frame buffer %d at %p.\n", i, kbuf); + + dev->framebuf[i].data = kbuf; + memset(kbuf, 0, STK11XX_FRAME_SIZE); + } + } + + // Allocate image buffer; double buffer for mmap() + kbuf = stk11xx_rvmalloc(dev->nbuffers * dev->len_per_image); + + if (kbuf == NULL) { + STK_ERROR("Failed to allocate image buffer(s). needed (%d)\n", + dev->nbuffers * dev->len_per_image); + return -ENOMEM; + } + + STK_DEBUG("Allocated image buffer at %p\n", kbuf); + + dev->image_data = kbuf; + + for (i = 0; i < dev->nbuffers; i++) { + dev->images[i].offset = i * dev->len_per_image; + dev->images[i].vma_use_count = 0; + } + + for (; i < STK11XX_MAX_IMAGES; i++) + dev->images[i].offset = 0; + + kbuf = NULL; + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reset all ISOC buffers. + * + * This function permits to reset all ISOC buffers. + */ +int stk11xx_reset_buffers(struct usb_stk11xx *dev) +{ + int i; + unsigned long flags; + + STK_DEBUG("Reset all buffers\n"); + + spin_lock_irqsave(&dev->spinlock, flags); + + dev->full_frames = NULL; + dev->full_frames_tail = NULL; + + for (i=0; inbuffers; i++) { + dev->framebuf[i].filled = 0; + dev->framebuf[i].errors = 0; + + if (i > 0) + dev->framebuf[i].next = &dev->framebuf[i - 1]; + else + dev->framebuf->next = NULL; + } + + dev->empty_frames = &dev->framebuf[dev->nbuffers - 1]; + dev->empty_frames_tail = dev->framebuf; + dev->read_frame = NULL; + dev->fill_frame = dev->empty_frames; + dev->empty_frames = dev->empty_frames->next; + + dev->image_read_pos = 0; + dev->fill_image = 0; + + spin_unlock_irqrestore(&dev->spinlock, flags); + + for (i=0; inbuffers; i++) + dev->image_used[i] = 0; + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Clear current buffers. + * + * This function permits to clear the memory. + */ +int stk11xx_clear_buffers(struct usb_stk11xx *dev) +{ + memset(dev->image_data, 0x00, dev->nbuffers * dev->len_per_image); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Release all buffers. + * + * This function permits to release and free the memory for each ISOC buffer. + */ +int stk11xx_free_buffers(struct usb_stk11xx *dev) +{ + int i; + + STK_DEBUG("Free buffers\n"); + + if (dev == NULL) + return -1; + + // Release iso pipe buffers + for (i=0; iisobuf[i].data != NULL) { + kfree(dev->isobuf[i].data); + dev->isobuf[i].data = NULL; + } + } + + // Release frame buffers + if (dev->framebuf != NULL) { + for (i=0; iframebuf[i].data != NULL) { + vfree(dev->framebuf[i].data); + dev->framebuf[i].data = NULL; + } + } + + kfree(dev->framebuf); + dev->framebuf = NULL; + } + + // Release image buffers + if (dev->image_data != NULL) + stk11xx_rvfree(dev->image_data, dev->nbuffers * dev->len_per_image); + + dev->image_data = NULL; + + return 0; +} + + +/** + * @param dev Device structure + * + * @brief Prepare the next image. + * + * This function is called when an image is ready, so as to prepare the next image. + */ +void stk11xx_next_image(struct usb_stk11xx *dev) +{ + STK_STREAM("Select next image\n"); + + dev->image_used[dev->fill_image] = 0; + dev->fill_image = (dev->fill_image + 1) % dev->nbuffers; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Prepare the next frame. + * + * This function is called when a frame is ready, so as to prepare the next frame. + */ +int stk11xx_next_frame(struct usb_stk11xx *dev) +{ + int ret = 0; + unsigned long flags; + + STK_STREAM("Select next frame\n"); + + spin_lock_irqsave(&dev->spinlock, flags); + + if (dev->fill_frame != NULL) { + if (dev->full_frames == NULL) { + dev->full_frames = dev->fill_frame; + dev->full_frames_tail = dev->full_frames; + } + else { + dev->full_frames_tail->next = dev->fill_frame; + dev->full_frames_tail = dev->fill_frame; + } + } + + if (dev->empty_frames != NULL) { + dev->fill_frame = dev->empty_frames; + dev->empty_frames = dev->empty_frames->next; + } + else { + if (dev->full_frames == NULL) { + STK_ERROR("Neither empty or full frames available!\n"); + spin_unlock_irqrestore(&dev->spinlock, flags); + return -EINVAL; + } + + dev->fill_frame = dev->full_frames; + dev->full_frames = dev->full_frames->next; + + ret = 1; + } + + dev->fill_frame->next = NULL; + + spin_unlock_irqrestore(&dev->spinlock, flags); + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Handler frame + * + * This function gets called for the isochronous pipe. This function is only called + * when a frame is ready. So we have to be fast to decompress the data. + */ +int stk11xx_handle_frame(struct usb_stk11xx *dev) +{ + int ret = 0; + unsigned long flags; + + STK_STREAM("Sync Handle Frame\n"); + + spin_lock_irqsave(&dev->spinlock, flags); + + if (dev->read_frame != NULL) { + spin_unlock_irqrestore(&dev->spinlock, flags); + return ret; + } + + if (dev->full_frames == NULL) { + } + else { + dev->read_frame = dev->full_frames; + dev->full_frames = dev->full_frames->next; + dev->read_frame->next = NULL; + } + + if (dev->read_frame != NULL) { + spin_unlock_irqrestore(&dev->spinlock, flags); + ret = dev_stk11xx_decompress(dev); + spin_lock_irqsave(&dev->spinlock, flags); + + if (dev->empty_frames == NULL) { + dev->empty_frames = dev->read_frame; + dev->empty_frames_tail = dev->empty_frames; + } + else { + dev->empty_frames_tail->next = dev->read_frame; + dev->empty_frames_tail = dev->read_frame; + } + + dev->read_frame = NULL; + } + + spin_unlock_irqrestore(&dev->spinlock, flags); + + dev_stk11xx_watchdog_camera(dev); + + return ret; +} + diff --git a/stk11xx-dev-0408.c b/stk11xx-dev-0408.c new file mode 100644 index 0000000..2e547f0 --- /dev/null +++ b/stk11xx-dev-0408.c @@ -0,0 +1,1173 @@ +/** + * @file stk11xx-dev-0408.c + * @author Ivor Hewitt + * @date 2009-01-01 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * Copyright (C) Ivor Hewitt + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +/* + * note currently only supporting 720x576, 704x576 and 640x480 PAL + * other resolutions should work but aren't + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23) +#include +#endif + +#include "stk11xx.h" +#include "stk11xx-dev.h" + +int dev_stk0408_check_device(struct usb_stk11xx *dev); +int dev_stk0408_select_input(struct usb_stk11xx *dev, int input); +int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val); + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk0408_initialize_device(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Capture device\n"); + +//what is all this writing to register 2 doing? + usb_stk11xx_write_registry(dev, 0x0002, 0x0000); + usb_stk11xx_write_registry(dev, 0x0000, 0x0000); + usb_stk11xx_write_registry(dev, 0x0002, 0x0000); + usb_stk11xx_write_registry(dev, 0x0003, 0x0000); + usb_stk11xx_write_registry(dev, 0x0002, 0x0007); + + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + dev_stk0408_write0(dev, 7, 4); + dev_stk0408_write0(dev, 7, 4); + dev_stk0408_write0(dev, 7, 6); + dev_stk0408_write0(dev, 7, 7); + dev_stk0408_write0(dev, 7, 6); + dev_stk0408_write0(dev, 7, 4); + dev_stk0408_write0(dev, 7, 5); + + for (i=0;i<7;i++) + { + dev_stk0408_write0(dev, 7, 4); + dev_stk0408_write0(dev, 7, 4); + dev_stk0408_write0(dev, 7, 5); + } + +/* start set */ + usb_stk11xx_write_registry(dev, 0x0002, 0x0007); + usb_stk11xx_write_registry(dev, 0x0000, 0x0001); + + dev_stk0408_configure_device(dev,1); + dev_stk0408_configure_device(dev,2); + + usb_stk11xx_write_registry(dev, 0x0500, 0x0094); + msleep(10); + + dev_stk0408_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0000); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + usb_stk11xx_read_registry(dev, 0x0003, &value); + usb_stk11xx_write_registry(dev, 0x0003, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0002, &value); //78? + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + + usb_stk11xx_read_registry(dev, 0x0002, &value); //7f? + usb_stk11xx_read_registry(dev, 0x0000, &value); //0? + + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x007); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x007); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x007); + dev_stk0408_write0(dev, 0x07f, 0x006); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x004); + dev_stk0408_write0(dev, 0x07f, 0x005); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0001); + + retok = dev_stk11xx_check_device(dev, 500); + + usb_stk11xx_set_feature(dev, 1); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Capture device is ready\n"); + + return 0; +} + +int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val) +{ + int value; + + usb_stk11xx_write_registry(dev, 0x0002, mask); + usb_stk11xx_write_registry(dev, 0x0000, val); + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + return 0; +} + +int dev_stk0408_write_208(struct usb_stk11xx *dev, int val) +{ + int value; + int retok; + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0208, val); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + + retok = dev_stk0408_check_device(dev); + + if (retok != 1) { + return -1; + } + + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + return 1; +} + +int dev_stk0408_write_saa(struct usb_stk11xx *dev, int reg, int val) +{ + int value; + int retok; + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0204, reg); + usb_stk11xx_write_registry(dev, 0x0205, val); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + + retok = dev_stk0408_check_device(dev); + + if (retok != 1) { + return -1; + } + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + return 1; +} + +int dev_stk0408_set_resolution(struct usb_stk11xx *dev) +{ +/* + * These registers control the resolution of the capture buffer. + * + * xres = (X - xsub) / 2 + * yres = (Y - ysub) + * + */ + int x,y,xsub,ysub; + + // RRK, need to return for NTSC ? + if (dev->vsettings.norm == 0) + return 0; + + switch (stk11xx_image_sizes[dev->resolution].x) + { + case 720: + x = 0x5a0; + xsub = 0; + break; + + case 704: + case 352: + case 176: + x = 0x584; + xsub = 4; + break; + + case 640: + case 320: + case 160: + x = 0x508; + xsub = 0x08; + break; + + default: + return -1; + } + + switch (stk11xx_image_sizes[dev->resolution].y) + { + case 576: + case 288: + case 144: + y = 0x121; + ysub = 0x1; + break; + + case 480: + y = 0x110; + ysub= 0x20; + break; + + case 120: + case 240: + y = 0x103; + ysub = 0x13; + break; + + default: + return -1; + } + + usb_stk11xx_write_registry(dev, 0x0110, xsub ); // xsub + usb_stk11xx_write_registry(dev, 0x0111, 0 ); + usb_stk11xx_write_registry(dev, 0x0112, ysub ); // ysub + usb_stk11xx_write_registry(dev, 0x0113, 0 ); + usb_stk11xx_write_registry(dev, 0x0114, x ); // X + usb_stk11xx_write_registry(dev, 0x0115, 5 ); + usb_stk11xx_write_registry(dev, 0x0116, y ); // Y + usb_stk11xx_write_registry(dev, 0x0117, 1 ); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-6] + * + * @returns 0 if all is OK + * + * @brief This function configures the device. + * + * This is called multiple times through intitialisation and configuration + * there appear to be six distinct steps + * + */ +int dev_stk0408_configure_device(struct usb_stk11xx *dev, int step) +{ + int value; + int asize; + int i; + + + static const int ids[] = { + 0x203,0x00d,0x00f,0x103,0x018,0x01b,0x01c,0x01a,0x019, + 0x300,0x350,0x351,0x352,0x353,0x300,0x018,0x202,0x110, + 0x111,0x112,0x113,0x114,0x115,0x116,0x117 + }; + + const int values[] = { + 0x04a,0x000,0x002,0x000,0x000,0x00e,0x046,0x014,0x000, + 0x012,0x02d,0x001,0x000,0x000,0x080,0x010,0x00f, + (dev->vsettings.norm ? 0x008 : 0x038), + 0x000, + (dev->vsettings.norm ? 0x013 : 0x003), + 0x000, + (dev->vsettings.norm ? 0x008 : 0x038), + 0x005, + (dev->vsettings.norm ? 0x003 : 0x0f3), + (dev->vsettings.norm ? 0x001 : 0x000) + }; + + if (step != 1) + { + usb_stk11xx_read_registry(dev, 0x0003, &value); + usb_stk11xx_read_registry(dev, 0x0001, &value); + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_read_registry(dev, 0x0003, &value); + usb_stk11xx_read_registry(dev, 0x0001, &value); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0000); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0001, 0x0003); + + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0030); + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + } + + asize = ARRAY_SIZE(values); + + for(i=0; iresolution == STK11XX_320x240)|| + (dev->resolution == STK11XX_352x288)) + { + usb_stk11xx_write_registry(dev, 0x0104, 0x0000); + usb_stk11xx_write_registry(dev, 0x0105, 0x0000); + } */ + + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + + dev_stk0408_write_saa(dev, 0x02, 0x80); + dev_stk0408_write_208(dev,0x09); + dev_stk0408_write_saa(dev, 0x09, 0x00); + + break; + } + + if (step == 3) + { + dev_stk0408_write_saa(dev, 0x02, 0x80); + dev_stk0408_write_208(dev,0x09); + dev_stk0408_write_saa(dev, 0x09, 0x00); + + //test and set? + usb_stk11xx_write_registry(dev, 0x0504, 0x0012); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0012); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0080); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x0010); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0010); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0000); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x000e); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x000e); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0000); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x0016); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0016); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0000); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x001a); + usb_stk11xx_write_registry(dev, 0x0502, 0x0004); + usb_stk11xx_write_registry(dev, 0x0503, 0x0004); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0080); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0080); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + dev_stk0408_write_saa(dev, 0x02, 0x80); + dev_stk0408_write_208(dev,0x09); + dev_stk0408_write_saa(dev, 0x09, 0x00); + + } + + if ((step == 4 )|| (step == 6)) + { + dev_stk0408_write_saa(dev, 0x02, 0x80); + dev_stk0408_write_208(dev,0x09); + dev_stk0408_write_saa(dev, 0x09, 0x00); + dev_stk0408_write_208(dev,0x0e); + dev_stk0408_write_saa(dev, 0x0e, 0x01); + + dev_stk0408_set_resolution(dev); + + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + dev_stk0408_set_camera_quality(dev); + } + + if (step == 6) + { + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + + dev_stk0408_write_208(dev,0x0e); + dev_stk0408_write_saa(dev, 0x0e, 0x01); + + dev_stk0408_set_resolution( dev); + + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + + dev_stk0408_select_input(dev, dev->vsettings.input); + + dev_stk0408_start_stream(dev); + + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0080); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0080); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x0002); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0000); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0500, 0x008b); + usb_stk11xx_write_registry(dev, 0x0504, 0x001c); + usb_stk11xx_write_registry(dev, 0x0502, 0x0000); + usb_stk11xx_write_registry(dev, 0x0503, 0x0000); + usb_stk11xx_write_registry(dev, 0x0500, 0x008c); + + dev_stk0408_start_stream(dev); + + } + + if (step==4) + { + dev_stk11xx_camera_on(dev); + } + + return 0; +} + + +int dev_stk0408_select_input(struct usb_stk11xx *dev, int input) +{ + switch (input) + { + case 1: + usb_stk11xx_write_registry(dev, 0x0000, 0x0098); + break; + case 2: + usb_stk11xx_write_registry(dev, 0x0000, 0x0090); + break; + case 3: + usb_stk11xx_write_registry(dev, 0x0000, 0x0088); + break; + case 4: + usb_stk11xx_write_registry(dev, 0x0000, 0x0080); + break; + } + usb_stk11xx_write_registry(dev, 0x0002, 0x0093); + + return 0; + +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk0408_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + int value0; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + + value = value & 0x7f; + usb_stk11xx_write_registry(dev, 0x0100, value); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0002, &value); + usb_stk11xx_read_registry(dev, 0x0000, &value0); + usb_stk11xx_write_registry(dev, 0x0002, value); + usb_stk11xx_read_registry(dev, 0x0000, &value0); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk0408_init_camera(struct usb_stk11xx *dev) +{ + dev_stk0408_camera_asleep(dev); + + dev_stk0408_configure_device(dev, 3); + dev_stk0408_configure_device(dev, 4); + dev_stk0408_configure_device(dev, 5); + + dev_stk0408_configure_device(dev, 6); + + return 0; +} + +int dev_stk0408_check_device(struct usb_stk11xx *dev) +{ + int i; + int value; + const int retry=2; + + for (i=0; i < retry; i++) { + usb_stk11xx_read_registry(dev, 0x201, &value); + +//writes to 204/204 return 4 on success +//writes to 208 return 1 on success + + if (value == 0x04 || value == 0x01) + return 1; + + if (value != 0x00) + { + STK_ERROR("Check device return error (0x0201 = %02X) !\n", value); + return -1; + } + +// msleep(10); + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the default sensor settings + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk0408_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int asize; + +// PAL registers + static const int registers[] = { + 0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, + 0x13,0x15,0x16,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c, + 0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b }; + + const int values[] = { + 0x08,0x33,0x00,0x00,0xe9,0x0d, + (dev->vsettings.norm ? 0x38 : 0x78), + 0x80,0x47,0x40,0x00,0x01,0x2a,0x00,0x0c,0xe7, + 0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xff,0xff,0x40,0x54, + (dev->vsettings.norm ? 0x07 : 0x0a), + 0x83 }; + + asize = ARRAY_SIZE(values); + + for(i=0; ivsettings.brightness >> 8); //80 +//contrast + dev_stk0408_write_saa(dev, 0x0b, dev->vsettings.contrast >> 9); //40 +//hue + dev_stk0408_write_saa(dev, 0x0d, (dev->vsettings.colour - 32768) >> 8); //00 +//saturation + dev_stk0408_write_saa(dev, 0x0c, (dev->vsettings.hue) >> 9); //40 + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set hue : %d\n", dev->vsettings.hue); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 1; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + * + */ +int dev_stk0408_set_camera_fps(struct usb_stk11xx *dev) +{ + //Unknown, setting FPS seems to have no effect + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk0408_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + value |= 0x80; + +// msleep(0x1f4); + usb_stk11xx_write_registry(dev, 0x0100, value); +// msleep(0x64); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk0408_reconf_camera(struct usb_stk11xx *dev) +{ + + dev_stk0408_configure_device(dev, 6); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk0408_stop_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0100, &value); + value &= 0x7f; + usb_stk11xx_write_registry(dev, 0x0100, value); + msleep(5); + + return 0; +} + +/* + * Needs some more work and optimisation! + */ +void stk11xx_copy_uvyv(uint8_t *src, uint8_t *rgb, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int hfactor, const int vfactor, + bool order, bool field) +{ + int width = image->x; + int height = image->y; + int x; + int y; + + uint8_t *line1 = NULL; + uint8_t *line2 = NULL; + + static uint8_t *prev=0; + if (!prev) + prev = rgb; + +// printk("copy image %d - %d %d,%d,%d\n", width, height, hfactor, vfactor, field); + +// vfactor=1 interlace rows +// vfactor=2 full frame copy, duplicate rows +// vfactor=4 half frame, copy rows + + if (field == false) // odd frame + { + prev += width * 2; + } + + for ( y=0; y < height/2; y++) + { + if (vfactor == 1) + { + if (field == false) // odd frame + { + line1 = rgb + (y*width*4); + line2 = rgb + (y*width*4) + width*2; + } + else + { + line1 = rgb + (y*width*4) + width*2; + line2 = rgb + (y*width*4); + } + } + else + { + line1 = rgb + (y*width*2); + } + + + if (order && hfactor == 1) //fast line copy with memcpy + { + memcpy(line1,src,width*2); + src += width*2; + } + else //slow line copy with hscaling or YUV reorder + { + for ( x = 0; x < width*2; x+=4) + { + if (order) //yuv order + { + line1[x] = src[0]; + line1[x+1] = src[1]; + line1[x+2] = src[2]; + line1[x+3] = src[3]; + } + else + { + line1[x] = src[1]; + line1[x+1] = src[0]; + line1[x+2] = src[3]; + line1[x+3] = src[2]; + } + src += (4 * hfactor); + } + } + + if (vfactor == 1) //interlaced copy from previous frame + { + memcpy(line2,prev,width*2); + prev += width*4; + } + else if (vfactor == 2) //1 : 1 + { + } + else if (vfactor == 4) // 2 : 1 + { + src += (width*2)*2; + } + } + + prev = rgb; +} + +/* + * needs more work and optimisation! + * + * rgb is horribly slow but just written to check the image is working + * replace with a proper yuv to rgb conversion + */ +#define CLAMP(x) x < 0 ? 0 : x > 255 ? 255 : x + +void stk11xx_copy_rgb(uint8_t *src, uint8_t *rgb, + struct stk11xx_coord *image, + struct stk11xx_coord *view, + const int hflip, const int vflip, + const int hfactor, const int vfactor, + bool order, bool four, bool field) +{ + + int width = image->x; + int height = image->y; + int x; + int y; + int step; + + bool off = false; + + uint8_t *line1 = NULL; + uint8_t *line2 = NULL; + + static uint8_t *prev=0; + if (!prev) + prev = rgb; + + step = four?4:3; + + if (field==false) + { + prev += width * step; + } + + //uvyv + for ( y=0; y < height/2; y++) + { + if (vfactor == 1) + { + if (field == false) // odd frame + {// + line1 = rgb + (y * width * step * 2); + line2 = rgb + (y * width * step * 2) + width * step; + } + else + { + line1 = rgb + (y * width * step * 2) + width * step; + line2 = rgb + (y * width * step * 2); + } + } + else + { + line1 = rgb + (y * width * step); + } + + off=false; + for ( x = 0; x < width*step; x+=step) + { +/* + C = Y - 16 + D = U - 128 + E = V - 128 + + R = clip(( 298 * C + 409 * E + 128) >> 8) + G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) + B = clip(( 298 * C + 516 * D + 128) >> 8) +*/ + int c = src[off ? 3 : 1]; + int d = src[0] - 128; + int e = src[2] - 128; + + int R = ((298*c + 409 * e + 128) >>8); + int G = ((298*c - 100 * d - 208 * e + 128)>>8); + int B = ((298*c + 516 * d + 128)>>8); + + R = CLAMP(R); + G = CLAMP(G); + B = CLAMP(B); + + if (order) + { + line1[x] = B; + line1[x+1] = G; + line1[x+2] = R; + } + else + { + line1[x] = R; + line1[x+1] = G; + line1[x+2] = B; + } + if (four) + line1[x+3] = 0; + + if (off) + { + src += (4 * hfactor); + off = false; + } + else + { + off = true; + } + + } + + + if (vfactor == 1) //interlaced copy from previous frame + { + for ( x = 0; x < width * step; x++ ) + { + line2[x] = (*prev++); //line1[x]; + } + prev += width * step; + } + } + + prev = rgb; +} + + +int dev_stk0408_decode(struct usb_stk11xx *dev) +{ + void *data; + void *image; + + int vfactor; + int hfactor; + bool odd; + + struct stk11xx_frame_buf *framebuf; + + if (dev == NULL) + return -EFAULT; + + framebuf = dev->read_frame; + + if (framebuf == NULL) + return -EFAULT; + + image = dev->image_data; + STK_DEBUG("fill image %d\n", dev->fill_image); + + image += dev->images[dev->fill_image].offset; + + data = framebuf->data; + odd = framebuf->odd; + + switch (dev->resolution) { + +/* +//Currently only 1:1 resolutions are working + case STK11XX_160x120: + case STK11XX_176x144: + hfactor = 4; + vfactor = 4; + break; + + case STK11XX_320x240: + case STK11XX_352x240: + case STK11XX_352x288: + hfactor = 2; + vfactor = 2; + break; +*/ + case STK11XX_640x480: +/* case STK11XX_720x480:*/ + case STK11XX_720x576: + hfactor = 1; + vfactor = 1; + break; + + default: + return -EFAULT; + } + + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_RGB24: + stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,false,odd); + break; + case STK11XX_PALETTE_RGB32: + stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,true,odd); + break; + case STK11XX_PALETTE_BGR24: + stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,false,odd); + break; + case STK11XX_PALETTE_BGR32: + stk11xx_copy_rgb(data, image, &dev->image, &dev->view, dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,true,odd); + break; + + case STK11XX_PALETTE_UYVY: + stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, true,odd); + break; + case STK11XX_PALETTE_YUYV: + stk11xx_copy_uvyv(data, image, &dev->image, &dev->view,dev->vsettings.hflip, dev->vsettings.vflip, hfactor, vfactor, false,odd); + break; + } + + return 0; + +} + diff --git a/stk11xx-dev-0500.c b/stk11xx-dev-0500.c new file mode 100644 index 0000000..f3eaa80 --- /dev/null +++ b/stk11xx-dev-0500.c @@ -0,0 +1,844 @@ +/** + * @file stk11xx-dev-0500.c + * @author Nicolas VIVIEN + * @date 2009-05-30 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-0500 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk0500_initialize_device(struct usb_stk11xx *dev) +{ + int retok; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk0500_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 8); + + dev_stk0500_configure_device(dev, 9); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 10); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 11); + + dev_stk0500_configure_device(dev, 12); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 13); + + dev_stk0500_configure_device(dev, 14); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk0500_configure_device(dev, 15); + + dev_stk0500_configure_device(dev, 16); + + dev_stk0500_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk0500_stop_stream(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stk0500_configure_device(struct usb_stk11xx *dev, int step) +{ + int retok; + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 + static const int values_001B[] = { + 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0e, 0x0e, 0x0e + }; + static const int values_001C[] = { + 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x46, 0x46 + }; + static const int values_0202[] = { + 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x0a, 0x1e, 0x1f, 0x1f, 0x0a, 0x1e, 0x1e + }; + static const int values_0110[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01 + }; + static const int values_0112[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 + }; + static const int values_0114[] = { + 0x80, 0x80, 0x80, 0x80, 0x00, 0xbe, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x81, 0x81 + }; + static const int values_0115[] = { + 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02 + }; + static const int values_0116[] = { + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe0, 0xe0, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1 + }; + static const int values_0117[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + static const int values_0100[] = { + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21 + }; + + + STK_DEBUG("dev_stk0500_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + +// usb_stk11xx_write_registry(dev, 0x0200, 0x0080); +// usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0204, 0x00ff); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001c); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001d); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 10: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ec); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 12: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x00f0); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 13: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 14: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0001); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + break; + + case 15: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + usb_stk11xx_write_registry(dev, 0x0205, 0x0030); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0061); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 16: + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 17: + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + + dev_stk0500_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0208, 0x0003); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0208, 0x0004); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0006); + retok = dev_stk11xx_check_device(dev, 500); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk0500_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0048); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk0500_init_camera(struct usb_stk11xx *dev) +{ + dev_stk0500_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + dev_stk0500_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0104, 0x0000); + usb_stk11xx_write_registry(dev, 0x0105, 0x0000); + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + + dev_stk11xx_camera_off(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk0500_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + static const int values_204[] = { + 0x1e, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x1e, 0x25, + 0x06, 0x25, 0x03, 0x04 + }; + static const int values_205[] = { + 0x10, 0x11, 0x7b, 0x19, 0x06, 0x78, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, + 0x04, 0x00, 0x0b, 0x04, 0x08, 0x05, 0x08, 0x01, 0x10, 0x09, + 0x00, 0x08, 0x24, 0x05, 0x48, 0x00, 0x20, 0x01, 0x00, 0x01, + 0x01, 0x01, 0x06, 0x78 + }; + + + asize = ARRAY_SIZE(values_204); + + for(i=0; ivsettings.contrast >> 8)); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + + ret = dev_stk11xx_check_device(dev, 500); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + // Whiteness register ? + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0204, 0x0004); + usb_stk11xx_write_registry(dev, 0x0205, (dev->vsettings.whiteness >> 8)); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + + ret = dev_stk11xx_check_device(dev, 500); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0208, 0x0003); + usb_stk11xx_write_registry(dev, 0x0208, 0x0020); + + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0050); + usb_stk11xx_write_registry(dev, 0x0208, 0x0004); + usb_stk11xx_write_registry(dev, 0x0208, 0x0020); + + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0006); + + ret = dev_stk11xx_check_device(dev, 500); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + */ +int dev_stk0500_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk0500_start_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a1); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0xa1 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a1); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk0500_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stk0500_configure_device(dev, 17); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk0500_stop_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0048); + + return 0; +} + diff --git a/stk11xx-dev-6a31.c b/stk11xx-dev-6a31.c new file mode 100644 index 0000000..e203f59 --- /dev/null +++ b/stk11xx-dev-6a31.c @@ -0,0 +1,872 @@ +/** + * @file stk11xx-dev-6a31.c + * @author Nicolas VIVIEN + * @date 2007-11-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-6A31 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk6a31_initialize_device(struct usb_stk11xx *dev) +{ + int retok; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a31_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 8); + + dev_stk6a31_configure_device(dev, 9); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 10); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a31_configure_device(dev, 11); + + dev_stk6a31_configure_device(dev, 12); + + dev_stk6a31_configure_device(dev, 13); + + dev_stk6a31_configure_device(dev, 14); + + dev_stk6a31_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stk6a31_configure_device(struct usb_stk11xx *dev, int step) +{ + int retok; + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + static const int values_001B[] = { + 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 + }; + static const int values_001C[] = { + 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 + }; + static const int values_0202[] = { + 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x0a, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f + }; + static const int values_0110[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0112[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0114[] = { + 0x80, 0x80, 0x80, 0x80, 0x00, 0xbe, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80 + }; + static const int values_0115[] = { + 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02 + }; + static const int values_0116[] = { + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe0, 0xe0, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0 + }; + static const int values_0117[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + static const int values_0100[] = { + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 + }; + + + STK_DEBUG("dev_stk6a31_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + +// usb_stk11xx_write_registry(dev, 0x0200, 0x0080); +// usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0204, 0x00ff); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001c); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001d); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 10: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ec); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 12: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x00f0); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x0204, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 13: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 14: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0001); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x0204, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 15: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + dev_stk6a31_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + + break; + + case 16: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + dev_stk6a31_sensor_settings(dev); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk6a31_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk6a31_init_camera(struct usb_stk11xx *dev) +{ +// int retok; +// int value; + + dev_stk6a31_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + dev_stk6a31_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a31_configure_device(dev, 15); + + dev_stk11xx_camera_off(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk6a31_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + static const int values_204[] = { + 0xf0, 0xf1, 0x0d, 0xf1, 0x0d, 0xf1, 0xf0, 0xf1, 0x35, 0xf1, + 0xf0, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0xdd, 0xf1, 0xf0, 0xf1, + 0x1f, 0xf1, 0x20, 0xf1, 0x21, 0xf1, 0x22, 0xf1, 0x23, 0xf1, + 0x24, 0xf1, 0x28, 0xf1, 0x29, 0xf1, 0x5e, 0xf1, 0x5f, 0xf1, + 0x60, 0xf1, 0xef, 0xf1, 0xf2, 0xf1, 0x02, 0xf1, 0x03, 0xf1, + 0x04, 0xf1, 0x09, 0xf1, 0x0a, 0xf1, 0x0b, 0xf1, 0x0c, 0xf1, + 0x0d, 0xf1, 0x0e, 0xf1, 0x0f, 0xf1, 0x10, 0xf1, 0x11, 0xf1, + 0x15, 0xf1, 0x16, 0xf1, 0x17, 0xf1, 0x18, 0xf1, 0x19, 0xf1, + 0x1a, 0xf1, 0x1b, 0xf1, 0x1c, 0xf1, 0x1d, 0xf1, 0x1e, 0xf1, + 0xf0, 0xf1, 0x06, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0x80, 0xf1, + 0x81, 0xf1, 0x82, 0xf1, 0x83, 0xf1, 0x84, 0xf1, 0x85, 0xf1, + 0x86, 0xf1, 0x87, 0xf1, 0x88, 0xf1, 0x89, 0xf1, 0x8a, 0xf1, + 0x8b, 0xf1, 0x8c, 0xf1, 0x8d, 0xf1, 0x8e, 0xf1, 0x8f, 0xf1, + 0x90, 0xf1, 0x91, 0xf1, 0x92, 0xf1, 0x93, 0xf1, 0x94, 0xf1, + 0x95, 0xf1, 0xb6, 0xf1, 0xb7, 0xf1, 0xb8, 0xf1, 0xb9, 0xf1, + 0xba, 0xf1, 0xbb, 0xf1, 0xbc, 0xf1, 0xbd, 0xf1, 0xbe, 0xf1, + 0xbf, 0xf1, 0xc0, 0xf1, 0xc1, 0xf1, 0xc2, 0xf1, 0xc3, 0xf1, + 0xc4, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0x53, 0xf1, 0x54, 0xf1, + 0x55, 0xf1, 0x56, 0xf1, 0x57, 0xf1, 0x58, 0xf1, 0xdc, 0xf1, + 0xdd, 0xf1, 0xde, 0xf1, 0xdf, 0xf1, 0xe0, 0xf1, 0xe1, 0xf1, + 0xf0, 0xf1, 0xa7, 0xf1, 0xaa, 0xf1, 0x3a, 0xf1, 0xa1, 0xf1, + 0xa4, 0xf1, 0x9b, 0xf1, 0x08, 0xf1, 0xf0, 0xf1, 0x2f, 0xf1, + 0x9c, 0xf1, 0xd2, 0xf1, 0xcc, 0xf1, 0xcb, 0xf1, 0x2e, 0xf1, + 0x67, 0xf1, 0xf0, 0xf1, 0x65, 0xf1, 0x66, 0xf1, 0x67, 0xf1, + 0x65, 0xf1, 0xf0, 0xf1, 0x05, 0xf1, 0x07, 0xf1, 0xf0, 0xf1, + 0x39, 0xf1, 0x3b, 0xf1, 0x3a, 0xf1, 0x3c, 0xf1, 0x57, 0xf1, + 0x58, 0xf1, 0x59, 0xf1, 0x5a, 0xf1, 0x5c, 0xf1, 0x5d, 0xf1, + 0x64, 0xf1, 0xf0, 0xf1, 0x5b, 0xf1, 0xf0, 0xf1, 0x36, 0xf1, + 0x37, 0xf1, 0xf0, 0xf1, 0x08, 0xf1 + }; + static const int values_205[] = { + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x01, 0x70, 0x0e, 0x00, 0x02, 0x18, 0xe0, 0x00, 0x02, + 0x01, 0x80, 0xc8, 0x14, 0x80, 0x80, 0xa0, 0x78, 0xa0, 0x78, + 0x5f, 0x20, 0xea, 0x02, 0x86, 0x7a, 0x59, 0x4c, 0x4d, 0x51, + 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0xee, 0x39, 0x23, + 0x07, 0x24, 0x00, 0xcd, 0x00, 0x93, 0x00, 0x04, 0x00, 0x5c, + 0x00, 0xd9, 0x00, 0x53, 0x00, 0x08, 0x00, 0x91, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf0, 0x0e, 0x70, 0x0e, 0x00, 0x01, 0x00, 0x07, + 0xde, 0x13, 0xeb, 0xe2, 0x00, 0xf6, 0xe1, 0x14, 0xea, 0xdd, + 0xfd, 0xf6, 0xe5, 0x11, 0xed, 0xe6, 0xfb, 0xf7, 0xd6, 0x13, + 0xed, 0xec, 0xf9, 0xf2, 0x00, 0x00, 0xd8, 0x15, 0xe9, 0xea, + 0xf9, 0xf1, 0x00, 0x02, 0xde, 0x10, 0xef, 0xef, 0xfb, 0xf4, + 0x00, 0x02, 0x0e, 0x06, 0x27, 0x13, 0x11, 0x06, 0x27, 0x13, + 0x0c, 0x03, 0x2a, 0x0f, 0x12, 0x08, 0x1a, 0x16, 0x00, 0x22, + 0x15, 0x0a, 0x1c, 0x1a, 0x00, 0x2d, 0x11, 0x09, 0x14, 0x14, + 0x00, 0x2a, 0x74, 0x0e, 0x00, 0x01, 0x0b, 0x03, 0x47, 0x22, + 0xac, 0x82, 0xda, 0xc7, 0xf5, 0xe9, 0xff, 0x00, 0x0b, 0x03, + 0x47, 0x22, 0xac, 0x82, 0xda, 0xc7, 0xf5, 0xe9, 0xff, 0x00, + 0x00, 0x01, 0x02, 0x80, 0x01, 0xe0, 0x43, 0x00, 0x05, 0x00, + 0x04, 0x00, 0x43, 0x00, 0x01, 0x80, 0x00, 0x02, 0xd1, 0x00, + 0xd1, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x0c, 0x3c, + 0x10, 0x10, 0x00, 0x00, 0xa0, 0x00, 0x20, 0x03, 0x05, 0x01, + 0x20, 0x00, 0x00, 0x00, 0x01, 0xb8, 0x00, 0xd8, 0x00, 0x02, + 0x06, 0xc0, 0x04, 0x0e, 0x06, 0xc0, 0x05, 0x64, 0x02, 0x08, + 0x02, 0x71, 0x02, 0x09, 0x02, 0x71, 0x12, 0x0d, 0x17, 0x12, + 0x5e, 0x1c, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x78, 0x10, + 0x83, 0x04, 0x00, 0x00, 0x00, 0x21 + }; + + + asize = ARRAY_SIZE(values_204); + + for(i=0; ivsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + */ +int dev_stk6a31_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk6a31_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0114, &value); // read 0x80 + usb_stk11xx_read_registry(dev, 0x0115, &value); // read 0x02 + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a0); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk6a31_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stk6a31_configure_device(dev, 16); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk6a31_stop_stream(struct usb_stk11xx *dev) +{ + return 0; +} + diff --git a/stk11xx-dev-6a33.c b/stk11xx-dev-6a33.c new file mode 100644 index 0000000..187f9af --- /dev/null +++ b/stk11xx-dev-6a33.c @@ -0,0 +1,993 @@ +/** + * @file stk11xx-dev-6a33.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-6A33 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk6a33_initialize_device(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 1 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 2 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 3 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0001); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a33_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 8); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 9); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 10); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 11); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a33_configure_device(dev, 12); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stk6a33_configure_device(dev, 13); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stk6a33_configure_device(dev, 14); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x0204, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stk6a33_configure_device(dev, 15); + + dev_stk6a33_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 11 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + * + * The steps 0 to 9 are called during the initialization. + */ +int dev_stk6a33_configure_device(struct usb_stk11xx *dev, int step) +{ + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 + + static const int values_001B[] = { + 0x0e, 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 + }; + static const int values_001C[] = { + 0x06, 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 + }; + static const int values_0202[] = { + 0x1e, 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x14, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f + }; + static const int values_0110[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0112[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0114[] = { + 0x87, 0x80, 0x80, 0x80, 0x80, 0xbe, 0xbe, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 + }; + static const int values_0115[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 + }; + static const int values_0116[] = { + 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe9, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0 + }; + static const int values_0117[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + static const int values_0100[] = { + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 + }; + + STK_DEBUG("dev_stk6a33_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0040); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0041); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0204, 0x001c); + usb_stk11xx_write_registry(dev, 0x0205, 0x0002); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x000a); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 10: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ec); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 12: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + break; + + case 13: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + break; + + case 14: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0001); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + break; + + case 15: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + dev_stk6a33_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + break; + + case 16: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + dev_stk6a33_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + + break; + + case 17: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + dev_stk6a33_sensor_settings(dev); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk6a33_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk6a33_init_camera(struct usb_stk11xx *dev) +{ + dev_stk6a33_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a33_configure_device(dev, 16); + + dev_stk11xx_camera_off(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk6a33_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + static const int values_204[] = { + 0xf0, 0xf1, 0x0d, 0xf1, 0x0d, 0xf1, 0xf0, 0xf1, 0x35, 0xf1, + 0xf0, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0xdd, 0xf1, 0xf0, 0xf1, + 0x1f, 0xf1, 0x20, 0xf1, 0x21, 0xf1, 0x22, 0xf1, 0x23, 0xf1, + 0x24, 0xf1, 0x28, 0xf1, 0x29, 0xf1, 0x5e, 0xf1, 0x5f, 0xf1, + 0x60, 0xf1, 0xef, 0xf1, 0xf2, 0xf1, 0x02, 0xf1, 0x03, 0xf1, + 0x04, 0xf1, 0x09, 0xf1, 0x0a, 0xf1, 0x0b, 0xf1, 0x0c, 0xf1, + 0x0d, 0xf1, 0x0e, 0xf1, 0x0f, 0xf1, 0x10, 0xf1, 0x11, 0xf1, + 0x15, 0xf1, 0x16, 0xf1, 0x17, 0xf1, 0x18, 0xf1, 0x19, 0xf1, + 0x1a, 0xf1, 0x1b, 0xf1, 0x1c, 0xf1, 0x1d, 0xf1, 0x1e, 0xf1, + 0xf0, 0xf1, 0x06, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0x80, 0xf1, + 0x81, 0xf1, 0x82, 0xf1, 0x83, 0xf1, 0x84, 0xf1, 0x85, 0xf1, + 0x86, 0xf1, 0x87, 0xf1, 0x88, 0xf1, 0x89, 0xf1, 0x8a, 0xf1, + 0x8b, 0xf1, 0x8c, 0xf1, 0x8d, 0xf1, 0x8e, 0xf1, 0x8f, 0xf1, + 0x90, 0xf1, 0x91, 0xf1, 0x92, 0xf1, 0x93, 0xf1, 0x94, 0xf1, + 0x95, 0xf1, 0xb6, 0xf1, 0xb7, 0xf1, 0xb8, 0xf1, 0xb9, 0xf1, + 0xba, 0xf1, 0xbb, 0xf1, 0xbc, 0xf1, 0xbd, 0xf1, 0xbe, 0xf1, + 0xbf, 0xf1, 0xc0, 0xf1, 0xc1, 0xf1, 0xc2, 0xf1, 0xc3, 0xf1, + 0xc4, 0xf1, 0x06, 0xf1, 0xf0, 0xf1, 0x53, 0xf1, 0x54, 0xf1, + 0x55, 0xf1, 0x56, 0xf1, 0x57, 0xf1, 0x58, 0xf1, 0xf0, 0xf1, + 0xa7, 0xf1, 0xaa, 0xf1, 0x3a, 0xf1, 0xa1, 0xf1, 0xa4, 0xf1, + 0x9b, 0xf1, 0x08, 0xf1, 0xf0, 0xf1, 0x2f, 0xf1, 0x9c, 0xf1, + 0xd2, 0xf1, 0xcc, 0xf1, 0xcb, 0xf1, 0x2e, 0xf1, 0x67, 0xf1, + 0xf0, 0xf1, 0x65, 0xf1, 0x66, 0xf1, 0x67, 0xf1, 0x65, 0xf1, + 0xf0, 0xf1, 0x05, 0xf1, 0x07, 0xf1, 0xf0, 0xf1, 0x39, 0xf1, + 0x3b, 0xf1, 0x3a, 0xf1, 0x3c, 0xf1, 0x57, 0xf1, 0x58, 0xf1, + 0x59, 0xf1, 0x5a, 0xf1, 0x5c, 0xf1, 0x5d, 0xf1, 0x64, 0xf1, + 0xf0, 0xf1, 0x5b, 0xf1, 0xf0, 0xf1, 0x36, 0xf1, 0x37, 0xf1, + 0xf0, 0xf1, 0x08, 0xf1 + }; + static const int values_205[] = { + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x01, 0x70, 0x0e, 0x00, 0x02, 0x18, 0xe0, 0x00, 0x02, + 0x01, 0x80, 0xc8, 0x14, 0x80, 0x80, 0xa0, 0x78, 0xa0, 0x78, + 0x5f, 0x20, 0xea, 0x02, 0x86, 0x7a, 0x59, 0x4c, 0x4d, 0x51, + 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0xee, 0x39, 0x23, + 0x07, 0x24, 0x00, 0xcd, 0x00, 0x93, 0x00, 0x04, 0x00, 0x5c, + 0x00, 0xd9, 0x00, 0x53, 0x00, 0x08, 0x00, 0x91, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf0, 0x0e, 0x70, 0x0e, 0x00, 0x01, 0x00, 0x0b, + 0xee, 0x08, 0xf8, 0xf3, 0x00, 0xfb, 0xee, 0x09, 0xf7, 0xf3, + 0xff, 0xfa, 0xf2, 0x08, 0xf9, 0xf5, 0xff, 0xf9, 0xe4, 0x10, + 0xf1, 0xea, 0xf8, 0xf6, 0x00, 0x00, 0xe9, 0x0f, 0xf2, 0xed, + 0xf6, 0xf6, 0x00, 0x00, 0xea, 0x0d, 0xf4, 0xf1, 0xf8, 0xf8, + 0x00, 0x00, 0x07, 0x06, 0x1c, 0x0b, 0x08, 0x06, 0x17, 0x0a, + 0x05, 0x06, 0x1a, 0x07, 0x06, 0x04, 0x0a, 0x08, 0x00, 0x19, + 0x06, 0x05, 0x07, 0x0a, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x08, + 0x00, 0x1b, 0x74, 0x0e, 0x00, 0x01, 0x0b, 0x03, 0x47, 0x22, + 0xac, 0x82, 0xda, 0xc7, 0xf5, 0xe9, 0xff, 0x00, 0x00, 0x01, + 0x02, 0x80, 0x01, 0xe0, 0x43, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x43, 0x00, 0x01, 0x80, 0x00, 0x02, 0xd1, 0x00, 0xd1, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x0c, 0x50, 0x10, 0x10, + 0x00, 0x00, 0xa0, 0x00, 0x20, 0x03, 0x05, 0x01, 0x20, 0x00, + 0x00, 0x00, 0x01, 0xb8, 0x00, 0xd8, 0x00, 0x02, 0x06, 0xc0, + 0x04, 0x0e, 0x06, 0xc0, 0x05, 0x64, 0x02, 0x08, 0x02, 0x71, + 0x02, 0x08, 0x02, 0x71, 0x12, 0x0d, 0x17, 0x12, 0x5e, 0x1c, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x78, 0x10, 0x83, 0x04, + 0x00, 0x00, 0x00, 0x21 + }; + + + asize = ARRAY_SIZE(values_204); + + for(i=0; i already looked 0x01 and 0x02) + * 0x204 = 0x00 : brightness / white balance (by default 0x00) + */ +int dev_stk6a33_set_camera_quality(struct usb_stk11xx *dev) +{ + int ret; + int value; + + // Contrast register + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0204, 0x00b3); + usb_stk11xx_write_registry(dev, 0x0205, (dev->vsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + * + * 0x204 = 0x2e : Fps MSB (by default 0x01) + * 0x204 = 0x2d : Fps LSB (by default 0x00) + * + * 0x2e | 0x2d | Nbr fps + * -----+------+-------- + * 0x00 | 0x00 | 30 + * 0x01 | 0x00 | 20 + * 0x02 | 0x00 | 15 + * 0x03 | 0x00 | 12 + * 0x04 | 0x00 | 10 + */ +int dev_stk6a33_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk6a33_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0114, &value); // read 0x80 + usb_stk11xx_read_registry(dev, 0x0115, &value); // read 0x02 + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a0); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk6a33_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stk6a33_configure_device(dev, 16); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk6a33_stop_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + + return 0; +} + diff --git a/stk11xx-dev-6a51.c b/stk11xx-dev-6a51.c new file mode 100644 index 0000000..f08b11a --- /dev/null +++ b/stk11xx-dev-6a51.c @@ -0,0 +1,1555 @@ +/** + * @file stk11xx-dev-6a51.c + * @author Nicolas VIVIEN + * @date 2007-12-07 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-6A51 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk6a51_initialize_device(struct usb_stk11xx *dev) +{ + int i; + int value; + int retok; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 1 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 2 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 3 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0001); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a51_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 8); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 9); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 10); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 11); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 12); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 13); + + dev_stk6a51_configure_device(dev, 14); + + dev_stk6a51_configure_device(dev, 15); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stk6a51_configure_device(dev, 16); + + dev_stk6a51_configure_device(dev, 17); + + + + + + dev_stk6a51_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stk6a51_configure_device(struct usb_stk11xx *dev, int step) +{ + int retok; + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + static const int values_001B[] = { + 0x0e, 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0e, 0x0e, 0x0e, 0x0e + }; + static const int values_001C[] = { + 0x06, 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x46, 0x46, 0x46 + }; + static const int values_0202[] = { + 0x1e, 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x0a, 0x1e, 0x14, 0x1e, 0x1f, 0x0a, 0x0a, 0x0a, 0x0a + }; + static const int values_0110[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0112[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01 + }; + static const int values_0114[] = { + 0x87, 0x80, 0x80, 0x80, 0x80, 0x00, 0xbe, 0xbe, 0x80, 0x80, 0x84, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 + }; + static const int values_0115[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 + }; + static const int values_0116[] = { + 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe9, 0xe0, 0xe0, 0xe4, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1 + }; + static const int values_0117[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + static const int values_0100[] = { + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 + }; + + + STK_DEBUG("dev_stk6a51_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + +// usb_stk11xx_write_registry(dev, 0x0200, 0x0080); +// usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0040); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0041); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0204, 0x001c); + usb_stk11xx_write_registry(dev, 0x0205, 0x0002); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 10: + usb_stk11xx_write_registry(dev, 0x0203, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x000a); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 12: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ec); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 13: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0208, 0x0020); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 14: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0208, 0x00f1); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + + case 15: + usb_stk11xx_write_registry(dev, 0x0203, 0x00ba); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0001); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 16: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0205, 0x0030); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_read_registry(dev, 0x0201, &value); + usb_stk11xx_read_registry(dev, 0x0201, &value); + usb_stk11xx_read_registry(dev, 0x0201, &value); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + usb_stk11xx_read_registry(dev, 0x0201, &value); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0002, 0x007f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x007d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + break; + + case 17: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + dev_stk6a51_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + usb_stk11xx_write_registry(dev, 0x0205, 0x0033); + usb_stk11xx_write_registry(dev, 0x0205, 0x0090); + usb_stk11xx_write_registry(dev, 0x0200, 0x0061); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_read_registry(dev, 0x0201, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + break; + + case 18: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + dev_stk6a51_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + usb_stk11xx_write_registry(dev, 0x0205, 0x0033); + usb_stk11xx_write_registry(dev, 0x0205, 0x0090); + usb_stk11xx_write_registry(dev, 0x0200, 0x0061); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + break; + + case 19: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + dev_stk6a51_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + usb_stk11xx_write_registry(dev, 0x0205, 0x0033); + usb_stk11xx_write_registry(dev, 0x0205, 0x0090); + usb_stk11xx_write_registry(dev, 0x0200, 0x0061); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk6a51_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk6a51_init_camera(struct usb_stk11xx *dev) +{ + dev_stk6a51_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + dev_stk6a51_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a51_configure_device(dev, 18); + + dev_stk11xx_camera_off(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk6a51_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + + static const int values_205[][4] = { + { 0x33, 0x86, 0x05, 0x01 }, + { 0x33, 0x86, 0x05, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x30, 0x1a, 0x0a, 0xcc }, + { 0x32, 0x02, 0x00, 0x08 }, + { 0x33, 0xf4, 0x03, 0x1d }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x34, 0x1e, 0x8f, 0x09 }, + { 0x34, 0x1c, 0x02, 0x50 }, + { 0x34, 0x1e, 0x8f, 0x09 }, + { 0x34, 0x1e, 0x8f, 0x08 }, + { 0x33, 0x8c, 0x04, 0x00 }, + { 0x33, 0x90, 0x30, 0x8f }, + { 0x33, 0x92, 0xc3, 0xff }, + { 0x33, 0x94, 0xed, 0x8f }, + { 0x33, 0x96, 0x35, 0x8f }, + { 0x33, 0x98, 0x18, 0x8f }, + { 0x33, 0x9a, 0x30, 0x8f }, + { 0x33, 0x9c, 0xc3, 0x00 }, + { 0x33, 0x9e, 0x15, 0x8f }, + { 0x33, 0x8c, 0x04, 0x10 }, + { 0x33, 0x90, 0xcc, 0x00 }, + { 0x33, 0x92, 0x07, 0xbd }, + { 0x33, 0x94, 0x04, 0xb5 }, + { 0x33, 0x96, 0xbd, 0x9e }, + { 0x33, 0x98, 0x9f, 0xf6 }, + { 0x33, 0x9a, 0x03, 0x22 }, + { 0x33, 0x9c, 0x30, 0xe7 }, + { 0x33, 0x9e, 0x0a, 0xf6 }, + { 0x33, 0x8c, 0x04, 0x20 }, + { 0x33, 0x90, 0x02, 0x39 }, + { 0x33, 0x92, 0xc1, 0x01 }, + { 0x33, 0x94, 0x26, 0x05 }, + { 0x33, 0x96, 0xf6, 0x03 }, + { 0x33, 0x98, 0x23, 0xe7 }, + { 0x33, 0x9a, 0x0a, 0x7d }, + { 0x33, 0x9c, 0x03, 0x21 }, + { 0x33, 0x9e, 0x27, 0x20 }, + { 0x33, 0x8c, 0x04, 0x30 }, + { 0x33, 0x90, 0xf6, 0x02 }, + { 0x33, 0x92, 0x39, 0xe7 }, + { 0x33, 0x94, 0x02, 0x8f }, + { 0x33, 0x96, 0xc3, 0x00 }, + { 0x33, 0x98, 0x0b, 0x30 }, + { 0x33, 0x9a, 0xed, 0x00 }, + { 0x33, 0x9c, 0xfe, 0x02 }, + { 0x33, 0x9e, 0x37, 0xee }, + { 0x33, 0x8c, 0x04, 0x40 }, + { 0x33, 0x90, 0x04, 0x5f }, + { 0x33, 0x92, 0xad, 0x00 }, + { 0x33, 0x94, 0x30, 0xe6 }, + { 0x33, 0x96, 0x0a, 0x4f }, + { 0x33, 0x98, 0xed, 0x08 }, + { 0x33, 0x9a, 0xec, 0x11 }, + { 0x33, 0x9c, 0xa3, 0x08 }, + { 0x33, 0x9e, 0xdd, 0x56 }, + { 0x33, 0x8c, 0x04, 0x50 }, + { 0x33, 0x90, 0x30, 0xc6 }, + { 0x33, 0x92, 0x13, 0x3a }, + { 0x33, 0x94, 0x35, 0x39 }, + { 0x33, 0x96, 0x3c, 0x3c }, + { 0x33, 0x98, 0x3c, 0xc6 }, + { 0x33, 0x9a, 0x01, 0xf7 }, + { 0x33, 0x9c, 0x03, 0x21 }, + { 0x33, 0x9e, 0xc6, 0x0a }, + { 0x33, 0x8c, 0x04, 0x60 }, + { 0x33, 0x90, 0xf7, 0x03 }, + { 0x33, 0x92, 0x22, 0xf7 }, + { 0x33, 0x94, 0x03, 0x23 }, + { 0x33, 0x96, 0xcc, 0x03 }, + { 0x33, 0x98, 0x03, 0x30 }, + { 0x33, 0x9a, 0xed, 0x02 }, + { 0x33, 0x9c, 0xfe, 0x10 }, + { 0x33, 0x9e, 0x50, 0xec }, + { 0x33, 0x8c, 0x04, 0x70 }, + { 0x33, 0x90, 0x04, 0xfd }, + { 0x33, 0x92, 0x02, 0xff }, + { 0x33, 0x94, 0xfe, 0x02 }, + { 0x33, 0x96, 0xff, 0xec }, + { 0x33, 0x98, 0x00, 0xfd }, + { 0x33, 0x9a, 0x03, 0x01 }, + { 0x33, 0x9c, 0x5f, 0x4f }, + { 0x33, 0x9e, 0x30, 0xed }, + { 0x33, 0x8c, 0x04, 0x80 }, + { 0x33, 0x90, 0x04, 0xec }, + { 0x33, 0x92, 0x04, 0x05 }, + { 0x33, 0x94, 0xf3, 0x03 }, + { 0x33, 0x96, 0x01, 0x8f }, + { 0x33, 0x98, 0xec, 0x00 }, + { 0x33, 0x9a, 0x30, 0xed }, + { 0x33, 0x9c, 0x00, 0xec }, + { 0x33, 0x9e, 0x04, 0x05 }, + { 0x33, 0x8c, 0x04, 0x90 }, + { 0x33, 0x90, 0xe3, 0x02 }, + { 0x33, 0x92, 0x18, 0x8f }, + { 0x33, 0x94, 0xec, 0x00 }, + { 0x33, 0x96, 0x18, 0xed }, + { 0x33, 0x98, 0x00, 0xec }, + { 0x33, 0x9a, 0x04, 0xc3 }, + { 0x33, 0x9c, 0x00, 0x01 }, + { 0x33, 0x9e, 0xed, 0x04 }, + { 0x33, 0x8c, 0x04, 0xa0 }, + { 0x33, 0x90, 0x83, 0x00 }, + { 0x33, 0x92, 0x0f, 0x25 }, + { 0x33, 0x94, 0xdc, 0xee }, + { 0x33, 0x96, 0x02, 0xcc }, + { 0x33, 0x98, 0x04, 0x00 }, + { 0x33, 0x9a, 0xed, 0x04 }, + { 0x33, 0x9c, 0xcc, 0x03 }, + { 0x33, 0x9e, 0x03, 0xdd }, + { 0x33, 0x8c, 0x04, 0xb0 }, + { 0x33, 0x90, 0x52, 0x38 }, + { 0x33, 0x92, 0x38, 0x38 }, + { 0x33, 0x94, 0x39, 0x37 }, + { 0x33, 0x96, 0x36, 0x8f }, + { 0x33, 0x98, 0x30, 0xe3 }, + { 0x33, 0x9a, 0x00, 0x8f }, + { 0x33, 0x9c, 0x18, 0x8f }, + { 0x33, 0x9e, 0x18, 0x30 }, + { 0x33, 0x8c, 0x04, 0xc0 }, + { 0x33, 0x90, 0x18, 0xe3 }, + { 0x33, 0x92, 0x00, 0x18 }, + { 0x33, 0x94, 0x8f, 0x32 }, + { 0x33, 0x96, 0x33, 0x36 }, + { 0x33, 0x98, 0xa6, 0x00 }, + { 0x33, 0x9a, 0x18, 0xa7 }, + { 0x33, 0x9c, 0x00, 0x09 }, + { 0x33, 0x9e, 0x18, 0x09 }, + { 0x33, 0x8c, 0x04, 0xd0 }, + { 0x33, 0x90, 0xc0, 0x01 }, + { 0x33, 0x92, 0x24, 0xf4 }, + { 0x33, 0x94, 0x32, 0x80 }, + { 0x33, 0x96, 0x01, 0x24 }, + { 0x33, 0x98, 0xee, 0x39 }, + { 0x33, 0x8c, 0x20, 0x03 }, + { 0x33, 0x90, 0x04, 0x56 }, + { 0x33, 0x8c, 0xa0, 0x02 }, + { 0x33, 0x90, 0x00, 0x01 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x34, 0xce, 0x81, 0x60 }, + { 0x34, 0xd0, 0x66, 0x33 }, + { 0x34, 0xd2, 0x31, 0x9a }, + { 0x34, 0xd4, 0x94, 0x63 }, + { 0x34, 0xd6, 0x4b, 0x25 }, + { 0x34, 0xd8, 0x26, 0x70 }, + { 0x34, 0xda, 0x72, 0x4c }, + { 0x34, 0xdc, 0xff, 0x04 }, + { 0x34, 0xde, 0x00, 0xf4 }, + { 0x34, 0xe6, 0x00, 0xcc }, + { 0x34, 0xee, 0x0e, 0x42 }, + { 0x34, 0xf6, 0x0d, 0xb5 }, + { 0x35, 0x00, 0x0a, 0xfa }, + { 0x35, 0x08, 0x0f, 0x10 }, + { 0x35, 0x10, 0x11, 0x22 }, + { 0x35, 0x18, 0x0c, 0x28 }, + { 0x35, 0x20, 0x1c, 0x2c }, + { 0x35, 0x28, 0x17, 0x40 }, + { 0x35, 0x30, 0x08, 0xf2 }, + { 0x35, 0x38, 0xfb, 0xd5 }, + { 0x35, 0x4c, 0x05, 0xc7 }, + { 0x35, 0x44, 0x04, 0xf9 }, + { 0x35, 0x5c, 0x05, 0xd0 }, + { 0x35, 0x54, 0x05, 0xf4 }, + { 0x34, 0xe0, 0x01, 0x05 }, + { 0x34, 0xe8, 0x00, 0xa0 }, + { 0x34, 0xf0, 0x0e, 0xa1 }, + { 0x34, 0xf8, 0x0e, 0x01 }, + { 0x35, 0x02, 0x0f, 0xeb }, + { 0x35, 0x0a, 0x09, 0x0a }, + { 0x35, 0x12, 0x10, 0x1e }, + { 0x35, 0x1a, 0x08, 0x23 }, + { 0x35, 0x22, 0x1c, 0x22 }, + { 0x35, 0x2a, 0x07, 0x22 }, + { 0x35, 0x32, 0x0b, 0x06 }, + { 0x35, 0x3a, 0xf9, 0x16 }, + { 0x35, 0x4e, 0x05, 0x9f }, + { 0x35, 0x46, 0x05, 0x30 }, + { 0x35, 0x5e, 0x06, 0x75 }, + { 0x35, 0x56, 0x06, 0x5c }, + { 0x34, 0xe4, 0x00, 0xc5 }, + { 0x34, 0xec, 0x00, 0x48 }, + { 0x34, 0xf4, 0x0f, 0x66 }, + { 0x34, 0xfc, 0x0e, 0x61 }, + { 0x35, 0x06, 0x1b, 0xdb }, + { 0x35, 0x0e, 0x04, 0x0a }, + { 0x35, 0x16, 0x11, 0x13 }, + { 0x35, 0x1e, 0x08, 0x1f }, + { 0x35, 0x26, 0x11, 0x19 }, + { 0x35, 0x2e, 0xf8, 0x1a }, + { 0x35, 0x36, 0x04, 0x0c }, + { 0x35, 0x3e, 0xfa, 0x00 }, + { 0x35, 0x52, 0x06, 0xf1 }, + { 0x35, 0x4a, 0x04, 0x0e }, + { 0x35, 0x62, 0x06, 0xa1 }, + { 0x35, 0x5a, 0x06, 0x91 }, + { 0x34, 0xe2, 0x00, 0xd2 }, + { 0x34, 0xea, 0x00, 0x72 }, + { 0x34, 0xf2, 0x0e, 0x1d }, + { 0x34, 0xfa, 0x0e, 0x06 }, + { 0x35, 0x04, 0x13, 0x0e }, + { 0x35, 0x0c, 0x0f, 0x0d }, + { 0x35, 0x14, 0x13, 0x1c }, + { 0x35, 0x1c, 0x13, 0x29 }, + { 0x35, 0x24, 0x0d, 0x24 }, + { 0x35, 0x2c, 0xfd, 0x29 }, + { 0x35, 0x34, 0x07, 0xf4 }, + { 0x35, 0x3c, 0xee, 0xe7 }, + { 0x35, 0x50, 0x06, 0x50 }, + { 0x35, 0x48, 0x05, 0xc1 }, + { 0x35, 0x60, 0x06, 0x11 }, + { 0x35, 0x58, 0x06, 0x58 }, + { 0x35, 0x40, 0x00, 0x00 }, + { 0x35, 0x42, 0x00, 0x00 }, + { 0x32, 0x10, 0x01, 0xfc }, + { 0x33, 0x8c, 0xa3, 0x52 }, + { 0x33, 0x90, 0x00, 0x3c }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x3c }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x0a }, + { 0x33, 0x8c, 0xa7, 0x6d }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6e }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x70 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa7, 0x71 }, + { 0x33, 0x90, 0x00, 0x10 }, + { 0x33, 0x8c, 0xa7, 0x72 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa7, 0x73 }, + { 0x33, 0x90, 0x00, 0x5b }, + { 0x33, 0x8c, 0xa7, 0x74 }, + { 0x33, 0x90, 0x00, 0x77 }, + { 0x33, 0x8c, 0xa7, 0x75 }, + { 0x33, 0x90, 0x00, 0x8e }, + { 0x33, 0x8c, 0xa7, 0x76 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0xa7, 0x77 }, + { 0x33, 0x90, 0x00, 0xaf }, + { 0x33, 0x8c, 0xa7, 0x78 }, + { 0x33, 0x90, 0x00, 0xbc }, + { 0x33, 0x8c, 0xa7, 0x79 }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x7a }, + { 0x33, 0x90, 0x00, 0xd0 }, + { 0x33, 0x8c, 0xa7, 0x7b }, + { 0x33, 0x90, 0x00, 0xd9 }, + { 0x33, 0x8c, 0xa7, 0x7c }, + { 0x33, 0x90, 0x00, 0xe0 }, + { 0x33, 0x8c, 0xa7, 0x7d }, + { 0x33, 0x90, 0x00, 0xe8 }, + { 0x33, 0x8c, 0xa7, 0x7e }, + { 0x33, 0x90, 0x00, 0xee }, + { 0x33, 0x8c, 0xa7, 0x7f }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x80 }, + { 0x33, 0x90, 0x00, 0xfa }, + { 0x33, 0x8c, 0xa7, 0x81 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa7, 0x82 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x83 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa7, 0x84 }, + { 0x33, 0x90, 0x00, 0x10 }, + { 0x33, 0x8c, 0xa7, 0x85 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa7, 0x86 }, + { 0x33, 0x90, 0x00, 0x5b }, + { 0x33, 0x8c, 0xa7, 0x87 }, + { 0x33, 0x90, 0x00, 0x77 }, + { 0x33, 0x8c, 0xa7, 0x88 }, + { 0x33, 0x90, 0x00, 0x8e }, + { 0x33, 0x8c, 0xa7, 0x89 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0xa7, 0x8a }, + { 0x33, 0x90, 0x00, 0xaf }, + { 0x33, 0x8c, 0xa7, 0x8b }, + { 0x33, 0x90, 0x00, 0xbc }, + { 0x33, 0x8c, 0xa7, 0x8c }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x8d }, + { 0x33, 0x90, 0x00, 0xd0 }, + { 0x33, 0x8c, 0xa7, 0x8e }, + { 0x33, 0x90, 0x00, 0xd9 }, + { 0x33, 0x8c, 0xa7, 0x8f }, + { 0x33, 0x90, 0x00, 0xe0 }, + { 0x33, 0x8c, 0xa7, 0x90 }, + { 0x33, 0x90, 0x00, 0xe8 }, + { 0x33, 0x8c, 0xa7, 0x91 }, + { 0x33, 0x90, 0x00, 0xee }, + { 0x33, 0x8c, 0xa7, 0x92 }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x93 }, + { 0x33, 0x90, 0x00, 0xfa }, + { 0x33, 0x8c, 0xa7, 0x94 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa2, 0x06 }, + { 0x33, 0x90, 0x00, 0x50 }, + { 0x33, 0x8c, 0x27, 0x03 }, + { 0x33, 0x90, 0x02, 0x82 }, + { 0x33, 0x8c, 0x27, 0x05 }, + { 0x33, 0x90, 0x01, 0xe2 }, + { 0x33, 0x8c, 0x27, 0x07 }, + { 0x33, 0x90, 0x05, 0x02 }, + { 0x33, 0x8c, 0x27, 0x09 }, + { 0x33, 0x90, 0x04, 0x02 }, + { 0x33, 0x8c, 0x27, 0x0d }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x0f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x11 }, + { 0x33, 0x90, 0x04, 0xbd }, + { 0x33, 0x8c, 0x27, 0x13 }, + { 0x33, 0x90, 0x06, 0x4d }, + { 0x33, 0x8c, 0x27, 0x15 }, + { 0x33, 0x90, 0x04, 0x00 }, + { 0x33, 0x8c, 0x27, 0x17 }, + { 0x33, 0x90, 0x21, 0x11 }, + { 0x33, 0x8c, 0x27, 0x19 }, + { 0x33, 0x90, 0x04, 0x6c }, + { 0x33, 0x8c, 0x27, 0x1b }, + { 0x33, 0x90, 0x02, 0x4f }, + { 0x33, 0x8c, 0x27, 0x1d }, + { 0x33, 0x90, 0x01, 0x02 }, + { 0x33, 0x8c, 0x27, 0x1f }, + { 0x33, 0x90, 0x02, 0x79 }, + { 0x33, 0x8c, 0x27, 0x21 }, + { 0x33, 0x90, 0x01, 0x55 }, + { 0x33, 0x8c, 0x27, 0x23 }, + { 0x33, 0x90, 0x03, 0x5b }, + { 0x33, 0x8c, 0x27, 0x25 }, + { 0x33, 0x90, 0x06, 0x0f }, + { 0x33, 0x8c, 0x27, 0x27 }, + { 0x33, 0x90, 0x20, 0x20 }, + { 0x33, 0x8c, 0x27, 0x29 }, + { 0x33, 0x90, 0x20, 0x20 }, + { 0x33, 0x8c, 0x27, 0x2b }, + { 0x33, 0x90, 0x10, 0x20 }, + { 0x33, 0x8c, 0x27, 0x2d }, + { 0x33, 0x90, 0x20, 0x07 }, + { 0x33, 0x8c, 0x27, 0x2f }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0x27, 0x31 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0x27, 0x33 }, + { 0x33, 0x90, 0x04, 0xbb }, + { 0x33, 0x8c, 0x27, 0x35 }, + { 0x33, 0x90, 0x06, 0x4b }, + { 0x33, 0x8c, 0x27, 0x37 }, + { 0x33, 0x90, 0x04, 0xce }, + { 0x33, 0x8c, 0x27, 0x39 }, + { 0x33, 0x90, 0x21, 0x11 }, + { 0x33, 0x8c, 0x27, 0x3b }, + { 0x33, 0x90, 0x00, 0x24 }, + { 0x33, 0x8c, 0x27, 0x3d }, + { 0x33, 0x90, 0x01, 0x20 }, + { 0x33, 0x8c, 0x27, 0x41 }, + { 0x33, 0x90, 0x01, 0x69 }, + { 0x33, 0x8c, 0x27, 0x45 }, + { 0x33, 0x90, 0x04, 0xff }, + { 0x33, 0x8c, 0x27, 0x47 }, + { 0x33, 0x90, 0x08, 0x24 }, + { 0x33, 0x8c, 0x27, 0x51 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x53 }, + { 0x33, 0x90, 0x03, 0x20 }, + { 0x33, 0x8c, 0x27, 0x55 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x57 }, + { 0x33, 0x90, 0x02, 0x58 }, + { 0x33, 0x8c, 0x27, 0x5f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x61 }, + { 0x33, 0x90, 0x06, 0x40 }, + { 0x33, 0x8c, 0x27, 0x63 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x65 }, + { 0x33, 0x90, 0x04, 0xb0 }, + { 0x33, 0x8c, 0x22, 0x2e }, + { 0x33, 0x90, 0x00, 0xd7 }, + { 0x33, 0x8c, 0xa4, 0x08 }, + { 0x33, 0x90, 0x00, 0x2a }, + { 0x33, 0x8c, 0xa4, 0x09 }, + { 0x33, 0x90, 0x00, 0x2c }, + { 0x33, 0x8c, 0xa4, 0x0a }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa4, 0x0b }, + { 0x33, 0x90, 0x00, 0x34 }, + { 0x33, 0x8c, 0x24, 0x11 }, + { 0x33, 0x90, 0x00, 0xd7 }, + { 0x33, 0x8c, 0x24, 0x13 }, + { 0x33, 0x90, 0x01, 0x02 }, + { 0x33, 0x8c, 0x24, 0x15 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0x24, 0x17 }, + { 0x33, 0x90, 0x00, 0xc0 }, + { 0x33, 0x8c, 0x27, 0x99 }, + { 0x33, 0x90, 0x64, 0x08 }, + { 0x33, 0x8c, 0x27, 0x9b }, + { 0x33, 0x90, 0x64, 0x08 }, + { 0x33, 0x8c, 0xa2, 0x0c }, + { 0x33, 0x90, 0x00, 0x18 }, + { 0x33, 0x8c, 0xa2, 0x14 }, + { 0x33, 0x90, 0x00, 0x24 }, + { 0x33, 0x8c, 0xa2, 0x15 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa2, 0x0d }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa2, 0x0e }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x06 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x30 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x15 }, + { 0x33, 0x90, 0x00, 0xef }, + { 0x33, 0x8c, 0xa1, 0x16 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa1, 0x17 }, + { 0x33, 0x90, 0x00, 0x55 }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x5a }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x28 }, + { 0x33, 0x8c, 0xa1, 0x1a }, + { 0x33, 0x90, 0x00, 0x08 }, + { 0x33, 0x8c, 0xa1, 0x1b }, + { 0x33, 0x90, 0x00, 0x1e }, + { 0x33, 0x8c, 0xa1, 0x1c }, + { 0x33, 0x90, 0x00, 0x02 }, + { 0x33, 0x8c, 0xa1, 0x1d }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x1e }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x1f }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xab, 0x05 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x6d }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6e }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x70 }, + { 0x33, 0x90, 0x00, 0x15 }, + { 0x33, 0x8c, 0xa7, 0x71 }, + { 0x33, 0x90, 0x00, 0x25 }, + { 0x33, 0x8c, 0xa7, 0x72 }, + { 0x33, 0x90, 0x00, 0x3f }, + { 0x33, 0x8c, 0xa7, 0x73 }, + { 0x33, 0x90, 0x00, 0x64 }, + { 0x33, 0x8c, 0xa7, 0x74 }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa7, 0x75 }, + { 0x33, 0x90, 0x00, 0x97 }, + { 0x33, 0x8c, 0xa7, 0x76 }, + { 0x33, 0x90, 0x00, 0xa9 }, + { 0x33, 0x8c, 0xa7, 0x77 }, + { 0x33, 0x90, 0x00, 0xba }, + { 0x33, 0x8c, 0xa7, 0x78 }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x79 }, + { 0x33, 0x90, 0x00, 0xd2 }, + { 0x33, 0x8c, 0xa7, 0x7a }, + { 0x33, 0x90, 0x00, 0xdc }, + { 0x33, 0x8c, 0xa7, 0x7b }, + { 0x33, 0x90, 0x00, 0xe4 }, + { 0x33, 0x8c, 0xa7, 0x7c }, + { 0x33, 0x90, 0x00, 0xea }, + { 0x33, 0x8c, 0xa7, 0x7d }, + { 0x33, 0x90, 0x00, 0xf0 }, + { 0x33, 0x8c, 0xa7, 0x7e }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x7f }, + { 0x33, 0x90, 0x00, 0xf8 }, + { 0x33, 0x8c, 0xa7, 0x80 }, + { 0x33, 0x90, 0x00, 0xfc }, + { 0x33, 0x8c, 0xa7, 0x81 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa7, 0x82 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x83 }, + { 0x33, 0x90, 0x00, 0x15 }, + { 0x33, 0x8c, 0xa7, 0x84 }, + { 0x33, 0x90, 0x00, 0x25 }, + { 0x33, 0x8c, 0xa7, 0x85 }, + { 0x33, 0x90, 0x00, 0x3f }, + { 0x33, 0x8c, 0xa7, 0x86 }, + { 0x33, 0x90, 0x00, 0x64 }, + { 0x33, 0x8c, 0xa7, 0x87 }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa7, 0x88 }, + { 0x33, 0x90, 0x00, 0x97 }, + { 0x33, 0x8c, 0xa7, 0x89 }, + { 0x33, 0x90, 0x00, 0xa9 }, + { 0x33, 0x8c, 0xa7, 0x8a }, + { 0x33, 0x90, 0x00, 0xba }, + { 0x33, 0x8c, 0xa7, 0x8b }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x8c }, + { 0x33, 0x90, 0x00, 0xd2 }, + { 0x33, 0x8c, 0xa7, 0x8d }, + { 0x33, 0x90, 0x00, 0xdc }, + { 0x33, 0x8c, 0xa7, 0x8e }, + { 0x33, 0x90, 0x00, 0xe4 }, + { 0x33, 0x8c, 0xa7, 0x8f }, + { 0x33, 0x90, 0x00, 0xea }, + { 0x33, 0x8c, 0xa7, 0x90 }, + { 0x33, 0x90, 0x00, 0xf0 }, + { 0x33, 0x8c, 0xa7, 0x91 }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x92 }, + { 0x33, 0x90, 0x00, 0xf8 }, + { 0x33, 0x8c, 0xa7, 0x93 }, + { 0x33, 0x90, 0x00, 0xfc }, + { 0x33, 0x8c, 0xa7, 0x94 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x06 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x35, 0xa4, 0x05, 0x96 }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x1e }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x1a }, + { 0x33, 0x90, 0x00, 0x0a }, + { 0x33, 0x8c, 0xa1, 0x1b }, + { 0x33, 0x90, 0x00, 0x20 }, + { 0x33, 0x8c, 0xa1, 0x3e }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x3f }, + { 0x33, 0x90, 0x00, 0x0e }, + { 0x33, 0x8c, 0xa1, 0x40 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x41 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x42 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x43 }, + { 0x33, 0x90, 0x00, 0x0f }, + { 0x33, 0x8c, 0xa1, 0x44 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x45 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x46 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x47 }, + { 0x33, 0x90, 0x00, 0x3a }, + { 0x33, 0x8c, 0x27, 0x95 }, + { 0x33, 0x90, 0x01, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0x27, 0x97 }, + { 0x33, 0x90, 0x01, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa4, 0x04 }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90 } + }; + + + asize = ARRAY_SIZE(values_205); + + for(i=0; ivsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + */ +int dev_stk6a51_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk6a51_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a0); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk6a51_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stk6a51_configure_device(dev, 19); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk6a51_stop_stream(struct usb_stk11xx *dev) +{ + return 0; +} + diff --git a/stk11xx-dev-6a54.c b/stk11xx-dev-6a54.c new file mode 100644 index 0000000..e00bd36 --- /dev/null +++ b/stk11xx-dev-6a54.c @@ -0,0 +1,525 @@ +/** + * @file stk11xx-dev-6a54.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-6A54 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk6a54_initialize_device(struct usb_stk11xx *dev) +{ + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6a54_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001c); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + usb_stk11xx_write_registry(dev, 0x0208, 0x001d); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x004b); + + + dev_stk6a54_configure_device(dev, 1); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stk6a54_configure_device(struct usb_stk11xx *dev, int step) +{ + int value; + + // 0, 1 + static const int values_001B[] = { + 0x0e, 0x0e + }; + static const int values_001C[] = { + 0x46, 0x46 + }; + static const int values_0202[] = { + 0x1e, 0x1e + }; + static const int values_0110[] = { + 0x00, 0x00 + }; + static const int values_0112[] = { + 0x00, 0x00 + }; + static const int values_0114[] = { + 0x00, 0x00 + }; + static const int values_0115[] = { + 0x00, 0x05 + }; + static const int values_0116[] = { + 0x00, 0xe0 + }; + static const int values_0117[] = { + 0x00, 0x01 + }; + static const int values_0100[] = { + 0x21, 0x21 + }; + + + STK_DEBUG("dev_stk6a54_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x00ff); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + dev_stk6a54_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk6a54_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk6a54_init_camera(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk6a54_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + + static const int values_204[] = { + 0xff, 0x12, 0xff, 0x2c, 0x2e, 0xff, 0x3c, 0x11, 0x09, 0x04, + 0x13, 0x14, 0x2c, 0x33, 0x3a, 0x3b, 0x3e, 0x43, 0x16, 0x39, + 0x35, 0x22, 0x37, 0x23, 0x34, 0x36, 0x06, 0x07, 0x0d, 0x0e, + 0x4c, 0x4a, 0x21, 0x24, 0x25, 0x26, 0x5c, 0x63, 0x46, 0x0c, + 0x61, 0x62, 0x7c, 0x20, 0x28, 0x6c, 0x6d, 0x6e, 0x70, 0x71, + 0x73, 0x3d, 0x5a, 0x4f, 0x50, 0xff, 0xe5, 0xf9, 0x41, 0xe0, + 0x76, 0x33, 0x42, 0x43, 0x4c, 0x87, 0x88, 0xd7, 0xd9, 0xd3, + 0xc8, 0xc9, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7d, 0x90, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x92, 0x93, + 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, + 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0xc3, 0xa4, 0xa8, 0xc5, + 0xc6, 0xbf, 0xc7, 0xb6, 0xb8, 0xb7, 0xb9, 0xb3, 0xb4, 0xb5, + 0xb0, 0xb1, 0xb2, 0xc4, 0xc0, 0xc1, 0x86, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x57, 0x5a, 0x5b, 0x5c, 0xc3, 0x7f, 0xda, + 0xd7, 0xe5, 0xe1, 0xe0, 0xdd, 0x05, 0xff, 0x12, 0x11, 0x17, + 0x18, 0x19, 0x1a, 0x32, 0x37, 0x4f, 0x50, 0x5a, 0x6d, 0x3d, + 0x39, 0x35, 0x22, 0x37, 0x23, 0x34, 0x36, 0x06, 0x07, 0x0d, + 0x0e, 0x4c, 0xff, 0xe0, 0xc0, 0xc1, 0x8c, 0x86, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x5a, 0x5b, 0x5c, 0xd3, 0xe0, 0xff, + 0xe0, 0xc0, 0xc1, 0x8c, 0x86, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x5a, 0x5b, 0x5c, 0xd3, 0xe0, 0xff, 0xff, 0x04, 0xff, + 0xff, 0xff, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7d, 0x7c, + 0xff, 0x7c, 0x7d, 0x7c, 0x7d, 0x7c, 0xff, 0x7c, 0x7d, 0x7c, + 0x7d, 0x7c, 0x7d, 0x7c, 0x7c, 0xff, 0x7c, 0x7d, 0x7c, 0x7d, + 0x7c, 0x7d, 0xff, 0x92, 0x93, 0xff, 0x90, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0xff, 0xc3, 0xc7, 0xce, 0xcc, 0xcd, 0xff, + 0x04, 0xff, 0x04 + }; + + static const int values_205[] = { + 0x01, 0x80, 0x00, 0xff, 0xdf, 0x01, 0x32, 0x00, 0x02, 0x28, + 0xe5, 0x48, 0x0c, 0x78, 0x33, 0xfb, 0x00, 0x11, 0x10, 0x02, + 0x88, 0x0a, 0x40, 0x00, 0xa0, 0x1a, 0x02, 0xc0, 0xb7, 0x01, + 0x00, 0x81, 0x99, 0x40, 0x38, 0x82, 0x00, 0x00, 0x3f, 0x3c, + 0x70, 0x80, 0x05, 0x80, 0x30, 0x00, 0x80, 0x00, 0x02, 0x94, + 0xc1, 0x34, 0x57, 0xbb, 0x9c, 0x00, 0x7f, 0xc0, 0x24, 0x14, + 0xff, 0xa0, 0x20, 0x18, 0x00, 0xd0, 0x3f, 0x03, 0x10, 0x82, + 0x08, 0x80, 0x00, 0x00, 0x03, 0x48, 0x48, 0x08, 0x20, 0x10, + 0x0e, 0x00, 0x0e, 0x1a, 0x31, 0x5a, 0x69, 0x75, 0x7e, 0x88, + 0x8f, 0x96, 0xa3, 0xaf, 0xc4, 0xd7, 0xe8, 0x20, 0x00, 0x06, + 0xe3, 0x05, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x19, 0x02, 0x0c, 0x24, 0x30, 0x28, + 0x26, 0x02, 0x98, 0x80, 0x00, 0x00, 0xed, 0x00, 0x00, 0x11, + 0x51, 0x80, 0x10, 0x66, 0xa5, 0x64, 0x7c, 0xaf, 0x97, 0xff, + 0xc5, 0x94, 0x0f, 0x5c, 0xc8, 0x96, 0x3d, 0x00, 0x90, 0x18, + 0x00, 0x00, 0x88, 0x00, 0x90, 0x18, 0x05, 0xed, 0x00, 0x00, + 0x01, 0x1f, 0x67, 0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0x11, + 0x43, 0x00, 0x4b, 0x09, 0xc0, 0xca, 0xa8, 0x23, 0x00, 0x38, + 0x12, 0xda, 0x1a, 0xc3, 0x00, 0xc0, 0x1a, 0x88, 0xc0, 0x87, + 0x41, 0x00, 0x00, 0x04, 0x64, 0x4b, 0x00, 0x1d, 0x00, 0xc8, + 0x96, 0x00, 0x00, 0x00, 0xc8, 0x96, 0x00, 0x82, 0x00, 0x00, + 0x04, 0x64, 0x4b, 0x00, 0x3d, 0x00, 0xc8, 0x96, 0x00, 0x00, + 0x00, 0xa0, 0x78, 0x00, 0x82, 0x00, 0x00, 0x01, 0xfa, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x0a, 0x09, 0x16, 0x0a, 0x06, 0x09, + 0x00, 0x00, 0x04, 0x08, 0x28, 0x08, 0x00, 0x00, 0x05, 0x01, + 0x7f, 0x02, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x07, 0x03, 0x4d, + 0x04, 0x4d, 0x00, 0x01, 0xc5, 0x00, 0x00, 0x00, 0x23, 0x3c, + 0x50, 0x63, 0x73, 0x83, 0x92, 0xa0, 0xad, 0xba, 0xc6, 0xd2, + 0xde, 0xe9, 0xf5, 0x01, 0x0c, 0x00, 0x80, 0x80, 0x80, 0x01, + 0xfa, 0x01, 0xfa + }; + + asize = ARRAY_SIZE(values_204); + + for(i=0; i +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-6D51 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk6d51_initialize_device(struct usb_stk11xx *dev) +{ + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stk6d51_configure_device(dev, 0); + + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stk6d51_camera_asleep(dev); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00f8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + + dev_stk6d51_configure_device(dev, 1); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stk6d51_configure_device(struct usb_stk11xx *dev, int step) +{ + int value; + + // 0, 1 + static const int values_001B[] = { + 0x0e, 0x0e + }; + static const int values_001C[] = { + 0x46, 0x46 + }; + static const int values_0202[] = { + 0x0a, 0x0a + }; + static const int values_0110[] = { + 0x00, 0x00 + }; + static const int values_0112[] = { + 0x01, 0x01 + }; + static const int values_0114[] = { + 0x80, 0x80 + }; + static const int values_0115[] = { + 0x02, 0x02 + }; + static const int values_0116[] = { + 0xe1, 0xe1 + }; + static const int values_0117[] = { + 0x01, 0x01 + }; + static const int values_0100[] = { + 0x20, 0x20 + }; + + + STK_DEBUG("dev_stk6d51_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0078); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + usb_stk11xx_write_registry(dev, 0x0205, 0x0030); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0061); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x007a); + + dev_stk6d51_sensor_settings(dev); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0200, 0x0021); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk6d51_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk6d51_init_camera(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stk6d51_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + + static const int values_205[][4] = { + { 0x33, 0x86, 0x05, 0x01 }, + { 0x33, 0x86, 0x05, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x30, 0x1a, 0x0a, 0xcc }, + { 0x32, 0x02, 0x00, 0x08 }, + { 0x33, 0xf4, 0x03, 0x1d }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x34, 0x1e, 0x8f, 0x09 }, + { 0x34, 0x1c, 0x02, 0x50 }, + { 0x34, 0x1e, 0x8f, 0x09 }, + { 0x34, 0x1e, 0x8f, 0x08 }, + { 0x33, 0x8c, 0x04, 0x00 }, + { 0x33, 0x90, 0x30, 0x8f }, + { 0x33, 0x92, 0xc3, 0xff }, + { 0x33, 0x94, 0xed, 0x8f }, + { 0x33, 0x96, 0x35, 0x8f }, + { 0x33, 0x98, 0x18, 0x8f }, + { 0x33, 0x9a, 0x30, 0x8f }, + { 0x33, 0x9c, 0xc3, 0x00 }, + { 0x33, 0x9e, 0x15, 0x8f }, + { 0x33, 0x8c, 0x04, 0x10 }, + { 0x33, 0x90, 0xcc, 0x00 }, + { 0x33, 0x92, 0x07, 0xbd }, + { 0x33, 0x94, 0x04, 0xb5 }, + { 0x33, 0x96, 0xbd, 0x9e }, + { 0x33, 0x98, 0x9f, 0xf6 }, + { 0x33, 0x9a, 0x03, 0x22 }, + { 0x33, 0x9c, 0x30, 0xe7 }, + { 0x33, 0x9e, 0x0a, 0xf6 }, + { 0x33, 0x8c, 0x04, 0x20 }, + { 0x33, 0x90, 0x02, 0x39 }, + { 0x33, 0x92, 0xc1, 0x01 }, + { 0x33, 0x94, 0x26, 0x05 }, + { 0x33, 0x96, 0xf6, 0x03 }, + { 0x33, 0x98, 0x23, 0xe7 }, + { 0x33, 0x9a, 0x0a, 0x7d }, + { 0x33, 0x9c, 0x03, 0x21 }, + { 0x33, 0x9e, 0x27, 0x20 }, + { 0x33, 0x8c, 0x04, 0x30 }, + { 0x33, 0x90, 0xf6, 0x02 }, + { 0x33, 0x92, 0x39, 0xe7 }, + { 0x33, 0x94, 0x02, 0x8f }, + { 0x33, 0x96, 0xc3, 0x00 }, + { 0x33, 0x98, 0x0b, 0x30 }, + { 0x33, 0x9a, 0xed, 0x00 }, + { 0x33, 0x9c, 0xfe, 0x02 }, + { 0x33, 0x9e, 0x37, 0xee }, + { 0x33, 0x8c, 0x04, 0x40 }, + { 0x33, 0x90, 0x04, 0x5f }, + { 0x33, 0x92, 0xad, 0x00 }, + { 0x33, 0x94, 0x30, 0xe6 }, + { 0x33, 0x96, 0x0a, 0x4f }, + { 0x33, 0x98, 0xed, 0x08 }, + { 0x33, 0x9a, 0xec, 0x11 }, + { 0x33, 0x9c, 0xa3, 0x08 }, + { 0x33, 0x9e, 0xdd, 0x56 }, + { 0x33, 0x8c, 0x04, 0x50 }, + { 0x33, 0x90, 0x30, 0xc6 }, + { 0x33, 0x92, 0x13, 0x3a }, + { 0x33, 0x94, 0x35, 0x39 }, + { 0x33, 0x96, 0x3c, 0x3c }, + { 0x33, 0x98, 0x3c, 0xc6 }, + { 0x33, 0x9a, 0x01, 0xf7 }, + { 0x33, 0x9c, 0x03, 0x21 }, + { 0x33, 0x9e, 0xc6, 0x0a }, + { 0x33, 0x8c, 0x04, 0x60 }, + { 0x33, 0x90, 0xf7, 0x03 }, + { 0x33, 0x92, 0x22, 0xf7 }, + { 0x33, 0x94, 0x03, 0x23 }, + { 0x33, 0x96, 0xcc, 0x03 }, + { 0x33, 0x98, 0x03, 0x30 }, + { 0x33, 0x9a, 0xed, 0x02 }, + { 0x33, 0x9c, 0xfe, 0x10 }, + { 0x33, 0x9e, 0x50, 0xec }, + { 0x33, 0x8c, 0x04, 0x70 }, + { 0x33, 0x90, 0x04, 0xfd }, + { 0x33, 0x92, 0x02, 0xff }, + { 0x33, 0x94, 0xfe, 0x02 }, + { 0x33, 0x96, 0xff, 0xec }, + { 0x33, 0x98, 0x00, 0xfd }, + { 0x33, 0x9a, 0x03, 0x01 }, + { 0x33, 0x9c, 0x5f, 0x4f }, + { 0x33, 0x9e, 0x30, 0xed }, + { 0x33, 0x8c, 0x04, 0x80 }, + { 0x33, 0x90, 0x04, 0xec }, + { 0x33, 0x92, 0x04, 0x05 }, + { 0x33, 0x94, 0xf3, 0x03 }, + { 0x33, 0x96, 0x01, 0x8f }, + { 0x33, 0x98, 0xec, 0x00 }, + { 0x33, 0x9a, 0x30, 0xed }, + { 0x33, 0x9c, 0x00, 0xec }, + { 0x33, 0x9e, 0x04, 0x05 }, + { 0x33, 0x8c, 0x04, 0x90 }, + { 0x33, 0x90, 0xe3, 0x02 }, + { 0x33, 0x92, 0x18, 0x8f }, + { 0x33, 0x94, 0xec, 0x00 }, + { 0x33, 0x96, 0x18, 0xed }, + { 0x33, 0x98, 0x00, 0xec }, + { 0x33, 0x9a, 0x04, 0xc3 }, + { 0x33, 0x9c, 0x00, 0x01 }, + { 0x33, 0x9e, 0xed, 0x04 }, + { 0x33, 0x8c, 0x04, 0xa0 }, + { 0x33, 0x90, 0x83, 0x00 }, + { 0x33, 0x92, 0x0f, 0x25 }, + { 0x33, 0x94, 0xdc, 0xee }, + { 0x33, 0x96, 0x02, 0xcc }, + { 0x33, 0x98, 0x04, 0x00 }, + { 0x33, 0x9a, 0xed, 0x04 }, + { 0x33, 0x9c, 0xcc, 0x03 }, + { 0x33, 0x9e, 0x03, 0xdd }, + { 0x33, 0x8c, 0x04, 0xb0 }, + { 0x33, 0x90, 0x52, 0x38 }, + { 0x33, 0x92, 0x38, 0x38 }, + { 0x33, 0x94, 0x39, 0x37 }, + { 0x33, 0x96, 0x36, 0x8f }, + { 0x33, 0x98, 0x30, 0xe3 }, + { 0x33, 0x9a, 0x00, 0x8f }, + { 0x33, 0x9c, 0x18, 0x8f }, + { 0x33, 0x9e, 0x18, 0x30 }, + { 0x33, 0x8c, 0x04, 0xc0 }, + { 0x33, 0x90, 0x18, 0xe3 }, + { 0x33, 0x92, 0x00, 0x18 }, + { 0x33, 0x94, 0x8f, 0x32 }, + { 0x33, 0x96, 0x33, 0x36 }, + { 0x33, 0x98, 0xa6, 0x00 }, + { 0x33, 0x9a, 0x18, 0xa7 }, + { 0x33, 0x9c, 0x00, 0x09 }, + { 0x33, 0x9e, 0x18, 0x09 }, + { 0x33, 0x8c, 0x04, 0xd0 }, + { 0x33, 0x90, 0xc0, 0x01 }, + { 0x33, 0x92, 0x24, 0xf4 }, + { 0x33, 0x94, 0x32, 0x80 }, + { 0x33, 0x96, 0x01, 0x24 }, + { 0x33, 0x98, 0xee, 0x39 }, + { 0x33, 0x8c, 0x20, 0x03 }, + { 0x33, 0x90, 0x04, 0x56 }, + { 0x33, 0x8c, 0xa0, 0x02 }, + { 0x33, 0x90, 0x00, 0x01 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x34, 0xce, 0x81, 0x60 }, + { 0x34, 0xd0, 0x66, 0x33 }, + { 0x34, 0xd2, 0x31, 0x9a }, + { 0x34, 0xd4, 0x94, 0x63 }, + { 0x34, 0xd6, 0x4b, 0x25 }, + { 0x34, 0xd8, 0x26, 0x70 }, + { 0x34, 0xda, 0x72, 0x4c }, + { 0x34, 0xdc, 0xff, 0x04 }, + { 0x34, 0xde, 0x00, 0xf4 }, + { 0x34, 0xe6, 0x00, 0xcc }, + { 0x34, 0xee, 0x0e, 0x42 }, + { 0x34, 0xf6, 0x0d, 0xb5 }, + { 0x35, 0x00, 0x0a, 0xfa }, + { 0x35, 0x08, 0x0f, 0x10 }, + { 0x35, 0x10, 0x11, 0x22 }, + { 0x35, 0x18, 0x0c, 0x28 }, + { 0x35, 0x20, 0x1c, 0x2c }, + { 0x35, 0x28, 0x17, 0x40 }, + { 0x35, 0x30, 0x08, 0xf2 }, + { 0x35, 0x38, 0xfb, 0xd5 }, + { 0x35, 0x4c, 0x05, 0xc7 }, + { 0x35, 0x44, 0x04, 0xf9 }, + { 0x35, 0x5c, 0x05, 0xd0 }, + { 0x35, 0x54, 0x05, 0xf4 }, + { 0x34, 0xe0, 0x01, 0x05 }, + { 0x34, 0xe8, 0x00, 0xa0 }, + { 0x34, 0xf0, 0x0e, 0xa1 }, + { 0x34, 0xf8, 0x0e, 0x01 }, + { 0x35, 0x02, 0x0f, 0xeb }, + { 0x35, 0x0a, 0x09, 0x0a }, + { 0x35, 0x12, 0x10, 0x1e }, + { 0x35, 0x1a, 0x08, 0x23 }, + { 0x35, 0x22, 0x1c, 0x22 }, + { 0x35, 0x2a, 0x07, 0x22 }, + { 0x35, 0x32, 0x0b, 0x06 }, + { 0x35, 0x3a, 0xf9, 0x16 }, + { 0x35, 0x4e, 0x05, 0x9f }, + { 0x35, 0x46, 0x05, 0x30 }, + { 0x35, 0x5e, 0x06, 0x75 }, + { 0x35, 0x56, 0x06, 0x5c }, + { 0x34, 0xe4, 0x00, 0xc5 }, + { 0x34, 0xec, 0x00, 0x48 }, + { 0x34, 0xf4, 0x0f, 0x66 }, + { 0x34, 0xfc, 0x0e, 0x61 }, + { 0x35, 0x06, 0x1b, 0xdb }, + { 0x35, 0x0e, 0x04, 0x0a }, + { 0x35, 0x16, 0x11, 0x13 }, + { 0x35, 0x1e, 0x08, 0x1f }, + { 0x35, 0x26, 0x11, 0x19 }, + { 0x35, 0x2e, 0xf8, 0x1a }, + { 0x35, 0x36, 0x04, 0x0c }, + { 0x35, 0x3e, 0xfa, 0x00 }, + { 0x35, 0x52, 0x06, 0xf1 }, + { 0x35, 0x4a, 0x04, 0x0e }, + { 0x35, 0x62, 0x06, 0xa1 }, + { 0x35, 0x5a, 0x06, 0x91 }, + { 0x34, 0xe2, 0x00, 0xd2 }, + { 0x34, 0xea, 0x00, 0x72 }, + { 0x34, 0xf2, 0x0e, 0x1d }, + { 0x34, 0xfa, 0x0e, 0x06 }, + { 0x35, 0x04, 0x13, 0x0e }, + { 0x35, 0x0c, 0x0f, 0x0d }, + { 0x35, 0x14, 0x13, 0x1c }, + { 0x35, 0x1c, 0x13, 0x29 }, + { 0x35, 0x24, 0x0d, 0x24 }, + { 0x35, 0x2c, 0xfd, 0x29 }, + { 0x35, 0x34, 0x07, 0xf4 }, + { 0x35, 0x3c, 0xee, 0xe7 }, + { 0x35, 0x50, 0x06, 0x50 }, + { 0x35, 0x48, 0x05, 0xc1 }, + { 0x35, 0x60, 0x06, 0x11 }, + { 0x35, 0x58, 0x06, 0x58 }, + { 0x35, 0x40, 0x00, 0x00 }, + { 0x35, 0x42, 0x00, 0x00 }, + { 0x32, 0x10, 0x01, 0xfc }, + { 0x33, 0x8c, 0xa3, 0x52 }, + { 0x33, 0x90, 0x00, 0x3c }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x3c }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x0a }, + { 0x33, 0x8c, 0xa7, 0x6d }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6e }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x70 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa7, 0x71 }, + { 0x33, 0x90, 0x00, 0x10 }, + { 0x33, 0x8c, 0xa7, 0x72 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa7, 0x73 }, + { 0x33, 0x90, 0x00, 0x5b }, + { 0x33, 0x8c, 0xa7, 0x74 }, + { 0x33, 0x90, 0x00, 0x77 }, + { 0x33, 0x8c, 0xa7, 0x75 }, + { 0x33, 0x90, 0x00, 0x8e }, + { 0x33, 0x8c, 0xa7, 0x76 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0xa7, 0x77 }, + { 0x33, 0x90, 0x00, 0xaf }, + { 0x33, 0x8c, 0xa7, 0x78 }, + { 0x33, 0x90, 0x00, 0xbc }, + { 0x33, 0x8c, 0xa7, 0x79 }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x7a }, + { 0x33, 0x90, 0x00, 0xd0 }, + { 0x33, 0x8c, 0xa7, 0x7b }, + { 0x33, 0x90, 0x00, 0xd9 }, + { 0x33, 0x8c, 0xa7, 0x7c }, + { 0x33, 0x90, 0x00, 0xe0 }, + { 0x33, 0x8c, 0xa7, 0x7d }, + { 0x33, 0x90, 0x00, 0xe8 }, + { 0x33, 0x8c, 0xa7, 0x7e }, + { 0x33, 0x90, 0x00, 0xee }, + { 0x33, 0x8c, 0xa7, 0x7f }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x80 }, + { 0x33, 0x90, 0x00, 0xfa }, + { 0x33, 0x8c, 0xa7, 0x81 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa7, 0x82 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x83 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa7, 0x84 }, + { 0x33, 0x90, 0x00, 0x10 }, + { 0x33, 0x8c, 0xa7, 0x85 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa7, 0x86 }, + { 0x33, 0x90, 0x00, 0x5b }, + { 0x33, 0x8c, 0xa7, 0x87 }, + { 0x33, 0x90, 0x00, 0x77 }, + { 0x33, 0x8c, 0xa7, 0x88 }, + { 0x33, 0x90, 0x00, 0x8e }, + { 0x33, 0x8c, 0xa7, 0x89 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0xa7, 0x8a }, + { 0x33, 0x90, 0x00, 0xaf }, + { 0x33, 0x8c, 0xa7, 0x8b }, + { 0x33, 0x90, 0x00, 0xbc }, + { 0x33, 0x8c, 0xa7, 0x8c }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x8d }, + { 0x33, 0x90, 0x00, 0xd0 }, + { 0x33, 0x8c, 0xa7, 0x8e }, + { 0x33, 0x90, 0x00, 0xd9 }, + { 0x33, 0x8c, 0xa7, 0x8f }, + { 0x33, 0x90, 0x00, 0xe0 }, + { 0x33, 0x8c, 0xa7, 0x90 }, + { 0x33, 0x90, 0x00, 0xe8 }, + { 0x33, 0x8c, 0xa7, 0x91 }, + { 0x33, 0x90, 0x00, 0xee }, + { 0x33, 0x8c, 0xa7, 0x92 }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x93 }, + { 0x33, 0x90, 0x00, 0xfa }, + { 0x33, 0x8c, 0xa7, 0x94 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa2, 0x06 }, + { 0x33, 0x90, 0x00, 0x50 }, + { 0x33, 0x8c, 0x27, 0x03 }, + { 0x33, 0x90, 0x02, 0x82 }, + { 0x33, 0x8c, 0x27, 0x05 }, + { 0x33, 0x90, 0x01, 0xe2 }, + { 0x33, 0x8c, 0x27, 0x07 }, + { 0x33, 0x90, 0x05, 0x02 }, + { 0x33, 0x8c, 0x27, 0x09 }, + { 0x33, 0x90, 0x04, 0x02 }, + { 0x33, 0x8c, 0x27, 0x0d }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x0f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x11 }, + { 0x33, 0x90, 0x04, 0xbd }, + { 0x33, 0x8c, 0x27, 0x13 }, + { 0x33, 0x90, 0x06, 0x4d }, + { 0x33, 0x8c, 0x27, 0x15 }, + { 0x33, 0x90, 0x04, 0x00 }, + { 0x33, 0x8c, 0x27, 0x17 }, + { 0x33, 0x90, 0x21, 0x11 }, + { 0x33, 0x8c, 0x27, 0x19 }, + { 0x33, 0x90, 0x04, 0x6c }, + { 0x33, 0x8c, 0x27, 0x1b }, + { 0x33, 0x90, 0x02, 0x4f }, + { 0x33, 0x8c, 0x27, 0x1d }, + { 0x33, 0x90, 0x01, 0x02 }, + { 0x33, 0x8c, 0x27, 0x1f }, + { 0x33, 0x90, 0x02, 0x79 }, + { 0x33, 0x8c, 0x27, 0x21 }, + { 0x33, 0x90, 0x01, 0x55 }, + { 0x33, 0x8c, 0x27, 0x23 }, + { 0x33, 0x90, 0x03, 0x5b }, + { 0x33, 0x8c, 0x27, 0x25 }, + { 0x33, 0x90, 0x06, 0x0f }, + { 0x33, 0x8c, 0x27, 0x27 }, + { 0x33, 0x90, 0x20, 0x20 }, + { 0x33, 0x8c, 0x27, 0x29 }, + { 0x33, 0x90, 0x20, 0x20 }, + { 0x33, 0x8c, 0x27, 0x2b }, + { 0x33, 0x90, 0x10, 0x20 }, + { 0x33, 0x8c, 0x27, 0x2d }, + { 0x33, 0x90, 0x20, 0x07 }, + { 0x33, 0x8c, 0x27, 0x2f }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0x27, 0x31 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0x27, 0x33 }, + { 0x33, 0x90, 0x04, 0xbb }, + { 0x33, 0x8c, 0x27, 0x35 }, + { 0x33, 0x90, 0x06, 0x4b }, + { 0x33, 0x8c, 0x27, 0x37 }, + { 0x33, 0x90, 0x04, 0xce }, + { 0x33, 0x8c, 0x27, 0x39 }, + { 0x33, 0x90, 0x21, 0x11 }, + { 0x33, 0x8c, 0x27, 0x3b }, + { 0x33, 0x90, 0x00, 0x24 }, + { 0x33, 0x8c, 0x27, 0x3d }, + { 0x33, 0x90, 0x01, 0x20 }, + { 0x33, 0x8c, 0x27, 0x41 }, + { 0x33, 0x90, 0x01, 0x69 }, + { 0x33, 0x8c, 0x27, 0x45 }, + { 0x33, 0x90, 0x04, 0xff }, + { 0x33, 0x8c, 0x27, 0x47 }, + { 0x33, 0x90, 0x08, 0x24 }, + { 0x33, 0x8c, 0x27, 0x51 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x53 }, + { 0x33, 0x90, 0x03, 0x20 }, + { 0x33, 0x8c, 0x27, 0x55 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x57 }, + { 0x33, 0x90, 0x02, 0x58 }, + { 0x33, 0x8c, 0x27, 0x5f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x61 }, + { 0x33, 0x90, 0x06, 0x40 }, + { 0x33, 0x8c, 0x27, 0x63 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0x27, 0x65 }, + { 0x33, 0x90, 0x04, 0xb0 }, + { 0x33, 0x8c, 0x22, 0x2e }, + { 0x33, 0x90, 0x00, 0xd7 }, + { 0x33, 0x8c, 0xa4, 0x08 }, + { 0x33, 0x90, 0x00, 0x2a }, + { 0x33, 0x8c, 0xa4, 0x09 }, + { 0x33, 0x90, 0x00, 0x2c }, + { 0x33, 0x8c, 0xa4, 0x0a }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa4, 0x0b }, + { 0x33, 0x90, 0x00, 0x34 }, + { 0x33, 0x8c, 0x24, 0x11 }, + { 0x33, 0x90, 0x00, 0xd7 }, + { 0x33, 0x8c, 0x24, 0x13 }, + { 0x33, 0x90, 0x01, 0x02 }, + { 0x33, 0x8c, 0x24, 0x15 }, + { 0x33, 0x90, 0x00, 0xa0 }, + { 0x33, 0x8c, 0x24, 0x17 }, + { 0x33, 0x90, 0x00, 0xc0 }, + { 0x33, 0x8c, 0x27, 0x99 }, + { 0x33, 0x90, 0x64, 0x08 }, + { 0x33, 0x8c, 0x27, 0x9b }, + { 0x33, 0x90, 0x64, 0x08 }, + { 0x33, 0x8c, 0xa2, 0x0c }, + { 0x33, 0x90, 0x00, 0x18 }, + { 0x33, 0x8c, 0xa2, 0x14 }, + { 0x33, 0x90, 0x00, 0x24 }, + { 0x33, 0x8c, 0xa2, 0x15 }, + { 0x33, 0x90, 0x00, 0x02 }, // 0x04 or 0x02 + { 0x33, 0x8c, 0xa2, 0x0d }, + { 0x33, 0x90, 0x00, 0x10 }, // 0x30 or 0x10 + { 0x33, 0x8c, 0xa2, 0x0e }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x06 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x30 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x15 }, + { 0x33, 0x90, 0x00, 0xef }, + { 0x33, 0x8c, 0xa1, 0x16 }, + { 0x33, 0x90, 0x00, 0x30 }, + { 0x33, 0x8c, 0xa1, 0x17 }, + { 0x33, 0x90, 0x00, 0x55 }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x5a }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x28 }, + { 0x33, 0x8c, 0xa1, 0x1a }, + { 0x33, 0x90, 0x00, 0x08 }, + { 0x33, 0x8c, 0xa1, 0x1b }, + { 0x33, 0x90, 0x00, 0x1e }, + { 0x33, 0x8c, 0xa1, 0x1c }, + { 0x33, 0x90, 0x00, 0x02 }, + { 0x33, 0x8c, 0xa1, 0x1d }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x1e }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x1f }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xab, 0x05 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x6d }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6e }, + { 0x33, 0x90, 0x00, 0x03 }, + { 0x33, 0x8c, 0xa7, 0x6f }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x70 }, + { 0x33, 0x90, 0x00, 0x15 }, + { 0x33, 0x8c, 0xa7, 0x71 }, + { 0x33, 0x90, 0x00, 0x25 }, + { 0x33, 0x8c, 0xa7, 0x72 }, + { 0x33, 0x90, 0x00, 0x3f }, + { 0x33, 0x8c, 0xa7, 0x73 }, + { 0x33, 0x90, 0x00, 0x64 }, + { 0x33, 0x8c, 0xa7, 0x74 }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa7, 0x75 }, + { 0x33, 0x90, 0x00, 0x97 }, + { 0x33, 0x8c, 0xa7, 0x76 }, + { 0x33, 0x90, 0x00, 0xa9 }, + { 0x33, 0x8c, 0xa7, 0x77 }, + { 0x33, 0x90, 0x00, 0xba }, + { 0x33, 0x8c, 0xa7, 0x78 }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x79 }, + { 0x33, 0x90, 0x00, 0xd2 }, + { 0x33, 0x8c, 0xa7, 0x7a }, + { 0x33, 0x90, 0x00, 0xdc }, + { 0x33, 0x8c, 0xa7, 0x7b }, + { 0x33, 0x90, 0x00, 0xe4 }, + { 0x33, 0x8c, 0xa7, 0x7c }, + { 0x33, 0x90, 0x00, 0xea }, + { 0x33, 0x8c, 0xa7, 0x7d }, + { 0x33, 0x90, 0x00, 0xf0 }, + { 0x33, 0x8c, 0xa7, 0x7e }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x7f }, + { 0x33, 0x90, 0x00, 0xf8 }, + { 0x33, 0x8c, 0xa7, 0x80 }, + { 0x33, 0x90, 0x00, 0xfc }, + { 0x33, 0x8c, 0xa7, 0x81 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa7, 0x82 }, + { 0x33, 0x90, 0x00, 0x00 }, + { 0x33, 0x8c, 0xa7, 0x83 }, + { 0x33, 0x90, 0x00, 0x15 }, + { 0x33, 0x8c, 0xa7, 0x84 }, + { 0x33, 0x90, 0x00, 0x25 }, + { 0x33, 0x8c, 0xa7, 0x85 }, + { 0x33, 0x90, 0x00, 0x3f }, + { 0x33, 0x8c, 0xa7, 0x86 }, + { 0x33, 0x90, 0x00, 0x64 }, + { 0x33, 0x8c, 0xa7, 0x87 }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa7, 0x88 }, + { 0x33, 0x90, 0x00, 0x97 }, + { 0x33, 0x8c, 0xa7, 0x89 }, + { 0x33, 0x90, 0x00, 0xa9 }, + { 0x33, 0x8c, 0xa7, 0x8a }, + { 0x33, 0x90, 0x00, 0xba }, + { 0x33, 0x8c, 0xa7, 0x8b }, + { 0x33, 0x90, 0x00, 0xc7 }, + { 0x33, 0x8c, 0xa7, 0x8c }, + { 0x33, 0x90, 0x00, 0xd2 }, + { 0x33, 0x8c, 0xa7, 0x8d }, + { 0x33, 0x90, 0x00, 0xdc }, + { 0x33, 0x8c, 0xa7, 0x8e }, + { 0x33, 0x90, 0x00, 0xe4 }, + { 0x33, 0x8c, 0xa7, 0x8f }, + { 0x33, 0x90, 0x00, 0xea }, + { 0x33, 0x8c, 0xa7, 0x90 }, + { 0x33, 0x90, 0x00, 0xf0 }, + { 0x33, 0x8c, 0xa7, 0x91 }, + { 0x33, 0x90, 0x00, 0xf4 }, + { 0x33, 0x8c, 0xa7, 0x92 }, + { 0x33, 0x90, 0x00, 0xf8 }, + { 0x33, 0x8c, 0xa7, 0x93 }, + { 0x33, 0x90, 0x00, 0xfc }, + { 0x33, 0x8c, 0xa7, 0x94 }, + { 0x33, 0x90, 0x00, 0xff }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x06 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x35, 0xa4, 0x05, 0x96 }, + { 0x33, 0x8c, 0xa1, 0x18 }, + { 0x33, 0x90, 0x00, 0x1e }, + { 0x33, 0x8c, 0xa1, 0x19 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x1a }, + { 0x33, 0x90, 0x00, 0x0a }, + { 0x33, 0x8c, 0xa1, 0x1b }, + { 0x33, 0x90, 0x00, 0x20 }, + { 0x33, 0x8c, 0xa1, 0x3e }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x3f }, + { 0x33, 0x90, 0x00, 0x0e }, + { 0x33, 0x8c, 0xa1, 0x40 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x41 }, + { 0x33, 0x90, 0x00, 0x04 }, + { 0x33, 0x8c, 0xa1, 0x42 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x43 }, + { 0x33, 0x90, 0x00, 0x0f }, + { 0x33, 0x8c, 0xa1, 0x44 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x45 }, + { 0x33, 0x90, 0x00, 0x32 }, + { 0x33, 0x8c, 0xa1, 0x46 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa1, 0x47 }, + { 0x33, 0x90, 0x00, 0x3a }, + { 0x33, 0x8c, 0x27, 0x95 }, + { 0x33, 0x90, 0x01, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0x27, 0x97 }, + { 0x33, 0x90, 0x01, 0x00 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa4, 0x04 }, + { 0x33, 0x90, 0x00, 0xc0 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 }, + { 0x33, 0x8c, 0xa2, 0x06 }, + { 0x33, 0x90, 0x00, 0x50 }, + { 0x33, 0x8c, 0xa2, 0x0c }, + { 0x33, 0x90, 0x00, 0x18 }, + { 0x33, 0x8c, 0xa2, 0x15 }, + { 0x33, 0x90, 0x00, 0x02 }, + { 0x33, 0x8c, 0xa2, 0x0d }, + { 0x33, 0x90, 0x00, 0x10 }, + { 0x33, 0x8c, 0xa2, 0x0e }, + { 0x33, 0x90, 0x00, 0x80 }, + { 0x33, 0x8c, 0xa4, 0x04 }, + { 0x33, 0x90, 0x00, 0xc0 }, + { 0x33, 0x8c, 0xa1, 0x03 }, + { 0x33, 0x90, 0x00, 0x05 }, + { 0x33, 0x8c, 0xa1, 0x04 }, + { 0x33, 0x90, -1 } + }; + + + asize = ARRAY_SIZE(values_205); + + for(i=0; ivsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + */ +int dev_stk6d51_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk6d51_start_stream(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk6d51_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk6d51_stop_stream(struct usb_stk11xx *dev) +{ + return 0; +} + + diff --git a/stk11xx-dev-a311.c b/stk11xx-dev-a311.c new file mode 100644 index 0000000..abaef75 --- /dev/null +++ b/stk11xx-dev-a311.c @@ -0,0 +1,1057 @@ +/** + * @file stk11xx-dev-a311.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-M811 API / STK-A311 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stka311_initialize_device(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 1 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 2 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 3 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0001); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka311_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka311_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka311_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0013); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stka311_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka311_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka311_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0013); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stka311_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0013); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stka311_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0013); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000a); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x000b); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka311_configure_device(dev, 8); + + dev_stka311_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 11 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + * + * The steps 0 to 9 are called during the initialization. + * Then, the driver choose the last step : + * 10 : for a resolution from 80x60 to 640x480 + * 11 : for a resolution from 800x600 to 1280x1024 + */ +int dev_stka311_configure_device(struct usb_stk11xx *dev, int step) +{ + int retok; + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + + static const int values_001B[] = { + 0x0e, 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e + }; + static const int values_001C[] = { + 0x06, 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x0e + }; + static const int values_0202[] = { + 0x1e, 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e + }; + static const int values_0110[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0112[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0114[] = { + 0x87, 0x80, 0x80, 0x80, 0x80, 0xbe, 0xbe, 0x80, 0x80, 0x80, 0x80, 0x00 + }; + static const int values_0115[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x05 + }; + static const int values_0116[] = { + 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe9, 0xe0, 0xe0, 0xe0, 0xe0, 0x00 + }; + static const int values_0117[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04 + }; + static const int values_0100[] = { + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 + }; + + STK_DEBUG("dev_stka311_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, values_0115[step]); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, values_0117[step]); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0040); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0041); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0204, 0x001c); + usb_stk11xx_write_registry(dev, 0x0205, 0x0002); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + dev_stka311_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + dev_stka311_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0104, 0x0000); + usb_stk11xx_write_registry(dev, 0x0105, 0x0000); + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + + break; + + case 10: + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + dev_stka311_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002a); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002b); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + break; + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stka311_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x004c); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stka311_init_camera(struct usb_stk11xx *dev) +{ + int retok; + int value; + + dev_stka311_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka311_configure_device(dev, 9); + + dev_stk11xx_camera_off(dev); + + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002a); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002b); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + dev_stka311_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stka311_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + int *values_204 = NULL; + int *values_205 = NULL; + + // From 80x60 to 640x480 + static const int values_1_204[] = { + 0x12, 0x11, 0x3b, 0x6a, 0x13, 0x10, 0x00, 0x01, 0x02, 0x13, + 0x39, 0x38, 0x37, 0x35, 0x0e, 0x12, 0x04, 0x0c, 0x0d, 0x17, + 0x18, 0x32, 0x19, 0x1a, 0x03, 0x1b, 0x16, 0x33, 0x34, 0x41, + 0x96, 0x3d, 0x69, 0x3a, 0x8e, 0x3c, 0x8f, 0x8b, 0x8c, 0x94, + 0x95, 0x40, 0x29, 0x0f, 0xa5, 0x1e, 0xa9, 0xaa, 0xab, 0x90, + 0x91, 0x9f, 0xa0, 0x24, 0x25, 0x26, 0x14, 0x2a, 0x2b + }; + static const int values_1_205[] = { + 0x45, 0x80, 0x01, 0x7d, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, + 0x50, 0x93, 0x00, 0x81, 0x20, 0x45, 0x00, 0x00, 0x00, 0x24, + 0xc4, 0xb6, 0x00, 0x3c, 0x36, 0x00, 0x07, 0xe2, 0xbf, 0x00, + 0x04, 0x19, 0x40, 0x0d, 0x00, 0x73, 0xdf, 0x06, 0x20, 0x88, + 0x88, 0xc1, 0x3f, 0x42, 0x80, 0x04, 0xb8, 0x92, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x68, 0x5c, 0xc3, 0x2e, 0x00, 0x00 + }; + + // From 800x600 to 1280x1024 + static const int values_2_204[] = { + 0x12, 0x11, 0x3b, 0x6a, 0x13, 0x10, 0x00, 0x01, 0x02, 0x13, + 0x39, 0x38, 0x37, 0x35, 0x0e, 0x12, 0x04, 0x0c, 0x0d, 0x17, + 0x18, 0x32, 0x19, 0x1a, 0x03, 0x1b, 0x16, 0x33, 0x34, 0x41, + 0x96, 0x3d, 0x69, 0x3a, 0x8e, 0x3c, 0x8f, 0x8b, 0x8c, 0x94, + 0x95, 0x40, 0x29, 0x0f, 0xa5, 0x1e, 0xa9, 0xaa, 0xab, 0x90, + 0x91, 0x9f, 0xa0, 0x24, 0x25, 0x26, 0x14, 0x2a, 0x2b + }; + static const int values_2_205[] = { + 0x05, 0x80, 0x01, 0x7d, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, + 0x50, 0x93, 0x00, 0x81, 0x20, 0x05, 0x00, 0x00, 0x00, 0x1b, + 0xbb, 0xa4, 0x01, 0x81, 0x12, 0x00, 0x07, 0xe2, 0xbf, 0x00, + 0x04, 0x19, 0x40, 0x0d, 0x00, 0x73, 0xdf, 0x06, 0x20, 0x88, + 0x88, 0xc1, 0x3f, 0x42, 0x80, 0x04, 0xb8, 0x92, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x68, 0x5c, 0xc3, 0x2e, 0x00, 0x00 + }; + + + // From the resolution + switch (dev->resolution) { + case STK11XX_1280x1024: + case STK11XX_1024x768: + case STK11XX_800x600: + case STK11XX_720x576: + asize = ARRAY_SIZE(values_2_204); + values_204 = (int *) values_2_204; + values_205 = (int *) values_2_205; + break; + + case STK11XX_640x480: + case STK11XX_320x240: + case STK11XX_160x120: + case STK11XX_213x160: + case STK11XX_128x96: + case STK11XX_80x60: + default: + asize = ARRAY_SIZE(values_1_204); + values_204 = (int *) values_1_204; + values_205 = (int *) values_1_205; + break; + } + + + for(i=0; i already looked 0x01 and 0x02) + * 0x204 = 0x00 : brightness / white balance (by default 0x00) + */ +int dev_stka311_set_camera_quality(struct usb_stk11xx *dev) +{ + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + + // Colour registers + usb_stk11xx_write_registry(dev, 0x0204, 0x0001); + usb_stk11xx_write_registry(dev, 0x0205, (255 - (dev->vsettings.colour >> 8))); + usb_stk11xx_write_registry(dev, 0x0204, 0x0002); + usb_stk11xx_write_registry(dev, 0x0205, (dev->vsettings.colour >> 8)); + + // Unknown register + usb_stk11xx_write_registry(dev, 0x0204, 0x00a1); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + + // Contrast register + usb_stk11xx_write_registry(dev, 0x0204, 0x0010); + usb_stk11xx_write_registry(dev, 0x0205, (dev->vsettings.contrast >> 9)); + + // Unknown register + usb_stk11xx_write_registry(dev, 0x0204, 0x0004); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + + // Whiteness register + usb_stk11xx_write_registry(dev, 0x0204, 0x0000); + usb_stk11xx_write_registry(dev, 0x0205, (dev->vsettings.whiteness >> 11) | 0x20); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0006); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + * + * 0x204 = 0x2e : Fps MSB (by default 0x01) + * 0x204 = 0x2d : Fps LSB (by default 0x00) + * + * 0x2e | 0x2d | Nbr fps + * -----+------+-------- + * 0x00 | 0x00 | 30 + * 0x01 | 0x00 | 20 + * 0x02 | 0x00 | 15 + * 0x03 | 0x00 | 12 + * 0x04 | 0x00 | 10 + */ +int dev_stka311_set_camera_fps(struct usb_stk11xx *dev) +{ + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + + // FPS register + switch (dev->vsettings.fps) { + case 10: + usb_stk11xx_write_registry(dev, 0x0204, 0x002e); + usb_stk11xx_write_registry(dev, 0x0205, 0x0004); + usb_stk11xx_write_registry(dev, 0x0204, 0x002d); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + break; + + case 15: + usb_stk11xx_write_registry(dev, 0x0204, 0x002e); + usb_stk11xx_write_registry(dev, 0x0205, 0x0002); + usb_stk11xx_write_registry(dev, 0x0204, 0x002d); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + break; + + case 20: + usb_stk11xx_write_registry(dev, 0x0204, 0x002e); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0204, 0x002d); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + break; + + default: + case 25: + usb_stk11xx_write_registry(dev, 0x0204, 0x002e); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002d); + usb_stk11xx_write_registry(dev, 0x0205, 0x0064); + break; + + case 30: + usb_stk11xx_write_registry(dev, 0x0204, 0x002e); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + usb_stk11xx_write_registry(dev, 0x0204, 0x002d); + usb_stk11xx_write_registry(dev, 0x0205, 0x0000); + break; + } + + usb_stk11xx_write_registry(dev, 0x0200, 0x0006); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stka311_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a1); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stka311_reconf_camera(struct usb_stk11xx *dev) +{ + int step = 10; + + // Choose the step from the resolution + switch (dev->resolution) { + case STK11XX_1280x1024: + case STK11XX_1024x768: + case STK11XX_800x600: + case STK11XX_720x576: + step = 11; + break; + + case STK11XX_640x480: + case STK11XX_320x240: + case STK11XX_160x120: + case STK11XX_213x160: + case STK11XX_128x96: + case STK11XX_80x60: + default: + step = 10; + break; + } + + dev_stka311_configure_device(dev, step); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stka311_stop_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + + return 0; +} + diff --git a/stk11xx-dev-a821.c b/stk11xx-dev-a821.c new file mode 100644 index 0000000..3a38539 --- /dev/null +++ b/stk11xx-dev-a821.c @@ -0,0 +1,904 @@ +/** + * @file stk11xx-dev-a821.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +//============================================================================= +// +// STK-A821 API +// +//============================================================================= + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stka821_initialize_device(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + STK_INFO("Initialize USB2.0 Syntek Camera\n"); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 1 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 2 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0027); + usb_stk11xx_write_registry(dev, 0x0000, 0x0026); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + + for (i=0; i<16; i++) { + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_read_registry(dev, 0x0000, &value); + + STK_DEBUG("Loop 3 : Read 0x0000 = %02X\n", value); + } + + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0001); + usb_stk11xx_read_registry(dev, 0x0103, &value); + usb_stk11xx_write_registry(dev, 0x0103, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka821_configure_device(dev, 0); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 1); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 2); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 3); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 4); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 5); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 6); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 7); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 8); + retok = dev_stk11xx_check_device(dev, 65); + usb_stk11xx_write_registry(dev, 0x0200, 0x0008); + + dev_stka821_configure_device(dev, 9); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x006d); + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0000, 0x0025); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka821_configure_device(dev, 10); + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0001); + usb_stk11xx_write_registry(dev, 0x0203, 0x00a0); + + dev_stka821_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + // Device is initialized and is ready !!! + STK_INFO("Syntek USB2.0 Camera is ready\n"); + + return 0; +} + + +/** + * @param dev Device structure + * @param step The step of configuration [0-11] + * + * @returns 0 if all is OK + * + * @brief This function permits to configure the device. + * + * The configuration of device is composed of 12 steps. + * This function is called by the initialization process. + * + * We don't know the meaning of these steps ! We only replay the USB log. + */ +int dev_stka821_configure_device(struct usb_stk11xx *dev, int step) +{ + int retok; + int value; + + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 + static const int values_001B[] = { + 0x0e, 0x03, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x07, 0x07, 0x07, 0x07, 0x07 + }; + static const int values_001C[] = { + 0x06, 0x02, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 + }; + static const int values_0202[] = { + 0x1e, 0x0a, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e + }; + static const int values_0110[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0112[] = { + 0x07, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + static const int values_0114[] = { + 0x87, 0x80, 0x80, 0x80, 0x80, 0xbe, 0xbe, 0x80, 0x84, 0x80, 0x80, 0x80, 0x80, 0x80 + }; + static const int values_0116[] = { + 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe9, 0xe9, 0xe0, 0xe4, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0 + }; + static const int values_0100[] = { + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20 + }; + + STK_DEBUG("dev_stka821_configure_device : %d\n", step); + + usb_stk11xx_write_registry(dev, 0x0000, 0x0024); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0003, 0x0080); + usb_stk11xx_write_registry(dev, 0x0005, 0x0000); + + usb_stk11xx_write_registry(dev, 0x0007, 0x0003); + usb_stk11xx_write_registry(dev, 0x000d, 0x0000); + usb_stk11xx_write_registry(dev, 0x000f, 0x0002); + usb_stk11xx_write_registry(dev, 0x0300, 0x0012); + usb_stk11xx_write_registry(dev, 0x0350, 0x0041); + + usb_stk11xx_write_registry(dev, 0x0351, 0x0000); + usb_stk11xx_write_registry(dev, 0x0352, 0x0000); + usb_stk11xx_write_registry(dev, 0x0353, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0010); + usb_stk11xx_write_registry(dev, 0x0019, 0x0000); + + usb_stk11xx_write_registry(dev, 0x001b, values_001B[step]); + usb_stk11xx_write_registry(dev, 0x001c, values_001C[step]); + usb_stk11xx_write_registry(dev, 0x0300, 0x0080); + usb_stk11xx_write_registry(dev, 0x001a, 0x0004); + usb_stk11xx_write_registry(dev, 0x0202, values_0202[step]); + + usb_stk11xx_write_registry(dev, 0x0110, values_0110[step]); + usb_stk11xx_write_registry(dev, 0x0111, 0x0000); + usb_stk11xx_write_registry(dev, 0x0112, values_0112[step]); + usb_stk11xx_write_registry(dev, 0x0113, 0x0000); + usb_stk11xx_write_registry(dev, 0x0114, values_0114[step]); + + usb_stk11xx_write_registry(dev, 0x0115, 0x0002); + usb_stk11xx_write_registry(dev, 0x0116, values_0116[step]); + usb_stk11xx_write_registry(dev, 0x0117, 0x0001); + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, values_0100[step]); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0080); + usb_stk11xx_write_registry(dev, 0x0200, 0x0000); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + + switch (step) { + case 0: + usb_stk11xx_write_registry(dev, 0x0203, 0x0040); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0041); + usb_stk11xx_write_registry(dev, 0x0205, 0x0001); + usb_stk11xx_write_registry(dev, 0x0204, 0x001c); + usb_stk11xx_write_registry(dev, 0x0205, 0x0002); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 1: + usb_stk11xx_write_registry(dev, 0x0203, 0x0022); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0027); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 2: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00bf); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 3: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 4: + usb_stk11xx_write_registry(dev, 0x0203, 0x0042); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0204, 0x0024); + usb_stk11xx_write_registry(dev, 0x0205, 0x00a5); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 5: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 6: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 7: + usb_stk11xx_write_registry(dev, 0x0203, 0x0060); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x0013); + usb_stk11xx_write_registry(dev, 0x0205, 0x00b7); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 8: + usb_stk11xx_write_registry(dev, 0x0203, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0012); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + usb_stk11xx_write_registry(dev, 0x0204, 0x000a); + usb_stk11xx_write_registry(dev, 0x0205, 0x00ff); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + break; + + case 9: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + usb_stk11xx_write_registry(dev, 0x0204, 0x0015); + usb_stk11xx_write_registry(dev, 0x0205, 0x0080); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0005); + + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0000); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0001); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_read_registry(dev, 0x02ff, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0208, 0x0002); + usb_stk11xx_write_registry(dev, 0x0200, 0x0020); + retok = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_read_registry(dev, 0x0209, &value); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + usb_stk11xx_write_registry(dev, 0x0002, 0x006f); + + break; + + case 10: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + dev_stka821_sensor_settings(dev); + + break; + + case 11: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + dev_stka821_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0104, 0x0000); + usb_stk11xx_write_registry(dev, 0x0105, 0x0000); + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + + break; + + case 12: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + dev_stka821_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0104, 0x0000); + usb_stk11xx_write_registry(dev, 0x0105, 0x0000); + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + + break; + + case 13: + usb_stk11xx_write_registry(dev, 0x0203, 0x00dc); + + dev_stka821_sensor_settings(dev); + + usb_stk11xx_write_registry(dev, 0x0106, 0x0000); + } + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stka821_camera_asleep(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0104, &value); + usb_stk11xx_read_registry(dev, 0x0105, &value); + usb_stk11xx_read_registry(dev, 0x0106, &value); + + usb_stk11xx_write_registry(dev, 0x0100, 0x0021); + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + usb_stk11xx_write_registry(dev, 0x0018, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0000, &value); + usb_stk11xx_write_registry(dev, 0x0000, 0x0049); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stka821_init_camera(struct usb_stk11xx *dev) +{ +// int retok; +// int value; + + dev_stka821_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka821_configure_device(dev, 11); + + dev_stk11xx_camera_off(dev); + + dev_stka821_camera_settings(dev); + + dev_stka821_camera_asleep(dev); + + usb_stk11xx_set_feature(dev, 0); + + usb_stk11xx_write_registry(dev, 0x0000, 0x00e0); + usb_stk11xx_write_registry(dev, 0x0002, 0x00e8); + usb_stk11xx_write_registry(dev, 0x0002, 0x0068); + usb_stk11xx_write_registry(dev, 0x0000, 0x0020); + + dev_stka821_configure_device(dev, 12); + + dev_stk11xx_camera_off(dev); + + dev_stka821_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to set default sensor settings. + * + * We set some registers in using a I2C bus. + * WARNING, the sensor settings can be different following the situation. + */ +int dev_stka821_sensor_settings(struct usb_stk11xx *dev) +{ + int i; + int retok; + int value; + + int asize; + static const int values_204[] = { + 0x17, 0x19, 0xb4, 0xa6, 0x12, 0x13, 0x1e, 0x21, 0x24, 0x32, + 0x36, 0x39, 0x4d, 0x53, 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x82, 0x83, 0x85, 0x86, 0x89, 0x97, 0x98, + 0xad, 0xae, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbf, 0x48, 0xd8, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0xd8, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0xd8, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x5c, 0xc0, + 0x59, 0x5a, 0x5b, 0xd4, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0xb3, 0x73, 0x06, 0x07, 0x0b, 0x15, 0x20, + 0x4e, 0x4f, 0x49, 0x4a, 0x4b, 0x4c, 0x46, 0x06, 0x07, 0xb9, + 0xba, 0xbb, 0xbc, 0x61, 0x62, 0x65, 0x66 + }; + static const int values_205[] = { + 0x41, 0x41, 0x03, 0x06, 0x06, 0x08, 0x06, 0x00, 0x02, 0x69, + 0x35, 0x60, 0xfe, 0x1c, 0x04, 0x08, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x10, 0x14, 0x01, 0x80, 0x0c, 0xb6, 0x00, 0x25, 0x25, + 0x3f, 0x24, 0x10, 0x07, 0xcc, 0x1f, 0x30, 0x02, 0x9c, 0x80, + 0x00, 0x0d, 0x18, 0x22, 0x2c, 0x3e, 0x4f, 0x6f, 0x8e, 0xac, + 0xc8, 0xe5, 0xa0, 0x00, 0x0d, 0x18, 0x22, 0x2c, 0x3e, 0x4f, + 0x6f, 0x8e, 0xac, 0xc8, 0xe5, 0xc0, 0x00, 0x0d, 0x18, 0x22, + 0x2c, 0x3e, 0x4f, 0x6f, 0x8e, 0xac, 0xc8, 0xe5, 0x70, 0x18, + 0x09, 0x07, 0x07, 0x3c, 0x3d, 0x95, 0x88, 0x89, 0x47, 0x9c, + 0x81, 0x9c, 0x3d, 0x76, 0x76, 0x01, 0xf3, 0x05, 0x00, 0x44, + 0x06, 0x0a, 0x96, 0x00, 0x7d, 0x00, 0x20, 0x01, 0xf3, 0x04, + 0xe4, 0x09, 0xc8, 0x08, 0x08, 0x10, 0x14 + }; + + + asize = ARRAY_SIZE(values_204); + + for(i=0; ivsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + asize = ARRAY_SIZE(values_204); + + for (i=1; ivsettings.contrast >> 8)); + + usb_stk11xx_write_registry(dev, 0x0200, 0x0001); + ret = dev_stk11xx_check_device(dev, 500); + usb_stk11xx_write_registry(dev, 0x02ff, 0x0000); + + STK_DEBUG("Set colour : %d\n", dev->vsettings.colour); + STK_DEBUG("Set contrast : %d\n", dev->vsettings.contrast); + STK_DEBUG("Set whiteness : %d\n", dev->vsettings.whiteness); + STK_DEBUG("Set brightness : %d\n", dev->vsettings.brightness); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the frame rate per second. + */ +int dev_stka821_set_camera_fps(struct usb_stk11xx *dev) +{ + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stka821_start_stream(struct usb_stk11xx *dev) +{ + int value; + int value_116, value_117; + + usb_stk11xx_read_registry(dev, 0x0116, &value_116); + usb_stk11xx_read_registry(dev, 0x0117, &value_117); + + usb_stk11xx_write_registry(dev, 0x0116, 0x0000); + usb_stk11xx_write_registry(dev, 0x0117, 0x0000); + + usb_stk11xx_read_registry(dev, 0x0100, &value); // read 0x21 + usb_stk11xx_write_registry(dev, 0x0100, 0x00a0); + + usb_stk11xx_write_registry(dev, 0x0116, value_116); + usb_stk11xx_write_registry(dev, 0x0117, value_117); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stka821_reconf_camera(struct usb_stk11xx *dev) +{ + dev_stka821_configure_device(dev, 13); + + dev_stk11xx_camera_settings(dev); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stka821_stop_stream(struct usb_stk11xx *dev) +{ + int value; + + usb_stk11xx_read_registry(dev, 0x0100, &value); + usb_stk11xx_write_registry(dev, 0x0100, 0x0020); + + return 0; +} + diff --git a/stk11xx-dev.c b/stk11xx-dev.c new file mode 100644 index 0000000..e6600a0 --- /dev/null +++ b/stk11xx-dev.c @@ -0,0 +1,756 @@ +/** + * @file stk11xx-dev.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" +#include "stk11xx-dev.h" + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to initialize the device. + * + * This function must be called at first. It's the start of the + * initialization process. After this process, the device is + * completly initalized and it's ready. + * + * This function is written from the USB log. + */ +int dev_stk11xx_initialize_device(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_initialize_device(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_initialize_device(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_initialize_device(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_initialize_device(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_initialize_device(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_initialize_device(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_initialize_device(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_initialize_device(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_initialize_device(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function initializes the device for the stream. + * + * It's the start. This function has to be called at first, before + * enabling the video stream. + */ +int dev_stk11xx_init_camera(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_init_camera(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_init_camera(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_init_camera(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_init_camera(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_init_camera(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_init_camera(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_init_camera(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_init_camera(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_init_camera(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * @param nbr Number of tries + * + * @returns 0 if all is OK + * + * @brief This function permits to check the device in reading the register 0x0201. + * + * When we configure the stk11xx, this function is used to check the device status. + * - If the read value is 0x00, then the device isn't ready. + * - If the read value is 0x04, then the device is ready. + * - If the read value is other, then the device is misconfigured. + */ +int dev_stk11xx_check_device(struct usb_stk11xx *dev, int nbr) +{ + int i; + int value; + + for (i=0; iudev; + + ret = usb_set_interface(udev, 0, 5); + + if (ret < 0) + STK_ERROR("usb_set_interface failed !\n"); + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function switchs off the camera. + * + * In fact, we choose the alternate interface '0'. + */ +int dev_stk11xx_camera_off(struct usb_stk11xx *dev) +{ + int ret = -1; + struct usb_device *udev = dev->udev; + + ret = usb_set_interface(udev, 0, 0); + + if (ret < 0) + STK_ERROR("usb_set_interface failed !\n"); + + return 0; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Wake-up the camera. + * + * This function permits to wake-up the device. + */ +int dev_stk11xx_camera_asleep(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_camera_asleep(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_camera_asleep(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_camera_asleep(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_camera_asleep(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_camera_asleep(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_camera_asleep(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_camera_asleep(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_camera_asleep(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_camera_asleep(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the settings of the camera. + * + * This functions permits to modify the settings : + * - brightness + * - contrast + * - white balance + * - ... + */ +int dev_stk11xx_camera_settings(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_camera_settings(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_camera_settings(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_camera_settings(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_camera_settings(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_camera_settings(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_camera_settings(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_camera_settings(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_camera_settings(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_camera_settings(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the quality video of the camera. + * + * This functions permits to modify the settings : + * - brightness + * - contrast + * - white balance + * - ... + */ +int dev_stk11xx_set_camera_quality(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_set_camera_quality(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_set_camera_quality(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_set_camera_quality(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_set_camera_quality(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_set_camera_quality(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_set_camera_quality(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_set_camera_quality(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_set_camera_quality(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_set_camera_quality(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function permits to modify the fps of the camera. + * + * This functions permits to modify the frame rate per second of the camera. + * So the number of images per second. + */ +int dev_stk11xx_set_camera_fps(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_set_camera_fps(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_set_camera_fps(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_set_camera_fps(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_set_camera_fps(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_set_camera_fps(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_set_camera_fps(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_set_camera_fps(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_set_camera_fps(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_set_camera_fps(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to start the stream. + * + * After the initialization of the device and the initialization of the video stream, + * this function permits to enable the stream. + */ +int dev_stk11xx_start_stream(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_start_stream(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_start_stream(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_start_stream(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_start_stream(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_start_stream(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_start_stream(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_start_stream(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_start_stream(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_start_stream(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Reconfigure the camera before the stream. + * + * Before enabling the video stream, you have to reconfigure the device. + */ +int dev_stk11xx_reconf_camera(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_reconf_camera(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_reconf_camera(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_reconf_camera(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_reconf_camera(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_reconf_camera(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_reconf_camera(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_reconf_camera(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_reconf_camera(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_reconf_camera(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief This function sets the device to stop the stream. + * + * You use the function start_stream to enable the video stream. So you + * have to use the function stop_strem to disable the video stream. + */ +int dev_stk11xx_stop_stream(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + ret = dev_stk0408_stop_stream(dev); + break; + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + ret = dev_stka311_stop_stream(dev); + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + ret = dev_stka821_stop_stream(dev); + break; + + case SYNTEK_STK_6A31: + ret = dev_stk6a31_stop_stream(dev); + break; + + case SYNTEK_STK_6A33: + ret = dev_stk6a33_stop_stream(dev); + break; + + case SYNTEK_STK_6A51: + ret = dev_stk6a51_stop_stream(dev); + break; + + case SYNTEK_STK_6A54: + ret = dev_stk6a54_stop_stream(dev); + break; + + case SYNTEK_STK_6D51: + ret = dev_stk6d51_stop_stream(dev); + break; + + case SYNTEK_STK_0500: + ret = dev_stk0500_stop_stream(dev); + break; + + default: + ret = -1; + } + + return ret; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Decompress/convert a frame from the video stream + * + * @param dev Device structure + */ +int dev_stk11xx_decompress(struct usb_stk11xx *dev) +{ + int ret; + + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + // Use a particular decompressor based uvyv + ret = dev_stk0408_decode(dev); + break; + + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + case SYNTEK_STK_6A31: + case SYNTEK_STK_6A33: + case SYNTEK_STK_6A51: + case SYNTEK_STK_6A54: + case SYNTEK_STK_6D51: + // Use a generec decompressor based bayer stream + ret = stk11xx_decompress(dev); + break; + + default: + ret = -1; + } + + return ret; +} + diff --git a/stk11xx-dev.h b/stk11xx-dev.h new file mode 100644 index 0000000..1b6e66b --- /dev/null +++ b/stk11xx-dev.h @@ -0,0 +1,146 @@ +/** + * @file stk11xx-dev.h + * @author Nicolas VIVIEN + * @date 2007-11-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#ifndef STK11XX_DEV_H +#define STK11XX_DEV_H + +int dev_stk0408_initialize_device(struct usb_stk11xx *); +int dev_stk0408_configure_device(struct usb_stk11xx *, int); +int dev_stk0408_start_stream(struct usb_stk11xx *); +int dev_stk0408_stop_stream(struct usb_stk11xx *); +int dev_stk0408_camera_asleep(struct usb_stk11xx *); +int dev_stk0408_init_camera(struct usb_stk11xx *); +int dev_stk0408_sensor_settings(struct usb_stk11xx *); +int dev_stk0408_reconf_camera(struct usb_stk11xx *); +int dev_stk0408_camera_settings(struct usb_stk11xx *); +int dev_stk0408_set_camera_quality(struct usb_stk11xx *); +int dev_stk0408_set_camera_fps(struct usb_stk11xx *); +int dev_stk0408_decode(struct usb_stk11xx *); + +int dev_stka311_initialize_device(struct usb_stk11xx *); +int dev_stka311_configure_device(struct usb_stk11xx *, int); +int dev_stka311_start_stream(struct usb_stk11xx *); +int dev_stka311_stop_stream(struct usb_stk11xx *); +int dev_stka311_camera_asleep(struct usb_stk11xx *); +int dev_stka311_init_camera(struct usb_stk11xx *); +int dev_stka311_sensor_settings(struct usb_stk11xx *); +int dev_stka311_reconf_camera(struct usb_stk11xx *); +int dev_stka311_camera_settings(struct usb_stk11xx *); +int dev_stka311_set_camera_quality(struct usb_stk11xx *); +int dev_stka311_set_camera_fps(struct usb_stk11xx *); + +int dev_stka821_initialize_device(struct usb_stk11xx *); +int dev_stka821_configure_device(struct usb_stk11xx *, int); +int dev_stka821_start_stream(struct usb_stk11xx *); +int dev_stka821_stop_stream(struct usb_stk11xx *); +int dev_stka821_camera_asleep(struct usb_stk11xx *); +int dev_stka821_init_camera(struct usb_stk11xx *); +int dev_stka821_sensor_settings(struct usb_stk11xx *); +int dev_stka821_reconf_camera(struct usb_stk11xx *); +int dev_stka821_camera_settings(struct usb_stk11xx *); +int dev_stka821_set_camera_quality(struct usb_stk11xx *); +int dev_stka821_set_camera_fps(struct usb_stk11xx *); + +int dev_stk6a31_initialize_device(struct usb_stk11xx *); +int dev_stk6a31_configure_device(struct usb_stk11xx *, int); +int dev_stk6a31_start_stream(struct usb_stk11xx *); +int dev_stk6a31_stop_stream(struct usb_stk11xx *); +int dev_stk6a31_camera_asleep(struct usb_stk11xx *); +int dev_stk6a31_init_camera(struct usb_stk11xx *); +int dev_stk6a31_sensor_settings(struct usb_stk11xx *); +int dev_stk6a31_reconf_camera(struct usb_stk11xx *); +int dev_stk6a31_camera_settings(struct usb_stk11xx *); +int dev_stk6a31_set_camera_quality(struct usb_stk11xx *); +int dev_stk6a31_set_camera_fps(struct usb_stk11xx *); + +int dev_stk6a33_initialize_device(struct usb_stk11xx *); +int dev_stk6a33_configure_device(struct usb_stk11xx *, int); +int dev_stk6a33_start_stream(struct usb_stk11xx *); +int dev_stk6a33_stop_stream(struct usb_stk11xx *); +int dev_stk6a33_camera_asleep(struct usb_stk11xx *); +int dev_stk6a33_init_camera(struct usb_stk11xx *); +int dev_stk6a33_sensor_settings(struct usb_stk11xx *); +int dev_stk6a33_reconf_camera(struct usb_stk11xx *); +int dev_stk6a33_camera_settings(struct usb_stk11xx *); +int dev_stk6a33_set_camera_quality(struct usb_stk11xx *); +int dev_stk6a33_set_camera_fps(struct usb_stk11xx *); + +int dev_stk6a51_initialize_device(struct usb_stk11xx *); +int dev_stk6a51_configure_device(struct usb_stk11xx *, int); +int dev_stk6a51_start_stream(struct usb_stk11xx *); +int dev_stk6a51_stop_stream(struct usb_stk11xx *); +int dev_stk6a51_camera_asleep(struct usb_stk11xx *); +int dev_stk6a51_init_camera(struct usb_stk11xx *); +int dev_stk6a51_sensor_settings(struct usb_stk11xx *); +int dev_stk6a51_reconf_camera(struct usb_stk11xx *); +int dev_stk6a51_camera_settings(struct usb_stk11xx *); +int dev_stk6a51_set_camera_quality(struct usb_stk11xx *); +int dev_stk6a51_set_camera_fps(struct usb_stk11xx *); + +int dev_stk6a54_initialize_device(struct usb_stk11xx *); +int dev_stk6a54_configure_device(struct usb_stk11xx *, int); +int dev_stk6a54_start_stream(struct usb_stk11xx *); +int dev_stk6a54_stop_stream(struct usb_stk11xx *); +int dev_stk6a54_camera_asleep(struct usb_stk11xx *); +int dev_stk6a54_init_camera(struct usb_stk11xx *); +int dev_stk6a54_sensor_settings(struct usb_stk11xx *); +int dev_stk6a54_reconf_camera(struct usb_stk11xx *); +int dev_stk6a54_camera_settings(struct usb_stk11xx *); +int dev_stk6a54_set_camera_quality(struct usb_stk11xx *); +int dev_stk6a54_set_camera_fps(struct usb_stk11xx *); + +int dev_stk6d51_initialize_device(struct usb_stk11xx *); +int dev_stk6d51_configure_device(struct usb_stk11xx *, int); +int dev_stk6d51_start_stream(struct usb_stk11xx *); +int dev_stk6d51_stop_stream(struct usb_stk11xx *); +int dev_stk6d51_camera_asleep(struct usb_stk11xx *); +int dev_stk6d51_init_camera(struct usb_stk11xx *); +int dev_stk6d51_sensor_settings(struct usb_stk11xx *); +int dev_stk6d51_reconf_camera(struct usb_stk11xx *); +int dev_stk6d51_camera_settings(struct usb_stk11xx *); +int dev_stk6d51_set_camera_quality(struct usb_stk11xx *); +int dev_stk6d51_set_camera_fps(struct usb_stk11xx *); + +int dev_stk0500_initialize_device(struct usb_stk11xx *); +int dev_stk0500_configure_device(struct usb_stk11xx *, int); +int dev_stk0500_start_stream(struct usb_stk11xx *); +int dev_stk0500_stop_stream(struct usb_stk11xx *); +int dev_stk0500_camera_asleep(struct usb_stk11xx *); +int dev_stk0500_init_camera(struct usb_stk11xx *); +int dev_stk0500_sensor_settings(struct usb_stk11xx *); +int dev_stk0500_reconf_camera(struct usb_stk11xx *); +int dev_stk0500_camera_settings(struct usb_stk11xx *); +int dev_stk0500_set_camera_quality(struct usb_stk11xx *); +int dev_stk0500_set_camera_fps(struct usb_stk11xx *); + +#endif diff --git a/stk11xx-sysfs.c b/stk11xx-sysfs.c new file mode 100644 index 0000000..de63680 --- /dev/null +++ b/stk11xx-sysfs.c @@ -0,0 +1,549 @@ +/** + * @file stk11xx-sysfs.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(VIDIOCGCAP) +#include +#endif + + +#include +#include +#include + +#include "stk11xx.h" + + +extern const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES]; + + +/** + * @brief show_release + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'release' value + * + * @returns Size of buffer + */ +static ssize_t show_release(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%d\n", dev->release); +} + + +/** + * @brief show_videostatus + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'videostatus' value + * + * @returns Size of buffer + */ +static ssize_t show_videostatus(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, + "Nbr ISOC errors : %d\n" + "Nbr dropped frames : %d\n" + "Nbr dumped frames : %d\n", + dev->visoc_errors, + dev->vframes_error, + dev->vframes_dumped); +} + + +/** + * @brief show_informations + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'informations' value + * + * @returns Size of buffer + */ +static ssize_t show_informations(struct device *class, struct device_attribute *attr, char *buf) +{ + int width, height; + char *pixelfmt = NULL; + + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + char *palette_rgb24 = "RGB24 - RGB-8-8-8 - 24 bits"; + char *palette_rgb32 = "RGB32 - RGB-8-8-8-8 - 32 bits"; + char *palette_bgr24 = "BGR24 - BGR-8-8-8 - 24 bits"; + char *palette_bgr32 = "BGR32 - BGR-8-8-8-8 - 32 bits"; + char *palette_uyvy = "UYVY - YUV 4:2:2 - 16 bits"; + char *palette_yuyv = "YUYV - YUV 4:2:2 - 16 bits"; + + + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_RGB24: + pixelfmt = palette_rgb24; + break; + + case STK11XX_PALETTE_RGB32: + pixelfmt = palette_rgb32; + break; + + case STK11XX_PALETTE_BGR24: + pixelfmt = palette_bgr24; + break; + + case STK11XX_PALETTE_BGR32: + pixelfmt = palette_bgr32; + break; + + case STK11XX_PALETTE_UYVY: + pixelfmt = palette_uyvy; + break; + + case STK11XX_PALETTE_YUYV: + pixelfmt = palette_yuyv; + break; + } + + switch (dev->resolution) { + case STK11XX_80x60: + case STK11XX_128x96: + case STK11XX_160x120: + case STK11XX_213x160: + case STK11XX_320x240: + case STK11XX_640x480: + width = stk11xx_image_sizes[STK11XX_640x480].x; + height = stk11xx_image_sizes[STK11XX_640x480].y; + break; + case STK11XX_720x576: + width = stk11xx_image_sizes[STK11XX_720x576].x; + height = stk11xx_image_sizes[STK11XX_720x576].y; + break; + case STK11XX_800x600: + case STK11XX_1024x768: + case STK11XX_1280x1024: + width = stk11xx_image_sizes[STK11XX_1280x1024].x; + height = stk11xx_image_sizes[STK11XX_1280x1024].y; + break; + + default: + width = 0; + height = 0; + } + + return sprintf(buf, + "Asked resolution : %dx%d\n" + "Driver resolution : %dx%d\n" + "Webcam resolution : %dx%d\n" + "\n" + "%s\n" + "\n" + "Brightness : 0x%X\n" + "Contrast : 0x%X\n" + "Whiteness : 0x%X\n" + "Colour : 0x%X\n", + dev->view.x, dev->view.y, + stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y, + width, height, + pixelfmt, + 0xFFFF & dev->vsettings.brightness, + 0xFFFF & dev->vsettings.contrast, + 0xFFFF & dev->vsettings.whiteness, + 0xFFFF & dev->vsettings.colour); +} + + +/** + * @brief show_fps + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'fps' value + * + * @returns Size of buffer + */ +static ssize_t show_fps(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%d\n", dev->vsettings.fps); +} + + +/** + * @brief show_brightness + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'brightness' value + * + * @returns Size of buffer + */ +static ssize_t show_brightness(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%X\n", dev->vsettings.brightness); +} + + +/** + * @brief store_brightness + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_brightness(struct device *class, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *endp; + unsigned long value; + + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + value = simple_strtoul(buf, &endp, 16); + + dev->vsettings.brightness = (int) value; + + dev_stk11xx_set_camera_quality(dev); + + return strlen(buf); +} + +/** + * @brief show_contrast + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'contrast' value + * + * @returns Size of buffer + */ +static ssize_t show_contrast(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%X\n", dev->vsettings.contrast); +} + + +/** + * @brief store_contrast + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_contrast(struct device *class, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *endp; + unsigned long value; + + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + value = simple_strtoul(buf, &endp, 16); + + dev->vsettings.contrast = (int) value; + + dev_stk11xx_set_camera_quality(dev); + + return strlen(buf); +} + + +/** + * @brief show_whitebalance + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'whitebalance' value + * + * @returns Size of buffer + */ +static ssize_t show_whitebalance(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%X\n", dev->vsettings.whiteness); +} + + +/** + * @brief store_whitebalance + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_whitebalance(struct device *class, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *endp; + unsigned long value; + + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + value = simple_strtoul(buf, &endp, 16); + + dev->vsettings.whiteness = (int) value; + + dev_stk11xx_set_camera_quality(dev); + + return strlen(buf); +} + + +/** + * @brief show_colour + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'colour' value + * + * @returns Size of buffer + */ +static ssize_t show_colour(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%X\n", dev->vsettings.colour); +} + + +/** + * @brief store_colour + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_colour(struct device *class, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *endp; + unsigned long value; + + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + value = simple_strtoul(buf, &endp, 16); + + dev->vsettings.colour = (int) value; + + dev_stk11xx_set_camera_quality(dev); + + return strlen(buf); +} + + +/** + * @brief show_hflip + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'hflip' value + * + * @returns Size of buffer + */ +static ssize_t show_hflip(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%d\n", dev->vsettings.hflip); +} + + +/** + * @brief store_hflip + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_hflip(struct device *class, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + if (strncmp(buf, "1", 1) == 0) + dev->vsettings.hflip = 1; + else if (strncmp(buf, "0", 1) == 0) + dev->vsettings.hflip = 0; + else + return -EINVAL; + + return strlen(buf); +} + + +/** + * @brief show_vflip + * + * @param class Class device + * + * @retval buf Adress of buffer with the 'vflip' value + * + * @returns Size of buffer + */ +static ssize_t show_vflip(struct device *class, struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + return sprintf(buf, "%d\n", dev->vsettings.vflip); +} + + +/** + * @brief store_vflip + * + * @param class Class device + * @param buf Buffer + * @param count Counter + * + * @returns Size of buffer + */ +static ssize_t store_vflip(struct device *class, struct device_attribute *attr, const char *buf, size_t count) +{ + struct video_device *vdev = to_video_device(class); + struct usb_stk11xx *dev = video_get_drvdata(vdev); + + if (strncmp(buf, "1", 1) == 0) + dev->vsettings.vflip = 1; + else if (strncmp(buf, "0", 1) == 0) + dev->vsettings.vflip = 0; + else + return -EINVAL; + + return strlen(buf); +} + + +static DEVICE_ATTR(release, S_IRUGO, show_release, NULL); /**< Release value */ +static DEVICE_ATTR(videostatus, S_IRUGO, show_videostatus, NULL); /**< Video status */ +static DEVICE_ATTR(informations, S_IRUGO, show_informations, NULL); /**< Informations */ +static DEVICE_ATTR(fps, S_IRUGO, show_fps, NULL); /**< FPS value */ +static DEVICE_ATTR(brightness, 0660, show_brightness, store_brightness); /**< Brightness value */ +static DEVICE_ATTR(contrast, 0660, show_contrast, store_contrast); /**< Contrast value */ +static DEVICE_ATTR(whitebalance, 0660, show_whitebalance, store_whitebalance); /**< Whitebalance value */ +static DEVICE_ATTR(colour, 0660, show_colour, store_colour); /**< Hue value */ +static DEVICE_ATTR(hflip, 0660, show_hflip, store_hflip); /**< Horizontal filp value */ +static DEVICE_ATTR(vflip, 0660, show_vflip, store_vflip); /**< Vertical filp value */ + + +/** + * @brief Create the 'sys' entries. + * + * This function permits to create all the entries in the 'sys' filesystem. + * + * @param vdev Video device structure + * + * @returns 0 if all is OK + */ +int stk11xx_create_sysfs_files(struct video_device *vdev) +{ + int ret; + + ret = device_create_file(&vdev->dev, &dev_attr_release); + ret = device_create_file(&vdev->dev, &dev_attr_videostatus); + ret = device_create_file(&vdev->dev, &dev_attr_informations); + ret = device_create_file(&vdev->dev, &dev_attr_fps); + ret = device_create_file(&vdev->dev, &dev_attr_brightness); + ret = device_create_file(&vdev->dev, &dev_attr_contrast); + ret = device_create_file(&vdev->dev, &dev_attr_whitebalance); + ret = device_create_file(&vdev->dev, &dev_attr_colour); + ret = device_create_file(&vdev->dev, &dev_attr_hflip); + ret = device_create_file(&vdev->dev, &dev_attr_vflip); + + return ret; +} + + +/** + * @brief Remove the 'sys' entries. + * + * This function permits to remove all the entries in the 'sys' filesystem. + * + * @param vdev Video device structure + * + * @returns 0 if all is OK + */ +void stk11xx_remove_sysfs_files(struct video_device *vdev) +{ + device_remove_file(&vdev->dev, &dev_attr_release); + device_remove_file(&vdev->dev, &dev_attr_videostatus); + device_remove_file(&vdev->dev, &dev_attr_informations); + device_remove_file(&vdev->dev, &dev_attr_fps); + device_remove_file(&vdev->dev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_contrast); + device_remove_file(&vdev->dev, &dev_attr_whitebalance); + device_remove_file(&vdev->dev, &dev_attr_colour); + device_remove_file(&vdev->dev, &dev_attr_hflip); + device_remove_file(&vdev->dev, &dev_attr_vflip); +} + diff --git a/stk11xx-usb.c b/stk11xx-usb.c new file mode 100644 index 0000000..59a4362 --- /dev/null +++ b/stk11xx-usb.c @@ -0,0 +1,1268 @@ +/** + * @file stk11xx-usb.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "stk11xx.h" + + +/** + * @var default_fps + * Number of frame per second by default + */ +static int default_fps = -1; + +/** + * @var default_hflip + * Enable / Disable horizontal flip image + */ +static int default_hflip = -1; + +/** + * @var default_vflip + * Enable / Disable vertical flip image + */ +static int default_vflip = -1; + +/** + * @var default_brightness + * Set brightness + */ +static int default_brightness = -1; + +/** + * @var default_whiteness + * Set whiteness + */ +static int default_whiteness = -1; + +/** + * @var default_contrast + * Set contrast + */ +static int default_contrast = -1; + +/** + * @var default_colour + * Set colour + */ +static int default_colour = -1; + +/** + * @var default_norm + * Set norm + */ +static int default_norm = -1; + + +/** + * @var stk11xx_table + * Define all the hotplug supported devices by this driver + */ +static struct usb_device_id stk11xx_table[] = { + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_A311_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_A821_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_AA11_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_6A31_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_6A33_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_6A51_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_6A54_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK1_VENDOR_ID, USB_STK_6D51_PRODUCT_ID) }, + + { USB_DEVICE(USB_SYNTEK2_VENDOR_ID, USB_STK_0408_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK2_VENDOR_ID, USB_STK_0500_PRODUCT_ID) }, + { USB_DEVICE(USB_SYNTEK2_VENDOR_ID, USB_STK_0501_PRODUCT_ID) }, + { } +}; + + +MODULE_DEVICE_TABLE(usb, stk11xx_table); /**< Define the supported devices */ + + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Initilize an isochronous pipe. + * + * This function permits to initialize an URB transfert (or isochronous pipe). + */ +int usb_stk11xx_isoc_init(struct usb_stk11xx *dev) +{ + int i, j; + int ret = 0; + struct urb *urb; + struct usb_device *udev; + + if (dev == NULL) + return -EFAULT; + + if (dev->isoc_init_ok) + return 0; + + udev = dev->udev; + + STK_DEBUG("usb_stk11xx_isoc_init()\n"); + + // Allocate URB structure + for (i=0; iisobuf[i].urb = urb; + } + + if (ret) { + while (i >= 0) { + if (dev->isobuf[i].urb != NULL) + usb_free_urb(dev->isobuf[i].urb); + + dev->isobuf[i].urb = NULL; + i--; + } + + return ret; + } + + // Init URB structure + for (i=0; iisobuf[i].urb; + + urb->interval = 1; + urb->dev = udev; + urb->pipe = usb_rcvisocpipe(udev, dev->isoc_in_endpointAddr); + urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_buffer = dev->isobuf[i].data; + urb->transfer_buffer_length = ISO_BUFFER_SIZE; + urb->complete = usb_stk11xx_isoc_handler; + urb->context = dev; + urb->start_frame = 0; + urb->number_of_packets = ISO_FRAMES_PER_DESC; + + for (j=0; jiso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE; + urb->iso_frame_desc[j].length = ISO_MAX_FRAME_SIZE; //dev->isoc_in_size; + } + } + + STK_DEBUG("dev->isoc_in_size = %X\n", dev->isoc_in_size); + STK_DEBUG("dev->isoc_in_endpointAddr = %X\n", dev->isoc_in_endpointAddr); + + // Link + for (i=0; iisobuf[i].urb, GFP_KERNEL); + + if (ret) + STK_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); + else + STK_DEBUG("URB 0x%p submitted.\n", dev->isobuf[i].urb); + + switch (ret) { + case -ENOMEM: + STK_ERROR("ENOMEM\n"); + break; + case -ENODEV: + STK_ERROR("ENODEV\n"); + break; + case -ENXIO: + STK_ERROR("ENXIO\n"); + break; + case -EINVAL: + STK_ERROR("EINVAL\n"); + break; + case -EAGAIN: + STK_ERROR("EAGAIN\n"); + break; + case -EFBIG: + STK_ERROR("EFBIG\n"); + break; + case -EPIPE: + STK_ERROR("EPIPE\n"); + break; + case -EMSGSIZE: + STK_ERROR("EMSGSIZE\n"); + break; + } + } + + // All is done + dev->isoc_init_ok = 1; + + return 0; +} + + +/** + * @param urb URB structure + * + * @brief ISOC handler + * + * This function is called as an URB transfert is complete (Isochronous pipe). + * So, the traitement is done in interrupt time, so it has be fast, not crash, + * ans not stall. Neat. + */ +void usb_stk11xx_isoc_handler(struct urb *urb) +{ + int i; + int ret; + int skip; + + int awake = 0; + int framestatus; + int framelen; + + unsigned char *fill = NULL; + unsigned char *iso_buf = NULL; + + struct usb_stk11xx *dev; + struct stk11xx_frame_buf *framebuf; + + STK_STREAM("Isoc handler\n"); + + dev = (struct usb_stk11xx *) urb->context; + + if (dev == NULL) { + STK_ERROR("isoc_handler called with NULL device !\n"); + return; + } + + if (urb->status == -ENOENT || urb->status == -ECONNRESET) { + STK_DEBUG("URB unlinked synchronuously !\n"); + return; + } + + if (urb->status != -EINPROGRESS && urb->status != 0) { + const char *errmsg; + + errmsg = "Unknown"; + + switch(urb->status) { + case -ENOSR: + errmsg = "Buffer error (overrun)"; + break; + + case -EPIPE: + errmsg = "Stalled (device not responding)"; + break; + + case -EOVERFLOW: + errmsg = "Babble (bad cable?)"; + break; + + case -EPROTO: + errmsg = "Bit-stuff error (bad cable?)"; + break; + + case -EILSEQ: + errmsg = "CRC/Timeout (could be anything)"; + break; + + case -ETIMEDOUT: + errmsg = "NAK (device does not respond)"; + break; + } + + STK_ERROR("isoc_handler() called with status %d [%s].\n", urb->status, errmsg); + + dev->visoc_errors++; + + wake_up_interruptible(&dev->wait_frame); + + urb->dev = dev->udev; + ret = usb_submit_urb(urb, GFP_ATOMIC); + + if (ret != 0) { + STK_ERROR("Error (%d) re-submitting urb in stk11xx_isoc_handler.\n", ret); + } + + return; + } + + framebuf = dev->fill_frame; + + if (framebuf == NULL) { + STK_ERROR("isoc_handler without valid fill frame !\n"); + + wake_up_interruptible(&dev->wait_frame); + + urb->dev = dev->udev; + ret = usb_submit_urb(urb, GFP_ATOMIC); + + if (ret != 0) { + STK_ERROR("Error (%d) re-submitting urb in stk11xx_isoc_handler.\n", ret); + } + + return; + } + else { + fill = framebuf->data + framebuf->filled; + } + + // Reset ISOC error counter + dev->visoc_errors = 0; + + // Compact data + for (i=0; inumber_of_packets; i++) { + framestatus = urb->iso_frame_desc[i].status; + framelen = urb->iso_frame_desc[i].actual_length; + iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; + + if (framestatus == 0) { + skip = 4; + + if (framelen > 4) { + // we found something informational from there + // the isoc frames have to type of headers + // type1: 00 xx 00 00 or 20 xx 00 00 + // type2: 80 xx 00 00 00 00 00 00 or a0 xx 00 00 00 00 00 00 + // xx is a sequencer which has never been seen over 0x3f + // + // imho data written down looks like bayer, i see similarities after + // every 640 bytes + if (*iso_buf & 0x80) { + skip = 8; + } + + // Determine if odd or even frame, and set a flag + if (framelen == 8) { + if (*iso_buf & 0x40) + framebuf->odd = true; + else + framebuf->odd = false; + } + + // Our buffer is full !!! + if (framelen - skip + framebuf->filled > dev->frame_size) { + STK_ERROR("Frame buffer overflow %d %d %d!\n", + framelen, framelen-skip+framebuf->filled, dev->frame_size); + framebuf->errors++; + } + // All is OK + else { + memcpy(fill, iso_buf + skip, framelen - skip); + fill += framelen - skip; + } + + // New size of our buffer + framebuf->filled += framelen - skip; + } + + STK_STREAM("URB : Length = %d - Skip = %d - Buffer size = %d\n", + framelen, skip, framebuf->filled); + + // Data is always follow by a frame with a length '4' + if (framelen == 4) { + if (framebuf->filled > 0) { + // Our buffer has enough data ? + if (framebuf->filled < dev->frame_size) + framebuf->errors++; + + // If there are errors, we skip a frame... + if (framebuf->errors == 0) { + if (stk11xx_next_frame(dev)) + dev->vframes_dumped++; + } + else + dev->vframes_error++; + + awake = 1; + framebuf = dev->fill_frame; + framebuf->filled = 0; + framebuf->errors = 0; + fill = framebuf->data; + } + } + } + else { + STK_ERROR("Iso frame %d of USB has error %d\n", i, framestatus); + } + } + + if (awake == 1) + wake_up_interruptible(&dev->wait_frame); + + urb->dev = dev->udev; + + ret = usb_submit_urb(urb, GFP_ATOMIC); + + if (ret != 0) { + STK_ERROR("Error (%d) re-submitting urb in stk11xx_isoc_handler.\n", ret); + } +} + + +/** + * @param dev Device structure + * + * @brief Clean-up all the ISOC buffers + * + * This function permits to clean-up all the ISOC buffers. + */ +void usb_stk11xx_isoc_cleanup(struct usb_stk11xx *dev) +{ + int i; + + STK_DEBUG("Isoc cleanup\n"); + + if (dev == NULL) + return; + + if (dev->isoc_init_ok == 0) + return; + + // Unlinking ISOC buffers + for (i=0; iisobuf[i].urb; + + if (urb != 0) { + if (dev->isoc_init_ok) + usb_kill_urb(urb); + + usb_free_urb(urb); + dev->isobuf[i].urb = NULL; + } + } + + // All is done + dev->isoc_init_ok = 0; +} + + + +/** + * @param dev Device structure + * @param index Choice of the interface + * + * @returns 0 if all is OK + * + * @brief Send the message SET_FEATURE and choose the interface + * + * This function permits to send the message SET_FEATURE on the USB bus. + */ +int usb_stk11xx_set_feature(struct usb_stk11xx *dev, int index) +{ + int result; + struct usb_device *udev = dev->udev; + + result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_FEATURE, + USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, + index, + NULL, + 0, + 500); + + if (result < 0) + STK_ERROR("SET FEATURE fail !\n"); + else + STK_DEBUG("SET FEATURE\n"); + + return result; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Send the message SET_CONFIGURATION + * + * This function permits to send the message SET_CONFIGURATION on the USB bus. + */ +int usb_stk11xx_set_configuration(struct usb_stk11xx *dev) +{ + int result; + struct usb_device *udev = dev->udev; + + result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_CONFIGURATION, + USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE, + 0, + udev->config[0].desc.bConfigurationValue, + NULL, + 0, + 500); + + if (result < 0) + STK_ERROR("SET CONFIGURATION fail !\n"); + else + STK_DEBUG("SET CONFIGURATION %d\n", udev->config[0].desc.bConfigurationValue); + + return result; +} + + +/** + * @param dev + * @param index + * @param value + * + * @returns 0 if all is OK + * + * @brief Write a 16-bits value to a 16-bits register + * + * This function permits to write a 16-bits value to a 16-bits register on the USB bus. + */ +int usb_stk11xx_write_registry(struct usb_stk11xx *dev, __u16 index, __u16 value) +{ + int result; + struct usb_device *udev = dev->udev; + + result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x01, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + NULL, + 0, + 500); + + if (result < 0) + STK_ERROR("Write registry fails %02X = %02X", index, value); + + return result; +} + + +/** + * @param dev + * @param index + * @param value + * + * @returns 0 if all is OK + * + * @brief Read a 16-bits value from a 16-bits register + * + * This function permits to read a 16-bits value from a 16-bits register on the USB bus. + */ +int usb_stk11xx_read_registry(struct usb_stk11xx *dev, __u16 index, int *value) +{ + int result; + + struct usb_device *udev = dev->udev; + + *value = 0; + + result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0x00, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x00, + index, + (__u8 *) value, + sizeof(__u8), + 500); + + if (result < 0) + STK_ERROR("Read registry fails %02X", index); + + return result; +} + + +/** + * @param dev + * + * @returns 0 if all is OK + * + * @brief Set the default value about the video settings. + * + * This function permits to set the video settings for each video camera model. + * + */ +static int usb_stk11xx_default_settings(struct usb_stk11xx *dev) +{ + switch (dev->webcam_model) { + case SYNTEK_STK_0408: + dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps; + dev->vsettings.vflip = (default_vflip == -1) ? 0 : default_vflip; + dev->vsettings.hflip = (default_hflip == -1) ? 0 : default_hflip; + + dev->vsettings.brightness = (default_brightness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_brightness; + dev->vsettings.whiteness = (default_whiteness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_whiteness; + dev->vsettings.contrast = (default_contrast == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_contrast; + dev->vsettings.colour = (default_colour == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_colour; + dev->vsettings.norm = (default_norm == -1) ? 0 : default_norm; + dev->vsettings.input = 0; + break; + + case SYNTEK_STK_M811: + case SYNTEK_STK_A311: + dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps; + dev->vsettings.vflip = (default_vflip == -1) ? 1 : default_vflip; + dev->vsettings.hflip = (default_hflip == -1) ? 1 : default_hflip; + + dev->vsettings.brightness = (default_brightness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_brightness; + dev->vsettings.whiteness = (default_whiteness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_whiteness; + dev->vsettings.contrast = (default_contrast == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_contrast; + dev->vsettings.colour = (default_colour == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_colour; + break; + + case SYNTEK_STK_A821: + case SYNTEK_STK_AA11: + dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps; + dev->vsettings.vflip = (default_vflip == -1) ? 0 : default_vflip; + dev->vsettings.hflip = (default_hflip == -1) ? 0 : default_hflip; + + dev->vsettings.brightness = (default_brightness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_brightness; + dev->vsettings.whiteness = (default_whiteness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_whiteness; + dev->vsettings.contrast = (default_contrast == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_contrast; + dev->vsettings.colour = (default_colour == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_colour; + break; + + case SYNTEK_STK_6A31: + case SYNTEK_STK_6A33: + case SYNTEK_STK_0500: + dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps; + dev->vsettings.vflip = (default_vflip == -1) ? 0 : default_vflip; + dev->vsettings.hflip = (default_hflip == -1) ? 0 : default_hflip; + + dev->vsettings.brightness = (default_brightness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_brightness; + dev->vsettings.whiteness = (default_whiteness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_whiteness; + dev->vsettings.contrast = (default_contrast == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_contrast; + dev->vsettings.colour = (default_colour == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_colour; + break; + + case SYNTEK_STK_6A51: + case SYNTEK_STK_6D51: + case SYNTEK_STK_6A54: + dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps; + dev->vsettings.vflip = (default_vflip == -1) ? 0 : default_vflip; + dev->vsettings.hflip = (default_hflip == -1) ? 0 : default_hflip; + + dev->vsettings.brightness = (default_brightness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_brightness; + dev->vsettings.whiteness = (default_whiteness == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_whiteness; + dev->vsettings.contrast = (default_contrast == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_contrast; + dev->vsettings.colour = (default_colour == -1) ? STK11XX_PERCENT(50, 0xFFFF) : default_colour; + break; + + default: + return -1; + } + + dev->vsettings.default_brightness = dev->vsettings.brightness; + dev->vsettings.default_whiteness = dev->vsettings.whiteness; + dev->vsettings.default_contrast = dev->vsettings.contrast; + dev->vsettings.default_colour = dev->vsettings.colour; + dev->vsettings.default_hflip = dev->vsettings.hflip; + dev->vsettings.default_vflip = dev->vsettings.vflip; + + return 0; +} + + +/** + * @param interface + * @param id + * + * @returns 0 if all is OK + * + * @brief Load the driver + * + * This function detects the device and allocate the buffers for the device + * and the video interface. + */ +static int usb_stk11xx_probe(struct usb_interface *interface, const struct usb_device_id *id) +{ + int i; + int err; + size_t buffer_size; + + int vendor_id; + int product_id; + int bNumInterfaces; + int webcam_model; + int webcam_type; + + struct usb_stk11xx *dev = NULL; + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + + + // Get USB VendorID and ProductID + vendor_id = le16_to_cpu(udev->descriptor.idVendor); + product_id = le16_to_cpu(udev->descriptor.idProduct); + + // Check if we can handle this device + STK_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n", + vendor_id, product_id, interface->cur_altsetting->desc.bInterfaceNumber); + + // The interface are probed one by one. + // We are interested in the video interface (always the interface '0') + // The interfaces '1' or '2' (if presents) are the audio control. + if (interface->cur_altsetting->desc.bInterfaceNumber > 0) + return -ENODEV; + + // Detect device + if (vendor_id == USB_SYNTEK1_VENDOR_ID) { + switch (product_id) { + case USB_STK_A311_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0xA311.\n"); + webcam_model = SYNTEK_STK_A311; + webcam_type = STK11XX_SXGA; + break; + + case USB_STK_A821_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 VGA WebCam - Product ID 0xA821.\n"); + webcam_model = SYNTEK_STK_A821; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_AA11_PRODUCT_ID: + STK_INFO("Syntek AVStream USB2.0 VGA WebCam - Product ID 0xAA11.\n"); + STK_INFO("Using code for Product ID AxA821\n"); + webcam_model = SYNTEK_STK_AA11; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_6A31_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x6A31.\n"); + webcam_model = SYNTEK_STK_6A31; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_6A33_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x6A33.\n"); + webcam_model = SYNTEK_STK_6A33; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_6A51_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x6A51.\n"); + webcam_model = SYNTEK_STK_6A51; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_6A54_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x6A54.\n"); + webcam_model = SYNTEK_STK_6A54; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_6D51_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x6D51.\n"); + webcam_model = SYNTEK_STK_6D51; + webcam_type = STK11XX_VGA; + break; + + default: + STK_ERROR("usb_stk11xx_probe failed ! Camera product 0x%04X is not supported.\n", + le16_to_cpu(udev->descriptor.idProduct)); + return -ENODEV; + } + } + else if (vendor_id == USB_SYNTEK2_VENDOR_ID) { + switch (product_id) { + case USB_STK_0408_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1160 based device found.\n"); + STK_INFO("Syntek AVStream USB2.0 Video Capture - Product ID 0x0408.\n"); + webcam_model = SYNTEK_STK_0408; + webcam_type = STK11XX_PAL; + break; + + case USB_STK_0500_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x0500.\n"); + webcam_model = SYNTEK_STK_0500; + webcam_type = STK11XX_VGA; + break; + + case USB_STK_0501_PRODUCT_ID: + STK_INFO("Syntek USB2.0 - STK-1135 based webcam found.\n"); + STK_INFO("Syntek AVStream USB2.0 1.3M WebCam - Product ID 0x0501.\n"); + webcam_model = SYNTEK_STK_M811; + webcam_type = STK11XX_SXGA; + break; + + default: + STK_ERROR("usb_stk11xx_probe failed ! Camera product 0x%04X is not supported.\n", + le16_to_cpu(udev->descriptor.idProduct)); + return -ENODEV; + } + } + else + return -ENODEV; + + // Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device + dev = kzalloc(sizeof(struct usb_stk11xx), GFP_KERNEL); + + if (dev == NULL) { + STK_ERROR("Out of memory !\n"); + return -ENOMEM; + } + + // Init mutexes, spinlock, etc. + +#ifndef init_MUTEX + sema_init(&dev->mutex,1); +#else + init_MUTEX(&dev->mutex); +#endif + mutex_init(&dev->modlock); + spin_lock_init(&dev->spinlock); + init_waitqueue_head(&dev->wait_frame); + + // Save pointers + dev->webcam_model = webcam_model; + dev->webcam_type = webcam_type; + dev->udev = udev; + dev->interface = interface; + + // Read the product release + dev->release = le16_to_cpu(udev->descriptor.bcdDevice); + STK_INFO("Release: %04x\n", dev->release); + + // How many interfaces (1 or 3) ? + bNumInterfaces = udev->config->desc.bNumInterfaces; + STK_INFO("Number of interfaces : %d\n", bNumInterfaces); + + + // Constructor + // 2 : enough for webcam + // 3 : for easycap... it's usefull ? + dev->nbuffers = 2; +// dev->nbuffers = 3; + dev->len_per_image = PAGE_ALIGN(STK11XX_FRAME_SIZE); + + + // Switch on the camera (to detect size of buffers) + dev_stk11xx_camera_on(dev); + + + // Set up the endpoint information + // use only the first int-in and isoc-in endpoints + // for the current alternate setting + iface_desc = interface->cur_altsetting; + + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (!dev->int_in_endpointAddr + && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { + // we found an interrupt in endpoint + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + + dev->int_in_size = buffer_size; + dev->int_in_endpointAddr = (endpoint->bEndpointAddress & 0xf); + } + + if (!dev->isoc_in_endpointAddr + && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)) { + // we found an isoc in endpoint + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + + dev->isoc_in_size = buffer_size; + dev->isoc_in_endpointAddr = (endpoint->bEndpointAddress & 0xf); + } + } + + if (!(dev->int_in_endpointAddr && dev->isoc_in_endpointAddr)) { + STK_ERROR("Could not find both int-in and isoc-in endpoints"); + + kfree(dev); + + return -ENODEV; + } + + + // Switch off camera + dev_stk11xx_camera_off(dev); + + // Initialize the video device + dev->vdev = video_device_alloc(); + + if (!dev->vdev) { + kfree(dev); + return -ENOMEM; + } + + // Initialize the camera + dev_stk11xx_initialize_device(dev); + + // Register the video device + err = v4l_stk11xx_register_video_device(dev); + + if (err) { + kfree(dev); + return err; + } + + // Create the entries in the sys filesystem + stk11xx_create_sysfs_files(dev->vdev); + + // Save our data pointer in this interface device + usb_set_intfdata(interface, dev); + + // Default settings video device + usb_stk11xx_default_settings(dev); + + // Enable power management feature +// usb_autopm_enable(dev->interface); + + return 0; +} + + +/** + * @param interface + * + * @brief This function is called when the device is disconnected + * or when the kernel module is unloaded. + */ +static void usb_stk11xx_disconnect(struct usb_interface *interface) +{ + struct usb_stk11xx *dev = usb_get_intfdata(interface); + + STK_INFO("Syntek USB2.0 Camera disconnected\n"); + + // We got unplugged; this is signalled by an EPIPE error code + if (dev->vopen) { + STK_INFO("Disconnected while webcam is in use !\n"); + dev->error_status = EPIPE; + } + + // Alert waiting processes + wake_up_interruptible(&dev->wait_frame); + + // Wait until device is closed + while (dev->vopen) + schedule(); + + // Remove the entries in the sys filesystem + stk11xx_remove_sysfs_files(dev->vdev); + + // Unregister the video device + v4l_stk11xx_unregister_video_device(dev); + + usb_set_intfdata(interface, NULL); + kfree(dev); +} + +#ifdef CONFIG_PM +int usb_stk11xx_suspend(struct usb_interface *interface, pm_message_t message) +{ + struct usb_stk11xx *dev = usb_get_intfdata(interface); + + STK_INFO("Syntek USB2.0 Camera Suspend\n"); + + mutex_lock(&dev->modlock); + if (dev->vopen) { + // Stop the video stream + dev_stk11xx_stop_stream(dev); + + // ISOC and URB cleanup + usb_stk11xx_isoc_cleanup(dev); + + // Free memory + // stk11xx_free_buffers(dev); + + // Switch off the camera + dev_stk11xx_camera_off(dev); + + dev_stk11xx_camera_asleep(dev); + } + mutex_unlock(&dev->modlock); + + return 0; +} + + +int usb_stk11xx_resume(struct usb_interface *interface) +{ + struct usb_stk11xx *dev = usb_get_intfdata(interface); + + STK_INFO("Syntek USB2.0 Camera Resume\n"); + + mutex_lock(&dev->modlock); + + // Initialize the camera + dev_stk11xx_initialize_device(dev); + + if (dev->vopen) { + // Select the video mode + v4l_stk11xx_select_video_mode(dev, dev->view.x, dev->view.y); + + // Clear the buffers + stk11xx_clear_buffers(dev); + + // Initialize the device + dev_stk11xx_init_camera(dev); + dev_stk11xx_camera_on(dev); + dev_stk11xx_reconf_camera(dev); + + // ISOC and URB init + usb_stk11xx_isoc_init(dev); + + // Start the video stream + dev_stk11xx_start_stream(dev); + + // Video settings + dev_stk11xx_camera_settings(dev); + } + mutex_unlock(&dev->modlock); + + return 0; +} +#endif /* CONFIG_PM */ + + +/** + * @var usb_stk11xx_driver + * + * This variable contains some callback + */ +static struct usb_driver usb_stk11xx_driver = { + .name = "usb_stk11xx_driver", + .probe = usb_stk11xx_probe, + .disconnect = usb_stk11xx_disconnect, + .id_table = stk11xx_table, +#ifdef CONFIG_PM + .suspend = usb_stk11xx_suspend, + .resume = usb_stk11xx_resume, +#endif +}; + + +/** + * @var fps + * Module parameter to set frame per second + */ +static int fps; + +/** + * @var hflip + * Module parameter to enable/disable the horizontal flip process + */ +static int hflip = -1; + +/** + * @var vflip + * Module parameter to enable/disable the vertical flip process + */ +static int vflip = -1; + +/** + * @var brightness + * Module parameter to set the brightness + */ +static int brightness = -1; + +/** + * @var whiteness + * Module parameter to set the whiteness + */ +static int whiteness = -1; + +/** + * @var contrast + * Module parameter to set the contrast + */ +static int contrast = -1; + +/** + * @var colour + * Module parameter to set the colour + */ +static int colour = -1; + +/** + * @var norm + * Module parameter to set the norm + */ +static int norm = -1; + + +module_param(fps, int, 0444); /**< @brief Module frame per second parameter */ +module_param(hflip, int, 0444); /**< @brief Module horizontal flip process */ +module_param(vflip, int, 0444); /**< @brief Module vertical flip process */ + +module_param(brightness, int, 0444); /**< @brief Module brightness */ +module_param(whiteness, int, 0444); /**< @brief Module whiteness */ +module_param(contrast, int, 0444); /**< @brief Module contrast */ +module_param(colour, int, 0444); /**< @brief Module colour */ +module_param(norm, int, 0444); /**< @brief Module norm */ + + +/** + * @returns 0 if all is OK + * + * @brief Initialize the driver. + * + * This function is called at first. + * This function permits to define the default values from the command line. + */ +static int __init usb_stk11xx_init(void) +{ + int result; + + + STK_INFO("Syntek USB2.0 webcam driver startup\n"); + STK_INFO("Copyright(c) 2006-2009 Nicolas VIVIEN\n"); + + // Frame per second parameter + if (fps) { + if (fps < 9 || fps > 30) { + STK_ERROR("Framerate out of bounds [10-30] !\n"); + return -EINVAL; + } + + default_fps = fps; + } + + // Horizontal flip value + if ((hflip == 0) || (hflip == 1)) { + STK_DEBUG("Set horizontal flip = %d\n", hflip); + + default_hflip = hflip; + } + + // Vertical flip value + if ((vflip == 0) || (vflip == 1)) { + STK_DEBUG("Set vertical flip = %d\n", vflip); + + default_vflip = vflip; + } + + // Brightness value + if (brightness > -1) { + STK_DEBUG("Set brightness = 0x%X\n", brightness); + + default_brightness = 0xffff & brightness; + } + + // Whiteness value + if (whiteness > -1) { + STK_DEBUG("Set whiteness = 0x%X\n", whiteness); + + default_whiteness = 0xffff & whiteness; + } + + // Contrast value + if (contrast > -1) { + STK_DEBUG("Set contrast = 0x%X\n", contrast); + + default_contrast = 0xffff & contrast; + } + + // Colour value + if (colour > -1) { + STK_DEBUG("Set colour = 0x%X\n", colour); + + default_colour = 0xffff & colour; + } + + // Norm value + if (norm > -1) { + default_norm = (norm > 0) ? 1 : 0; + + STK_INFO("Set norm = %s\n", (default_norm > 0) ? "NTSC" : "PAL"); + } + + + // Register the driver with the USB subsystem + result = usb_register(&usb_stk11xx_driver); + + if (result) + STK_ERROR("usb_register failed ! Error number %d\n", result); + + STK_INFO(DRIVER_VERSION " : " DRIVER_DESC "\n"); + + return result; +} + + +/** + * @brief Close the driver + * + * This function is called at last when you unload the driver. + */ +static void __exit usb_stk11xx_exit(void) +{ + STK_INFO("usb_stk11xx_exit: Syntek USB2.0 webcam driver shutdown\n"); + + // Deregister this driver with the USB subsystem + usb_deregister(&usb_stk11xx_driver); +} + + +module_init(usb_stk11xx_init); /**< @brief Module initialize */ +module_exit(usb_stk11xx_exit); /**< @brief Module exit */ + + +MODULE_PARM_DESC(fps, "Frames per second [5-30]"); /**< @brief Description of 'fps' parameter */ +MODULE_PARM_DESC(hflip, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */ +MODULE_PARM_DESC(vflip, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */ +MODULE_PARM_DESC(brightness, "Brightness setting"); /**< @brief Description of 'brightness' parameter */ +MODULE_PARM_DESC(whiteness, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */ +MODULE_PARM_DESC(colour, "Colour setting"); /**< @brief Description of 'colour' parameter */ +MODULE_PARM_DESC(contrast, "Contrast setting"); /**< @brief Description of 'contrast' parameter */ +MODULE_PARM_DESC(norm, "Norm setting (0=NTSC, 1=PAL)"); /**< @brief Description of 'default_norm' parameter */ + + +MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */ +MODULE_AUTHOR(DRIVER_AUTHOR); /**< @brief Driver is written by Nicolas VIVIEN */ +MODULE_DESCRIPTION(DRIVER_DESC); /**< @brief Define the description of the driver */ +MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT); /**< @brief List of supported device */ + + diff --git a/stk11xx-v4l.c b/stk11xx-v4l.c new file mode 100644 index 0000000..2513d50 --- /dev/null +++ b/stk11xx-v4l.c @@ -0,0 +1,1922 @@ +/** + * @file stk11xx-v4l.c + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(VIDIOCGCAP) +#include +#endif + + +#include +#include +#include + +#include "stk11xx.h" + + +static struct v4l2_file_operations v4l_stk11xx_fops; + + +/** + * @var stk11xx_image_sizes + * List of all resolutions supported by the driver + */ +const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES] = { + { 80, 60 }, + { 128, 96 }, + { 160, 120 }, + { 213, 160 }, + { 320, 240 }, + { 640, 480 }, + { 720, 576 }, + { 800, 600 }, + { 1024, 768 }, + { 1280, 1024 } +}; + + +/** + * @var stk11xx_controls + * List of all V4Lv2 controls supported by the driver + * default_value field will be overridden at runtime + */ +static struct v4l2_queryctrl stk11xx_controls[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x7f00, + }, + { + .id = V4L2_CID_WHITENESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Whiteness", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x7f00, + }, + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x7f00, + }, + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x7f00, + }, + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x7f00, + }, + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontally", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, // will be actually set later + }, + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, // will be actually set later + } +}; + + +/** + * @param dev + * @param width Width of wished resolution + * @param height Height of wished resolution + * + * @returns 0 if all is OK + * + * @brief Select a video mode + * + * This function permits to check and select a video mode. + */ +int v4l_stk11xx_select_video_mode(struct usb_stk11xx *dev, int width, int height) +{ + int i; + int find; + + + // Check width and height + // Notice : this test is usefull for the Kopete application ! + + // Driver can't build an image smaller than the minimal resolution ! + if ((width < stk11xx_image_sizes[0].x) + || (height < stk11xx_image_sizes[0].y)) { + width = stk11xx_image_sizes[0].x; + height = stk11xx_image_sizes[0].y; + } + + // Driver can't build an image bigger than the maximal resolution ! + switch (dev->webcam_type) { + case STK11XX_SXGA: + if ((width > stk11xx_image_sizes[STK11XX_1280x1024].x) + || (height > stk11xx_image_sizes[STK11XX_1280x1024].y)) { + width = stk11xx_image_sizes[STK11XX_1280x1024].x; + height = stk11xx_image_sizes[STK11XX_1280x1024].y; + } + break; + + case STK11XX_VGA: + if ((width > stk11xx_image_sizes[STK11XX_640x480].x) + || (height > stk11xx_image_sizes[STK11XX_640x480].y)) { + width = stk11xx_image_sizes[STK11XX_640x480].x; + height = stk11xx_image_sizes[STK11XX_640x480].y; + } + break; + + case STK11XX_PAL: + if (! (((width == 720) && (height==576)) + || ((width == 720) && (height==480)) + || ((width == 640) && (height==480)))) { + width = 640; + height = 480; + } + break; + + default: + return -1; + } + + + // Seek the best resolution + switch (dev->webcam_type) { + case STK11XX_SXGA: + for (i=0, find=0; i<=STK11XX_1280x1024; i++) { + if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height) + find = i; + } + break; + + case STK11XX_VGA: + for (i=0, find=0; i<=STK11XX_640x480; i++) { + if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height) + find = i; + } + break; + + case STK11XX_PAL: + for (i=0, find=0; i<=STK11XX_720x576; i++) { + if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height) + find = i; + } + break; + + default: + return -1; + } + + // Save the new resolution + dev->resolution = find; + + STK_DEBUG("Set mode %d [%dx%d]\n", dev->resolution, + stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y); + + // Save the new size + dev->view.x = width; + dev->view.y = height; + + + // Calculate the frame size + if (dev->webcam_type == STK11XX_PAL) { + // Here, dev->resolution equals : 640x480 || 720x576 + dev->image.x = stk11xx_image_sizes[dev->resolution].x; + dev->image.y = stk11xx_image_sizes[dev->resolution].y; + dev->frame_size = dev->image.x * dev->image.y; + } + else { + switch (dev->resolution) { + case STK11XX_80x60: + case STK11XX_128x96: + case STK11XX_160x120: + case STK11XX_213x160: + case STK11XX_320x240: + case STK11XX_640x480: + dev->image.x = stk11xx_image_sizes[STK11XX_640x480].x; + dev->image.y = stk11xx_image_sizes[STK11XX_640x480].y; + dev->frame_size = dev->image.x * dev->image.y; + break; + + case STK11XX_720x576: + case STK11XX_800x600: + case STK11XX_1024x768: + case STK11XX_1280x1024: + dev->image.x = stk11xx_image_sizes[STK11XX_1280x1024].x; + dev->image.y = stk11xx_image_sizes[STK11XX_1280x1024].y; + dev->frame_size = dev->image.x * dev->image.y; + break; + } + } + + + // Calculate the image size + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_RGB24: + case STK11XX_PALETTE_BGR24: + dev->view_size = 3 * dev->view.x * dev->view.y; + dev->image_size = 3 * dev->frame_size; + break; + + case STK11XX_PALETTE_RGB32: + case STK11XX_PALETTE_BGR32: + dev->view_size = 3 * dev->view.x * dev->view.y; + dev->image_size = 4 * dev->frame_size; + break; + + case STK11XX_PALETTE_UYVY: + case STK11XX_PALETTE_YUYV: + dev->view_size = 2 * dev->view.x * dev->view.y; + dev->image_size = 2 * dev->frame_size; + break; + } + + return 0; +} + + +/** + * @param fp File pointer + * + * @returns 0 if all is OK + * + * @brief Open the video device + * + * This function permits to open a video device (/dev/videoX) + */ +static int v4l_stk11xx_open(struct file *fp) +{ + int err; + + struct usb_stk11xx *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + if (dev == NULL) { + STK_ERROR("Device not initialized !!!\n"); + BUG(); + } + + mutex_lock(&dev->modlock); + + if (dev->vopen) { + STK_DEBUG("Device is busy, someone is using the device\n"); + mutex_unlock(&dev->modlock); + return -EBUSY; + } + + // Allocate memory + err = stk11xx_allocate_buffers(dev); + + if (err < 0) { + STK_ERROR("Failed to allocate buffer memory !\n"); + mutex_unlock(&dev->modlock); + return err; + } + + // Reset buffers and parameters + stk11xx_reset_buffers(dev); + + // Settings + dev->vsync = 0; + dev->v1st_cap = 5; + dev->error_status = 0; + dev->visoc_errors = 0; + dev->vframes_error = 0; + dev->vframes_dumped = 0; + dev->vsettings.hue = 0xffff; + dev->vsettings.whiteness = 0xffff; + dev->vsettings.depth = 24; + dev->vsettings.palette = STK11XX_PALETTE_BGR24; + + // Select the resolution by default + v4l_stk11xx_select_video_mode(dev, 640, 480); + + // Initialize the device + dev_stk11xx_init_camera(dev); + dev_stk11xx_camera_on(dev); + dev_stk11xx_reconf_camera(dev); + + // Init Isoc and URB + err = usb_stk11xx_isoc_init(dev); + + if (err) { + STK_ERROR("Failed to init ISOC stuff !\n"); + usb_stk11xx_isoc_cleanup(dev); + stk11xx_free_buffers(dev); + mutex_unlock(&dev->modlock); + return err; + } + + // Start the video stream + dev_stk11xx_start_stream(dev); + + // Video settings + dev_stk11xx_camera_settings(dev); + + // Register interface on power management + usb_autopm_get_interface(dev->interface); + + dev->vopen++; + fp->private_data = vdev; + + mutex_unlock(&dev->modlock); + + return 0; +} + + +/** + * @param fp File pointer + * + * @returns 0 if all is OK + * + * @brief Release an opened file. + * + * This function permits to release an opened file with the 'open' method. + */ +static int v4l_stk11xx_release(struct file *fp) +{ + struct usb_stk11xx *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + if (dev->vopen == 0) + STK_ERROR("v4l_release called on closed device\n"); + + // Stop the video stream + dev_stk11xx_stop_stream(dev); + + // ISOC and URB cleanup + usb_stk11xx_isoc_cleanup(dev); + + // Free memory + stk11xx_free_buffers(dev); + + // Switch off the camera + dev_stk11xx_camera_off(dev); + + dev_stk11xx_camera_asleep(dev); + + // Unregister interface on power management + usb_autopm_put_interface(dev->interface); + + dev->vopen--; + + return 0; +} + + +/** + * @param fp File pointer + * + * @retval buf Buffer in user space + * @retval count + * @retval f_pos + * + * @returns Count value + * + * @brief Read the video device + * + * This function is called by the application is reading the video device. + */ +static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf, + size_t count, loff_t *f_pos) +{ + int noblock = fp->f_flags & O_NONBLOCK; + + struct usb_stk11xx *dev; + struct video_device *vdev; + + int bytes_to_read; + void *image_buffer_addr; + + DECLARE_WAITQUEUE(wait, current); + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + STK_STREAM("Read vdev=0x%p, buf=0x%p, count=%zd\n", vdev, buf, count); + + if (dev == NULL) + return -EFAULT; + + if (vdev == NULL) + return -EFAULT; + + mutex_lock(&dev->modlock); + + if (dev->image_read_pos == 0) { + add_wait_queue(&dev->wait_frame, &wait); + + while (dev->full_frames == NULL) { + if (dev->error_status) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + mutex_unlock(&dev->modlock); + return -dev->error_status ; + } + + if (noblock) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + mutex_unlock(&dev->modlock); + return -EWOULDBLOCK; + } + + if (signal_pending(current)) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + mutex_unlock(&dev->modlock); + return -ERESTARTSYS; + } + + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + + if (stk11xx_handle_frame(dev)) { + mutex_unlock(&dev->modlock); + return -EFAULT; + } + } + + bytes_to_read = dev->view_size; + + if (count + dev->image_read_pos > bytes_to_read) + count = bytes_to_read - dev->image_read_pos; + + image_buffer_addr = dev->image_data; + image_buffer_addr += dev->images[dev->fill_image].offset; + image_buffer_addr += dev->image_read_pos; + + if (copy_to_user(buf, image_buffer_addr, count)) { + mutex_unlock(&dev->modlock); + return -EFAULT; + } + + dev->image_read_pos += count; + + if (dev->image_read_pos >= bytes_to_read) { + dev->image_read_pos = 0; + stk11xx_next_image(dev); + } + + mutex_unlock(&dev->modlock); + + return count; +} + + +/** + * @param fp File pointer + * @param wait + * + * @returns 0 if all is OK + * + * @brief Polling function + */ +static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait) +{ + struct usb_stk11xx *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + STK_STREAM("Poll\n"); + + if (vdev == NULL) + return -EFAULT; + + if (dev == NULL) + return -EFAULT; + + poll_wait(fp, &dev->wait_frame, wait); + + if (dev->error_status) + return POLLERR; + + if (dev->full_frames != NULL) + return (POLLIN | POLLRDNORM); + + return 0; +} + + +/** + * @param fp File pointer + * @param vma VMA structure + * + * @returns 0 if all is OK + * + * @brief Memory map + * + * This function permits to map a memory space. + */ +static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma) +{ + unsigned int i; + + unsigned long size; + unsigned long start; + unsigned long pos; + unsigned long page; + + struct usb_stk11xx *dev; + + struct video_device *vdev; + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + STK_STREAM("mmap\n"); + + start = vma->vm_start; + size = vma->vm_end - vma->vm_start; + + // Find the buffer for this mapping... + for (i=0; inbuffers; i++) { + pos = dev->images[i].offset; + + if ((pos >> PAGE_SHIFT) == vma->vm_pgoff) + break; + } + + // If no buffer found ! + if (i == STK11XX_MAX_IMAGES) { + STK_ERROR("mmap no buffer found !\n"); + return -EINVAL; + } + + if (i == 0) { + unsigned long total_size; + + total_size = dev->nbuffers * dev->len_per_image; + + if (size != dev->len_per_image && size != total_size) { + STK_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n", + size, dev->len_per_image, total_size); + + return -EINVAL; + } + } + else if (size > dev->len_per_image) + return -EINVAL; + + vma->vm_flags |= VM_IO; + + pos = (unsigned long) dev->image_data; + + while (size > 0) { + page = vmalloc_to_pfn((void *) pos); + + if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + + start += PAGE_SIZE; + pos += PAGE_SIZE; + + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + return 0; +} + + +/** + * @param fp File pointer + * @param cmd Command + * @param arg Arguments of the command + * + * @returns 0 if all is OK + * + * @brief Manage IOCTL + * + * This function permits to manage all the IOCTL from the application. + */ +static long v4l_stk11xx_do_ioctl(struct file *fp, + unsigned int cmd, void __user *arg) +{ + struct usb_stk11xx *dev; + struct video_device *vdev; + + DECLARE_WAITQUEUE(wait, current); + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + +#if (CONFIG_STK11XX_DEBUG == 1) + v4l_printk_ioctl(cmd); +#endif + + switch (cmd) { +#ifdef VIDIOCGCAP + // Video 4 Linux v1 + + case VIDIOCGCAP: + { + struct video_capability *cap = arg; + + STK_DEBUG("VIDIOCGCAP\n"); + + memset(cap, 0, sizeof(*cap)); + strlcpy(cap->name, "stk11xx", sizeof(cap->name)); + cap->type = VID_TYPE_CAPTURE; + cap->channels = 1; + cap->audios = 0; + + switch (dev->webcam_type) { + case STK11XX_SXGA: + cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x; + cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y; + cap->maxwidth = stk11xx_image_sizes[STK11XX_1280x1024].x; + cap->maxheight = stk11xx_image_sizes[STK11XX_1280x1024].y; + break; + + case STK11XX_PAL: + cap->minwidth = stk11xx_image_sizes[STK11XX_640x480].x; + cap->minheight = stk11xx_image_sizes[STK11XX_640x480].y; + cap->maxwidth = stk11xx_image_sizes[STK11XX_720x576].x; + cap->maxheight = stk11xx_image_sizes[STK11XX_720x576].y; + break; + + case STK11XX_VGA: + cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x; + cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y; + cap->maxwidth = stk11xx_image_sizes[STK11XX_640x480].x; + cap->maxheight = stk11xx_image_sizes[STK11XX_640x480].y; + break; + } + } + break; + + case VIDIOCGCHAN: + { + struct video_channel *v = arg; + + STK_DEBUG("VIDIOCGCHAN\n"); + + if (v->channel != 0) + return -EINVAL; + + v->flags = 0; + v->tuners = 0; + v->type = VIDEO_TYPE_CAMERA; + strcpy(v->name, "Webcam"); + } + break; + + case VIDIOCSCHAN: + { + struct video_channel *v = arg; + + STK_DEBUG("VIDIOCSCHAN\n"); + + if (v->channel != 0) + return -EINVAL; + } + break; + + case VIDIOCGPICT: + { + struct video_picture *p = arg; + + STK_DEBUG("VIDIOCGPICT\n"); + + p->brightness = dev->vsettings.brightness; + p->contrast = dev->vsettings.contrast; + p->whiteness = dev->vsettings.whiteness; + p->colour = dev->vsettings.colour; + p->depth = dev->vsettings.depth; + p->palette = dev->vsettings.palette; + p->hue = dev->vsettings.hue; + + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_BGR24: + p->palette = VIDEO_PALETTE_RGB24; + break; + + case STK11XX_PALETTE_BGR32: + p->palette = VIDEO_PALETTE_RGB32; + break; + + case STK11XX_PALETTE_UYVY: + p->palette = VIDEO_PALETTE_UYVY; + break; + + case STK11XX_PALETTE_YUYV: + p->palette = VIDEO_PALETTE_YUYV; + break; + } + } + break; + + case VIDIOCSPICT: + { + struct video_picture *p = arg; + + STK_DEBUG("VIDIOCSPICT\n"); + + dev->vsettings.brightness = p->brightness; + dev->vsettings.contrast = p->contrast; + dev->vsettings.whiteness = p->whiteness; + dev->vsettings.colour = p->colour; + dev->vsettings.hue = p->hue; + + if (p->palette && p->palette != dev->vsettings.palette) { + switch (p->palette) { + case VIDEO_PALETTE_RGB24: + dev->vsettings.depth = 24; + dev->vsettings.palette = STK11XX_PALETTE_BGR24; + break; + + case VIDEO_PALETTE_RGB32: + dev->vsettings.depth = 32; + dev->vsettings.palette = STK11XX_PALETTE_BGR32; + break; + + case VIDEO_PALETTE_UYVY: + dev->vsettings.depth = 16; + dev->vsettings.palette = STK11XX_PALETTE_UYVY; + break; + + case VIDEO_PALETTE_YUYV: + dev->vsettings.depth = 16; + dev->vsettings.palette = STK11XX_PALETTE_YUYV; + break; + + default: + return -EINVAL; + } + } + + dev_stk11xx_camera_settings(dev); + + STK_DEBUG("VIDIOCSPICT done\n"); + } + break; + + case VIDIOCGWIN: + { + struct video_window *vw = arg; + + STK_DEBUG("VIDIOCGWIN\n"); + + vw->x = 0; + vw->y = 0; + vw->width = dev->view.x; + vw->height = dev->view.y; + vw->chromakey = 0; + } + break; + + case VIDIOCSWIN: + { + struct video_window *vw = arg; + + STK_DEBUG("VIDIOCSWIN\n"); + + STK_DEBUG("Set x=%d, y=%d\n", vw->x, vw->y); + STK_DEBUG("Set width=%d, height=%d\n", vw->width, vw->height); + STK_DEBUG("Flags = %X\n", vw->flags); + + // Stop the video stream + dev_stk11xx_stop_stream(dev); + + // ISOC and URB cleanup + usb_stk11xx_isoc_cleanup(dev); + + // Switch off the camera + dev_stk11xx_camera_off(dev); + + dev_stk11xx_camera_asleep(dev); + + // Select the new video mode + if (v4l_stk11xx_select_video_mode(dev, vw->width, vw->height)) { + STK_ERROR("Select video mode failed !\n"); + return -EAGAIN; + } + + // Clear the buffers + stk11xx_clear_buffers(dev); + + // Initialize the device + dev_stk11xx_init_camera(dev); + dev_stk11xx_camera_on(dev); + dev_stk11xx_reconf_camera(dev); + + // ISOC and URB init + usb_stk11xx_isoc_init(dev); + + // Re-start the stream + dev_stk11xx_start_stream(dev); + + // Video settings + dev_stk11xx_camera_settings(dev); + } + break; + + case VIDIOCGFBUF: + { + struct video_buffer *vb = arg; + + STK_DEBUG("VIDIOCGFBUF\n"); + + memset(vb, 0, sizeof(*vb)); + } + break; + + case VIDIOCGMBUF: + { + int i; + struct video_mbuf *vm = arg; + + STK_DEBUG("VIDIOCGMBUF\n"); + + memset(vm, 0, sizeof(*vm)); + + vm->size = dev->nbuffers * dev->len_per_image; + vm->frames = dev->nbuffers; + + for (i=0; inbuffers; i++) + vm->offsets[i] = i * dev->len_per_image; + } + break; + + case VIDIOCMCAPTURE: + { + struct video_mmap *vm = arg; + + STK_DEBUG("VIDIOCMCAPTURE format=%d\n", vm->format); + + if (vm->frame < 0 || vm->frame >= dev->nbuffers) + return -EINVAL; + + if (vm->format) { + switch (vm->format) { + case VIDEO_PALETTE_RGB32: + break; + + case VIDEO_PALETTE_RGB24: + break; + + case VIDEO_PALETTE_UYVY: + break; + + case VIDEO_PALETTE_YUYV: + break; + + default: + return -EINVAL; + } + } + + if ((vm->width != dev->view.x) || (vm->height != dev->view.y)) + return -EAGAIN; + + if (dev->image_used[vm->frame]) + return -EBUSY; + + dev->image_used[vm->frame] = 1; + + STK_DEBUG("VIDIOCMCAPTURE done\n"); + } + break; + + case VIDIOCSYNC: + { + int ret; + int *mbuf = arg; + + STK_DEBUG("VIDIOCSYNC\n"); + + if (*mbuf < 0 || *mbuf >= dev->nbuffers) + return -EINVAL; + + if (dev->image_used[*mbuf] == 0) + return -EINVAL; + + add_wait_queue(&dev->wait_frame, &wait); + + while (dev->full_frames == NULL) { + if (dev->error_status) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + return -dev->error_status; + } + + if (signal_pending(current)) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + return -ERESTARTSYS; + } + + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + + STK_DEBUG("VIDIOCSYNC: frame ready\n"); + + dev->fill_image = *mbuf; + + ret = stk11xx_handle_frame(dev); + + if (ret != 0) + STK_ERROR("VIDIOCSYNC error !\n"); + + dev->image_used[*mbuf] = 0; + } + break; + + case VIDIOCGAUDIO: + STK_DEBUG("VIDIOCGAUDIO\n"); + return -EINVAL; + break; + + case VIDIOCSAUDIO: + STK_DEBUG("VIDIOCSAUDIO\n"); + return -EINVAL; + break; + + case VIDIOCGUNIT: + { + struct video_unit *vu = arg; + + vu->video = dev->vdev->minor & 0x3f; + vu->audio = -1; + vu->vbi = -1; + vu->radio = -1; + vu->teletext = -1; + } + break; +#endif /* VIDIOCGCAP */ + + + // Video 4 Linux v2 + + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = arg; + + STK_DEBUG("VIDIOC_QUERYCAP\n"); + + memset(cap, 0, sizeof(*cap)); + strlcpy(cap->driver, "stk11xx", sizeof(cap->driver)); + + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + cap->version = (__u32) DRIVER_VERSION_NUM, strlcpy(cap->card, dev->vdev->name, sizeof(cap->card)); + + if (usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)) < 0) + strlcpy(cap->bus_info, dev->vdev->name, sizeof(cap->bus_info)); + } + break; + + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + + STK_DEBUG("VIDIOC_ENUMINPUT %d\n", i->index); + + if (dev->webcam_model != SYNTEK_STK_0408) { + if (i->index) + return -EINVAL; + strlcpy(i->name, "USB", sizeof(i->name)); + } + else { + if (i->index > 3) + return -EINVAL; + + switch (i->index) { + case 0: + strlcpy(i->name, "Input1", sizeof(i->name)); + break; + case 1: + strlcpy(i->name, "Input2", sizeof(i->name)); + break; + case 2: + strlcpy(i->name, "Input3", sizeof(i->name)); + break; + case 3: + strlcpy(i->name, "Input4", sizeof(i->name)); + break; + } + } + + i->type = V4L2_INPUT_TYPE_CAMERA; + } + break; + + case VIDIOC_G_INPUT: + { + STK_DEBUG("GET INPUT\n"); + + return dev->vsettings.input; + } + break; + + case VIDIOC_S_INPUT: + { + struct v4l2_input *i = arg; + + STK_DEBUG("SET INPUT %d\n", i->index); + + // TODO add input switching + + if (i->index > 3) + return -EINVAL; + + dev->vsettings.input = i->index + 1; + + dev_stk11xx_camera_settings(dev); + } + break; + + case VIDIOC_QUERYCTRL: + { + int i; + int nbr; + struct v4l2_queryctrl *c = arg; + + STK_DEBUG("VIDIOC_QUERYCTRL id = %d\n", c->id); + + nbr = sizeof(stk11xx_controls)/sizeof(struct v4l2_queryctrl); + + for (i=0; iid) { + STK_DEBUG("VIDIOC_QUERYCTRL found\n"); + memcpy(c, &stk11xx_controls[i], sizeof(struct v4l2_queryctrl)); + switch(c->id) + { + case V4L2_CID_BRIGHTNESS: + c->default_value = dev->vsettings.default_brightness; + break; + case V4L2_CID_WHITENESS: + c->default_value = dev->vsettings.default_whiteness; + break; + case V4L2_CID_SATURATION: + c->default_value = dev->vsettings.default_colour; + break; + case V4L2_CID_CONTRAST: + c->default_value = dev->vsettings.default_contrast; + break; + case V4L2_CID_HFLIP: + c->default_value = dev->vsettings.default_hflip; + break; + case V4L2_CID_VFLIP: + c->default_value = dev->vsettings.default_vflip; + break; + } + break; + } + } + + if (i >= nbr) + return -EINVAL; + } + break; + + case VIDIOC_G_CTRL: + { + struct v4l2_control *c = arg; + + STK_DEBUG("GET CTRL id=%d\n", c->id); + + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + c->value = dev->vsettings.brightness; + break; + + case V4L2_CID_WHITENESS: + c->value = dev->vsettings.whiteness; + break; + + case V4L2_CID_HUE: + c->value = dev->vsettings.hue; + break; + + case V4L2_CID_SATURATION: + c->value = dev->vsettings.colour; + break; + + case V4L2_CID_CONTRAST: + c->value = dev->vsettings.contrast; + break; + + case V4L2_CID_HFLIP: + c->value = dev->vsettings.hflip; + break; + + case V4L2_CID_VFLIP: + c->value = dev->vsettings.vflip; + break; + + default: + return -EINVAL; + } + } + break; + + case VIDIOC_S_CTRL: + { + struct v4l2_control *c = arg; + + STK_DEBUG("SET CTRL id=%d value=%d\n", c->id, c->value); + + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + dev->vsettings.brightness = (0xff00 & c->value); + break; + + case V4L2_CID_HUE: + dev->vsettings.hue = (0xff00 & c->value); + break; + + case V4L2_CID_SATURATION: + dev->vsettings.colour = (0xff00 & c->value); + break; + + case V4L2_CID_CONTRAST: + dev->vsettings.contrast = (0xff00 & c->value); + break; + + case V4L2_CID_HFLIP: + dev->vsettings.hflip = c->value ? 1: 0; + break; + + case V4L2_CID_VFLIP: + dev->vsettings.vflip = c->value ? 1: 0; + break; + + default: + return -EINVAL; + } + + dev_stk11xx_camera_settings(dev); + } + break; + + case VIDIOC_ENUM_FMT: + { + int index; + struct v4l2_fmtdesc *fmtd = arg; + + STK_DEBUG("VIDIOC_ENUM_FMT %d\n", fmtd->index); + + index = fmtd->index; + + memset(fmtd, 0, sizeof(*fmtd)); + + fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmtd->index = index; + + switch (index) { + case 0: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_RGB24; + + strcpy(fmtd->description, "rgb24"); + break; + + case 1: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_RGB32; + + strcpy(fmtd->description, "rgb32"); + break; + + case 2: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_BGR24; + + strcpy(fmtd->description, "bgr24"); + break; + + case 3: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_BGR32; + + strcpy(fmtd->description, "bgr32"); + break; + + case 4: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_UYVY; + + strcpy(fmtd->description, "uyvy"); + break; + + case 5: + fmtd->flags = 0; + fmtd->pixelformat = V4L2_PIX_FMT_YUYV; + + strcpy(fmtd->description, "yuyv"); + break; + + default: + return -EINVAL; + } + } + break; + + case VIDIOC_G_FMT: + { + struct v4l2_format *fmtd = arg; + struct v4l2_pix_format pix_format; + + STK_DEBUG("GET FMT %d\n", fmtd->type); + + if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + pix_format.width = dev->view.x; + pix_format.height = dev->view.y; + pix_format.field = V4L2_FIELD_NONE; + pix_format.colorspace = V4L2_COLORSPACE_SRGB; + pix_format.priv = 0; + + switch (dev->vsettings.palette) { + case STK11XX_PALETTE_RGB24: + pix_format.pixelformat = V4L2_PIX_FMT_RGB24; + pix_format.sizeimage = pix_format.width * pix_format.height * 3; + pix_format.bytesperline = 3 * pix_format.width; + break; + + case STK11XX_PALETTE_RGB32: + pix_format.pixelformat = V4L2_PIX_FMT_RGB32; + pix_format.sizeimage = pix_format.width * pix_format.height * 4; + pix_format.bytesperline = 4 * pix_format.width; + break; + + case STK11XX_PALETTE_BGR24: + pix_format.pixelformat = V4L2_PIX_FMT_BGR24; + pix_format.sizeimage = pix_format.width * pix_format.height * 3; + pix_format.bytesperline = 3 * pix_format.width; + break; + + case STK11XX_PALETTE_BGR32: + pix_format.pixelformat = V4L2_PIX_FMT_BGR32; + pix_format.sizeimage = pix_format.width * pix_format.height * 4; + pix_format.bytesperline = 4 * pix_format.width; + break; + + case STK11XX_PALETTE_UYVY: + pix_format.pixelformat = V4L2_PIX_FMT_UYVY; + pix_format.sizeimage = pix_format.width * pix_format.height * 2; + pix_format.bytesperline = 2 * pix_format.width; + break; + + case STK11XX_PALETTE_YUYV: + pix_format.pixelformat = V4L2_PIX_FMT_YUYV; + pix_format.sizeimage = pix_format.width * pix_format.height * 2; + pix_format.bytesperline = 2 * pix_format.width; + break; + + default: + pix_format.pixelformat = 0; + pix_format.sizeimage = 0; + pix_format.bytesperline = 0; + } + + memcpy(&(fmtd->fmt.pix), &pix_format, sizeof(pix_format)); + } + break; + + case VIDIOC_TRY_FMT: + { + struct v4l2_format *fmtd = arg; + + STK_DEBUG("TRY FMT %d\n", fmtd->type); + + if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + switch (dev->webcam_type) { + case STK11XX_SXGA: + if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_1280x1024].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_1280x1024].x; + else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[0].x; + + if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_1280x1024].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_1280x1024].y; + else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[0].y; + break; + + case STK11XX_PAL: + if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_720x576].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_720x576].x; + else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[0].x; + + if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_720x576].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_720x576].y; + else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[0].y; + break; + + case STK11XX_VGA: + if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_640x480].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_640x480].x; + else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x) + fmtd->fmt.pix.width = stk11xx_image_sizes[0].x; + + if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_640x480].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_640x480].y; + else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y) + fmtd->fmt.pix.height = stk11xx_image_sizes[0].y; + break; + } + + fmtd->fmt.pix.field = V4L2_FIELD_NONE; + fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + fmtd->fmt.pix.priv = 0; + switch (fmtd->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + dev->vsettings.depth = 24; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3; + fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: + dev->vsettings.depth = 32; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4; + fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + dev->vsettings.depth = 16; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2; + fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; + break; + + default: + return -EINVAL; + } + } + break; + + case VIDIOC_S_FMT: + { + struct v4l2_format *fmtd = arg; + + STK_DEBUG("SET FMT %d : %d\n", fmtd->type, fmtd->fmt.pix.pixelformat); + + if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + fmtd->fmt.pix.field = V4L2_FIELD_NONE; + fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + fmtd->fmt.pix.priv = 0; + + switch (fmtd->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + dev->vsettings.depth = 24; + dev->vsettings.palette = STK11XX_PALETTE_RGB24; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3; + fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_RGB32: + dev->vsettings.depth = 32; + dev->vsettings.palette = STK11XX_PALETTE_RGB32; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4; + fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_BGR24: + dev->vsettings.depth = 24; + dev->vsettings.palette = STK11XX_PALETTE_BGR24; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3; + fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_BGR32: + dev->vsettings.depth = 32; + dev->vsettings.palette = STK11XX_PALETTE_BGR32; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4; + fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_UYVY: + dev->vsettings.depth = 16; + dev->vsettings.palette = STK11XX_PALETTE_UYVY; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2; + fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; + break; + + case V4L2_PIX_FMT_YUYV: + dev->vsettings.depth = 16; + dev->vsettings.palette = STK11XX_PALETTE_YUYV; + fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2; + fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; + break; + + default: + return -EINVAL; + } + + STK_DEBUG("Set width=%d, height=%d\n", fmtd->fmt.pix.width, fmtd->fmt.pix.height); + + // Stop the video stream + dev_stk11xx_stop_stream(dev); + + // ISOC and URB cleanup + usb_stk11xx_isoc_cleanup(dev); + + // Switch off the camera + dev_stk11xx_camera_off(dev); + + dev_stk11xx_camera_asleep(dev); + + // Select the new video mode + if (v4l_stk11xx_select_video_mode(dev, fmtd->fmt.pix.width, fmtd->fmt.pix.height)) { + STK_ERROR("Select video mode failed !\n"); + return -EAGAIN; + } + + // Clear the buffers + stk11xx_clear_buffers(dev); + + // Initialize the device + dev_stk11xx_init_camera(dev); + dev_stk11xx_camera_on(dev); + dev_stk11xx_reconf_camera(dev); + + // ISOC and URB init + usb_stk11xx_isoc_init(dev); + + // Re-start the stream + dev_stk11xx_start_stream(dev); + + // Video settings + dev_stk11xx_camera_settings(dev); + } + break; + + case VIDIOC_QUERYSTD: + { + STK_DEBUG("QUERY STD\n"); + return -EINVAL; + } + break; + + case VIDIOC_G_STD: + { + v4l2_std_id *std = arg; + + STK_DEBUG("GET STD\n"); + + *std = V4L2_STD_UNKNOWN; + } + break; + + case VIDIOC_S_STD: + { + v4l2_std_id *std = arg; + + STK_DEBUG("SET STD\n"); + + if (*std != V4L2_STD_UNKNOWN) + return -EINVAL; + } + break; + + case VIDIOC_ENUMSTD: + { + struct v4l2_standard *std = arg; + + STK_DEBUG("VIDIOC_ENUMSTD\n"); + + if (std->index != 0) + return -EINVAL; + + std->id = V4L2_STD_UNKNOWN; + strncpy(std->name, "webcam", sizeof(std->name)); + + break; + } + + case VIDIOC_REQBUFS: + { + int nbuffers; + struct v4l2_requestbuffers *rb = arg; + + if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (rb->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + nbuffers = rb->count; + + if (nbuffers < 2) + nbuffers = 2; + else if (nbuffers > dev->nbuffers) + nbuffers = dev->nbuffers; + + rb->count = dev->nbuffers; + } + break; + + case VIDIOC_QUERYBUF: + { + int index; + struct v4l2_buffer *buf = arg; + + STK_DEBUG("QUERY BUFFERS %d %d\n", buf->index, dev->nbuffers); + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (buf->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + index = buf->index; + + if (index < 0 || index >= dev->nbuffers) + return -EINVAL; + + memset(buf, 0, sizeof(struct v4l2_buffer)); + + buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf->index = index; + buf->m.offset = index * dev->len_per_image; + buf->bytesused = dev->view_size; + buf->field = V4L2_FIELD_NONE; + buf->memory = V4L2_MEMORY_MMAP; + buf->length = dev->len_per_image; + } + break; + + case VIDIOC_QBUF: + { + struct v4l2_buffer *buf = arg; + + STK_DEBUG("VIDIOC_QBUF\n"); + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (buf->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + if (buf->index < 0 || buf->index >= dev->nbuffers) + return -EINVAL; + + buf->flags |= V4L2_BUF_FLAG_QUEUED; + buf->flags &= ~V4L2_BUF_FLAG_DONE; + } + break; + + case VIDIOC_DQBUF: + { + int ret; + struct v4l2_buffer *buf = arg; + + STK_DEBUG("VIDIOC_DQBUF\n"); + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + add_wait_queue(&dev->wait_frame, &wait); + + while (dev->full_frames == NULL) { + if (dev->error_status) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + + return -dev->error_status; + } + + if (signal_pending(current)) { + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + + return -ERESTARTSYS; + } + + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + + remove_wait_queue(&dev->wait_frame, &wait); + set_current_state(TASK_RUNNING); + + STK_DEBUG("VIDIOC_DQBUF : frame ready.\n"); + + ret = stk11xx_handle_frame(dev); + + if (ret) + return -EFAULT; + + buf->index = dev->fill_image; + buf->bytesused = dev->view_size; + buf->flags = V4L2_BUF_FLAG_MAPPED; + buf->field = V4L2_FIELD_NONE; + do_gettimeofday(&buf->timestamp); + buf->sequence = 0; + buf->memory = V4L2_MEMORY_MMAP; + buf->m.offset = dev->fill_image * dev->len_per_image; + buf->length = dev->len_per_image; //buf->bytesused; + + stk11xx_next_image(dev); + } + break; + + case VIDIOC_STREAMON: + { + STK_DEBUG("VIDIOC_STREAMON\n"); + + usb_stk11xx_isoc_init(dev); + } + break; + + case VIDIOC_STREAMOFF: + { + STK_DEBUG("VIDIOC_STREAMOFF\n"); + + usb_stk11xx_isoc_cleanup(dev); + } + break; + + case VIDIOC_G_PARM: + { + struct v4l2_streamparm *sp = arg; + + STK_DEBUG("GET PARM %d\n", sp->type); + + if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp->parm.capture.capability = 0; + sp->parm.capture.capturemode = 0; + sp->parm.capture.timeperframe.numerator = 1; + sp->parm.capture.timeperframe.denominator = 30; + sp->parm.capture.readbuffers = 2; + sp->parm.capture.extendedmode = 0; + } + break; + + + case VIDIOC_G_AUDIO: + STK_DEBUG("GET AUDIO\n"); + return -EINVAL; + break; + + case VIDIOC_S_AUDIO: + STK_DEBUG("SET AUDIO\n"); + return -EINVAL; + break; + + case VIDIOC_S_TUNER: + STK_DEBUG("SET TUNER\n"); + return -EINVAL; + break; + + case VIDIOC_G_FBUF: + case VIDIOC_S_FBUF: + case VIDIOC_OVERLAY: + return -EINVAL; + break; + + case VIDIOC_G_TUNER: + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: + return -EINVAL; + break; + + case VIDIOC_QUERYMENU: + return -EINVAL; + break; +/* + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap cc; + + cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc.pixelaspect.numerator = 1; + cc.pixelaspect.denominator = 1; + cc.bounds.top = 0; + cc.bounds.left = 0; + cc.bounds.width = 640; + cc.bounds.height = 480; + cc.defrect.top = 0; + cc.defrect.left = 0; + cc.defrect.width = 640; + cc.defrect.height = 480; + + memcpy(arg, &cc, sizeof(cc)); + } + break; +*/ + default: + STK_DEBUG("IOCTL unknown !\n"); + return -ENOIOCTLCMD; + } + + return 0; +} + + +/** + * @param fp File pointer + * @param cmd Command + * @param arg Arguements of the command + * + * @returns 0 if all is OK + * + * @brief Manage IOCTL + * + * This function permits to manage all the IOCTL from the application. + */ +static long v4l_stk11xx_ioctl(struct file *fp, + unsigned int cmd, unsigned long arg) +{ + long err; + struct usb_stk11xx *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + dev = video_get_drvdata(video_devdata(fp)); + + STK_DEBUG("v4l_stk11xx_ioctl %02X\n", (unsigned char) cmd); + + if (dev == NULL) + return -EFAULT; + + if (vdev == NULL) + return -EFAULT; + + mutex_lock(&dev->modlock); + + err = video_usercopy(fp, cmd, arg, v4l_stk11xx_do_ioctl); + + mutex_unlock(&dev->modlock); + + return err; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Register the video device + * + * This function permits to register the USB device to the video device. + */ +int v4l_stk11xx_register_video_device(struct usb_stk11xx *dev) +{ + int err; + + err = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev); + if (err < 0) { + STK_ERROR("couldn't register v4l2_device\n"); + kfree(dev); + return err; + } + + strcpy(dev->vdev->name, DRIVER_DESC); + +// dev->vdev->parent = &dev->interface->dev; + dev->vdev->v4l2_dev = &dev->v4l2_dev; + dev->vdev->fops = &v4l_stk11xx_fops; + dev->vdev->release = video_device_release; + dev->vdev->minor = -1; + + video_set_drvdata(dev->vdev, dev); + + err = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); + + if (err) + STK_ERROR("Video register fail !\n"); + else + STK_INFO("Syntek USB2.0 Camera is now controlling video device /dev/video%d\n", dev->vdev->minor); + + return err; +} + + +/** + * @param dev Device structure + * + * @returns 0 if all is OK + * + * @brief Unregister the video device + * + * This function permits to unregister the video device. + */ +int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *dev) +{ + STK_INFO("Syntek USB2.0 Camera release resources video device /dev/video%d\n", dev->vdev->minor); + + video_set_drvdata(dev->vdev, NULL); + video_unregister_device(dev->vdev); + v4l2_device_unregister(&dev->v4l2_dev); + + return 0; +} + + +/** + * @var v4l_stk11xx_fops + * + * This variable contains some callback + */ +static struct v4l2_file_operations v4l_stk11xx_fops = { + .owner = THIS_MODULE, + .open = v4l_stk11xx_open, + .release = v4l_stk11xx_release, + .read = v4l_stk11xx_read, + .poll = v4l_stk11xx_poll, + .mmap = v4l_stk11xx_mmap, +// patch .ioctl > .unlocked_ioctl + .unlocked_ioctl = v4l_stk11xx_ioctl, +#if defined(CONFIG_COMPAT) && defined(v4l_compat_ioctl32) + .compat_ioctl = v4l_compat_ioctl32, +#endif +}; + diff --git a/stk11xx.h b/stk11xx.h new file mode 100644 index 0000000..660aa2d --- /dev/null +++ b/stk11xx.h @@ -0,0 +1,440 @@ +/** + * @file stk11xx.h + * @author Nicolas VIVIEN + * @date 2006-10-23 + * @version v2.2.x + * + * @brief Driver for Syntek USB video camera + * + * @note Copyright (C) Nicolas VIVIEN + * + * @par Licences + * + * 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 + * + * @par SubVersion + * $Date$ + * $Revision$ + * $Author$ + * $HeadURL$ + */ + +#ifndef STK11XX_H +#define STK11XX_H +#include + + +#define DRIVER_NAME "stk11xx" /**< Name of this driver */ +#define DRIVER_VERSION "v2.2.0" /**< Version of this driver */ +#define DRIVER_VERSION_NUM 0x020200 /**< Version numerical of this driver */ +#define DRIVER_DESC "Syntek USB Video Camera" /**< Short description of this driver */ +#define DRIVER_AUTHOR "Nicolas VIVIEN" /**< Author of this driver */ +#define PREFIX DRIVER_NAME ": " /**< Prefix use for the STK "printk" */ + +#define USB_SYNTEK1_VENDOR_ID 0x174f /**< Vendor ID of the camera */ +#define USB_SYNTEK2_VENDOR_ID 0x05e1 /**< Vendor ID of the camera */ + +#define USB_STK_A311_PRODUCT_ID 0xa311 /**< Product ID of the camera STK-1125 */ +#define USB_STK_A821_PRODUCT_ID 0xa821 /**< Product ID of the camera STK-1135 */ +#define USB_STK_AA11_PRODUCT_ID 0xaa11 /**< Product ID of the camera STK-1135 */ +#define USB_STK_6A31_PRODUCT_ID 0x6a31 /**< Product ID of the camera DC-NEW */ +#define USB_STK_6A33_PRODUCT_ID 0x6a33 /**< Product ID of the camera DC-NEW */ +#define USB_STK_6A51_PRODUCT_ID 0x6a51 /**< Product ID of the camera DC-NEW */ +#define USB_STK_6A54_PRODUCT_ID 0x6a54 /**< Product ID of the camera DC-NEW */ +#define USB_STK_6D51_PRODUCT_ID 0x6d51 /**< Product ID of the camera DC-NEW */ + +#define USB_STK_0408_PRODUCT_ID 0x0408 /**< Product ID of the camera STK-1160 */ +#define USB_STK_0500_PRODUCT_ID 0x0500 /**< Product ID of the camera DC-1125 */ +#define USB_STK_0501_PRODUCT_ID 0x0501 /**< Product ID of the camera DC-1125 */ + + +/** + * @def VID_HARDWARE_STK11XX + * + * This value must be inserted into the kernel headers linux/videodev.h + * It's useful only for the support of V4L v1 + */ +#define VID_HARDWARE_STK11XX 88 + + + + +/** + * @def MAX_ISO_BUFS + * Number maximal of ISOC buffers + * + * @def ISO_FRAMES_PER_DESC + * Number frames per ISOC descriptor + * + * @def ISO_MAX_FRAME_SIZE + * Maximale size of frame + * + * @def ISO_BUFFER_SIZE + * Maximal size of buffer + */ +#define MAX_ISO_BUFS 16 +#define ISO_FRAMES_PER_DESC 10 +#define ISO_MAX_FRAME_SIZE 3 * 1024 +#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) + + +/** + * @def STK11XX_MAX_IMAGES + * Absolute maximum number of buffers available for mmap() + * + * @def STK11XX_FRAME_SIZE + * Maximum size after decompression. Warning, we use a big buffer to be able to work + * with a image resolution 1280x1024 ! If your device doesn't support these resolutions + * or that you work in an embedded device, you should use a smaller buffer. + * TODO : + * Allocate a buffer with a dynamical size adapted for the current resolution... + */ +#define STK11XX_MAX_IMAGES 10 +#define STK11XX_FRAME_SIZE (1280 * 1024 * 4) + + + + + + + +/** + * @def DRIVER_SUPPORT + * + * List of supported device + * - DC1125 : USB2.0 Syntek chipset + */ +#define DRIVER_SUPPORT "Syntek USB Camera : STK-1135" + +/** + * @def CONFIG_STK11XX_DEBUG + * Enable / Disable the debug mode. + * + * @def STK_INFO(str, args...) + * Print information message. + * @a Use this function like the function printf. + * + * @def STK_ERROR(str, args...) + * Print error message. + * @a Use this function like the function printf. + * + * @def STK_WARNING(str, args...) + * Print warning message. + * @a Use this function like the function printf. + * + * @def STK_DEBUG(str, args...) + * Print debug message. + * @a Use this function like the function printf. + */ +#ifndef CONFIG_STK11XX_DEBUG +#define CONFIG_STK11XX_DEBUG 0 +#endif + +#if CONFIG_STK11XX_DEBUG + +#define STK_INFO(str, args...) printk(KERN_INFO PREFIX str, ##args) +#define STK_ERROR(str, args...) printk(KERN_ERR PREFIX str, ##args) +#define STK_WARNING(str, args...) printk(KERN_WARNING PREFIX str, ##args) +#define STK_DEBUG(str, args...) printk(KERN_DEBUG PREFIX str, ##args) + +#else + +#define STK_INFO(str, args...) printk(KERN_INFO PREFIX str, ##args) +#define STK_ERROR(str, args...) printk(KERN_ERR PREFIX str, ##args) +#define STK_WARNING(str, args...) printk(KERN_WARNING PREFIX str, ##args) +#define STK_DEBUG(str, args...) do { } while(0) + +#endif + + +/** + * @def CONFIG_STK11XX_DEBUG_STREAM + * Enable / Disable the debug mode about the stream. + * + * @def STK_STREAM(str, args...) + * Print stream debug message. + * @a Use this function like the function printf. + */ +#ifndef CONFIG_STK11XX_DEBUG_STREAM +#define CONFIG_STK11XX_DEBUG_STREAM 0 +#endif + +#if CONFIG_STK11XX_DEBUG_STREAM + +#define STK_STREAM(str, args...) printk(KERN_DEBUG PREFIX str, ##args) + +#else + +#define STK_STREAM(str, args...) do { } while(0) + +#endif + + + +/** + * @enum T_SYNTEK_DEVICE Video camera supported by the driver + */ +typedef enum { + SYNTEK_STK_M811 = 1, + SYNTEK_STK_A311 = 2, + SYNTEK_STK_A821 = 3, + SYNTEK_STK_6A31 = 4, + SYNTEK_STK_6A33 = 5, + SYNTEK_STK_6A51 = 6, + SYNTEK_STK_6A54 = 7, + SYNTEK_STK_6D51 = 8, + SYNTEK_STK_0500 = 9, + SYNTEK_STK_0408 = 10, + SYNTEK_STK_AA11 = 11, +} T_SYNTEK_DEVICE; + + +/** + * @enum T_STK11XX_VIDEOMODE Video feature supported by camera + */ +typedef enum { + STK11XX_VGA, /**< For VGA video camera */ + STK11XX_SXGA, /**< For SXGA video camera 1.3M */ + STK11XX_PAL, /**< For PAL capture card */ + STK11XX_UXGA /**< For UXGA video camera 2M */ +} T_STK11XX_VIDEOMODE; + + +/** + * @enum T_STK11XX_RESOLUTION Video resolution + */ +typedef enum { + STK11XX_80x60, + STK11XX_128x96, + STK11XX_160x120, + STK11XX_213x160, + STK11XX_320x240, + STK11XX_640x480, + STK11XX_720x576, + STK11XX_800x600, + STK11XX_1024x768, + STK11XX_1280x1024, + STK11XX_NBR_SIZES +} T_STK11XX_RESOLUTION; + + +/** + * @enum T_STK11XX_PALETTE Color palette + */ +typedef enum { + STK11XX_PALETTE_RGB24, + STK11XX_PALETTE_RGB32, + STK11XX_PALETTE_BGR24, + STK11XX_PALETTE_BGR32, + STK11XX_PALETTE_UYVY, + STK11XX_PALETTE_YUYV +} T_STK11XX_PALETTE; + + +/** + * @struct stk11xx_iso_buf + */ +struct stk11xx_iso_buf { + void *data; + int length; + int read; + struct urb *urb; +}; + + +/** + * @struct stk11xx_frame_buf + */ +struct stk11xx_frame_buf { + int errors; + void *data; + volatile bool odd; + volatile int filled; + struct stk11xx_frame_buf *next; +}; + + +/** + * @struct stk11xx_image_buf + */ +struct stk11xx_image_buf { + unsigned long offset; /**< Memory offset */ + int vma_use_count; /**< VMA counter */ +}; + + +/** + * @struct stk11xx_coord + */ +struct stk11xx_coord { + int x; /**< X-coordonate */ + int y; /**< Y-coordonate */ +}; + + +/** + * @struct stk11xx_video + */ +struct stk11xx_video { + int fps; /**< FPS setting */ + int brightness; /**< Brightness setting */ + int contrast; /**< Contrast setting */ + int whiteness; /**< Whiteness setting */ + int colour; /**< Colour setting */ + int depth; /**< Depth colour setting */ + int palette; /**< Palette setting */ + int hue; /**< Hue setting */ + int hflip; /**< Horizontal flip */ + int vflip; /**< Vertical flip */ + int input; /**< Input for multiinput cards */ + int norm; /**< Norm, NTSC or PAL */ + + /* Default values for the device. Above are values currently in use. */ + int default_brightness; + int default_contrast; + int default_colour; + int default_whiteness; + int default_hflip; + int default_vflip; +}; + + +/** + * @struct usb_stk11xx + */ +struct usb_stk11xx { + struct v4l2_device v4l2_dev; + struct video_device *vdev; /**< Pointer on a V4L2 video device */ + struct usb_device *udev; /**< Pointer on a USB device */ + struct usb_interface *interface; /**< Pointer on a USB interface */ + + int release; /**< Release of the device (bcdDevice) */ + int webcam_model; /**< Model of video camera device */ + int webcam_type; /**< Type of camera : VGA, SXGA (1.3M), UXGA (2M) */ + + unsigned char *int_in_buffer; /**< Interrupt IN buffer */ + size_t int_in_size; /**< Interrupt IN buffer size */ + __u8 int_in_endpointAddr; /**< Interrupt IN endpoint address */ + + size_t isoc_in_size; /**< Isochrone IN size */ + __u8 isoc_in_endpointAddr; /**< Isochrone IN endpoint address */ + + int watchdog; /**< Counter for the software watchdog */ + + struct stk11xx_video vsettings; /**< Video settings (brightness, whiteness...) */ + + int error_status; + + int vopen; /**< Video status (Opened or Closed) */ + int visoc_errors; /**< Count the number of ISOCH errors */ + int vframes_error; /**< Count the number of fault frames (so dropped) */ + int vframes_dumped; /**< Count the number of ignored frames */ + int vsync; /**< sync on valid frame */ + int v1st_cap; /**< used to get a clean 1st capture */ + + + spinlock_t spinlock; /**< Spin lock */ + struct semaphore mutex; /**< Mutex */ + wait_queue_head_t wait_frame; /**< Queue head */ + struct mutex modlock; /**< To prevent races in video_open(), etc */ + + + // 1: isoc + char isoc_init_ok; + struct stk11xx_iso_buf isobuf[MAX_ISO_BUFS]; + + // 2: frame + int frame_size; + struct stk11xx_frame_buf *framebuf; + struct stk11xx_frame_buf *empty_frames, *empty_frames_tail; + struct stk11xx_frame_buf *full_frames, *full_frames_tail; + struct stk11xx_frame_buf *fill_frame; + struct stk11xx_frame_buf *read_frame; + + // 3: image + int view_size; + int image_size; + void *image_data; + struct stk11xx_image_buf images[STK11XX_MAX_IMAGES]; + int image_used[STK11XX_MAX_IMAGES]; + unsigned int nbuffers; + unsigned int len_per_image; + int image_read_pos; + int fill_image; + int resolution; + struct stk11xx_coord view; + struct stk11xx_coord image; +}; + + +/** + * @def STK11XX_PERCENT + * Calculate a value from a percent + */ +#define STK11XX_PERCENT(x,y) ( ((int)x * (int)y) / 100) + + +/** + * @def to_stk11xx_dev(d) + * Cast a member of a structure out to the containing structure + */ +#define to_stk11xx_dev(d) container_of(d, struct usb_stk11xx, kref) + + +extern const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES]; + + +int usb_stk11xx_write_registry(struct usb_stk11xx *, __u16, __u16); +int usb_stk11xx_read_registry(struct usb_stk11xx *, __u16, int *); +int usb_stk11xx_set_feature(struct usb_stk11xx *, int); +int usb_stk11xx_set_configuration(struct usb_stk11xx *); +int usb_stk11xx_isoc_init(struct usb_stk11xx *); +void usb_stk11xx_isoc_handler(struct urb *); +void usb_stk11xx_isoc_cleanup(struct usb_stk11xx *); + +int dev_stk11xx_decompress(struct usb_stk11xx *); +int dev_stk11xx_initialize_device(struct usb_stk11xx *); +int dev_stk11xx_start_stream(struct usb_stk11xx *); +int dev_stk11xx_stop_stream(struct usb_stk11xx *); +int dev_stk11xx_check_device(struct usb_stk11xx *, int); +int dev_stk11xx_camera_on(struct usb_stk11xx *); +int dev_stk11xx_camera_off(struct usb_stk11xx *); +int dev_stk11xx_camera_asleep(struct usb_stk11xx *); +int dev_stk11xx_init_camera(struct usb_stk11xx *); +int dev_stk11xx_reconf_camera(struct usb_stk11xx *); +int dev_stk11xx_camera_settings(struct usb_stk11xx *); +int dev_stk11xx_set_camera_quality(struct usb_stk11xx *); +int dev_stk11xx_set_camera_fps(struct usb_stk11xx *); +int dev_stk11xx_watchdog_camera(struct usb_stk11xx *); + +int v4l_stk11xx_select_video_mode(struct usb_stk11xx *, int, int); +int v4l_stk11xx_register_video_device(struct usb_stk11xx *); +int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *); + +int stk11xx_create_sysfs_files(struct video_device *); +void stk11xx_remove_sysfs_files(struct video_device *); + +int stk11xx_allocate_buffers(struct usb_stk11xx *); +int stk11xx_reset_buffers(struct usb_stk11xx *); +int stk11xx_clear_buffers(struct usb_stk11xx *); +int stk11xx_free_buffers(struct usb_stk11xx *); +void stk11xx_next_image(struct usb_stk11xx *); +int stk11xx_next_frame(struct usb_stk11xx *); +int stk11xx_handle_frame(struct usb_stk11xx *); + +int stk11xx_decompress(struct usb_stk11xx *); + + +#endif diff --git a/stk11xx.txt b/stk11xx.txt new file mode 100644 index 0000000..358979b --- /dev/null +++ b/stk11xx.txt @@ -0,0 +1,19 @@ +/** + * @mainpage Syntek USB2.0 Video Camera + * + * @section chap1 Introduction + * + * Syntek USB2.0 Video Camera Driver is documented with Doxygen. + * This Syntek project starts. So this driver isn't usable. + * + * @section chap2 Help us + * + * To write this driver, we need logs and traces about USB traffic. + * Using an USB sniffer, you can get this logs. + * + * @section chap3 Summary + * + * We hope you will be interested in this project and we will have + * quickly an usable driver. + * + */ diff --git a/tags b/tags new file mode 100644 index 0000000..b9b6db1 --- /dev/null +++ b/tags @@ -0,0 +1,387 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.9~svn20110310 // +CLAMP stk11xx-dev-0408.c 974;" d file: +CLIP stk11xx-bayer.c 50;" d file: +CONFIG_STK11XX_DEBUG stk11xx.h 142;" d +CONFIG_STK11XX_DEBUG_STREAM stk11xx.h 171;" d +DRIVER_AUTHOR stk11xx-usb.c /^MODULE_AUTHOR(DRIVER_AUTHOR); \/**< @brief Driver is written by Nicolas VIVIEN *\/$/;" v +DRIVER_AUTHOR stk11xx.h 43;" d +DRIVER_DESC stk11xx-usb.c /^MODULE_DESCRIPTION(DRIVER_DESC); \/**< @brief Define the description of the driver *\/$/;" v +DRIVER_DESC stk11xx.h 42;" d +DRIVER_NAME stk11xx.h 39;" d +DRIVER_SUPPORT stk11xx-usb.c /^MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT); \/**< @brief List of supported device *\/$/;" v +DRIVER_SUPPORT stk11xx.h 119;" d +DRIVER_VERSION stk11xx.h 40;" d +DRIVER_VERSION_NUM stk11xx.h 41;" d +ISO_BUFFER_SIZE stk11xx.h 90;" d +ISO_FRAMES_PER_DESC stk11xx.h 88;" d +ISO_MAX_FRAME_SIZE stk11xx.h 89;" d +MAX stk11xx-bayer.c 48;" d file: +MAX_ISO_BUFS stk11xx.h 87;" d +MIN stk11xx-bayer.c 49;" d file: +PREFIX stk11xx.h 44;" d +STK11XX_1024x768 stk11xx.h /^ STK11XX_1024x768,$/;" e enum:__anon3 +STK11XX_1280x1024 stk11xx.h /^ STK11XX_1280x1024,$/;" e enum:__anon3 +STK11XX_128x96 stk11xx.h /^ STK11XX_128x96,$/;" e enum:__anon3 +STK11XX_160x120 stk11xx.h /^ STK11XX_160x120,$/;" e enum:__anon3 +STK11XX_213x160 stk11xx.h /^ STK11XX_213x160,$/;" e enum:__anon3 +STK11XX_320x240 stk11xx.h /^ STK11XX_320x240,$/;" e enum:__anon3 +STK11XX_640x480 stk11xx.h /^ STK11XX_640x480,$/;" e enum:__anon3 +STK11XX_720x576 stk11xx.h /^ STK11XX_720x576,$/;" e enum:__anon3 +STK11XX_800x600 stk11xx.h /^ STK11XX_800x600,$/;" e enum:__anon3 +STK11XX_80x60 stk11xx.h /^ STK11XX_80x60,$/;" e enum:__anon3 +STK11XX_DEV_H stk11xx-dev.h 35;" d +STK11XX_FRAME_SIZE stk11xx.h 105;" d +STK11XX_H stk11xx.h 35;" d +STK11XX_MAX_IMAGES stk11xx.h 104;" d +STK11XX_NBR_SIZES stk11xx.h /^ STK11XX_NBR_SIZES$/;" e enum:__anon3 +STK11XX_PAL stk11xx.h /^ STK11XX_PAL, \/**< For PAL capture card *\/$/;" e enum:__anon2 +STK11XX_PALETTE_BGR24 stk11xx.h /^ STK11XX_PALETTE_BGR24,$/;" e enum:__anon4 +STK11XX_PALETTE_BGR32 stk11xx.h /^ STK11XX_PALETTE_BGR32,$/;" e enum:__anon4 +STK11XX_PALETTE_RGB24 stk11xx.h /^ STK11XX_PALETTE_RGB24,$/;" e enum:__anon4 +STK11XX_PALETTE_RGB32 stk11xx.h /^ STK11XX_PALETTE_RGB32,$/;" e enum:__anon4 +STK11XX_PALETTE_UYVY stk11xx.h /^ STK11XX_PALETTE_UYVY,$/;" e enum:__anon4 +STK11XX_PALETTE_YUYV stk11xx.h /^ STK11XX_PALETTE_YUYV$/;" e enum:__anon4 +STK11XX_PERCENT stk11xx.h 386;" d +STK11XX_SXGA stk11xx.h /^ STK11XX_SXGA, \/**< For SXGA video camera 1.3M *\/$/;" e enum:__anon2 +STK11XX_UXGA stk11xx.h /^ STK11XX_UXGA \/**< For UXGA video camera 2M *\/$/;" e enum:__anon2 +STK11XX_VGA stk11xx.h /^ STK11XX_VGA, \/**< For VGA video camera *\/$/;" e enum:__anon2 +STK_DEBUG stk11xx.h 150;" d +STK_DEBUG stk11xx.h 157;" d +STK_ERROR stk11xx.h 148;" d +STK_ERROR stk11xx.h 155;" d +STK_INFO stk11xx.h 147;" d +STK_INFO stk11xx.h 154;" d +STK_STREAM stk11xx.h 176;" d +STK_STREAM stk11xx.h 180;" d +STK_WARNING stk11xx.h 149;" d +STK_WARNING stk11xx.h 156;" d +SYNTEK_STK_0408 stk11xx.h /^ SYNTEK_STK_0408 = 10,$/;" e enum:__anon1 +SYNTEK_STK_0500 stk11xx.h /^ SYNTEK_STK_0500 = 9,$/;" e enum:__anon1 +SYNTEK_STK_6A31 stk11xx.h /^ SYNTEK_STK_6A31 = 4,$/;" e enum:__anon1 +SYNTEK_STK_6A33 stk11xx.h /^ SYNTEK_STK_6A33 = 5,$/;" e enum:__anon1 +SYNTEK_STK_6A51 stk11xx.h /^ SYNTEK_STK_6A51 = 6,$/;" e enum:__anon1 +SYNTEK_STK_6A54 stk11xx.h /^ SYNTEK_STK_6A54 = 7,$/;" e enum:__anon1 +SYNTEK_STK_6D51 stk11xx.h /^ SYNTEK_STK_6D51 = 8,$/;" e enum:__anon1 +SYNTEK_STK_A311 stk11xx.h /^ SYNTEK_STK_A311 = 2,$/;" e enum:__anon1 +SYNTEK_STK_A821 stk11xx.h /^ SYNTEK_STK_A821 = 3,$/;" e enum:__anon1 +SYNTEK_STK_AA11 stk11xx.h /^ SYNTEK_STK_AA11 = 11,$/;" e enum:__anon1 +SYNTEK_STK_M811 stk11xx.h /^ SYNTEK_STK_M811 = 1,$/;" e enum:__anon1 +T_STK11XX_PALETTE stk11xx.h /^} T_STK11XX_PALETTE;$/;" t typeref:enum:__anon4 +T_STK11XX_RESOLUTION stk11xx.h /^} T_STK11XX_RESOLUTION;$/;" t typeref:enum:__anon3 +T_STK11XX_VIDEOMODE stk11xx.h /^} T_STK11XX_VIDEOMODE;$/;" t typeref:enum:__anon2 +T_SYNTEK_DEVICE stk11xx.h /^} T_SYNTEK_DEVICE;$/;" t typeref:enum:__anon1 +USB_STK_0408_PRODUCT_ID stk11xx.h 58;" d +USB_STK_0500_PRODUCT_ID stk11xx.h 59;" d +USB_STK_0501_PRODUCT_ID stk11xx.h 60;" d +USB_STK_6A31_PRODUCT_ID stk11xx.h 52;" d +USB_STK_6A33_PRODUCT_ID stk11xx.h 53;" d +USB_STK_6A51_PRODUCT_ID stk11xx.h 54;" d +USB_STK_6A54_PRODUCT_ID stk11xx.h 55;" d +USB_STK_6D51_PRODUCT_ID stk11xx.h 56;" d +USB_STK_A311_PRODUCT_ID stk11xx.h 49;" d +USB_STK_A821_PRODUCT_ID stk11xx.h 50;" d +USB_STK_AA11_PRODUCT_ID stk11xx.h 51;" d +USB_SYNTEK1_VENDOR_ID stk11xx.h 46;" d +USB_SYNTEK2_VENDOR_ID stk11xx.h 47;" d +VID_HARDWARE_STK11XX stk11xx.h 69;" d +__this_module stk11xx.mod.c /^__visible struct module __this_module$/;" v typeref:struct:module +__used stk11xx.mod.c /^__used$/;" v file: +__used stk11xx.mod.c /^__used$/;" v typeref:struct:____versions file: +brightness stk11xx-usb.c /^static int brightness = -1;$/;" v file: +brightness stk11xx.h /^ int brightness; \/**< Brightness setting *\/$/;" m struct:stk11xx_video +colour stk11xx-usb.c /^static int colour = -1;$/;" v file: +colour stk11xx.h /^ int colour; \/**< Colour setting *\/$/;" m struct:stk11xx_video +contrast stk11xx-usb.c /^static int contrast = -1;$/;" v file: +contrast stk11xx.h /^ int contrast; \/**< Contrast setting *\/$/;" m struct:stk11xx_video +data stk11xx.h /^ void *data;$/;" m struct:stk11xx_frame_buf +data stk11xx.h /^ void *data;$/;" m struct:stk11xx_iso_buf +default_brightness stk11xx-usb.c /^static int default_brightness = -1;$/;" v file: +default_brightness stk11xx.h /^ int default_brightness;$/;" m struct:stk11xx_video +default_colour stk11xx-usb.c /^static int default_colour = -1;$/;" v file: +default_colour stk11xx.h /^ int default_colour;$/;" m struct:stk11xx_video +default_contrast stk11xx-usb.c /^static int default_contrast = -1;$/;" v file: +default_contrast stk11xx.h /^ int default_contrast;$/;" m struct:stk11xx_video +default_fps stk11xx-usb.c /^static int default_fps = -1;$/;" v file: +default_hflip stk11xx-usb.c /^static int default_hflip = -1;$/;" v file: +default_hflip stk11xx.h /^ int default_hflip;$/;" m struct:stk11xx_video +default_nbrframebuf stk11xx-buf.c /^static int default_nbrframebuf = 3;$/;" v file: +default_norm stk11xx-usb.c /^static int default_norm = -1;$/;" v file: +default_vflip stk11xx-usb.c /^static int default_vflip = -1;$/;" v file: +default_vflip stk11xx.h /^ int default_vflip;$/;" m struct:stk11xx_video +default_whiteness stk11xx-usb.c /^static int default_whiteness = -1;$/;" v file: +default_whiteness stk11xx.h /^ int default_whiteness;$/;" m struct:stk11xx_video +depth stk11xx.h /^ int depth; \/**< Depth colour setting *\/$/;" m struct:stk11xx_video +dev_stk0408_camera_asleep stk11xx-dev-0408.c /^int dev_stk0408_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk0408_camera_settings stk11xx-dev-0408.c /^int dev_stk0408_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk0408_check_device stk11xx-dev-0408.c /^int dev_stk0408_check_device(struct usb_stk11xx *dev)$/;" f +dev_stk0408_configure_device stk11xx-dev-0408.c /^int dev_stk0408_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk0408_decode stk11xx-dev-0408.c /^int dev_stk0408_decode(struct usb_stk11xx *dev)$/;" f +dev_stk0408_init_camera stk11xx-dev-0408.c /^int dev_stk0408_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk0408_initialize_device stk11xx-dev-0408.c /^int dev_stk0408_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk0408_reconf_camera stk11xx-dev-0408.c /^int dev_stk0408_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk0408_select_input stk11xx-dev-0408.c /^int dev_stk0408_select_input(struct usb_stk11xx *dev, int input)$/;" f +dev_stk0408_sensor_settings stk11xx-dev-0408.c /^int dev_stk0408_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk0408_set_camera_fps stk11xx-dev-0408.c /^int dev_stk0408_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk0408_set_camera_quality stk11xx-dev-0408.c /^int dev_stk0408_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk0408_set_resolution stk11xx-dev-0408.c /^int dev_stk0408_set_resolution(struct usb_stk11xx *dev)$/;" f +dev_stk0408_start_stream stk11xx-dev-0408.c /^int dev_stk0408_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk0408_stop_stream stk11xx-dev-0408.c /^int dev_stk0408_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk0408_write0 stk11xx-dev-0408.c /^int dev_stk0408_write0(struct usb_stk11xx *dev, int mask, int val)$/;" f +dev_stk0408_write_208 stk11xx-dev-0408.c /^int dev_stk0408_write_208(struct usb_stk11xx *dev, int val)$/;" f +dev_stk0408_write_saa stk11xx-dev-0408.c /^int dev_stk0408_write_saa(struct usb_stk11xx *dev, int reg, int val)$/;" f +dev_stk0500_camera_asleep stk11xx-dev-0500.c /^int dev_stk0500_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk0500_camera_settings stk11xx-dev-0500.c /^int dev_stk0500_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk0500_configure_device stk11xx-dev-0500.c /^int dev_stk0500_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk0500_init_camera stk11xx-dev-0500.c /^int dev_stk0500_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk0500_initialize_device stk11xx-dev-0500.c /^int dev_stk0500_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk0500_reconf_camera stk11xx-dev-0500.c /^int dev_stk0500_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk0500_sensor_settings stk11xx-dev-0500.c /^int dev_stk0500_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk0500_set_camera_fps stk11xx-dev-0500.c /^int dev_stk0500_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk0500_set_camera_quality stk11xx-dev-0500.c /^int dev_stk0500_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk0500_start_stream stk11xx-dev-0500.c /^int dev_stk0500_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk0500_stop_stream stk11xx-dev-0500.c /^int dev_stk0500_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_camera_asleep stk11xx-dev.c /^int dev_stk11xx_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_camera_off stk11xx-dev.c /^int dev_stk11xx_camera_off(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_camera_on stk11xx-dev.c /^int dev_stk11xx_camera_on(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_camera_settings stk11xx-dev.c /^int dev_stk11xx_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_check_device stk11xx-dev.c /^int dev_stk11xx_check_device(struct usb_stk11xx *dev, int nbr)$/;" f +dev_stk11xx_decompress stk11xx-dev.c /^int dev_stk11xx_decompress(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_init_camera stk11xx-dev.c /^int dev_stk11xx_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_initialize_device stk11xx-dev.c /^int dev_stk11xx_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_reconf_camera stk11xx-dev.c /^int dev_stk11xx_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_set_camera_fps stk11xx-dev.c /^int dev_stk11xx_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_set_camera_quality stk11xx-dev.c /^int dev_stk11xx_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_start_stream stk11xx-dev.c /^int dev_stk11xx_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_stop_stream stk11xx-dev.c /^int dev_stk11xx_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk11xx_watchdog_camera stk11xx-dev.c /^int dev_stk11xx_watchdog_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_camera_asleep stk11xx-dev-6a31.c /^int dev_stk6a31_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_camera_settings stk11xx-dev-6a31.c /^int dev_stk6a31_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_configure_device stk11xx-dev-6a31.c /^int dev_stk6a31_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk6a31_init_camera stk11xx-dev-6a31.c /^int dev_stk6a31_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_initialize_device stk11xx-dev-6a31.c /^int dev_stk6a31_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_reconf_camera stk11xx-dev-6a31.c /^int dev_stk6a31_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_sensor_settings stk11xx-dev-6a31.c /^int dev_stk6a31_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_set_camera_fps stk11xx-dev-6a31.c /^int dev_stk6a31_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_set_camera_quality stk11xx-dev-6a31.c /^int dev_stk6a31_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_start_stream stk11xx-dev-6a31.c /^int dev_stk6a31_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a31_stop_stream stk11xx-dev-6a31.c /^int dev_stk6a31_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_camera_asleep stk11xx-dev-6a33.c /^int dev_stk6a33_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_camera_settings stk11xx-dev-6a33.c /^int dev_stk6a33_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_configure_device stk11xx-dev-6a33.c /^int dev_stk6a33_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk6a33_init_camera stk11xx-dev-6a33.c /^int dev_stk6a33_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_initialize_device stk11xx-dev-6a33.c /^int dev_stk6a33_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_reconf_camera stk11xx-dev-6a33.c /^int dev_stk6a33_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_sensor_settings stk11xx-dev-6a33.c /^int dev_stk6a33_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_set_camera_fps stk11xx-dev-6a33.c /^int dev_stk6a33_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_set_camera_quality stk11xx-dev-6a33.c /^int dev_stk6a33_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_start_stream stk11xx-dev-6a33.c /^int dev_stk6a33_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a33_stop_stream stk11xx-dev-6a33.c /^int dev_stk6a33_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_camera_asleep stk11xx-dev-6a51.c /^int dev_stk6a51_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_camera_settings stk11xx-dev-6a51.c /^int dev_stk6a51_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_configure_device stk11xx-dev-6a51.c /^int dev_stk6a51_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk6a51_init_camera stk11xx-dev-6a51.c /^int dev_stk6a51_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_initialize_device stk11xx-dev-6a51.c /^int dev_stk6a51_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_reconf_camera stk11xx-dev-6a51.c /^int dev_stk6a51_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_sensor_settings stk11xx-dev-6a51.c /^int dev_stk6a51_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_set_camera_fps stk11xx-dev-6a51.c /^int dev_stk6a51_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_set_camera_quality stk11xx-dev-6a51.c /^int dev_stk6a51_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_start_stream stk11xx-dev-6a51.c /^int dev_stk6a51_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a51_stop_stream stk11xx-dev-6a51.c /^int dev_stk6a51_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_camera_asleep stk11xx-dev-6a54.c /^int dev_stk6a54_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_camera_settings stk11xx-dev-6a54.c /^int dev_stk6a54_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_configure_device stk11xx-dev-6a54.c /^int dev_stk6a54_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk6a54_init_camera stk11xx-dev-6a54.c /^int dev_stk6a54_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_initialize_device stk11xx-dev-6a54.c /^int dev_stk6a54_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_reconf_camera stk11xx-dev-6a54.c /^int dev_stk6a54_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_sensor_settings stk11xx-dev-6a54.c /^int dev_stk6a54_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_set_camera_fps stk11xx-dev-6a54.c /^int dev_stk6a54_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_set_camera_quality stk11xx-dev-6a54.c /^int dev_stk6a54_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_start_stream stk11xx-dev-6a54.c /^int dev_stk6a54_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6a54_stop_stream stk11xx-dev-6a54.c /^int dev_stk6a54_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_camera_asleep stk11xx-dev-6d51.c /^int dev_stk6d51_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_camera_settings stk11xx-dev-6d51.c /^int dev_stk6d51_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_configure_device stk11xx-dev-6d51.c /^int dev_stk6d51_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stk6d51_init_camera stk11xx-dev-6d51.c /^int dev_stk6d51_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_initialize_device stk11xx-dev-6d51.c /^int dev_stk6d51_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_reconf_camera stk11xx-dev-6d51.c /^int dev_stk6d51_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_sensor_settings stk11xx-dev-6d51.c /^int dev_stk6d51_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_set_camera_fps stk11xx-dev-6d51.c /^int dev_stk6d51_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_set_camera_quality stk11xx-dev-6d51.c /^int dev_stk6d51_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_start_stream stk11xx-dev-6d51.c /^int dev_stk6d51_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stk6d51_stop_stream stk11xx-dev-6d51.c /^int dev_stk6d51_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stka311_camera_asleep stk11xx-dev-a311.c /^int dev_stka311_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stka311_camera_settings stk11xx-dev-a311.c /^int dev_stka311_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stka311_configure_device stk11xx-dev-a311.c /^int dev_stka311_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stka311_init_camera stk11xx-dev-a311.c /^int dev_stka311_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stka311_initialize_device stk11xx-dev-a311.c /^int dev_stka311_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stka311_reconf_camera stk11xx-dev-a311.c /^int dev_stka311_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stka311_sensor_settings stk11xx-dev-a311.c /^int dev_stka311_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stka311_set_camera_fps stk11xx-dev-a311.c /^int dev_stka311_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stka311_set_camera_quality stk11xx-dev-a311.c /^int dev_stka311_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stka311_start_stream stk11xx-dev-a311.c /^int dev_stka311_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stka311_stop_stream stk11xx-dev-a311.c /^int dev_stka311_stop_stream(struct usb_stk11xx *dev)$/;" f +dev_stka821_camera_asleep stk11xx-dev-a821.c /^int dev_stka821_camera_asleep(struct usb_stk11xx *dev)$/;" f +dev_stka821_camera_settings stk11xx-dev-a821.c /^int dev_stka821_camera_settings(struct usb_stk11xx *dev)$/;" f +dev_stka821_configure_device stk11xx-dev-a821.c /^int dev_stka821_configure_device(struct usb_stk11xx *dev, int step)$/;" f +dev_stka821_init_camera stk11xx-dev-a821.c /^int dev_stka821_init_camera(struct usb_stk11xx *dev)$/;" f +dev_stka821_initialize_device stk11xx-dev-a821.c /^int dev_stka821_initialize_device(struct usb_stk11xx *dev)$/;" f +dev_stka821_reconf_camera stk11xx-dev-a821.c /^int dev_stka821_reconf_camera(struct usb_stk11xx *dev)$/;" f +dev_stka821_sensor_settings stk11xx-dev-a821.c /^int dev_stka821_sensor_settings(struct usb_stk11xx *dev)$/;" f +dev_stka821_set_camera_fps stk11xx-dev-a821.c /^int dev_stka821_set_camera_fps(struct usb_stk11xx *dev)$/;" f +dev_stka821_set_camera_quality stk11xx-dev-a821.c /^int dev_stka821_set_camera_quality(struct usb_stk11xx *dev)$/;" f +dev_stka821_start_stream stk11xx-dev-a821.c /^int dev_stka821_start_stream(struct usb_stk11xx *dev)$/;" f +dev_stka821_stop_stream stk11xx-dev-a821.c /^int dev_stka821_stop_stream(struct usb_stk11xx *dev)$/;" f +empty_frames stk11xx.h /^ struct stk11xx_frame_buf *empty_frames, *empty_frames_tail;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_frame_buf +empty_frames_tail stk11xx.h /^ struct stk11xx_frame_buf *empty_frames, *empty_frames_tail;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx:: +error_status stk11xx.h /^ int error_status;$/;" m struct:usb_stk11xx +errors stk11xx.h /^ int errors;$/;" m struct:stk11xx_frame_buf +fill_frame stk11xx.h /^ struct stk11xx_frame_buf *fill_frame;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_frame_buf +fill_image stk11xx.h /^ int fill_image;$/;" m struct:usb_stk11xx +filled stk11xx.h /^ volatile int filled;$/;" m struct:stk11xx_frame_buf +fps stk11xx-usb.c /^static int fps;$/;" v file: +fps stk11xx.h /^ int fps; \/**< FPS setting *\/$/;" m struct:stk11xx_video +frame_size stk11xx.h /^ int frame_size;$/;" m struct:usb_stk11xx +framebuf stk11xx.h /^ struct stk11xx_frame_buf *framebuf;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_frame_buf +full_frames stk11xx.h /^ struct stk11xx_frame_buf *full_frames, *full_frames_tail;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_frame_buf +full_frames_tail stk11xx.h /^ struct stk11xx_frame_buf *full_frames, *full_frames_tail;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx:: +hflip stk11xx-usb.c /^static int hflip = -1;$/;" v file: +hflip stk11xx.h /^ int hflip; \/**< Horizontal flip *\/$/;" m struct:stk11xx_video +hue stk11xx.h /^ int hue; \/**< Hue setting *\/$/;" m struct:stk11xx_video +image stk11xx.h /^ struct stk11xx_coord image;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_coord +image_data stk11xx.h /^ void *image_data;$/;" m struct:usb_stk11xx +image_read_pos stk11xx.h /^ int image_read_pos;$/;" m struct:usb_stk11xx +image_size stk11xx.h /^ int image_size;$/;" m struct:usb_stk11xx +image_used stk11xx.h /^ int image_used[STK11XX_MAX_IMAGES];$/;" m struct:usb_stk11xx +images stk11xx.h /^ struct stk11xx_image_buf images[STK11XX_MAX_IMAGES];$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_image_buf +input stk11xx.h /^ int input; \/**< Input for multiinput cards *\/$/;" m struct:stk11xx_video +int_in_buffer stk11xx.h /^ unsigned char *int_in_buffer; \/**< Interrupt IN buffer *\/$/;" m struct:usb_stk11xx +int_in_endpointAddr stk11xx.h /^ __u8 int_in_endpointAddr; \/**< Interrupt IN endpoint address *\/$/;" m struct:usb_stk11xx +int_in_size stk11xx.h /^ size_t int_in_size; \/**< Interrupt IN buffer size *\/$/;" m struct:usb_stk11xx +interface stk11xx.h /^ struct usb_interface *interface; \/**< Pointer on a USB interface *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::usb_interface +isobuf stk11xx.h /^ struct stk11xx_iso_buf isobuf[MAX_ISO_BUFS];$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_iso_buf +isoc_in_endpointAddr stk11xx.h /^ __u8 isoc_in_endpointAddr; \/**< Isochrone IN endpoint address *\/$/;" m struct:usb_stk11xx +isoc_in_size stk11xx.h /^ size_t isoc_in_size; \/**< Isochrone IN size *\/$/;" m struct:usb_stk11xx +isoc_init_ok stk11xx.h /^ char isoc_init_ok;$/;" m struct:usb_stk11xx +len_per_image stk11xx.h /^ unsigned int len_per_image;$/;" m struct:usb_stk11xx +length stk11xx.h /^ int length;$/;" m struct:stk11xx_iso_buf +modlock stk11xx.h /^ struct mutex modlock; \/**< To prevent races in video_open(), etc *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::mutex +mutex stk11xx.h /^ struct semaphore mutex; \/**< Mutex *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::semaphore +nbuffers stk11xx.h /^ unsigned int nbuffers;$/;" m struct:usb_stk11xx +next stk11xx.h /^ struct stk11xx_frame_buf *next;$/;" m struct:stk11xx_frame_buf typeref:struct:stk11xx_frame_buf::stk11xx_frame_buf +norm stk11xx-usb.c /^static int norm = -1;$/;" v file: +norm stk11xx.h /^ int norm; \/**< Norm, NTSC or PAL *\/$/;" m struct:stk11xx_video +odd stk11xx.h /^ volatile bool odd;$/;" m struct:stk11xx_frame_buf +offset stk11xx.h /^ unsigned long offset; \/**< Memory offset *\/$/;" m struct:stk11xx_image_buf +palette stk11xx.h /^ int palette; \/**< Palette setting *\/$/;" m struct:stk11xx_video +read stk11xx.h /^ int read;$/;" m struct:stk11xx_iso_buf +read_frame stk11xx.h /^ struct stk11xx_frame_buf *read_frame;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_frame_buf +release stk11xx.h /^ int release; \/**< Release of the device (bcdDevice) *\/$/;" m struct:usb_stk11xx +resolution stk11xx.h /^ int resolution;$/;" m struct:usb_stk11xx +show_brightness stk11xx-sysfs.c /^static ssize_t show_brightness(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_colour stk11xx-sysfs.c /^static ssize_t show_colour(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_contrast stk11xx-sysfs.c /^static ssize_t show_contrast(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_fps stk11xx-sysfs.c /^static ssize_t show_fps(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_hflip stk11xx-sysfs.c /^static ssize_t show_hflip(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_informations stk11xx-sysfs.c /^static ssize_t show_informations(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_release stk11xx-sysfs.c /^static ssize_t show_release(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_vflip stk11xx-sysfs.c /^static ssize_t show_vflip(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_videostatus stk11xx-sysfs.c /^static ssize_t show_videostatus(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +show_whitebalance stk11xx-sysfs.c /^static ssize_t show_whitebalance(struct device *class, struct device_attribute *attr, char *buf)$/;" f file: +spinlock stk11xx.h /^ spinlock_t spinlock; \/**< Spin lock *\/$/;" m struct:usb_stk11xx +stk11xx-objs Makefile /^stk11xx-objs := stk11xx-usb.o stk11xx-v4l.o stk11xx-sysfs.o stk11xx-dev.o stk11xx-buf.o stk11xx-bayer.o$/;" m +stk11xx_allocate_buffers stk11xx-buf.c /^int stk11xx_allocate_buffers(struct usb_stk11xx *dev)$/;" f +stk11xx_b2bgr24 stk11xx-bayer.c /^void stk11xx_b2bgr24(uint8_t *bayer, uint8_t *bgr,$/;" f +stk11xx_b2bgr32 stk11xx-bayer.c /^void stk11xx_b2bgr32(uint8_t *bayer, uint8_t *bgr,$/;" f +stk11xx_b2rgb24 stk11xx-bayer.c /^void stk11xx_b2rgb24(uint8_t *bayer, uint8_t *rgb,$/;" f +stk11xx_b2rgb32 stk11xx-bayer.c /^void stk11xx_b2rgb32(uint8_t *bayer, uint8_t *rgb,$/;" f +stk11xx_b2uyvy stk11xx-bayer.c /^void stk11xx_b2uyvy(uint8_t *bayer, uint8_t *yuv,$/;" f +stk11xx_b2yuyv stk11xx-bayer.c /^void stk11xx_b2yuyv(uint8_t *bayer, uint8_t *yuv,$/;" f +stk11xx_clear_buffers stk11xx-buf.c /^int stk11xx_clear_buffers(struct usb_stk11xx *dev)$/;" f +stk11xx_controls stk11xx-v4l.c /^static struct v4l2_queryctrl stk11xx_controls[] = {$/;" v typeref:struct:v4l2_queryctrl file: +stk11xx_coord stk11xx.h /^struct stk11xx_coord {$/;" s +stk11xx_copy_rgb stk11xx-dev-0408.c /^void stk11xx_copy_rgb(uint8_t *src, uint8_t *rgb,$/;" f +stk11xx_copy_uvyv stk11xx-dev-0408.c /^void stk11xx_copy_uvyv(uint8_t *src, uint8_t *rgb,$/;" f +stk11xx_correct_brightness stk11xx-bayer.c /^void stk11xx_correct_brightness(uint8_t *img, const int width, const int height, $/;" f +stk11xx_create_sysfs_files stk11xx-sysfs.c /^int stk11xx_create_sysfs_files(struct video_device *vdev)$/;" f +stk11xx_decompress stk11xx-bayer.c /^int stk11xx_decompress(struct usb_stk11xx *dev)$/;" f +stk11xx_frame_buf stk11xx.h /^struct stk11xx_frame_buf {$/;" s +stk11xx_free_buffers stk11xx-buf.c /^int stk11xx_free_buffers(struct usb_stk11xx *dev)$/;" f +stk11xx_handle_frame stk11xx-buf.c /^int stk11xx_handle_frame(struct usb_stk11xx *dev)$/;" f +stk11xx_image_buf stk11xx.h /^struct stk11xx_image_buf {$/;" s +stk11xx_image_sizes stk11xx-v4l.c /^const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES] = {$/;" v typeref:struct:stk11xx_coord +stk11xx_iso_buf stk11xx.h /^struct stk11xx_iso_buf {$/;" s +stk11xx_next_frame stk11xx-buf.c /^int stk11xx_next_frame(struct usb_stk11xx *dev)$/;" f +stk11xx_next_image stk11xx-buf.c /^void stk11xx_next_image(struct usb_stk11xx *dev)$/;" f +stk11xx_remove_sysfs_files stk11xx-sysfs.c /^void stk11xx_remove_sysfs_files(struct video_device *vdev)$/;" f +stk11xx_reset_buffers stk11xx-buf.c /^int stk11xx_reset_buffers(struct usb_stk11xx *dev)$/;" f +stk11xx_rvfree stk11xx-buf.c /^void stk11xx_rvfree(void *mem, unsigned long size)$/;" f +stk11xx_rvmalloc stk11xx-buf.c /^void * stk11xx_rvmalloc(unsigned long size)$/;" f +stk11xx_table stk11xx-usb.c /^static struct usb_device_id stk11xx_table[] = {$/;" v typeref:struct:usb_device_id file: +stk11xx_video stk11xx.h /^struct stk11xx_video {$/;" s +stk11xx_yuv_interp stk11xx-bayer.c /^static signed short stk11xx_yuv_interp[256][8] = {$/;" v file: +store_brightness stk11xx-sysfs.c /^static ssize_t store_brightness(struct device *class, struct device_attribute *attr, $/;" f file: +store_colour stk11xx-sysfs.c /^static ssize_t store_colour(struct device *class, struct device_attribute *attr,$/;" f file: +store_contrast stk11xx-sysfs.c /^static ssize_t store_contrast(struct device *class, struct device_attribute *attr,$/;" f file: +store_hflip stk11xx-sysfs.c /^static ssize_t store_hflip(struct device *class, struct device_attribute *attr,$/;" f file: +store_vflip stk11xx-sysfs.c /^static ssize_t store_vflip(struct device *class, struct device_attribute *attr, const char *buf, size_t count)$/;" f file: +store_whitebalance stk11xx-sysfs.c /^static ssize_t store_whitebalance(struct device *class, struct device_attribute *attr,$/;" f file: +to_stk11xx_dev stk11xx.h 393;" d +udev stk11xx.h /^ struct usb_device *udev; \/**< Pointer on a USB device *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::usb_device +urb stk11xx.h /^ struct urb *urb;$/;" m struct:stk11xx_iso_buf typeref:struct:stk11xx_iso_buf::urb +usb_stk11xx stk11xx.h /^struct usb_stk11xx {$/;" s +usb_stk11xx_default_settings stk11xx-usb.c /^static int usb_stk11xx_default_settings(struct usb_stk11xx *dev)$/;" f file: +usb_stk11xx_disconnect stk11xx-usb.c /^static void usb_stk11xx_disconnect(struct usb_interface *interface)$/;" f file: +usb_stk11xx_driver stk11xx-usb.c /^static struct usb_driver usb_stk11xx_driver = {$/;" v typeref:struct:usb_driver file: +usb_stk11xx_exit stk11xx-usb.c /^module_exit(usb_stk11xx_exit); \/**< @brief Module exit *\/$/;" v +usb_stk11xx_exit stk11xx-usb.c /^static void __exit usb_stk11xx_exit(void)$/;" f file: +usb_stk11xx_init stk11xx-usb.c /^module_init(usb_stk11xx_init); \/**< @brief Module initialize *\/$/;" v +usb_stk11xx_init stk11xx-usb.c /^static int __init usb_stk11xx_init(void)$/;" f file: +usb_stk11xx_isoc_cleanup stk11xx-usb.c /^void usb_stk11xx_isoc_cleanup(struct usb_stk11xx *dev)$/;" f +usb_stk11xx_isoc_handler stk11xx-usb.c /^void usb_stk11xx_isoc_handler(struct urb *urb)$/;" f +usb_stk11xx_isoc_init stk11xx-usb.c /^int usb_stk11xx_isoc_init(struct usb_stk11xx *dev)$/;" f +usb_stk11xx_probe stk11xx-usb.c /^static int usb_stk11xx_probe(struct usb_interface *interface, const struct usb_device_id *id)$/;" f file: +usb_stk11xx_read_registry stk11xx-usb.c /^int usb_stk11xx_read_registry(struct usb_stk11xx *dev, __u16 index, int *value)$/;" f +usb_stk11xx_resume stk11xx-usb.c /^int usb_stk11xx_resume(struct usb_interface *interface)$/;" f +usb_stk11xx_set_configuration stk11xx-usb.c /^int usb_stk11xx_set_configuration(struct usb_stk11xx *dev)$/;" f +usb_stk11xx_set_feature stk11xx-usb.c /^int usb_stk11xx_set_feature(struct usb_stk11xx *dev, int index)$/;" f +usb_stk11xx_suspend stk11xx-usb.c /^int usb_stk11xx_suspend(struct usb_interface *interface, pm_message_t message)$/;" f +usb_stk11xx_write_registry stk11xx-usb.c /^int usb_stk11xx_write_registry(struct usb_stk11xx *dev, __u16 index, __u16 value)$/;" f +v1st_cap stk11xx.h /^ int v1st_cap; \/**< used to get a clean 1st capture *\/$/;" m struct:usb_stk11xx +v4l2_dev stk11xx.h /^ struct v4l2_device v4l2_dev;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::v4l2_device +v4l_stk11xx_do_ioctl stk11xx-v4l.c /^static long v4l_stk11xx_do_ioctl(struct file *fp,$/;" f file: +v4l_stk11xx_fops stk11xx-v4l.c /^static struct v4l2_file_operations v4l_stk11xx_fops = {$/;" v typeref:struct:v4l2_file_operations file: +v4l_stk11xx_fops stk11xx-v4l.c /^static struct v4l2_file_operations v4l_stk11xx_fops;$/;" v typeref:struct:v4l2_file_operations file: +v4l_stk11xx_ioctl stk11xx-v4l.c /^static long v4l_stk11xx_ioctl(struct file *fp,$/;" f file: +v4l_stk11xx_mmap stk11xx-v4l.c /^static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma)$/;" f file: +v4l_stk11xx_open stk11xx-v4l.c /^static int v4l_stk11xx_open(struct file *fp)$/;" f file: +v4l_stk11xx_poll stk11xx-v4l.c /^static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait)$/;" f file: +v4l_stk11xx_read stk11xx-v4l.c /^static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf,$/;" f file: +v4l_stk11xx_register_video_device stk11xx-v4l.c /^int v4l_stk11xx_register_video_device(struct usb_stk11xx *dev)$/;" f +v4l_stk11xx_release stk11xx-v4l.c /^static int v4l_stk11xx_release(struct file *fp)$/;" f file: +v4l_stk11xx_select_video_mode stk11xx-v4l.c /^int v4l_stk11xx_select_video_mode(struct usb_stk11xx *dev, int width, int height)$/;" f +v4l_stk11xx_unregister_video_device stk11xx-v4l.c /^int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *dev)$/;" f +vdev stk11xx.h /^ struct video_device *vdev; \/**< Pointer on a V4L2 video device *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::video_device +vflip stk11xx-usb.c /^static int vflip = -1;$/;" v file: +vflip stk11xx.h /^ int vflip; \/**< Vertical flip *\/$/;" m struct:stk11xx_video +vframes_dumped stk11xx.h /^ int vframes_dumped; \/**< Count the number of ignored frames *\/$/;" m struct:usb_stk11xx +vframes_error stk11xx.h /^ int vframes_error; \/**< Count the number of fault frames (so dropped) *\/$/;" m struct:usb_stk11xx +view stk11xx.h /^ struct stk11xx_coord view;$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_coord +view_size stk11xx.h /^ int view_size;$/;" m struct:usb_stk11xx +visoc_errors stk11xx.h /^ int visoc_errors; \/**< Count the number of ISOCH errors *\/$/;" m struct:usb_stk11xx +vma_use_count stk11xx.h /^ int vma_use_count; \/**< VMA counter *\/$/;" m struct:stk11xx_image_buf +vopen stk11xx.h /^ int vopen; \/**< Video status (Opened or Closed) *\/$/;" m struct:usb_stk11xx +vsettings stk11xx.h /^ struct stk11xx_video vsettings; \/**< Video settings (brightness, whiteness...) *\/$/;" m struct:usb_stk11xx typeref:struct:usb_stk11xx::stk11xx_video +vsync stk11xx.h /^ int vsync; \/**< sync on valid frame *\/$/;" m struct:usb_stk11xx +wait_frame stk11xx.h /^ wait_queue_head_t wait_frame; \/**< Queue head *\/$/;" m struct:usb_stk11xx +watchdog stk11xx.h /^ int watchdog; \/**< Counter for the software watchdog *\/$/;" m struct:usb_stk11xx +webcam_model stk11xx.h /^ int webcam_model; \/**< Model of video camera device *\/$/;" m struct:usb_stk11xx +webcam_type stk11xx.h /^ int webcam_type; \/**< Type of camera : VGA, SXGA (1.3M), UXGA (2M) *\/$/;" m struct:usb_stk11xx +whiteness stk11xx-usb.c /^static int whiteness = -1;$/;" v file: +whiteness stk11xx.h /^ int whiteness; \/**< Whiteness setting *\/$/;" m struct:stk11xx_video +x stk11xx.h /^ int x; \/**< X-coordonate *\/$/;" m struct:stk11xx_coord +y stk11xx.h /^ int y; \/**< Y-coordonate *\/$/;" m struct:stk11xx_coord