Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 Dec 2009 18:09:16 +0000 (10:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 Dec 2009 18:09:16 +0000 (10:09 -0800)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (116 commits)
  V4L/DVB (13698): pms: replace asm/uaccess.h to linux/uaccess.h
  V4L/DVB (13690): radio/si470x: #include <sched.h>
  V4L/DVB (13688): au8522: modify the attributes of local filter coefficients
  V4L/DVB (13687): cx231xx: use NULL when pointer is needed
  V4L/DVB: Davinci VPFE Capture: remove unused #include <linux/version.h>
  V4L/DVB (13685): Correct code taking the size of a pointer
  V4L/DVB (13684): Fix some cut-and-paste noise in dib0090.h
  V4L/DVB (13683): sanio-ms: clean up init, exit and id_table
  V4L/DVB (13682): dib8000: make some constant static
  V4L/DVB: lgs8gxx: Use shifts rather than multiply/divide when possible
  V4L/DVB (13680b): DocBook/media: create links for included sources
  V4L/DVB (13680a): DocBook/media: copy images after building HTML
  V4L/DVB (13678): Add support for yet another DvbWorld, TeVii and Prof USB devices
  V4L/DVB (13676): configurable IRQ mode on NetUP Dual DVB-S2 CI; IRQ from CAM processing (CI interface works faster)
  V4L/DVB (13674): stv090x: Add DiSEqC envelope mode
  V4L/DVB (13673): lnbp21: Implement 22 kHz tone control
  V4L/DVB (13671): sh_mobile_ceu_camera: Remove frame size page alignment
  V4L/DVB (13670): soc-camera: Add mt9t112 camera driver
  V4L/DVB (13669): tw9910: Add sync polarity support
  V4L/DVB (13668): tw9910: remove cropping
  ...

227 files changed:
Documentation/DocBook/Makefile
Documentation/DocBook/media-entities.tmpl
Documentation/DocBook/media-indices.tmpl
Documentation/DocBook/v4l/common.xml
Documentation/DocBook/v4l/compat.xml
Documentation/DocBook/v4l/v4l2.xml
Documentation/DocBook/v4l/videodev2.h.xml
Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml [new file with mode: 0644]
Documentation/DocBook/v4l/vidioc-enuminput.xml
Documentation/DocBook/v4l/vidioc-enumoutput.xml
Documentation/DocBook/v4l/vidioc-g-dv-preset.xml [new file with mode: 0644]
Documentation/DocBook/v4l/vidioc-g-dv-timings.xml [new file with mode: 0644]
Documentation/DocBook/v4l/vidioc-g-std.xml
Documentation/DocBook/v4l/vidioc-query-dv-preset.xml [new file with mode: 0644]
Documentation/DocBook/v4l/vidioc-querystd.xml
Documentation/video4linux/gspca.txt
Documentation/video4linux/sh_mobile_ceu_camera.txt [new file with mode: 0644]
Documentation/video4linux/v4l2-framework.txt
arch/sh/boards/mach-ap325rxa/setup.c
arch/sh/boards/mach-kfr2r09/setup.c
arch/sh/boards/mach-migor/setup.c
drivers/media/IR/Kconfig [new file with mode: 0644]
drivers/media/IR/Makefile [new file with mode: 0644]
drivers/media/IR/ir-functions.c [moved from drivers/media/common/ir-functions.c with 92% similarity]
drivers/media/IR/ir-keymaps.c [moved from drivers/media/common/ir-keymaps.c with 97% similarity]
drivers/media/IR/ir-keytable.c [moved from drivers/media/common/ir-keytable.c with 81% similarity]
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/Makefile
drivers/media/common/saa7146_fops.c
drivers/media/dvb/dm1105/dm1105.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/dib0700.h
drivers/media/dvb/dvb-usb/dib0700_core.c
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dw2102.c
drivers/media/dvb/dvb-usb/friio-fe.c
drivers/media/dvb/dvb-usb/gp8psk-fe.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/au8522_decoder.c
drivers/media/dvb/frontends/dib0070.c
drivers/media/dvb/frontends/dib0070.h
drivers/media/dvb/frontends/dib0090.c [new file with mode: 0644]
drivers/media/dvb/frontends/dib0090.h [new file with mode: 0644]
drivers/media/dvb/frontends/dib8000.c
drivers/media/dvb/frontends/dib8000.h
drivers/media/dvb/frontends/dibx000_common.c
drivers/media/dvb/frontends/dibx000_common.h
drivers/media/dvb/frontends/lgs8gxx.c
drivers/media/dvb/frontends/lnbp21.c
drivers/media/dvb/frontends/stv0900_core.c
drivers/media/dvb/frontends/stv090x.c
drivers/media/dvb/frontends/stv090x.h
drivers/media/dvb/siano/smsdvb.c
drivers/media/dvb/siano/smssdio.c
drivers/media/dvb/siano/smsusb.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/radio/Kconfig
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/radio-rtrack2.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-terratec.c
drivers/media/radio/radio-trust.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/radio/si470x/radio-si470x-usb.c
drivers/media/radio/si470x/radio-si470x.h
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/arv.c
drivers/media/video/au0828/au0828-video.c
drivers/media/video/au0828/au0828.h
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bt8xx/bttv-i2c.c
drivers/media/video/bt8xx/bttv-input.c
drivers/media/video/c-qcam.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cpia.c
drivers/media/video/cpia2/cpia2_v4l.c
drivers/media/video/cx18/cx18-fileops.c
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx231xx/cx231xx-core.c
drivers/media/video/cx231xx/cx231xx-input.c
drivers/media/video/cx231xx/cx231xx-video.c
drivers/media/video/cx231xx/cx231xx.h
drivers/media/video/cx23885/cimax2.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-core.c
drivers/media/video/cx23885/cx23885-input.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/cx23885/cx23885.h
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h
drivers/media/video/davinci/vpfe_capture.c
drivers/media/video/davinci/vpif.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/davinci/vpss.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/gspca/conex.c
drivers/media/video/gspca/etoms.c
drivers/media/video/gspca/gl860/gl860-mi1320.c
drivers/media/video/gspca/gl860/gl860-mi2020.c
drivers/media/video/gspca/gl860/gl860.c
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h
drivers/media/video/gspca/m5602/m5602_core.c
drivers/media/video/gspca/m5602/m5602_ov9650.c
drivers/media/video/gspca/m5602/m5602_s5k4aa.c
drivers/media/video/gspca/mr97310a.c
drivers/media/video/gspca/ov519.c
drivers/media/video/gspca/pac7302.c
drivers/media/video/gspca/pac7311.c
drivers/media/video/gspca/sn9c20x.c
drivers/media/video/gspca/sonixb.c
drivers/media/video/gspca/spca506.c
drivers/media/video/gspca/stk014.c
drivers/media/video/gspca/sunplus.c
drivers/media/video/gspca/zc3xx.c
drivers/media/video/hdpvr/hdpvr-core.c
drivers/media/video/hdpvr/hdpvr-video.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/meye.c
drivers/media/video/mt9m001.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9t031.c
drivers/media/video/mt9t112.c [new file with mode: 0644]
drivers/media/video/mt9v022.c
drivers/media/video/mx1_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/omap24xxcam.c
drivers/media/video/ov511.c
drivers/media/video/ov772x.c
drivers/media/video/ov9640.c
drivers/media/video/pms.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/pxa_camera.c
drivers/media/video/rj54n1cb0c.c
drivers/media/video/s2255drv.c
drivers/media/video/saa5246a.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/se401.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/soc_camera.c
drivers/media/video/soc_camera_platform.c
drivers/media/video/soc_mediabus.c [new file with mode: 0644]
drivers/media/video/stk-webcam.c
drivers/media/video/stradis.c
drivers/media/video/stv680.c
drivers/media/video/tw9910.c
drivers/media/video/usbvideo/usbvideo.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/v4l2-common.c
drivers/media/video/v4l2-compat-ioctl32.c
drivers/media/video/v4l2-dev.c
drivers/media/video/v4l2-ioctl.c
drivers/media/video/videobuf-dma-contig.c
drivers/media/video/vino.c
drivers/media/video/vivi.c
drivers/media/video/w9968cf.c
drivers/media/video/zc0301/zc0301_core.c
drivers/media/video/zoran/zoran_driver.c
drivers/media/video/zr364xx.c
drivers/staging/cx25821/cx25821-audups11.c
drivers/staging/cx25821/cx25821-video.c
drivers/staging/cx25821/cx25821-video0.c
drivers/staging/cx25821/cx25821-video1.c
drivers/staging/cx25821/cx25821-video2.c
drivers/staging/cx25821/cx25821-video3.c
drivers/staging/cx25821/cx25821-video4.c
drivers/staging/cx25821/cx25821-video5.c
drivers/staging/cx25821/cx25821-video6.c
drivers/staging/cx25821/cx25821-video7.c
drivers/staging/cx25821/cx25821-videoioctl.c
drivers/staging/cx25821/cx25821-vidups10.c
drivers/staging/cx25821/cx25821-vidups9.c
drivers/staging/go7007/go7007-v4l2.c
include/linux/videodev2.h
include/media/ir-common.h
include/media/ir-core.h [new file with mode: 0644]
include/media/mt9t112.h [new file with mode: 0644]
include/media/ov772x.h
include/media/rj54n1cb0c.h [new file with mode: 0644]
include/media/saa7146_vv.h
include/media/sh_mobile_ceu.h
include/media/soc_camera.h
include/media/soc_camera_platform.h
include/media/soc_mediabus.h [new file with mode: 0644]
include/media/tw9910.h
include/media/v4l2-chip-ident.h
include/media/v4l2-common.h
include/media/v4l2-dev.h
include/media/v4l2-ioctl.h
include/media/v4l2-mediabus.h [new file with mode: 0644]
include/media/v4l2-subdev.h

index ee34ceb9ad5f15ab009fbdb1b21285d4cc35c0c8..325cfd1d6d9929686c6f5c42f93272c3147a7b9c 100644 (file)
@@ -32,10 +32,10 @@ PS_METHOD   = $(prefer-db2x)
 
 ###
 # The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
 
 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
-xmldocs: $(BOOKS)
+xmldocs: $(BOOKS) xmldoclinks
 sgmldocs: xmldocs
 
 PS := $(patsubst %.xml, %.ps, $(BOOKS))
@@ -45,15 +45,24 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
 pdfdocs: $(PDF)
 
 HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
-htmldocs: media $(HTML)
+htmldocs: $(HTML)
        $(call build_main_index)
+       $(call build_images)
 
 MAN := $(patsubst %.xml, %.9, $(BOOKS))
 mandocs: $(MAN)
 
-media:
-       mkdir -p $(srctree)/Documentation/DocBook/media/
-       cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
+build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
+              cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
+
+xmldoclinks:
+ifneq ($(objtree),$(srctree))
+       for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
+               rm -f $(objtree)/Documentation/DocBook/$$dep \
+               && ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
+               || exit; \
+       done
+endif
 
 installmandocs: mandocs
        mkdir -p /usr/local/man/man9/
index bb5ab741220ef3ed3a8dbdedbbae87787e2a8825..c725cb852c540df0d5d061d19c9f467ae921c8e7 100644 (file)
@@ -23,6 +23,7 @@
 <!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
 <!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
 <!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
+<!ENTITY VIDIOC-ENUM-DV-PRESETS "<link linkend='vidioc-enum-dv-presets'><constant>VIDIOC_ENUM_DV_PRESETS</constant></link>">
 <!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
 <!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
 <!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
@@ -30,6 +31,8 @@
 <!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
 <!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
 <!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
+<!ENTITY VIDIOC-G-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_G_DV_PRESET</constant></link>">
+<!ENTITY VIDIOC-G-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_G_DV_TIMINGS</constant></link>">
 <!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
 <!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
 <!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
@@ -53,6 +56,7 @@
 <!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
 <!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
 <!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
+<!ENTITY VIDIOC-QUERY-DV-PRESET "<link linkend='vidioc-query-dv-preset'><constant>VIDIOC_QUERY_DV_PRESET</constant></link>">
 <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
 <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
 <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
@@ -60,6 +64,8 @@
 <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
 <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
 <!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
+<!ENTITY VIDIOC-S-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_S_DV_PRESET</constant></link>">
+<!ENTITY VIDIOC-S-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_S_DV_TIMINGS</constant></link>">
 <!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
 <!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
 <!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
 <!-- Structures -->
 <!ENTITY v4l2-audio "struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link>">
 <!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
+<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
 <!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
 <!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
 <!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
 <!ENTITY v4l2-dbg-chip-ident "struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
 <!ENTITY v4l2-dbg-match "struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
 <!ENTITY v4l2-dbg-register "struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
+<!ENTITY v4l2-dv-enum-preset "struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link>">
+<!ENTITY v4l2-dv-preset "struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link>">
+<!ENTITY v4l2-dv-timings "struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link>">
 <!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
 <!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
 <!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
 <!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
 <!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
 <!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY sub-enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
+<!ENTITY sub-g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
+<!ENTITY sub-query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
+<!ENTITY sub-g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
 <!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
 <!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
 <!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
 <!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
 <!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
 <!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
+<!ENTITY g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
+<!ENTITY query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
+<!ENTITY g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
 <!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
 <!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
 <!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
index 9e30a236d74f7af2aaa1fc71e914266cf7b17660..78d6031de001bc5fd46a926c91037058e85aa3ff 100644 (file)
@@ -36,6 +36,7 @@
 <indexentry><primaryie>enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
@@ -46,6 +47,9 @@
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
index b1a81d246d581913af349d7adbec4be57ec58c79..c65f0ac9b6eec58942562c7e8d1a5386554a4fa9 100644 (file)
@@ -716,6 +716,41 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
 }
       </programlisting>
     </example>
+  <section id="dv-timings">
+       <title>Digital Video (DV) Timings</title>
+       <para>
+       The video standards discussed so far has been dealing with Analog TV and the
+corresponding video timings. Today there are many more different hardware interfaces
+such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
+video signals and there is a need to extend the API to select the video timings
+for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
+the limited bits available, a new set of IOCTLs is added to set/get video timings at
+the input and output: </para><itemizedlist>
+       <listitem>
+       <para>DV Presets: Digital Video (DV) presets. These are IDs representing a
+video timing at the input/output. Presets are pre-defined timings implemented
+by the hardware according to video standards. A __u32 data type is used to represent
+a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions
+to support as many different presets as needed.</para>
+       </listitem>
+       <listitem>
+       <para>Custom DV Timings: This will allow applications to define more detailed
+custom video timings for the interface. This includes parameters such as width, height,
+polarities, frontporch, backporch etc.
+       </para>
+       </listitem>
+       </itemizedlist>
+       <para>To enumerate and query the attributes of DV presets supported by a device,
+applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset,
+applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the
+&VIDIOC-S-DV-PRESET; ioctl.</para>
+       <para>To set custom DV timings for the device, applications use the
+&VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the
+&VIDIOC-G-DV-TIMINGS; ioctl.</para>
+       <para>Applications can make use of the <xref linkend="input-capabilities" /> and
+<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
+video timings for the device.</para>
+       </section>
   </section>
 
   &sub-controls;
index 4d1902a54d613fe6ca2169b1046f8ba3bf544dc9..b9dbdf9e6d29bd29b3df3617a77311b947b27e80 100644 (file)
@@ -2291,8 +2291,8 @@ was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structn
        <listitem>
          <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
        </listitem>
-       </orderedlist>
-     </section>
+      </orderedlist>
+    </section>
     <section>
       <title>V4L2 in Linux 2.6.32</title>
       <orderedlist>
@@ -2322,8 +2322,16 @@ more information.</para>
        <listitem>
          <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
        </listitem>
-       </orderedlist>
-     </section>
+      </orderedlist>
+    </section>
+    <section>
+      <title>V4L2 in Linux 2.6.33</title>
+      <orderedlist>
+       <listitem>
+         <para>Added support for Digital Video timings in order to support HDTV receivers and transmitters.</para>
+       </listitem>
+      </orderedlist>
+    </section>
    </section>
 
    <section id="other">
index 937b4157a5d07ba48322d34a289154a7cf9c2823..060105af49e5989b2f1dad9a9c38f00d532e1602 100644 (file)
@@ -74,6 +74,17 @@ Remote Controller chapter.</contrib>
          </address>
        </affiliation>
       </author>
+
+      <author>
+       <firstname>Muralidharan</firstname>
+       <surname>Karicheri</surname>
+       <contrib>Documented the Digital Video timings API.</contrib>
+       <affiliation>
+         <address>
+           <email>m-karicheri2@ti.com</email>
+         </address>
+       </affiliation>
+      </author>
     </authorgroup>
 
     <copyright>
@@ -89,7 +100,7 @@ Remote Controller chapter.</contrib>
       <year>2008</year>
       <year>2009</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
-Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
+Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
     </copyright>
     <legalnotice>
     <para>Except when explicitly stated as GPL, programming examples within
@@ -102,6 +113,13 @@ structs, ioctls) must be noted in more detail in the history chapter
 (compat.sgml), along with the possible impact on existing drivers and
 applications. -->
 
+      <revision>
+       <revnumber>2.6.33</revnumber>
+       <date>2009-12-03</date>
+       <authorinitials>mk</authorinitials>
+       <revremark>Added documentation for the Digital Video timings API.</revremark>
+      </revision>
+
       <revision>
        <revnumber>2.6.32</revnumber>
        <date>2009-08-31</date>
@@ -355,7 +373,7 @@ and discussions on the V4L mailing list.</revremark>
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 2.6.32</subtitle>
+ <subtitle>Revision 2.6.33</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -411,6 +429,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-encoder-cmd;
     &sub-enumaudio;
     &sub-enumaudioout;
+    &sub-enum-dv-presets;
     &sub-enum-fmt;
     &sub-enum-framesizes;
     &sub-enum-frameintervals;
@@ -421,6 +440,8 @@ and discussions on the V4L mailing list.</revremark>
     &sub-g-audioout;
     &sub-g-crop;
     &sub-g-ctrl;
+    &sub-g-dv-preset;
+    &sub-g-dv-timings;
     &sub-g-enc-index;
     &sub-g-ext-ctrls;
     &sub-g-fbuf;
@@ -441,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-querybuf;
     &sub-querycap;
     &sub-queryctrl;
+    &sub-query-dv-preset;
     &sub-querystd;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
index 3e282ed9f593820d3240d025ffdb186a405f948f..068325940658ee78ed9515f6270f17b3360eede2 100644 (file)
@@ -733,6 +733,99 @@ struct <link linkend="v4l2-standard">v4l2_standard</link> {
         __u32                reserved[4];
 };
 
+/*
+ *      V I D E O       T I M I N G S   D V     P R E S E T
+ */
+struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link> {
+        __u32   preset;
+        __u32   reserved[4];
+};
+
+/*
+ *      D V     P R E S E T S   E N U M E R A T I O N
+ */
+struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link> {
+        __u32   index;
+        __u32   preset;
+        __u8    name[32]; /* Name of the preset timing */
+        __u32   width;
+        __u32   height;
+        __u32   reserved[4];
+};
+
+/*
+ *      D V     P R E S E T     V A L U E S
+ */
+#define         V4L2_DV_INVALID         0
+#define         V4L2_DV_480P59_94       1 /* BT.1362 */
+#define         V4L2_DV_576P50          2 /* BT.1362 */
+#define         V4L2_DV_720P24          3 /* SMPTE 296M */
+#define         V4L2_DV_720P25          4 /* SMPTE 296M */
+#define         V4L2_DV_720P30          5 /* SMPTE 296M */
+#define         V4L2_DV_720P50          6 /* SMPTE 296M */
+#define         V4L2_DV_720P59_94       7 /* SMPTE 274M */
+#define         V4L2_DV_720P60          8 /* SMPTE 274M/296M */
+#define         V4L2_DV_1080I29_97      9 /* BT.1120/ SMPTE 274M */
+#define         V4L2_DV_1080I30         10 /* BT.1120/ SMPTE 274M */
+#define         V4L2_DV_1080I25         11 /* BT.1120 */
+#define         V4L2_DV_1080I50         12 /* SMPTE 296M */
+#define         V4L2_DV_1080I60         13 /* SMPTE 296M */
+#define         V4L2_DV_1080P24         14 /* SMPTE 296M */
+#define         V4L2_DV_1080P25         15 /* SMPTE 296M */
+#define         V4L2_DV_1080P30         16 /* SMPTE 296M */
+#define         V4L2_DV_1080P50         17 /* BT.1120 */
+#define         V4L2_DV_1080P60         18 /* BT.1120 */
+
+/*
+ *      D V     B T     T I M I N G S
+ */
+
+/* BT.656/BT.1120 timing data */
+struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> {
+        __u32   width;          /* width in pixels */
+        __u32   height;         /* height in lines */
+        __u32   interlaced;     /* Interlaced or progressive */
+        __u32   polarities;     /* Positive or negative polarity */
+        __u64   pixelclock;     /* Pixel clock in HZ. Ex. 74.25MHz-&gt;74250000 */
+        __u32   hfrontporch;    /* Horizpontal front porch in pixels */
+        __u32   hsync;          /* Horizontal Sync length in pixels */
+        __u32   hbackporch;     /* Horizontal back porch in pixels */
+        __u32   vfrontporch;    /* Vertical front porch in pixels */
+        __u32   vsync;          /* Vertical Sync length in lines */
+        __u32   vbackporch;     /* Vertical back porch in lines */
+        __u32   il_vfrontporch; /* Vertical front porch for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   il_vsync;       /* Vertical sync length for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   il_vbackporch;  /* Vertical back porch for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   reserved[16];
+} __attribute__ ((packed));
+
+/* Interlaced or progressive format */
+#define V4L2_DV_PROGRESSIVE     0
+#define V4L2_DV_INTERLACED      1
+
+/* Polarities. If bit is not set, it is assumed to be negative polarity */
+#define V4L2_DV_VSYNC_POS_POL   0x00000001
+#define V4L2_DV_HSYNC_POS_POL   0x00000002
+
+
+/* DV timings */
+struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link> {
+        __u32 type;
+        union {
+                struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link>  bt;
+                __u32   reserved[32];
+        };
+} __attribute__ ((packed));
+
+/* Values for the type field */
+#define V4L2_DV_BT_656_1120     0       /* BT.656/1120 timing type */
+
 /*
  *      V I D E O   I N P U T S
  */
@@ -744,7 +837,8 @@ struct <link linkend="v4l2-input">v4l2_input</link> {
         __u32        tuner;             /*  Associated tuner */
         v4l2_std_id  std;
         __u32        status;
-        __u32        reserved[4];
+        __u32        capabilities;
+        __u32        reserved[3];
 };
 
 /*  Values for the 'type' field */
@@ -775,6 +869,11 @@ struct <link linkend="v4l2-input">v4l2_input</link> {
 #define V4L2_IN_ST_NO_ACCESS   0x02000000  /* Conditional access denied */
 #define V4L2_IN_ST_VTR         0x04000000  /* VTR time constant */
 
+/* capabilities flags */
+#define V4L2_IN_CAP_PRESETS             0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_IN_CAP_CUSTOM_TIMINGS      0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_IN_CAP_STD                 0x00000004 /* Supports S_STD */
+
 /*
  *      V I D E O   O U T P U T S
  */
@@ -785,13 +884,19 @@ struct <link linkend="v4l2-output">v4l2_output</link> {
         __u32        audioset;          /*  Associated audios (bitfield) */
         __u32        modulator;         /*  Associated modulator */
         v4l2_std_id  std;
-        __u32        reserved[4];
+        __u32        capabilities;
+        __u32        reserved[3];
 };
 /*  Values for the 'type' field */
 #define V4L2_OUTPUT_TYPE_MODULATOR              1
 #define V4L2_OUTPUT_TYPE_ANALOG                 2
 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY       3
 
+/* capabilities flags */
+#define V4L2_OUT_CAP_PRESETS            0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_OUT_CAP_CUSTOM_TIMINGS     0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_OUT_CAP_STD                0x00000004 /* Supports S_STD */
+
 /*
  *      C O N T R O L S
  */
@@ -1626,6 +1731,13 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
 #endif
 
 #define VIDIOC_S_HW_FREQ_SEEK    _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>)
+#define VIDIOC_ENUM_DV_PRESETS  _IOWR('V', 83, struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link>)
+#define VIDIOC_S_DV_PRESET      _IOWR('V', 84, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_G_DV_PRESET      _IOWR('V', 85, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_QUERY_DV_PRESET  _IOR('V',  86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_S_DV_TIMINGS     _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
+#define VIDIOC_G_DV_TIMINGS     _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
new file mode 100644 (file)
index 0000000..1d31427
--- /dev/null
@@ -0,0 +1,238 @@
+<refentry id="vidioc-enum-dv-presets">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUM_DV_PRESETS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUM_DV_PRESETS</refname>
+    <refpurpose>Enumerate supported Digital Video presets</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>struct v4l2_dv_enum_preset *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_ENUM_DV_PRESETS</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a DV preset, applications initialize the
+<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset;
+and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all DV Presets supported,
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
+different set of DV presets after switching the video input or
+output.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-enum-preset">
+      <title>struct <structname>v4l2_dv_enum_presets</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>index</structfield></entry>
+           <entry>Number of the DV preset, set by the
+application.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>preset</structfield></entry>
+           <entry>This field identifies one of the DV preset values listed in <xref linkend="v4l2-dv-presets-vals"/>.</entry>
+         </row>
+         <row>
+           <entry>__u8</entry>
+           <entry><structfield>name</structfield>[24]</entry>
+           <entry>Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is
+intended for the user.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>width</structfield></entry>
+           <entry>Width of the active video in pixels for the DV preset.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>height</structfield></entry>
+           <entry>Height of the active video in lines for the DV preset.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[4]</entry>
+           <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-presets-vals">
+      <title>struct <structname>DV Presets</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>Preset</entry>
+           <entry>Preset value</entry>
+           <entry>Description</entry>
+         </row>
+         <row>
+           <entry></entry>
+           <entry></entry>
+           <entry></entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_INVALID</entry>
+           <entry>0</entry>
+           <entry>Invalid preset value.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_480P59_94</entry>
+           <entry>1</entry>
+           <entry>720x480 progressive video at 59.94 fps as per BT.1362.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_576P50</entry>
+           <entry>2</entry>
+           <entry>720x576 progressive video at 50 fps as per BT.1362.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P24</entry>
+           <entry>3</entry>
+           <entry>1280x720 progressive video at 24 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P25</entry>
+           <entry>4</entry>
+           <entry>1280x720 progressive video at 25 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P30</entry>
+           <entry>5</entry>
+           <entry>1280x720 progressive video at 30 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P50</entry>
+           <entry>6</entry>
+           <entry>1280x720 progressive video at 50 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P59_94</entry>
+           <entry>7</entry>
+           <entry>1280x720 progressive video at 59.94 fps as per SMPTE 274M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_720P60</entry>
+           <entry>8</entry>
+           <entry>1280x720 progressive video at 60 fps as per SMPTE 274M/296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080I29_97</entry>
+           <entry>9</entry>
+           <entry>1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080I30</entry>
+           <entry>10</entry>
+           <entry>1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080I25</entry>
+           <entry>11</entry>
+           <entry>1920x1080 interlaced video at 25 fps as per BT.1120.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080I50</entry>
+           <entry>12</entry>
+           <entry>1920x1080 interlaced video at 50 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080I60</entry>
+           <entry>13</entry>
+           <entry>1920x1080 interlaced video at 60 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080P24</entry>
+           <entry>14</entry>
+           <entry>1920x1080 progressive video at 24 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080P25</entry>
+           <entry>15</entry>
+           <entry>1920x1080 progressive video at 25 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080P30</entry>
+           <entry>16</entry>
+           <entry>1920x1080 progressive video at 30 fps as per SMPTE 296M.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080P50</entry>
+           <entry>17</entry>
+           <entry>1920x1080 progressive video at 50 fps as per BT.1120.</entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_1080P60</entry>
+           <entry>18</entry>
+           <entry>1920x1080 progressive video at 60 fps as per BT.1120.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>The &v4l2-dv-enum-preset; <structfield>index</structfield>
+is out of bounds.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
index 414856b824730ec83a348e9187c896c2a617987e..71b868e2fb8fd5eb36de50f6f9c397844aafdea2 100644 (file)
@@ -124,7 +124,13 @@ current input.</entry>
          </row>
          <row>
            <entry>__u32</entry>
-           <entry><structfield>reserved</structfield>[4]</entry>
+           <entry><structfield>capabilities</structfield></entry>
+           <entry>This field provides capabilities for the
+input. See <xref linkend="input-capabilities" /> for flags.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[3]</entry>
            <entry>Reserved for future extensions. Drivers must set
 the array to zero.</entry>
          </row>
@@ -261,6 +267,34 @@ flag is set Macrovision has been detected.</entry>
        </tbody>
       </tgroup>
     </table>
+
+    <!-- Capability flags based on video timings RFC by Muralidharan
+Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
+input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
+       -->
+    <table frame="none" pgwide="1" id="input-capabilities">
+      <title>Input capabilities</title>
+      <tgroup cols="3">
+       &cs-def;
+       <tbody valign="top">
+         <row>
+           <entry><constant>V4L2_IN_CAP_PRESETS</constant></entry>
+           <entry>0x00000001</entry>
+           <entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
+           <entry>0x00000002</entry>
+           <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_IN_CAP_STD</constant></entry>
+           <entry>0x00000004</entry>
+           <entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
   </refsect1>
 
   <refsect1>
index e8d16dcd50cf0e293cc73c607cad9653db807f36..a281d26a195fbb501fcd96059080b8965ff7a69f 100644 (file)
@@ -114,7 +114,13 @@ details on video standards and how to switch see <xref
          </row>
          <row>
            <entry>__u32</entry>
-           <entry><structfield>reserved</structfield>[4]</entry>
+           <entry><structfield>capabilities</structfield></entry>
+           <entry>This field provides capabilities for the
+output. See <xref linkend="output-capabilities" /> for flags.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[3]</entry>
            <entry>Reserved for future extensions. Drivers must set
 the array to zero.</entry>
          </row>
@@ -147,6 +153,34 @@ CVBS, S-Video, RGB.</entry>
       </tgroup>
     </table>
 
+    <!-- Capabilities flags based on video timings RFC by Muralidharan
+Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
+input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
+       -->
+    <table frame="none" pgwide="1" id="output-capabilities">
+      <title>Output capabilities</title>
+      <tgroup cols="3">
+       &cs-def;
+       <tbody valign="top">
+         <row>
+           <entry><constant>V4L2_OUT_CAP_PRESETS</constant></entry>
+           <entry>0x00000001</entry>
+           <entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
+           <entry>0x00000002</entry>
+           <entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_OUT_CAP_STD</constant></entry>
+           <entry>0x00000004</entry>
+           <entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
   </refsect1>
   <refsect1>
     &return-value;
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
new file mode 100644 (file)
index 0000000..3c6784e
--- /dev/null
@@ -0,0 +1,111 @@
+<refentry id="vidioc-g-dv-preset">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_DV_PRESET</refname>
+    <refname>VIDIOC_S_DV_PRESET</refname>
+    <refpurpose>Query or select the DV preset of the current input or output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>&v4l2-dv-preset;
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>To query and select the current DV preset, applications
+use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant>
+ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
+Applications must zero the reserved array in &v4l2-dv-preset;.
+<constant>VIDIOC_G_DV_PRESET</constant> returns a dv preset in the field
+<structfield>preset</structfield> of &v4l2-dv-preset;.</para>
+
+    <para><constant>VIDIOC_S_DV_PRESET</constant> accepts a pointer to a &v4l2-dv-preset;
+that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;.
+If the preset is not supported, it returns an &EINVAL; </para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_DV_PRESET</constant>,<constant>VIDIOC_S_DV_PRESET</constant> parameter was unsuitable.</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>The device is busy and therefore can not change the preset.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-preset">
+      <title>struct <structname>v4l2_dv_preset</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>preset</structfield></entry>
+           <entry>Preset value to represent the digital video timings</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved[4]</structfield></entry>
+           <entry>Reserved fields for future use</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml b/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
new file mode 100644 (file)
index 0000000..ecc1957
--- /dev/null
@@ -0,0 +1,224 @@
+<refentry id="vidioc-g-dv-timings">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_DV_TIMINGS</refname>
+    <refname>VIDIOC_S_DV_TIMINGS</refname>
+    <refpurpose>Get or set custom DV timings for input or output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>&v4l2-dv-timings;
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>To set custom DV timings for the input or output, applications use the
+<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current custom timings,
+applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing
+information is filled in using the structure &v4l2-dv-timings;. These ioctls take
+a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported
+or the timing values are not correct, the driver returns &EINVAL;.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_DV_TIMINGS</constant> parameter was unsuitable.</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>The device is busy and therefore can not change the timings.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <table pgwide="1" frame="none" id="v4l2-bt-timings">
+      <title>struct <structname>v4l2_bt_timings</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>width</structfield></entry>
+           <entry>Width of the active video in pixels</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>height</structfield></entry>
+           <entry>Height of the active video in lines</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>interlaced</structfield></entry>
+           <entry>Progressive (0) or interlaced (1)</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>polarities</structfield></entry>
+           <entry>This is a bit mask that defines polarities of sync signals.
+bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_HSYNC_POS_POL) is for horizontal sync polarity. If the bit is set
+(1) it is positive polarity and if is cleared (0), it is negative polarity.</entry>
+         </row>
+         <row>
+           <entry>__u64</entry>
+           <entry><structfield>pixelclock</structfield></entry>
+           <entry>Pixel clock in Hz. Ex. 74.25MHz->74250000</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>hfrontporch</structfield></entry>
+           <entry>Horizontal front porch in pixels</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>hsync</structfield></entry>
+           <entry>Horizontal sync length in pixels</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>hbackporch</structfield></entry>
+           <entry>Horizontal back porch in pixels</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>vfrontporch</structfield></entry>
+           <entry>Vertical front porch in lines</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>vsync</structfield></entry>
+           <entry>Vertical sync length in lines</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>vbackporch</structfield></entry>
+           <entry>Vertical back porch in lines</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>il_vfrontporch</structfield></entry>
+           <entry>Vertical front porch in lines for bottom field of interlaced field formats</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>il_vsync</structfield></entry>
+           <entry>Vertical sync length in lines for bottom field of interlaced field formats</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>il_vbackporch</structfield></entry>
+           <entry>Vertical back porch in lines for bottom field of interlaced field formats</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-timings">
+      <title>struct <structname>v4l2_dv_timings</structname></title>
+      <tgroup cols="4">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>type</structfield></entry>
+           <entry></entry>
+           <entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry>
+         </row>
+         <row>
+           <entry>union</entry>
+           <entry><structfield></structfield></entry>
+           <entry></entry>
+         </row>
+         <row>
+           <entry></entry>
+           <entry>&v4l2-bt-timings;</entry>
+           <entry><structfield>bt</structfield></entry>
+           <entry>Timings defined by BT.656/1120 specifications</entry>
+         </row>
+         <row>
+           <entry></entry>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[32]</entry>
+           <entry></entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="dv-timing-types">
+      <title>DV Timing types</title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>Timing type</entry>
+           <entry>value</entry>
+           <entry>Description</entry>
+         </row>
+         <row>
+           <entry></entry>
+           <entry></entry>
+           <entry></entry>
+         </row>
+         <row>
+           <entry>V4L2_DV_BT_656_1120</entry>
+           <entry>0</entry>
+           <entry>BT.656/1120 timings</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
index b6f5d267e85612ed0d7e0aa575b2f1390eb795d1..912f8513e5daeb5ef0fe2a91876ae49af19f5a79 100644 (file)
@@ -86,6 +86,12 @@ standards.</para>
 <constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
        </listitem>
       </varlistentry>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>The device is busy and therefore can not change the standard</para>
+       </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 </refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
new file mode 100644 (file)
index 0000000..87e4f0f
--- /dev/null
@@ -0,0 +1,85 @@
+<refentry id="vidioc-query-dv-preset">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERY_DV_PRESET</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERY_DV_PRESET</refname>
+    <refpurpose>Sense the DV preset received by the current
+input</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>&v4l2-dv-preset; *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+       <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_QUERY_DV_PRESET</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The hardware may be able to detect the current DV preset
+automatically, similar to sensing the video standard. To do so, applications
+call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
+&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
+returned in the preset field of &v4l2-dv-preset;. When detection is not
+possible or fails, the value V4L2_DV_INVALID is returned.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>This ioctl is not supported.</para>
+       </listitem>
+    </varlistentry>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>The device is busy and therefore can not sense the preset</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
index b5a7ff934486523e8989a1e7c4c0eebb0f578bcd..1a9e60393091e0519ecd1a53848b2d1ad872b359 100644 (file)
@@ -70,6 +70,12 @@ current video input or output.</para>
          <para>This ioctl is not supported.</para>
        </listitem>
       </varlistentry>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>The device is busy and therefore can not detect the standard</para>
+       </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 </refentry>
index 319d9838e87e0ffbd1f35945c84d8c1ff1c38d3c..1800a62cf13538e72e61d90e23d0abf327159210 100644 (file)
@@ -12,6 +12,7 @@ m5602         0402:5602       ALi Video Camera Controller
 spca501                040a:0002       Kodak DVC-325
 spca500                040a:0300       Kodak EZ200
 zc3xx          041e:041e       Creative WebCam Live!
+ov519          041e:4003       Video Blaster WebCam Go Plus
 spca500                041e:400a       Creative PC-CAM 300
 sunplus                041e:400b       Creative PC-CAM 600
 sunplus                041e:4012       PC-Cam350
@@ -168,10 +169,14 @@ sunplus           055f:c650       Mustek MDC5500Z
 zc3xx          055f:d003       Mustek WCam300A
 zc3xx          055f:d004       Mustek WCam300 AN
 conex          0572:0041       Creative Notebook cx11646
+ov519          05a9:0511       Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
+ov519          05a9:0518       Creative WebCam
 ov519          05a9:0519       OV519 Microphone
 ov519          05a9:0530       OmniVision
+ov519          05a9:2800       OmniVision SuperCAM
 ov519          05a9:4519       Webcam Classic
 ov519          05a9:8519       OmniVision
+ov519          05a9:a511       D-Link USB Digital Video Camera
 ov519          05a9:a518       D-Link DSB-C310 Webcam
 sunplus                05da:1018       Digital Dream Enigma 1.3
 stk014         05e1:0893       Syntek DV4000
@@ -187,7 +192,7 @@ ov534               06f8:3002       Hercules Blog Webcam
 ov534          06f8:3003       Hercules Dualpix HD Weblog
 sonixj         06f8:3004       Hercules Classic Silver
 sonixj         06f8:3008       Hercules Deluxe Optical Glass
-pac7311                06f8:3009       Hercules Classic Link
+pac7302                06f8:3009       Hercules Classic Link
 spca508                0733:0110       ViewQuest VQ110
 spca501                0733:0401       Intel Create and Share
 spca501                0733:0402       ViewQuest M318B
@@ -199,6 +204,7 @@ sunplus             0733:2221       Mercury Digital Pro 3.1p
 sunplus                0733:3261       Concord 3045 spca536a
 sunplus                0733:3281       Cyberpix S550V
 spca506                0734:043b       3DeMon USB Capture aka
+ov519          0813:0002       Dual Mode USB Camera Plus
 spca500                084d:0003       D-Link DSC-350
 spca500                08ca:0103       Aiptek PocketDV
 sunplus                08ca:0104       Aiptek PocketDVII 1.3
@@ -236,15 +242,15 @@ pac7311           093a:2603       Philips SPC 500 NC
 pac7311                093a:2608       Trust WB-3300p
 pac7311                093a:260e       Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
 pac7311                093a:260f       SnakeCam
-pac7311                093a:2620       Apollo AC-905
-pac7311                093a:2621       PAC731x
-pac7311                093a:2622       Genius Eye 312
-pac7311                093a:2624       PAC7302
-pac7311                093a:2626       Labtec 2200
-pac7311                093a:2628       Genius iLook 300
-pac7311                093a:2629       Genious iSlim 300
-pac7311                093a:262a       Webcam 300k
-pac7311                093a:262c       Philips SPC 230 NC
+pac7302                093a:2620       Apollo AC-905
+pac7302                093a:2621       PAC731x
+pac7302                093a:2622       Genius Eye 312
+pac7302                093a:2624       PAC7302
+pac7302                093a:2626       Labtec 2200
+pac7302                093a:2628       Genius iLook 300
+pac7302                093a:2629       Genious iSlim 300
+pac7302                093a:262a       Webcam 300k
+pac7302                093a:262c       Philips SPC 230 NC
 jeilinj                0979:0280       Sakar 57379
 zc3xx          0ac8:0302       Z-star Vimicro zc0302
 vc032x         0ac8:0321       Vimicro generic vc0321
@@ -259,6 +265,7 @@ vc032x              0ac8:c002       Sony embedded vimicro
 vc032x         0ac8:c301       Samsung Q1 Ultra Premium
 spca508                0af9:0010       Hama USB Sightcam 100
 spca508                0af9:0011       Hama USB Sightcam 100
+ov519          0b62:0059       iBOT2 Webcam
 sonixb         0c45:6001       Genius VideoCAM NB
 sonixb         0c45:6005       Microdia Sweex Mini Webcam
 sonixb         0c45:6007       Sonix sn9c101 + Tas5110D
@@ -318,8 +325,10 @@ sn9c20x            0c45:62b3       PC Camera (SN9C202 + OV9655)
 sn9c20x                0c45:62bb       PC Camera (SN9C202 + OV7660)
 sn9c20x                0c45:62bc       PC Camera (SN9C202 + HV7131R)
 sunplus                0d64:0303       Sunplus FashionCam DXG
+ov519          0e96:c001       TRUST 380 USB2 SPACEC@M
 etoms          102c:6151       Qcam Sangha CIF
 etoms          102c:6251       Qcam xxxxxx VGA
+ov519          1046:9967       W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
 zc3xx          10fd:0128       Typhoon Webshot II USB 300k 0x0128
 spca561                10fd:7e50       FlyCam Usb 100
 zc3xx          10fd:8050       Typhoon Webshot II USB 300k
@@ -332,7 +341,12 @@ spca501            1776:501c       Arowana 300K CMOS Camera
 t613           17a1:0128       TASCORP JPEG Webcam, NGS Cyclops
 vc032x         17ef:4802       Lenovo Vc0323+MI1310_SOC
 pac207         2001:f115       D-Link DSB-C120
+sq905c         2770:9050       sq905c
+sq905c         2770:905c       DualCamera
+sq905          2770:9120       Argus Digital Camera DC1512
+sq905c         2770:913d       sq905c
 spca500                2899:012c       Toptro Industrial
+ov519          8020:ef04       ov519
 spca508                8086:0110       Intel Easy PC Camera
 spca500                8086:0630       Intel Pocket PC Camera
 spca506                99fa:8988       Grandtec V.cap
diff --git a/Documentation/video4linux/sh_mobile_ceu_camera.txt b/Documentation/video4linux/sh_mobile_ceu_camera.txt
new file mode 100644 (file)
index 0000000..2ae1634
--- /dev/null
@@ -0,0 +1,157 @@
+       Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
+       =======================================================================
+
+Terminology
+-----------
+
+sensor scales: horizontal and vertical scales, configured by the sensor driver
+host scales: -"- host driver
+combined scales: sensor_scale * host_scale
+
+
+Generic scaling / cropping scheme
+---------------------------------
+
+-1--
+|
+-2-- -\
+|      --\
+|         --\
++-5-- -\     -- -3--
+|       ---\
+|           --- -4-- -\
+|                      -\
+|                        - -6--
+|
+|                        - -6'-
+|                      -/
+|           --- -4'- -/
+|       ---/
++-5'- -/
+|            -- -3'-
+|         --/
+|      --/
+-2'- -/
+|
+|
+-1'-
+
+Produced by user requests:
+
+S_CROP(left / top = (5) - (1), width / height = (5') - (5))
+S_FMT(width / height = (6') - (6))
+
+Here:
+
+(1) to (1') - whole max width or height
+(1) to (2)  - sensor cropped left or top
+(2) to (2') - sensor cropped width or height
+(3) to (3') - sensor scale
+(3) to (4)  - CEU cropped left or top
+(4) to (4') - CEU cropped width or height
+(5) to (5') - reverse sensor scale applied to CEU cropped width or height
+(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
+(6) to (6') - CEU scale - user window
+
+
+S_FMT
+-----
+
+Do not touch input rectangle - it is already optimal.
+
+1. Calculate current sensor scales:
+
+       scale_s = ((3') - (3)) / ((2') - (2))
+
+2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
+current sensor scales onto input window - this is user S_CROP:
+
+       width_u = (5') - (5) = ((4') - (4)) * scale_s
+
+3. Calculate new combined scales from "effective" input window to requested user
+window:
+
+       scale_comb = width_u / ((6') - (6))
+
+4. Calculate sensor output window by applying combined scales to real input
+window:
+
+       width_s_out = ((2') - (2)) / scale_comb
+
+5. Apply iterative sensor S_FMT for sensor output window.
+
+       subdev->video_ops->s_fmt(.width = width_s_out)
+
+6. Retrieve sensor output window (g_fmt)
+
+7. Calculate new sensor scales:
+
+       scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
+
+8. Calculate new CEU crop - apply sensor scales to previously calculated
+"effective" crop:
+
+       width_ceu = (4')_new - (4)_new = width_u / scale_s_new
+       left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
+
+9. Use CEU cropping to crop to the new window:
+
+       ceu_crop(.width = width_ceu, .left = left_ceu)
+
+10. Use CEU scaling to scale to the requested user window:
+
+       scale_ceu = width_ceu / width
+
+
+S_CROP
+------
+
+If old scale applied to new crop is invalid produce nearest new scale possible
+
+1. Calculate current combined scales.
+
+       scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
+
+2. Apply iterative sensor S_CROP for new input window.
+
+3. If old combined scales applied to new crop produce an impossible user window,
+adjust scales to produce nearest possible window.
+
+       width_u_out = ((5') - (5)) / scale_comb
+
+       if (width_u_out > max)
+               scale_comb = ((5') - (5)) / max;
+       else if (width_u_out < min)
+               scale_comb = ((5') - (5)) / min;
+
+4. Issue G_CROP to retrieve actual input window.
+
+5. Using actual input window and calculated combined scales calculate sensor
+target output window.
+
+       width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
+
+6. Apply iterative S_FMT for new sensor target output window.
+
+7. Issue G_FMT to retrieve the actual sensor output window.
+
+8. Calculate sensor scales.
+
+       scale_s = ((3') - (3)) / ((2') - (2))
+
+9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
+scales to the requested window.
+
+       width_ceu = ((5') - (5)) / scale_s
+
+10. Use CEU cropping for above calculated window.
+
+11. Calculate CEU scales from sensor scales from results of (10) and user window
+from (3)
+
+       scale_ceu = calc_scale(((5') - (5)), &width_u_out)
+
+12. Apply CEU scales.
+
+--
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
index b806edaf3e752027a7101b006251dd1a1e9faae6..74d677c8b036c076b49ffa8cc287f7948fe9f0e1 100644 (file)
@@ -561,6 +561,8 @@ video_device helper functions
 
 There are a few useful helper functions:
 
+- file/video_device private data
+
 You can set/get driver private data in the video_device struct using:
 
 void *video_get_drvdata(struct video_device *vdev);
@@ -575,8 +577,7 @@ struct video_device *video_devdata(struct file *file);
 
 returns the video_device belonging to the file struct.
 
-The final helper function combines video_get_drvdata with
-video_devdata:
+The video_drvdata function combines video_get_drvdata with video_devdata:
 
 void *video_drvdata(struct file *file);
 
@@ -584,6 +585,17 @@ You can go from a video_device struct to the v4l2_device struct using:
 
 struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
 
+- Device node name
+
+The video_device node kernel name can be retrieved using
+
+const char *video_device_node_name(struct video_device *vdev);
+
+The name is used as a hint by userspace tools such as udev. The function
+should be used where possible instead of accessing the video_device::num and
+video_device::minor fields.
+
+
 video buffer helper functions
 -----------------------------
 
index cf9dc12dfeb153d78ccd2ff2bcdcbfb8b5fe7804..7a9f69663f1a51f3dfff94d155ca0f49ac775a54 100644 (file)
@@ -316,20 +316,23 @@ static struct soc_camera_platform_info camera_info = {
        .format_name = "UYVY",
        .format_depth = 16,
        .format = {
-               .pixelformat = V4L2_PIX_FMT_UYVY,
+               .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
                .colorspace = V4L2_COLORSPACE_SMPTE170M,
+               .field = V4L2_FIELD_NONE,
                .width = 640,
                .height = 480,
        },
        .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
        SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
        .set_capture = camera_set_capture,
-       .link = {
-               .bus_id         = 0,
-               .add_device     = ap325rxa_camera_add,
-               .del_device     = ap325rxa_camera_del,
-               .module_name    = "soc_camera_platform",
-       },
+};
+
+struct soc_camera_link camera_link = {
+       .bus_id         = 0,
+       .add_device     = ap325rxa_camera_add,
+       .del_device     = ap325rxa_camera_del,
+       .module_name    = "soc_camera_platform",
+       .priv           = &camera_info,
 };
 
 static void dummy_release(struct device *dev)
@@ -347,7 +350,7 @@ static struct platform_device camera_device = {
 static int ap325rxa_camera_add(struct soc_camera_link *icl,
                               struct device *dev)
 {
-       if (icl != &camera_info.link || camera_probe() <= 0)
+       if (icl != &camera_link || camera_probe() <= 0)
                return -ENODEV;
 
        camera_info.dev = dev;
@@ -357,7 +360,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl,
 
 static void ap325rxa_camera_del(struct soc_camera_link *icl)
 {
-       if (icl != &camera_info.link)
+       if (icl != &camera_link)
                return;
 
        platform_device_unregister(&camera_device);
@@ -470,13 +473,15 @@ static struct ov772x_camera_info ov7725_info = {
        .buswidth       = SOCAM_DATAWIDTH_8,
        .flags          = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
        .edgectrl       = OV772X_AUTO_EDGECTRL(0xf, 0),
-       .link = {
-               .bus_id         = 0,
-               .power          = ov7725_power,
-               .board_info     = &ap325rxa_i2c_camera[0],
-               .i2c_adapter_id = 0,
-               .module_name    = "ov772x",
-       },
+};
+
+static struct soc_camera_link ov7725_link = {
+       .bus_id         = 0,
+       .power          = ov7725_power,
+       .board_info     = &ap325rxa_i2c_camera[0],
+       .i2c_adapter_id = 0,
+       .module_name    = "ov772x",
+       .priv           = &ov7725_info,
 };
 
 static struct platform_device ap325rxa_camera[] = {
@@ -484,13 +489,13 @@ static struct platform_device ap325rxa_camera[] = {
                .name   = "soc-camera-pdrv",
                .id     = 0,
                .dev    = {
-                       .platform_data = &ov7725_info.link,
+                       .platform_data = &ov7725_link,
                },
        }, {
                .name   = "soc-camera-pdrv",
                .id     = 1,
                .dev    = {
-                       .platform_data = &camera_info.link,
+                       .platform_data = &camera_link,
                },
        },
 };
index 87438d6603d63e89502d146cba841a5b7feaeba5..9038d768a52582084576051e6f180b96aa82f5b9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/i2c.h>
 #include <linux/usb/r8a66597.h>
+#include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
 #include <media/sh_mobile_ceu.h>
 #include <video/sh_mobile_lcdc.h>
@@ -255,6 +256,9 @@ static struct i2c_board_info kfr2r09_i2c_camera = {
 
 static struct clk *camera_clk;
 
+/* set VIO_CKO clock to 25MHz */
+#define CEU_MCLK_FREQ 25000000
+
 #define DRVCRB 0xA405018C
 static int camera_power(struct device *dev, int mode)
 {
@@ -267,8 +271,7 @@ static int camera_power(struct device *dev, int mode)
                if (IS_ERR(camera_clk))
                        return PTR_ERR(camera_clk);
 
-               /* set VIO_CKO clock to 25MHz */
-               rate = clk_round_rate(camera_clk, 25000000);
+               rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ);
                ret = clk_set_rate(camera_clk, rate);
                if (ret < 0)
                        goto eclkrate;
@@ -318,11 +321,17 @@ eclkrate:
        return ret;
 }
 
+static struct rj54n1_pdata rj54n1_priv = {
+       .mclk_freq      = CEU_MCLK_FREQ,
+       .ioctl_high     = false,
+};
+
 static struct soc_camera_link rj54n1_link = {
        .power          = camera_power,
        .board_info     = &kfr2r09_i2c_camera,
        .i2c_adapter_id = 1,
        .module_name    = "rj54n1cb0c",
+       .priv           = &rj54n1_priv,
 };
 
 static struct platform_device kfr2r09_camera = {
index 9099b6da99576112ca121ac2ad9966cc8df7575c..507c77be476d649c454f6b0b0653df1ca8ce907f 100644 (file)
@@ -432,23 +432,27 @@ static struct i2c_board_info migor_i2c_camera[] = {
 
 static struct ov772x_camera_info ov7725_info = {
        .buswidth       = SOCAM_DATAWIDTH_8,
-       .link = {
-               .power          = ov7725_power,
-               .board_info     = &migor_i2c_camera[0],
-               .i2c_adapter_id = 0,
-               .module_name    = "ov772x",
-       },
+};
+
+static struct soc_camera_link ov7725_link = {
+       .power          = ov7725_power,
+       .board_info     = &migor_i2c_camera[0],
+       .i2c_adapter_id = 0,
+       .module_name    = "ov772x",
+       .priv           = &ov7725_info,
 };
 
 static struct tw9910_video_info tw9910_info = {
        .buswidth       = SOCAM_DATAWIDTH_8,
        .mpout          = TW9910_MPO_FIELD,
-       .link = {
-               .power          = tw9910_power,
-               .board_info     = &migor_i2c_camera[1],
-               .i2c_adapter_id = 0,
-               .module_name    = "tw9910",
-       }
+};
+
+static struct soc_camera_link tw9910_link = {
+       .power          = tw9910_power,
+       .board_info     = &migor_i2c_camera[1],
+       .i2c_adapter_id = 0,
+       .module_name    = "tw9910",
+       .priv           = &tw9910_info,
 };
 
 static struct platform_device migor_camera[] = {
@@ -456,13 +460,13 @@ static struct platform_device migor_camera[] = {
                .name   = "soc-camera-pdrv",
                .id     = 0,
                .dev    = {
-                       .platform_data = &ov7725_info.link,
+                       .platform_data = &ov7725_link,
                },
        }, {
                .name   = "soc-camera-pdrv",
                .id     = 1,
                .dev    = {
-                       .platform_data = &tw9910_info.link,
+                       .platform_data = &tw9910_link,
                },
        },
 };
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
new file mode 100644 (file)
index 0000000..4dde7d1
--- /dev/null
@@ -0,0 +1,9 @@
+config IR_CORE
+       tristate
+       depends on INPUT
+       default INPUT
+
+config VIDEO_IR
+       tristate
+       depends on IR_CORE
+       default IR_CORE
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
new file mode 100644 (file)
index 0000000..df5ddb4
--- /dev/null
@@ -0,0 +1,5 @@
+ir-common-objs  := ir-functions.o ir-keymaps.o
+ir-core-objs   := ir-keytable.o
+
+obj-$(CONFIG_IR_CORE) += ir-core.o
+obj-$(CONFIG_VIDEO_IR) += ir-common.o
similarity index 92%
rename from drivers/media/common/ir-functions.c
rename to drivers/media/IR/ir-functions.c
index e616f624ceaac7a0fe1518875d5b712cc1f74304..776a136616d6ee7c8c8f878c649291aee339b282 100644 (file)
@@ -34,9 +34,6 @@ static int repeat = 1;
 module_param(repeat, int, 0444);
 MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
 
-int media_ir_debug;    /* media_ir_debug level (0,1,2) */
-module_param_named(debug, media_ir_debug, int, 0644);
-
 /* -------------------------------------------------------------------------- */
 
 static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
@@ -55,25 +52,10 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
 /* -------------------------------------------------------------------------- */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-                  int ir_type, struct ir_scancode_table *ir_codes)
+                  int ir_type)
 {
        ir->ir_type = ir_type;
 
-       ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
-       ir->keytable.scan = kzalloc(ir->keytable.size *
-                                   sizeof(struct ir_scancode), GFP_KERNEL);
-       if (!ir->keytable.scan)
-               return -ENOMEM;
-
-       IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
-               ir->keytable.size,
-               ir->keytable.size * sizeof(ir->keytable.scan));
-
-       ir_copy_table(&ir->keytable, ir_codes);
-       ir_set_keycode_table(dev, &ir->keytable);
-
-       clear_bit(0, dev->keybit);
-       set_bit(EV_KEY, dev->evbit);
        if (repeat)
                set_bit(EV_REP, dev->evbit);
 
similarity index 97%
rename from drivers/media/common/ir-keymaps.c
rename to drivers/media/IR/ir-keymaps.c
index 328c973a083833536ee016fc80ebb4d1bc128eb7..9bbe6b1e9871f48816f598d6318165964fb97592 100644 (file)
@@ -1847,76 +1847,6 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = {
 };
 EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
 
-/*
- * Hauppauge:the newer, gray remotes (seems there are multiple
- * slightly different versions), shipped with cx88+ivtv cards.
- *
- * This table contains the complete RC5 code, instead of just the data part
- */
-static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
-       /* Keys 0 to 9 */
-       { 0x1e00, KEY_0 },
-       { 0x1e01, KEY_1 },
-       { 0x1e02, KEY_2 },
-       { 0x1e03, KEY_3 },
-       { 0x1e04, KEY_4 },
-       { 0x1e05, KEY_5 },
-       { 0x1e06, KEY_6 },
-       { 0x1e07, KEY_7 },
-       { 0x1e08, KEY_8 },
-       { 0x1e09, KEY_9 },
-
-       { 0x1e0a, KEY_TEXT },           /* keypad asterisk as well */
-       { 0x1e0b, KEY_RED },            /* red button */
-       { 0x1e0c, KEY_RADIO },
-       { 0x1e0d, KEY_MENU },
-       { 0x1e0e, KEY_SUBTITLE },               /* also the # key */
-       { 0x1e0f, KEY_MUTE },
-       { 0x1e10, KEY_VOLUMEUP },
-       { 0x1e11, KEY_VOLUMEDOWN },
-       { 0x1e12, KEY_PREVIOUS },               /* previous channel */
-       { 0x1e14, KEY_UP },
-       { 0x1e15, KEY_DOWN },
-       { 0x1e16, KEY_LEFT },
-       { 0x1e17, KEY_RIGHT },
-       { 0x1e18, KEY_VIDEO },          /* Videos */
-       { 0x1e19, KEY_AUDIO },          /* Music */
-       /* 0x1e1a: Pictures - presume this means
-          "Multimedia Home Platform" -
-          no "PICTURES" key in input.h
-        */
-       { 0x1e1a, KEY_MHP },
-
-       { 0x1e1b, KEY_EPG },            /* Guide */
-       { 0x1e1c, KEY_TV },
-       { 0x1e1e, KEY_NEXTSONG },               /* skip >| */
-       { 0x1e1f, KEY_EXIT },           /* back/exit */
-       { 0x1e20, KEY_CHANNELUP },      /* channel / program + */
-       { 0x1e21, KEY_CHANNELDOWN },    /* channel / program - */
-       { 0x1e22, KEY_CHANNEL },                /* source (old black remote) */
-       { 0x1e24, KEY_PREVIOUSSONG },   /* replay |< */
-       { 0x1e25, KEY_ENTER },          /* OK */
-       { 0x1e26, KEY_SLEEP },          /* minimize (old black remote) */
-       { 0x1e29, KEY_BLUE },           /* blue key */
-       { 0x1e2e, KEY_GREEN },          /* green button */
-       { 0x1e30, KEY_PAUSE },          /* pause */
-       { 0x1e32, KEY_REWIND },         /* backward << */
-       { 0x1e34, KEY_FASTFORWARD },    /* forward >> */
-       { 0x1e35, KEY_PLAY },
-       { 0x1e36, KEY_STOP },
-       { 0x1e37, KEY_RECORD },         /* recording */
-       { 0x1e38, KEY_YELLOW },         /* yellow key */
-       { 0x1e3b, KEY_SELECT },         /* top right button */
-       { 0x1e3c, KEY_ZOOM },           /* full */
-       { 0x1e3d, KEY_POWER },          /* system power (green button) */
-};
-
-struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
-       .scan = ir_codes_rc5_hauppauge_new,
-       .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
-};
-EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
-
 static struct ir_scancode ir_codes_npgtech[] = {
        { 0x1d, KEY_SWITCHVIDEOMODE },  /* switch inputs */
        { 0x2a, KEY_FRONT },
@@ -3314,3 +3244,152 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
 };
 EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
 
+/*************************************************************
+ *             COMPLETE SCANCODE TABLES
+ * Instead of just a partial scancode, the tables bellow
+ * contains the complete scancode and the receiver protocol
+ *************************************************************/
+
+/*
+ * Hauppauge:the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ *
+ * This table contains the complete RC5 code, instead of just the data part
+ */
+static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
+       /* Keys 0 to 9 */
+       { 0x1e00, KEY_0 },
+       { 0x1e01, KEY_1 },
+       { 0x1e02, KEY_2 },
+       { 0x1e03, KEY_3 },
+       { 0x1e04, KEY_4 },
+       { 0x1e05, KEY_5 },
+       { 0x1e06, KEY_6 },
+       { 0x1e07, KEY_7 },
+       { 0x1e08, KEY_8 },
+       { 0x1e09, KEY_9 },
+
+       { 0x1e0a, KEY_TEXT },           /* keypad asterisk as well */
+       { 0x1e0b, KEY_RED },            /* red button */
+       { 0x1e0c, KEY_RADIO },
+       { 0x1e0d, KEY_MENU },
+       { 0x1e0e, KEY_SUBTITLE },               /* also the # key */
+       { 0x1e0f, KEY_MUTE },
+       { 0x1e10, KEY_VOLUMEUP },
+       { 0x1e11, KEY_VOLUMEDOWN },
+       { 0x1e12, KEY_PREVIOUS },               /* previous channel */
+       { 0x1e14, KEY_UP },
+       { 0x1e15, KEY_DOWN },
+       { 0x1e16, KEY_LEFT },
+       { 0x1e17, KEY_RIGHT },
+       { 0x1e18, KEY_VIDEO },          /* Videos */
+       { 0x1e19, KEY_AUDIO },          /* Music */
+       /* 0x1e1a: Pictures - presume this means
+          "Multimedia Home Platform" -
+          no "PICTURES" key in input.h
+        */
+       { 0x1e1a, KEY_MHP },
+
+       { 0x1e1b, KEY_EPG },            /* Guide */
+       { 0x1e1c, KEY_TV },
+       { 0x1e1e, KEY_NEXTSONG },               /* skip >| */
+       { 0x1e1f, KEY_EXIT },           /* back/exit */
+       { 0x1e20, KEY_CHANNELUP },      /* channel / program + */
+       { 0x1e21, KEY_CHANNELDOWN },    /* channel / program - */
+       { 0x1e22, KEY_CHANNEL },                /* source (old black remote) */
+       { 0x1e24, KEY_PREVIOUSSONG },   /* replay |< */
+       { 0x1e25, KEY_ENTER },          /* OK */
+       { 0x1e26, KEY_SLEEP },          /* minimize (old black remote) */
+       { 0x1e29, KEY_BLUE },           /* blue key */
+       { 0x1e2e, KEY_GREEN },          /* green button */
+       { 0x1e30, KEY_PAUSE },          /* pause */
+       { 0x1e32, KEY_REWIND },         /* backward << */
+       { 0x1e34, KEY_FASTFORWARD },    /* forward >> */
+       { 0x1e35, KEY_PLAY },
+       { 0x1e36, KEY_STOP },
+       { 0x1e37, KEY_RECORD },         /* recording */
+       { 0x1e38, KEY_YELLOW },         /* yellow key */
+       { 0x1e3b, KEY_SELECT },         /* top right button */
+       { 0x1e3c, KEY_ZOOM },           /* full */
+       { 0x1e3d, KEY_POWER },          /* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
+       .scan = ir_codes_rc5_hauppauge_new,
+       .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
+       .ir_type = IR_TYPE_RC5,
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
+
+/* Terratec Cinergy Hybrid T USB XS FM
+   Mauro Carvalho Chehab <mchehab@redhat.com>
+ */
+static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
+       { 0x1441, KEY_HOME},
+       { 0x1401, KEY_POWER2},
+
+       { 0x1442, KEY_MENU},            /* DVD menu */
+       { 0x1443, KEY_SUBTITLE},
+       { 0x1444, KEY_TEXT},            /* Teletext */
+       { 0x1445, KEY_DELETE},
+
+       { 0x1402, KEY_1},
+       { 0x1403, KEY_2},
+       { 0x1404, KEY_3},
+       { 0x1405, KEY_4},
+       { 0x1406, KEY_5},
+       { 0x1407, KEY_6},
+       { 0x1408, KEY_7},
+       { 0x1409, KEY_8},
+       { 0x140a, KEY_9},
+       { 0x140c, KEY_0},
+
+       { 0x140b, KEY_TUNER},           /* AV */
+       { 0x140d, KEY_MODE},            /* A.B */
+
+       { 0x1446, KEY_TV},
+       { 0x1447, KEY_DVD},
+       { 0x1449, KEY_VIDEO},
+       { 0x144a, KEY_RADIO},           /* Music */
+       { 0x144b, KEY_CAMERA},          /* PIC */
+
+       { 0x1410, KEY_UP},
+       { 0x1411, KEY_LEFT},
+       { 0x1412, KEY_OK},
+       { 0x1413, KEY_RIGHT},
+       { 0x1414, KEY_DOWN},
+
+       { 0x140f, KEY_EPG},
+       { 0x1416, KEY_INFO},
+       { 0x144d, KEY_BACKSPACE},
+
+       { 0x141c, KEY_VOLUMEUP},
+       { 0x141e, KEY_VOLUMEDOWN},
+
+       { 0x144c, KEY_PLAY},
+       { 0x141d, KEY_MUTE},
+
+       { 0x141b, KEY_CHANNELUP},
+       { 0x141f, KEY_CHANNELDOWN},
+
+       { 0x1417, KEY_RED},
+       { 0x1418, KEY_GREEN},
+       { 0x1419, KEY_YELLOW},
+       { 0x141a, KEY_BLUE},
+
+       { 0x1458, KEY_RECORD},
+       { 0x1448, KEY_STOP},
+       { 0x1440, KEY_PAUSE},
+
+       { 0x1454, KEY_LAST},
+       { 0x144e, KEY_REWIND},
+       { 0x144f, KEY_FASTFORWARD},
+       { 0x145c, KEY_NEXT},
+};
+struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
+       .scan = ir_codes_nec_terratec_cinergy_xs,
+       .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
+       .ir_type = IR_TYPE_NEC,
+};
+EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
+
similarity index 81%
rename from drivers/media/common/ir-keytable.c
rename to drivers/media/IR/ir-keytable.c
index 26ce5bc2fdd545de4bf3088e655e1ec7e9a0507a..bff7a5356037bc6172cd21e95605572a92ed34b0 100644 (file)
@@ -1,10 +1,19 @@
 /* ir-register.c - handle IR scancode->keycode tables
  *
  * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation version 2 of the License.
+ *
+ *  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.
  */
 
-#include <linux/usb/input.h>
 
+#include <linux/usb/input.h>
 #include <media/ir-common.h>
 
 #define IR_TAB_MIN_SIZE        32
@@ -72,6 +81,7 @@ int ir_roundup_tablesize(int n_elems)
 
        return n_elems;
 }
+EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
 
 /**
  * ir_copy_table() - copies a keytable, discarding the unused entries
@@ -100,6 +110,7 @@ int ir_copy_table(struct ir_scancode_table *destin,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ir_copy_table);
 
 /**
  * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
@@ -114,7 +125,8 @@ static int ir_getkeycode(struct input_dev *dev,
                         int scancode, int *keycode)
 {
        int elem;
-       struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+       struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+       struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
 
        elem = ir_seek_table(rc_tab, scancode);
        if (elem >= 0) {
@@ -136,7 +148,6 @@ static int ir_getkeycode(struct input_dev *dev,
        return 0;
 }
 
-
 /**
  * ir_is_resize_needed() - Check if the table needs rezise
  * @table:             keycode table that may need to resize
@@ -286,7 +297,8 @@ static int ir_setkeycode(struct input_dev *dev,
                         int scancode, int keycode)
 {
        int rc = 0;
-       struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+       struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+       struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
        struct ir_scancode *keymap = rc_tab->scan;
        unsigned long flags;
 
@@ -360,7 +372,8 @@ static int ir_setkeycode(struct input_dev *dev,
  */
 u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
 {
-       struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+       struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+       struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
        struct ir_scancode *keymap = rc_tab->scan;
        int elem;
 
@@ -378,9 +391,10 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
        /* Reports userspace that an unknown keycode were got */
        return KEY_RESERVED;
 }
+EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
 
 /**
- * ir_set_keycode_table() - sets the IR keycode table and add the handlers
+ * ir_input_register() - sets the IR keycode table and add the handlers
  *                         for keymap table get/set
  * @input_dev: the struct input_dev descriptor of the device
  * @rc_tab:    the struct ir_scancode_table table of scancode/keymap
@@ -389,17 +403,34 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
  * an IR.
  * It should be called before registering the IR device.
  */
-int ir_set_keycode_table(struct input_dev *input_dev,
-                        struct ir_scancode_table *rc_tab)
+int ir_input_register(struct input_dev *input_dev,
+                     struct ir_scancode_table *rc_tab)
 {
-       struct ir_scancode *keymap = rc_tab->scan;
-       int i;
-
-       spin_lock_init(&rc_tab->lock);
+       struct ir_input_dev *ir_dev;
+       struct ir_scancode  *keymap    = rc_tab->scan;
+       int i, rc;
 
        if (rc_tab->scan == NULL || !rc_tab->size)
                return -EINVAL;
 
+       ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
+       if (!ir_dev)
+               return -ENOMEM;
+
+       spin_lock_init(&rc_tab->lock);
+
+       ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
+       ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
+                                   sizeof(struct ir_scancode), GFP_KERNEL);
+       if (!ir_dev->rc_tab.scan)
+               return -ENOMEM;
+
+       IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
+               ir_dev->rc_tab.size,
+               ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
+
+       ir_copy_table(&ir_dev->rc_tab, rc_tab);
+
        /* set the bits for the keys */
        IR_dprintk(1, "key map size: %d\n", rc_tab->size);
        for (i = 0; i < rc_tab->size; i++) {
@@ -407,23 +438,48 @@ int ir_set_keycode_table(struct input_dev *input_dev,
                        i, keymap[i].keycode);
                set_bit(keymap[i].keycode, input_dev->keybit);
        }
+       clear_bit(0, input_dev->keybit);
+
+       set_bit(EV_KEY, input_dev->evbit);
 
        input_dev->getkeycode = ir_getkeycode;
        input_dev->setkeycode = ir_setkeycode;
-       input_set_drvdata(input_dev, rc_tab);
+       input_set_drvdata(input_dev, ir_dev);
 
-       return 0;
+       rc = input_register_device(input_dev);
+       if (rc < 0) {
+               kfree(rc_tab->scan);
+               kfree(ir_dev);
+               input_set_drvdata(input_dev, NULL);
+       }
+
+       return rc;
 }
+EXPORT_SYMBOL_GPL(ir_input_register);
 
-void ir_input_free(struct input_dev *dev)
+void ir_input_unregister(struct input_dev *dev)
 {
-       struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+       struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+       struct ir_scancode_table *rc_tab;
+
+       if (!ir_dev)
+               return;
 
        IR_dprintk(1, "Freed keycode table\n");
 
+       rc_tab = &ir_dev->rc_tab;
        rc_tab->size = 0;
        kfree(rc_tab->scan);
        rc_tab->scan = NULL;
+
+       kfree(ir_dev);
+       input_unregister_device(dev);
 }
-EXPORT_SYMBOL_GPL(ir_input_free);
+EXPORT_SYMBOL_GPL(ir_input_unregister);
+
+int ir_core_debug;    /* ir_debug level (0,1,2) */
+EXPORT_SYMBOL_GPL(ir_core_debug);
+module_param_named(debug, ir_core_debug, int, 0644);
 
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
index ba69beeb0e21a850aab9d1a49b11c409b332f44e..a28541b2b1a219e5a2804f20201191f1ff98c953 100644 (file)
@@ -99,6 +99,7 @@ config VIDEO_MEDIA
 comment "Multimedia drivers"
 
 source "drivers/media/common/Kconfig"
+source "drivers/media/IR/Kconfig"
 
 #
 # Tuner drivers for DVB and V4L
index 09a829d8a7e71a4b7b0b5de035f7034d1748e82d..499b0810d01984f465b23ac1d490abcb30258156 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y += common/ video/
+obj-y += common/ IR/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
 obj-$(CONFIG_DVB_CORE)  += dvb/
index 169b337b7c9df6c16083995129ec7ce20683aa0c..e3ec9639321b750ab10d953899e843687adc0cc3 100644 (file)
@@ -1,8 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
-ir-common-objs  := ir-functions.o ir-keymaps.o ir-keytable.o
 
 obj-y += tuners/
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
-obj-$(CONFIG_VIDEO_IR) += ir-common.o
index 620f655fa9c5b1e2602755fff2dadf9f7689000b..7364b9642d005c0579838c4efdf7c61888767f98 100644 (file)
@@ -1,7 +1,5 @@
 #include <media/saa7146_vv.h>
 
-#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
-
 /****************************************************************************/
 /* resource management functions, shamelessly stolen from saa7134 driver */
 
@@ -194,43 +192,24 @@ void saa7146_buffer_timeout(unsigned long data)
 
 static int fops_open(struct file *file)
 {
-       unsigned int minor = video_devdata(file)->minor;
-       struct saa7146_dev *h = NULL, *dev = NULL;
-       struct list_head *list;
+       struct video_device *vdev = video_devdata(file);
+       struct saa7146_dev *dev = video_drvdata(file);
        struct saa7146_fh *fh = NULL;
        int result = 0;
 
-       enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       enum v4l2_buf_type type;
 
-       DEB_EE(("file:%p, minor:%d\n", file, minor));
+       DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev)));
 
        if (mutex_lock_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
-       list_for_each(list,&saa7146_devices) {
-               h = list_entry(list, struct saa7146_dev, item);
-               if( NULL == h->vv_data ) {
-                       DEB_D(("device %p has not registered video devices.\n",h));
-                       continue;
-               }
-               DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
-
-               if (h->vv_data->video_minor == minor) {
-                       dev = h;
-               }
-               if (h->vv_data->vbi_minor == minor) {
-                       type = V4L2_BUF_TYPE_VBI_CAPTURE;
-                       dev = h;
-               }
-       }
-       if (NULL == dev) {
-               DEB_S(("no such video device.\n"));
-               result = -ENODEV;
-               goto out;
-       }
-
        DEB_D(("using: %p\n",dev));
 
+       type = vdev->vfl_type == VFL_TYPE_GRABBER
+            ? V4L2_BUF_TYPE_VIDEO_CAPTURE
+            : V4L2_BUF_TYPE_VBI_CAPTURE;
+
        /* check if an extension is registered */
        if( NULL == dev->ext ) {
                DEB_S(("no extension registered for this device.\n"));
@@ -474,9 +453,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
           configuration data) */
        dev->ext_vv_data = ext_vv;
 
-       vv->video_minor = -1;
-       vv->vbi_minor = -1;
-
        vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
        if( NULL == vv->d_clipping.cpu_addr ) {
                ERR(("out of memory. aborting.\n"));
@@ -515,7 +491,6 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release);
 int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
                            char *name, int type)
 {
-       struct saa7146_vv *vv = dev->vv_data;
        struct video_device *vfd;
        int err;
        int i;
@@ -543,15 +518,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
                return err;
        }
 
-       if( VFL_TYPE_GRABBER == type ) {
-               vv->video_minor = vfd->minor;
-               INFO(("%s: registered device video%d [v4l2]\n",
-                       dev->name, vfd->num));
-       } else {
-               vv->vbi_minor = vfd->minor;
-               INFO(("%s: registered device vbi%d [v4l2]\n",
-                       dev->name, vfd->num));
-       }
+       INFO(("%s: registered device %s [v4l2]\n",
+               dev->name, video_device_node_name(vfd)));
 
        *vid = vfd;
        return 0;
@@ -560,16 +528,8 @@ EXPORT_SYMBOL_GPL(saa7146_register_device);
 
 int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
 {
-       struct saa7146_vv *vv = dev->vv_data;
-
        DEB_EE(("dev:%p\n",dev));
 
-       if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
-               vv->video_minor = -1;
-       } else {
-               vv->vbi_minor = -1;
-       }
-
        video_unregister_device(*vid);
        *vid = NULL;
 
index 53e3f2a7d31aa0f9ed8c4a50f98451920033784f..f0f483ac8b891760d822f7081eae139f0f45bad4 100644 (file)
@@ -589,7 +589,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
        snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
                "pci-%s/ir0", pci_name(dm1105->pdev));
 
-       err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
+       err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
        if (err < 0) {
                input_free_device(input_dev);
                return err;
@@ -611,20 +611,14 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
 
        INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
-       err = input_register_device(input_dev);
-       if (err) {
-               ir_input_free(input_dev);
-               input_free_device(input_dev);
-               return err;
-       }
+       err = ir_input_register(input_dev, ir_codes);
 
-       return 0;
+       return err;
 }
 
 void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
 {
-       ir_input_free(dm1105->ir.input_dev);
-       input_unregister_device(dm1105->ir.input_dev);
+       ir_input_unregister(dm1105->ir.input_dev);
 }
 
 static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
index 2dee1bf73577feea70525e96efff84b24c8f8246..1b249897c9fbecf6c82fa9017e562d94b5909e46 100644 (file)
@@ -265,9 +265,13 @@ config DVB_USB_DW2102
        select DVB_TDA10021 if !DVB_FE_CUSTOMISE
        select DVB_MT312 if !DVB_FE_CUSTOMISE
        select DVB_ZL10039 if !DVB_FE_CUSTOMISE
+       select DVB_DS3000 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110 if !DVB_FE_CUSTOMISE
+       select DVB_STV0900 if !DVB_FE_CUSTOMISE
        help
-         Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
-         and the TeVii S650, S630.
+         Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
+         receivers.
 
 config DVB_USB_CINERGY_T2
        tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
index 8b544fe79b0de11842f883c48dc041f9889a968b..495a90577c5f7f1f9d0524b5edf55d141bb77846 100644 (file)
@@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug;
 #define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
 #define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
 
-#define REQUEST_I2C_READ     0x2
-#define REQUEST_I2C_WRITE    0x3
-#define REQUEST_POLL_RC      0x4 /* deprecated in firmware v1.20 */
-#define REQUEST_JUMPRAM      0x8
-#define REQUEST_SET_CLOCK    0xB
-#define REQUEST_SET_GPIO     0xC
-#define REQUEST_ENABLE_VIDEO 0xF
+#define REQUEST_SET_USB_XFER_LEN    0x0 /* valid only for firmware version */
+                                       /* higher than 1.21 */
+#define REQUEST_I2C_READ            0x2
+#define REQUEST_I2C_WRITE           0x3
+#define REQUEST_POLL_RC             0x4 /* deprecated in firmware v1.20 */
+#define REQUEST_JUMPRAM             0x8
+#define REQUEST_SET_CLOCK           0xB
+#define REQUEST_SET_GPIO            0xC
+#define REQUEST_ENABLE_VIDEO        0xF
        // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
        // 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
        // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
-#define REQUEST_SET_RC       0x11
-#define REQUEST_NEW_I2C_READ 0x12
-#define REQUEST_NEW_I2C_WRITE 0x13
-#define REQUEST_GET_VERSION  0x15
+#define REQUEST_SET_RC              0x11
+#define REQUEST_NEW_I2C_READ        0x12
+#define REQUEST_NEW_I2C_WRITE       0x13
+#define REQUEST_GET_VERSION         0x15
 
 struct dib0700_state {
        u8 channel_state;
@@ -44,6 +46,8 @@ struct dib0700_state {
        u8 is_dib7000pc;
        u8 fw_use_new_i2c_api;
        u8 disable_streaming_master_mode;
+    u32 fw_version;
+    u32 nb_packet_buffer_size;
 };
 
 extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
index db7f7f79a66ce5796998629fe63ab2e812f34124..0d3c9a9a33be4bd1bf74d7a51042592099b315de 100644 (file)
@@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1;
 module_param(dvb_usb_dib0700_ir_proto, int, 0644);
 MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
 
+static int nb_packet_buffer_size = 21;
+module_param(nb_packet_buffer_size, int, 0644);
+MODULE_PARM_DESC(nb_packet_buffer_size,
+       "Set the dib0700 driver data buffer size. This parameter "
+       "corresponds to the number of TS packets. The actual size of "
+       "the data buffer corresponds to this parameter "
+       "multiplied by 188 (default: 21)");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
@@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
                                  REQUEST_GET_VERSION,
                                  USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
                                  b, sizeof(b), USB_CTRL_GET_TIMEOUT);
-       *hwversion  = (b[0] << 24)  | (b[1] << 16)  | (b[2] << 8)  | b[3];
-       *romversion = (b[4] << 24)  | (b[5] << 16)  | (b[6] << 8)  | b[7];
-       *ramversion = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
-       *fwtype     = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
+       if (hwversion != NULL)
+               *hwversion  = (b[0] << 24)  | (b[1] << 16)  | (b[2] << 8)  | b[3];
+       if (romversion != NULL)
+               *romversion = (b[4] << 24)  | (b[5] << 16)  | (b[6] << 8)  | b[7];
+       if (ramversion != NULL)
+               *ramversion = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
+       if (fwtype != NULL)
+               *fwtype     = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
        return ret;
 }
 
@@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
        return dib0700_ctrl_wr(d,buf,3);
 }
 
+static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
+{
+    struct dib0700_state *st = d->priv;
+    u8 b[3];
+    int ret;
+
+    if (st->fw_version >= 0x10201) {
+       b[0] = REQUEST_SET_USB_XFER_LEN;
+       b[1] = (nb_ts_packets >> 8)&0xff;
+       b[2] = nb_ts_packets & 0xff;
+
+       deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
+
+       ret = dib0700_ctrl_wr(d, b, 3);
+    } else {
+       deb_info("this firmware does not allow to change the USB xfer len\n");
+       ret = -EIO;
+    }
+    return ret;
+}
+
 /*
  * I2C master xfer function (supported in 1.20 firmware)
  */
@@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address)
 int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
 {
        struct hexline hx;
-       int pos = 0, ret, act_len;
+       int pos = 0, ret, act_len, i, adap_num;
+       u8 b[16];
+       u32 fw_version;
 
        u8 buf[260];
 
@@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
        } else
                ret = -EIO;
 
+       /* the number of ts packet has to be at least 1 */
+       if (nb_packet_buffer_size < 1)
+               nb_packet_buffer_size = 1;
+
+       /* get the fimware version */
+       usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                 REQUEST_GET_VERSION,
+                                 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                                 b, sizeof(b), USB_CTRL_GET_TIMEOUT);
+       fw_version = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
+
+       /* set the buffer size - DVB-USB is allocating URB buffers
+        * only after the firwmare download was successful */
+       for (i = 0; i < dib0700_device_count; i++) {
+               for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
+                               adap_num++) {
+                       if (fw_version >= 0x10201)
+                               dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
+                       else {
+                               /* for fw version older than 1.20.1,
+                                * the buffersize has to be n times 512 */
+                               dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
+                               if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
+                                       dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
+                       }
+               }
+       }
+
        return ret;
 }
 
@@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
        struct dib0700_state *st = adap->dev->priv;
        u8 b[4];
+       int ret;
+
+       if ((onoff != 0) && (st->fw_version >= 0x10201)) {
+               /* for firmware later than 1.20.1,
+                * the USB xfer length can be set  */
+               ret = dib0700_set_usb_xfer_len(adap->dev,
+                       st->nb_packet_buffer_size);
+               if (ret < 0) {
+                       deb_info("can not set the USB xfer len\n");
+                       return ret;
+               }
+       }
 
        b[0] = REQUEST_ENABLE_VIDEO;
        b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
@@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf,
 
        for (i = 0; i < dib0700_device_count; i++)
                if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
-                                       &dev, adapter_nr) == 0)
-               {
+                   &dev, adapter_nr) == 0) {
+                       struct dib0700_state *st = dev->priv;
+                       u32 hwversion, romversion, fw_version, fwtype;
+
+                       dib0700_get_version(dev, &hwversion, &romversion,
+                               &fw_version, &fwtype);
+
+                       deb_info("Firmware version: %x, %d, 0x%x, %d\n",
+                               hwversion, romversion, fw_version, fwtype);
+
+                       st->fw_version = fw_version;
+                       st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
+
                        dib0700_rc_setup(dev);
+
                        return 0;
                }
 
index 684146f98eb753fb53376fbcfc010c29180df7c4..44972d01bbd02fddc22b66e84b78dcad712cb21a 100644 (file)
@@ -18,6 +18,7 @@
 #include "xc5000.h"
 #include "s5h1411.h"
 #include "dib0070.h"
+#include "dib0090.h"
 #include "lgdt3305.h"
 #include "mxl5007t.h"
 
@@ -130,93 +131,95 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
 /* MT226x */
 static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
        {
-               BAND_UHF, // band_caps
+               BAND_UHF,
 
                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
                * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
-
-               1130,  // inv_gain
-               21,  // time_stabiliz
-
-               0,  // alpha_level
-               118,  // thlock
-
-               0,     // wbd_inv
-               3530,  // wbd_ref
-               1,     // wbd_sel
-               0,     // wbd_alpha
-
-               65535,  // agc1_max
-               33770,  // agc1_min
-               65535,  // agc2_max
-               23592,  // agc2_min
-
-               0,    // agc1_pt1
-               62,   // agc1_pt2
-               255,  // agc1_pt3
-               64,   // agc1_slope1
-               64,   // agc1_slope2
-               132,  // agc2_pt1
-               192,  // agc2_pt2
-               80,   // agc2_slope1
-               80,   // agc2_slope2
-
-               17,  // alpha_mant
-               27,  // alpha_exp
-               23,  // beta_mant
-               51,  // beta_exp
-
-               1,  // perform_agc_softsplit
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+           | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+               1130,
+               21,
+
+               0,
+               118,
+
+               0,
+               3530,
+               1,
+               0,
+
+               65535,
+               33770,
+               65535,
+               23592,
+
+               0,
+               62,
+               255,
+               64,
+               64,
+               132,
+               192,
+               80,
+               80,
+
+               17,
+               27,
+               23,
+               51,
+
+               1,
        }, {
-               BAND_VHF | BAND_LBAND, // band_caps
+               BAND_VHF | BAND_LBAND,
 
                /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
                * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
-
-               2372, // inv_gain
-               21,   // time_stabiliz
-
-               0,    // alpha_level
-               118,  // thlock
-
-               0,    // wbd_inv
-               3530, // wbd_ref
-               1,     // wbd_sel
-               0,    // wbd_alpha
-
-               65535, // agc1_max
-               0,     // agc1_min
-               65535, // agc2_max
-               23592, // agc2_min
-
-               0,    // agc1_pt1
-               128,  // agc1_pt2
-               128,  // agc1_pt3
-               128,  // agc1_slope1
-               0,    // agc1_slope2
-               128,  // agc2_pt1
-               253,  // agc2_pt2
-               81,   // agc2_slope1
-               0,    // agc2_slope2
-
-               17,  // alpha_mant
-               27,  // alpha_exp
-               23,  // beta_mant
-               51,  // beta_exp
-
-               1,  // perform_agc_softsplit
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+           | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+
+               2372,
+               21,
+
+               0,
+               118,
+
+               0,
+               3530,
+               1,
+               0,
+
+               65535,
+               0,
+               65535,
+               23592,
+
+               0,
+               128,
+               128,
+               128,
+               0,
+               128,
+               253,
+               81,
+               0,
+
+               17,
+               27,
+               23,
+               51,
+
+               1,
        }
 };
 
 static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
-       60000, 30000, // internal, sampling
-       1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-       0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-       (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-       0, // ifreq
-       20452225, // timf
+       60000, 30000,
+       1, 8, 3, 1, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       0,
+       20452225,
 };
 
 static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
@@ -605,17 +608,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
                }
                break;
        default:
-               if (actlen != sizeof(buf)) {
-                       /* We didn't get back the 6 byte message we expected */
-                       err("Unexpected RC response size [%d]", actlen);
-                       return -1;
-               }
+       if (actlen != sizeof(buf)) {
+               /* We didn't get back the 6 byte message we expected */
+               err("Unexpected RC response size [%d]", actlen);
+               return -1;
+       }
 
-               poll_reply.report_id  = buf[0];
-               poll_reply.data_state = buf[1];
+       poll_reply.report_id  = buf[0];
+       poll_reply.data_state = buf[1];
                poll_reply.system     = (buf[2] << 8) | buf[3];
-               poll_reply.data       = buf[4];
-               poll_reply.not_data   = buf[5];
+       poll_reply.data       = buf[4];
+       poll_reply.not_data   = buf[5];
 
                break;
        }
@@ -632,7 +635,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
        /* Find the key in the map */
        for (i = 0; i < d->props.rc_key_map_size; i++) {
                if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
-                   rc5_data(&keymap[i]) == poll_reply.data) {
+                       rc5_data(&keymap[i]) == poll_reply.data) {
                        *event = keymap[i].event;
                        found = 1;
                        break;
@@ -641,8 +644,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
 
        if (found == 0) {
                err("Unknown remote controller key: %04x %02x %02x",
-                   poll_reply.system,
-                   poll_reply.data, poll_reply.not_data);
+                       poll_reply.system,
+                       poll_reply.data, poll_reply.not_data);
                d->last_event = 0;
                return 0;
        }
@@ -933,47 +936,48 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
 
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
-       BAND_UHF | BAND_VHF,       // band_caps
+       BAND_UHF | BAND_VHF,
 
        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
-
-       712,  // inv_gain
-       41,  // time_stabiliz
-
-       0,  // alpha_level
-       118,  // thlock
-
-       0,     // wbd_inv
-       4095,  // wbd_ref
-       0,     // wbd_sel
-       0,     // wbd_alpha
-
-       42598,  // agc1_max
-       17694,  // agc1_min
-       45875,  // agc2_max
-       2621,  // agc2_min
-       0,  // agc1_pt1
-       76,  // agc1_pt2
-       139,  // agc1_pt3
-       52,  // agc1_slope1
-       59,  // agc1_slope2
-       107,  // agc2_pt1
-       172,  // agc2_pt2
-       57,  // agc2_slope1
-       70,  // agc2_slope2
-
-       21,  // alpha_mant
-       25,  // alpha_exp
-       28,  // beta_mant
-       48,  // beta_exp
-
-       1,  // perform_agc_softsplit
-       {  0,     // split_min
-          107,   // split_max
-          51800, // global_split_min
-          24700  // global_split_max
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+
+       712,
+       41,
+
+       0,
+       118,
+
+       0,
+       4095,
+       0,
+       0,
+
+       42598,
+       17694,
+       45875,
+       2621,
+       0,
+       76,
+       139,
+       52,
+       59,
+       107,
+       172,
+       57,
+       70,
+
+       21,
+       25,
+       28,
+       48,
+
+       1,
+       {  0,
+          107,
+          51800,
+          24700
        },
 };
 
@@ -982,54 +986,55 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
 
        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
 
-       712, // inv_gain
-       41,  // time_stabiliz
+       712,
+       41,
 
-       0,   // alpha_level
-       118, // thlock
+       0,
+       118,
 
-       0,    // wbd_inv
-       4095, // wbd_ref
-       0,    // wbd_sel
-       0,    // wbd_alpha
+       0,
+       4095,
+       0,
+       0,
 
-       42598, // agc1_max
-       16384, // agc1_min
-       42598, // agc2_max
-           0, // agc2_min
+       42598,
+       16384,
+       42598,
+           0,
 
-         0,   // agc1_pt1
-       137,   // agc1_pt2
-       255,   // agc1_pt3
+         0,
+       137,
+       255,
 
-         0,   // agc1_slope1
-       255,   // agc1_slope2
+         0,
+       255,
 
-       0,     // agc2_pt1
-       0,     // agc2_pt2
+       0,
+       0,
 
-        0,    // agc2_slope1
-       41,    // agc2_slope2
+        0,
+       41,
 
-       15, // alpha_mant
-       25, // alpha_exp
+       15,
+       25,
 
-       28, // beta_mant
-       48, // beta_exp
+       28,
+       48,
 
-       0, // perform_agc_softsplit
+       0,
 };
 
 static struct dibx000_bandwidth_config stk7700p_pll_config = {
-       60000, 30000, // internal, sampling
-       1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-       0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-       (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-       60258167, // ifreq
-       20452225, // timf
-       30000000, // xtal
+       60000, 30000,
+       1, 8, 3, 1, 0,
+       0, 0, 1, 1, 0,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       60258167,
+       20452225,
+       30000000,
 };
 
 static struct dib7000m_config stk7700p_dib7000m_config = {
@@ -1115,41 +1120,42 @@ static struct dibx000_agc_config dib7070_agc_config = {
        BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
        /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
         * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
-
-       600, // inv_gain
-       10,  // time_stabiliz
-
-       0,  // alpha_level
-       118,  // thlock
-
-       0,     // wbd_inv
-       3530,  // wbd_ref
-       1,     // wbd_sel
-       5,     // wbd_alpha
-
-       65535,  // agc1_max
-               0,  // agc1_min
-
-       65535,  // agc2_max
-       0,      // agc2_min
-
-       0,      // agc1_pt1
-       40,     // agc1_pt2
-       183,    // agc1_pt3
-       206,    // agc1_slope1
-       255,    // agc1_slope2
-       72,     // agc2_pt1
-       152,    // agc2_pt2
-       88,     // agc2_slope1
-       90,     // agc2_slope2
-
-       17,  // alpha_mant
-       27,  // alpha_exp
-       23,  // beta_mant
-       51,  // beta_exp
-
-       0,  // perform_agc_softsplit
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       600,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       65535,
+               0,
+
+       65535,
+       0,
+
+       0,
+       40,
+       183,
+       206,
+       255,
+       72,
+       152,
+       88,
+       90,
+
+       17,
+       27,
+       23,
+       51,
+
+       0,
 };
 
 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
@@ -1276,13 +1282,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
 }
 
 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
-       60000, 15000, // internal, sampling
-       1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-       0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-       (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-       (0 << 25) | 0, // ifreq = 0.000000 MHz
-       20452225, // timf
-       12000000, // xtal_hz
+       60000, 15000,
+       1, 20, 3, 1, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       (0 << 25) | 0,
+       20452225,
+       12000000,
 };
 
 static struct dib7000p_config dib7070p_dib7000p_config = {
@@ -1476,12 +1482,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = {
        }
 };
 
-static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
 {
        return dib8000_set_gpio(fe, 5, 0, !onoff);
 }
 
-static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
 {
        return dib8000_set_gpio(fe, 0, 0, onoff);
 }
@@ -1494,8 +1500,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
 static struct dib0070_config dib807x_dib0070_config[2] = {
        {
                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib807x_tuner_reset,
-               .sleep = dib807x_tuner_sleep,
+               .reset = dib80xx_tuner_reset,
+               .sleep = dib80xx_tuner_sleep,
                .clock_khz = 12000,
                .clock_pad_drive = 4,
                .vga_filter = 1,
@@ -1508,8 +1514,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = {
                .freq_offset_khz_vhf = -100,
        }, {
                .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib807x_tuner_reset,
-               .sleep = dib807x_tuner_sleep,
+               .reset = dib80xx_tuner_reset,
+               .sleep = dib80xx_tuner_sleep,
                .clock_khz = 12000,
                .clock_pad_drive = 2,
                .vga_filter = 1,
@@ -1566,12 +1572,14 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
        return 0;
 }
 
-static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
+       u16 pid, int onoff)
 {
     return dib8000_pid_filter(adapter->fe, index, pid, onoff);
 }
 
-static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
+       int onoff)
 {
     return dib8000_pid_filter_ctrl(adapter->fe, onoff);
 }
@@ -1624,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
        dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
        /* initialize IC 0 */
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
 
        adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
                              &dib807x_dib8000_config[0]);
@@ -1635,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
 static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
 {
        /* initialize IC 1 */
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
 
        adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
                              &dib807x_dib8000_config[1]);
@@ -1643,6 +1651,245 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
        return adap->fe == NULL ? -ENODEV : 0;
 }
 
+/* STK8096GP */
+struct dibx000_agc_config dib8090_agc_config[2] = {
+    {
+       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+     * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+     * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       787,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       65535,
+       0,
+
+       65535,
+       0,
+
+       0,
+       32,
+       114,
+       143,
+       144,
+       114,
+       227,
+       116,
+       117,
+
+       28,
+       26,
+       31,
+       51,
+
+       0,
+    },
+    {
+       BAND_CBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+     * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+     * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       787,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       0,
+       0,
+
+       65535,
+       0,
+
+       0,
+       32,
+       114,
+       143,
+       144,
+       114,
+       227,
+       116,
+       117,
+
+       28,
+       26,
+       31,
+       51,
+
+       0,
+    }
+};
+
+static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
+    54000, 13500,
+    1, 18, 3, 1, 0,
+    0, 0, 1, 1, 2,
+    (3 << 14) | (1 << 12) | (599 << 0),
+    (0 << 25) | 0,
+    20199727,
+    12000000,
+};
+
+static int dib8090_get_adc_power(struct dvb_frontend *fe)
+{
+    return dib8000_get_adc_power(fe, 1);
+}
+
+static struct dib8000_config dib809x_dib8000_config = {
+    .output_mpeg2_in_188_bytes = 1,
+
+    .agc_config_count = 2,
+    .agc = dib8090_agc_config,
+    .agc_control = dib0090_dcc_freq,
+    .pll = &dib8090_pll_config_12mhz,
+    .tuner_is_baseband = 1,
+
+    .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+    .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+    .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+    .hostbus_diversity = 1,
+    .div_cfg = 0x31,
+    .output_mode = OUTMODE_MPEG2_FIFO,
+    .drives = 0x2d98,
+    .diversity_delay = 144,
+    .refclksel = 3,
+};
+
+static struct dib0090_config dib809x_dib0090_config = {
+    .io.pll_bypass = 1,
+    .io.pll_range = 1,
+    .io.pll_prediv = 1,
+    .io.pll_loopdiv = 20,
+    .io.adc_clock_ratio = 8,
+    .io.pll_int_loop_filt = 0,
+    .io.clock_khz = 12000,
+    .reset = dib80xx_tuner_reset,
+    .sleep = dib80xx_tuner_sleep,
+    .clkouttobamse = 1,
+    .analog_output = 1,
+    .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
+    .wbd_vhf_offset = 100,
+    .wbd_cband_offset = 450,
+    .use_pwm_agc = 1,
+    .clkoutdrive = 1,
+    .get_adc_power = dib8090_get_adc_power,
+       .freq_offset_khz_uhf = 0,
+       .freq_offset_khz_vhf = -143,
+};
+
+static int dib8096_set_param_override(struct dvb_frontend *fe,
+               struct dvb_frontend_parameters *fep)
+{
+    struct dvb_usb_adapter *adap = fe->dvb->priv;
+    struct dib0700_adapter_state *state = adap->priv;
+    u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+    u16 offset;
+    int ret = 0;
+    enum frontend_tune_state tune_state = CT_SHUTDOWN;
+    u16 ltgain, rf_gain_limit;
+
+    ret = state->set_param_save(fe, fep);
+    if (ret < 0)
+       return ret;
+
+    switch (band) {
+    case BAND_VHF:
+           offset = 100;
+           break;
+    case BAND_UHF:
+           offset = 550;
+           break;
+    default:
+           offset = 0;
+           break;
+    }
+    offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
+    dib8000_set_wbd_ref(fe, offset);
+
+
+    if (band == BAND_CBAND) {
+       deb_info("tuning in CBAND - soft-AGC startup\n");
+       /* TODO specific wbd target for dib0090 - needed for startup ? */
+       dib0090_set_tune_state(fe, CT_AGC_START);
+       do {
+               ret = dib0090_gain_control(fe);
+               msleep(ret);
+               tune_state = dib0090_get_tune_state(fe);
+               if (tune_state == CT_AGC_STEP_0)
+                       dib8000_set_gpio(fe, 6, 0, 1);
+               else if (tune_state == CT_AGC_STEP_1) {
+                       dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
+                       if (rf_gain_limit == 0)
+                               dib8000_set_gpio(fe, 6, 0, 0);
+               }
+       } while (tune_state < CT_AGC_STOP);
+       dib0090_pwm_gain_reset(fe);
+       dib8000_pwm_agc_reset(fe);
+       dib8000_set_tune_state(fe, CT_DEMOD_START);
+    } else {
+       deb_info("not tuning in CBAND - standard AGC startup\n");
+       dib0090_pwm_gain_reset(fe);
+    }
+
+    return 0;
+}
+
+static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+    struct dib0700_adapter_state *st = adap->priv;
+    struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+    if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+       return -ENODEV;
+
+    st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+    adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
+    return 0;
+}
+
+static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
+
+       adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
+
+       return adap->fe == NULL ?  -ENODEV : 0;
+}
 
 /* STK7070PD */
 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
@@ -1929,14 +2176,17 @@ struct usb_device_id dib0700_usb_id_table[] = {
        { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
 /* 55 */{ USB_DEVICE(USB_VID_YUAN,     USB_PID_YUAN_STK7700D_2) },
        { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73A) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73ESE) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
+       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV73ESE) },
+       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV282E) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
 /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
        { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
        { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
+/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096GP) },
        { 0 }           /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2238,11 +2488,11 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { NULL },
                        },
                        {   "Pinnacle PCTV 73e SE",
-                               { &dib0700_usb_id_table[57], NULL },
+                               { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
                                { NULL },
                        },
                        {   "Pinnacle PCTV 282e",
-                               { &dib0700_usb_id_table[58], NULL },
+                               { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
                                { NULL },
                        },
                },
@@ -2471,8 +2721,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        {
                                .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
                                .pid_filter_count = 32,
-                               .pid_filter = stk807x_pid_filter,
-                               .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
                                .frontend_attach  = stk807x_frontend_attach,
                                .tuner_attach     = dib807x_tuner_attach,
 
@@ -2510,8 +2760,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        {
                                .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
                                .pid_filter_count = 32,
-                               .pid_filter = stk807x_pid_filter,
-                               .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
                                .frontend_attach  = stk807xpvr_frontend_attach0,
                                .tuner_attach     = dib807x_tuner_attach,
 
@@ -2523,8 +2773,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        {
                                .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
                                .pid_filter_count = 32,
-                               .pid_filter = stk807x_pid_filter,
-                               .pid_filter_ctrl = stk807x_pid_filter_ctrl,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
                                .frontend_attach  = stk807xpvr_frontend_attach1,
                                .tuner_attach     = dib807x_tuner_attach,
 
@@ -2543,6 +2793,37 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        },
                },
 
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_key_map       = dib0700_rc_keys,
+               .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+               .rc_query         = dib0700_rc_query
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = stk809x_frontend_attach,
+                               .tuner_attach     = dib809x_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom STK8096GP reference design",
+                               { &dib0700_usb_id_table[67], NULL },
+                               { NULL },
+                       },
+               },
+
                .rc_interval      = DEFAULT_RC_INTERVAL,
                .rc_key_map       = dib0700_rc_keys,
                .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
index da34979b5337732d62084e3d3acb3eae041969e3..9143b5631e88b9e2bcbe3b02851fcf09b3055171 100644 (file)
@@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                } else if ((msg[i].flags & I2C_M_RD) == 0) {
                        if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
                                break;
-               } else
-                       break;
+               } else if (msg[i].addr != 0x50) {
+                       /* 0x50 is the address of the eeprom - we need to protect it
+                        * from dibusb's bad i2c implementation: reads without
+                        * writing the offset before are forbidden */
+                       if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
+                               break;
+               }
        }
 
        mutex_unlock(&d->i2c_mutex);
@@ -243,6 +248,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
 
 int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
 {
+       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+                       adap->dev->udev->descriptor.idProduct ==
+                       USB_PID_LITEON_DVB_T_WARM) {
+               msleep(1000);
+       }
+
        if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS,  &mod3000p_dib3000p_config)) != NULL ||
                (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
                if (adap->priv != NULL) {
index f1602d4ace6db599b4d31709302d2240582bf36c..bc3581d58cedb8be3afe98555d8d5e1544ea8406 100644 (file)
@@ -47,6 +47,7 @@
 #define USB_VID_MSI_2                          0x1462
 #define USB_VID_OPERA1                         0x695c
 #define USB_VID_PINNACLE                       0x2304
+#define USB_VID_PCTV                           0x2013
 #define USB_VID_PIXELVIEW                      0x1554
 #define USB_VID_TECHNOTREND                    0x0b48
 #define USB_VID_TERRATEC                       0x0ccd
 #define USB_PID_DIBCOM_STK7070PD                       0x1ebe
 #define USB_PID_DIBCOM_STK807XP                                0x1f90
 #define USB_PID_DIBCOM_STK807XPVR                      0x1f98
+#define USB_PID_DIBCOM_STK8096GP                        0x1fa0
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
 #define USB_PID_DIBCOM_STK7770P                                0x1e80
 #define USB_PID_DPOSH_M9206_COLD                       0x9206
 #define USB_PID_PINNACLE_PCTV801E_SE                   0x023b
 #define USB_PID_PINNACLE_PCTV73A                       0x0243
 #define USB_PID_PINNACLE_PCTV73ESE                     0x0245
+#define USB_PID_PINNACLE_PCTV74E                       0x0246
 #define USB_PID_PINNACLE_PCTV282E                      0x0248
 #define USB_PID_PIXELVIEW_SBTVD                                0x5010
 #define USB_PID_PCTV_200E                              0x020e
index 5bb9479d154ed8bffa673e0af51f4fa316293b77..64132c0cf80d1f0fdb2b9ab004502c2b4a97be5d 100644 (file)
 #include "tda1002x.h"
 #include "mt312.h"
 #include "zl10039.h"
+#include "ds3000.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
 
 #ifndef USB_PID_DW2102
 #define USB_PID_DW2102 0x2102
 #define USB_PID_CINERGY_S 0x0064
 #endif
 
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
+#endif
+
 #ifndef USB_PID_TEVII_S650
 #define USB_PID_TEVII_S650 0xd650
 #endif
 
-#ifndef USB_PID_TEVII_S630
-#define USB_PID_TEVII_S630 0xd630
+#ifndef USB_PID_TEVII_S660
+#define USB_PID_TEVII_S660 0xd660
+#endif
+
+#ifndef USB_PID_PROF_1100
+#define USB_PID_PROF_1100 0xb012
 #endif
 
 #define DW210X_READ_MSG 0
 #define DW2102_VOLTAGE_CTRL (0x1800)
 #define DW2102_RC_QUERY (0x1a00)
 
+#define        err_str "did not find the firmware file. (%s) " \
+               "Please see linux/Documentation/dvb/ for more details " \
+               "on firmware-problems."
+
 struct dvb_usb_rc_keys_table {
        struct dvb_usb_rc_key *rc_keys;
        int rc_keys_size;
@@ -71,6 +88,12 @@ static int ir_keymap;
 module_param_named(keymap, ir_keymap, int, 0644);
 MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ...");
 
+/* demod probe */
+static int demod_probe = 1;
+module_param_named(demod, demod_probe, int, 0644);
+MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
+                       "4=stv0903+stb6100(or-able)).");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
        switch (num) {
        case 2:
                /* read si2109 register by number */
-               buf6[0] = 0xd0;
+               buf6[0] = msg[0].addr << 1;
                buf6[1] = msg[0].len;
                buf6[2] = msg[0].buf[0];
                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
                switch (msg[0].addr) {
                case 0x68:
                        /* write to si2109 register */
-                       buf6[0] = 0xd0;
+                       buf6[0] = msg[0].addr << 1;
                        buf6[1] = msg[0].len;
                        memcpy(buf6 + 2, msg[0].buf, msg[0].len);
                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                /* read */
                /* first write first register number */
                u8 ibuf[msg[1].len + 2], obuf[3];
-               obuf[0] = 0xd0;
+               obuf[0] = msg[0].addr << 1;
                obuf[1] = msg[0].len;
                obuf[2] = msg[0].buf[0];
                ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                case 0x68: {
                        /* write to register */
                        u8 obuf[msg[0].len + 2];
-                       obuf[0] = 0xd0;
+                       obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
                case 0x61: {
                        /* write to tuner */
                        u8 obuf[msg[0].len + 2];
-                       obuf[0] = 0xc2;
+                       obuf[0] = msg[0].addr << 1;
                        obuf[1] = msg[0].len;
                        memcpy(obuf + 2, msg[0].buf, msg[0].len);
                        ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int ret = 0;
-       int len, i;
+       int len, i, j;
 
        if (!d)
                return -ENODEV;
        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
-       switch (num) {
-       case 2: {
-               /* read */
-               /* first write first register number */
-               u8 ibuf[msg[1].len + 2], obuf[3];
-               obuf[0] = 0xaa;
-               obuf[1] = msg[0].len;
-               obuf[2] = msg[0].buf[0];
-               ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-               /* second read registers */
-               ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
-                               ibuf, msg[1].len + 2, DW210X_READ_MSG);
-               memcpy(msg[1].buf, ibuf + 2, msg[1].len);
-
-               break;
-       }
-       case 1:
-               switch (msg[0].addr) {
-               case 0x55: {
-                       if (msg[0].buf[0] == 0xf7) {
-                               /* firmware */
-                               /* Write in small blocks */
-                               u8 obuf[19];
-                               obuf[0] = 0xaa;
-                               obuf[1] = 0x11;
-                               obuf[2] = 0xf7;
-                               len = msg[0].len - 1;
-                               i = 1;
-                               do {
-                                       memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
-                                       ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                               obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
-                                       i += 16;
-                                       len -= 16;
-                               } while (len > 0);
-                       } else {
-                               /* write to register */
-                               u8 obuf[msg[0].len + 2];
-                               obuf[0] = 0xaa;
-                               obuf[1] = msg[0].len;
-                               memcpy(obuf + 2, msg[0].buf, msg[0].len);
-                               ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-                       }
-                       break;
-               }
+       for (j = 0; j < num; j++) {
+               switch (msg[j].addr) {
                case(DW2102_RC_QUERY): {
                        u8 ibuf[2];
                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
                                        ibuf, 2, DW210X_READ_MSG);
-                       memcpy(msg[0].buf, ibuf , 2);
+                       memcpy(msg[j].buf, ibuf , 2);
                        break;
                }
                case(DW2102_VOLTAGE_CTRL): {
                        u8 obuf[2];
                        obuf[0] = 0x30;
-                       obuf[1] = msg[0].buf[0];
+                       obuf[1] = msg[j].buf[0];
                        ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
                                        obuf, 2, DW210X_WRITE_MSG);
                        break;
                }
+               /*case 0x55: cx24116
+               case 0x6a: stv0903
+               case 0x68: ds3000, stv0903
+               case 0x60: ts2020, stv6110, stb6100 */
+               default: {
+                       if (msg[j].flags == I2C_M_RD) {
+                               /* read registers */
+                               u8  ibuf[msg[j].len + 2];
+                               ret = dw210x_op_rw(d->udev, 0xc3,
+                                               (msg[j].addr << 1) + 1, 0,
+                                               ibuf, msg[j].len + 2,
+                                               DW210X_READ_MSG);
+                               memcpy(msg[j].buf, ibuf + 2, msg[j].len);
+                       mdelay(10);
+                       } else if (((msg[j].buf[0] == 0xb0) &&
+                                               (msg[j].addr == 0x68)) ||
+                                               ((msg[j].buf[0] == 0xf7) &&
+                                               (msg[j].addr == 0x55))) {
+                               /* write firmware */
+                               u8 obuf[19];
+                               obuf[0] = msg[j].addr << 1;
+                               obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
+                               obuf[2] = msg[j].buf[0];
+                               len = msg[j].len - 1;
+                               i = 1;
+                               do {
+                                       memcpy(obuf + 3, msg[j].buf + i,
+                                                       (len > 16 ? 16 : len));
+                                       ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                               obuf, (len > 16 ? 16 : len) + 3,
+                                               DW210X_WRITE_MSG);
+                                       i += 16;
+                                       len -= 16;
+                               } while (len > 0);
+                       } else {
+                               /* write registers */
+                               u8 obuf[msg[j].len + 2];
+                               obuf[0] = msg[j].addr << 1;
+                               obuf[1] = msg[j].len;
+                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
+                               ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                               obuf, msg[j].len + 2,
+                                               DW210X_WRITE_MSG);
+                       }
+                       break;
+               }
                }
 
-               break;
        }
 
        mutex_unlock(&d->i2c_mutex);
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
        return num;
 }
 
-static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                                                int num)
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int ret = 0;
+       int len, i, j;
 
        if (!d)
                return -ENODEV;
        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
-       switch (num) {
-       case 2: { /* read */
-               u8 ibuf[msg[1].len], obuf[3];
-               obuf[0] = msg[1].len;
-               obuf[1] = (msg[0].addr << 1);
-               obuf[2] = msg[0].buf[0];
-
-               ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
-                                       obuf, 3, DW210X_WRITE_MSG);
-               msleep(5);
-               ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
-                                       ibuf, msg[1].len, DW210X_READ_MSG);
-               memcpy(msg[1].buf, ibuf, msg[1].len);
-               break;
-       }
-       case 1:
-               switch (msg[0].addr) {
-               case 0x60:
-               case 0x0e: {
-                       /* write to zl10313, zl10039 register, */
-                       u8 obuf[msg[0].len + 2];
-                       obuf[0] = msg[0].len + 1;
-                       obuf[1] = (msg[0].addr << 1);
-                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
-                       ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
-                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-                       break;
-               }
+       for (j = 0; j < num; j++) {
+               switch (msg[j].addr) {
                case (DW2102_RC_QUERY): {
                        u8 ibuf[4];
                        ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
                                        ibuf, 4, DW210X_READ_MSG);
-                       msg[0].buf[0] = ibuf[3];
+                       memcpy(msg[j].buf, ibuf + 1, 2);
                        break;
                }
                case (DW2102_VOLTAGE_CTRL): {
                        u8 obuf[2];
-                       obuf[0] = 0x03;
-                       obuf[1] = msg[0].buf[0];
+                       obuf[0] = 3;
+                       obuf[1] = msg[j].buf[0];
                        ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
                                        obuf, 2, DW210X_WRITE_MSG);
                        break;
                }
+               /*case 0x55: cx24116
+               case 0x6a: stv0903
+               case 0x68: ds3000, stv0903
+               case 0x60: ts2020, stv6110, stb6100
+               case 0xa0: eeprom */
+               default: {
+                       if (msg[j].flags == I2C_M_RD) {
+                               /* read registers */
+                               u8 ibuf[msg[j].len];
+                               ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+                                               ibuf, msg[j].len,
+                                               DW210X_READ_MSG);
+                               memcpy(msg[j].buf, ibuf, msg[j].len);
+                               break;
+                       } else if ((msg[j].buf[0] == 0xb0) &&
+                                               (msg[j].addr == 0x68)) {
+                               /* write firmware */
+                               u8 obuf[19];
+                               obuf[0] = (msg[j].len > 16 ?
+                                               18 : msg[j].len + 1);
+                               obuf[1] = msg[j].addr << 1;
+                               obuf[2] = msg[j].buf[0];
+                               len = msg[j].len - 1;
+                               i = 1;
+                               do {
+                                       memcpy(obuf + 3, msg[j].buf + i,
+                                                       (len > 16 ? 16 : len));
+                                       ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
+                                               obuf, (len > 16 ? 16 : len) + 3,
+                                               DW210X_WRITE_MSG);
+                                       i += 16;
+                                       len -= 16;
+                               } while (len > 0);
+                       } else {
+                               /* write registers */
+                               u8 obuf[msg[j].len + 2];
+                               obuf[0] = msg[j].len + 1;
+                               obuf[1] = (msg[j].addr << 1);
+                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
+                               ret = dw210x_op_rw(d->udev,
+                                               (num > 1 ? 0x90 : 0x80), 0, 0,
+                                               obuf, msg[j].len + 2,
+                                               DW210X_WRITE_MSG);
+                               break;
+                       }
+                       break;
+               }
                }
 
-               break;
+               msleep(3);
        }
 
        mutex_unlock(&d->i2c_mutex);
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = {
        .functionality = dw210x_i2c_func,
 };
 
-static struct i2c_algorithm s630_i2c_algo = {
-       .master_xfer = s630_i2c_transfer,
+static struct i2c_algorithm s6x0_i2c_algo = {
+       .master_xfer = s6x0_i2c_transfer,
        .functionality = dw210x_i2c_func,
 };
 
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
        return 0;
 };
 
-static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 {
        int i, ret;
-       u8 buf[3], eeprom[256], eepromline[16];
+       u8 ibuf[] = { 0 }, obuf[] = { 0 };
+       u8 eeprom[256], eepromline[16];
+       struct i2c_msg msg[] = {
+               {
+                       .addr = 0xa0 >> 1,
+                       .flags = 0,
+                       .buf = obuf,
+                       .len = 1,
+               }, {
+                       .addr = 0xa0 >> 1,
+                       .flags = I2C_M_RD,
+                       .buf = ibuf,
+                       .len = 1,
+               }
+       };
 
        for (i = 0; i < 256; i++) {
-               buf[0] = 1;
-               buf[1] = 0xa0;
-               buf[2] = i;
-               ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
-                                       buf, 3, DW210X_WRITE_MSG);
-               ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
-                                       buf, 1, DW210X_READ_MSG);
-               if (ret < 0) {
+               obuf[0] = i;
+               ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
+               if (ret != 2) {
                        err("read eeprom failed.");
                        return -1;
                } else {
-                       eepromline[i % 16] = buf[0];
-                       eeprom[i] = buf[0];
+                       eepromline[i % 16] = ibuf[0];
+                       eeprom[i] = ibuf[0];
                }
 
                if ((i % 16) == 15) {
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config = {
        .demod_address = 0x0e,
 };
 
+static struct ds3000_config dw2104_ds3000_config = {
+       .demod_address = 0x68,
+};
+
+static struct stv0900_config dw2104a_stv0900_config = {
+       .demod_address = 0x6a,
+       .demod_mode = 0,
+       .xtal = 27000000,
+       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+       .diseqc_mode = 2,/* 2/3 PWM */
+       .tun1_maddress = 0,/* 0x60 */
+       .tun1_adc = 0,/* 2 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stb6100_config dw2104a_stb6100_config = {
+       .tuner_address = 0x60,
+       .refclock = 27000000,
+};
+
+static struct stv0900_config dw2104_stv0900_config = {
+       .demod_address = 0x68,
+       .demod_mode = 0,
+       .xtal = 8000000,
+       .clkmode = 3,
+       .diseqc_mode = 2,
+       .tun1_maddress = 0,
+       .tun1_adc = 1,/* 1 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stv6110_config dw2104_stv6110_config = {
+       .i2c_address = 0x60,
+       .mclk = 16000000,
+       .clk_div = 1,
+};
+
 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
 {
-       if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
-                       &d->dev->i2c_adap)) != NULL) {
+       struct dvb_tuner_ops *tuner_ops = NULL;
+
+       if (demod_probe & 4) {
+               d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
+                               &d->dev->i2c_adap, 0);
+               if (d->fe != NULL) {
+                       if (dvb_attach(stb6100_attach, d->fe,
+                                       &dw2104a_stb6100_config,
+                                       &d->dev->i2c_adap)) {
+                               tuner_ops = &d->fe->ops.tuner_ops;
+                               tuner_ops->set_frequency = stb6100_set_freq;
+                               tuner_ops->get_frequency = stb6100_get_freq;
+                               tuner_ops->set_bandwidth = stb6100_set_bandw;
+                               tuner_ops->get_bandwidth = stb6100_get_bandw;
+                               d->fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached STV0900+STB6100!\n");
+                               return 0;
+                       }
+               }
+       }
+
+       if (demod_probe & 2) {
+               d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
+                               &d->dev->i2c_adap, 0);
+               if (d->fe != NULL) {
+                       if (dvb_attach(stv6110_attach, d->fe,
+                                       &dw2104_stv6110_config,
+                                       &d->dev->i2c_adap)) {
+                               d->fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached STV0900+STV6110A!\n");
+                               return 0;
+                       }
+               }
+       }
+
+       if (demod_probe & 1) {
+               d->fe = dvb_attach(cx24116_attach, &dw2104_config,
+                               &d->dev->i2c_adap);
+               if (d->fe != NULL) {
+                       d->fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached cx24116!\n");
+                       return 0;
+               }
+       }
+
+       d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+                       &d->dev->i2c_adap);
+       if (d->fe != NULL) {
                d->fe->ops.set_voltage = dw210x_set_voltage;
-               info("Attached cx24116!\n");
+               info("Attached DS3000!\n");
                return 0;
        }
+
        return -EIO;
 }
 
 static struct dvb_usb_device_properties dw2102_properties;
 static struct dvb_usb_device_properties dw2104_properties;
+static struct dvb_usb_device_properties s6x0_properties;
 
 static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
 {
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
                        return 0;
                }
        }
+
        if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
-               /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
                d->fe = dvb_attach(stv0288_attach, &earda_config,
                                        &d->dev->i2c_adap);
                if (d->fe != NULL) {
-                       d->fe->ops.set_voltage = dw210x_set_voltage;
-                       info("Attached stv0288!\n");
-                       return 0;
+                       if (dvb_attach(stb6000_attach, d->fe, 0x61,
+                                       &d->dev->i2c_adap)) {
+                               d->fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached stv0288!\n");
+                               return 0;
+                       }
                }
        }
 
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
        return -EIO;
 }
 
-static int s630_frontend_attach(struct dvb_usb_adapter *d)
+static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
 {
        d->fe = dvb_attach(mt312_attach, &zl313_config,
-                               &d->dev->i2c_adap);
+                       &d->dev->i2c_adap);
+       if (d->fe != NULL) {
+               if (dvb_attach(zl10039_attach, d->fe, 0x60,
+                               &d->dev->i2c_adap)) {
+                       d->fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached zl100313+zl10039!\n");
+                       return 0;
+               }
+       }
+
+       d->fe = dvb_attach(stv0288_attach, &earda_config,
+                       &d->dev->i2c_adap);
+       if (d->fe != NULL) {
+               if (dvb_attach(stb6000_attach, d->fe, 0x61,
+                               &d->dev->i2c_adap)) {
+                       d->fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached stv0288+stb6000!\n");
+                       return 0;
+               }
+       }
+
+       d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+                       &d->dev->i2c_adap);
        if (d->fe != NULL) {
                d->fe->ops.set_voltage = dw210x_set_voltage;
-               info("Attached zl10313!\n");
+               info("Attached ds3000+ds2020!\n");
                return 0;
        }
+
        return -EIO;
 }
 
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
        return 0;
 }
 
-static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(stb6000_attach, adap->fe, 0x61,
-               &adap->dev->i2c_adap);
-
-       return 0;
-}
-
 static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
 {
        dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
        return 0;
 }
 
-static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(zl10039_attach, adap->fe, 0x60,
-               &adap->dev->i2c_adap);
-
-       return 0;
-}
-
 static struct dvb_usb_rc_key dw210x_rc_keys[] = {
        { 0xf80a, KEY_Q },              /*power*/
        { 0xf80c, KEY_M },              /*mute*/
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = {
        {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
        {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
        {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
+       {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
+       {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
        { }
 };
 
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev,
        u8 reset;
        u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
        const struct firmware *fw;
-       const char *filename = "dvb-usb-dw2101.fw";
+       const char *fw_2101 = "dvb-usb-dw2101.fw";
 
        switch (dev->descriptor.idProduct) {
        case 0x2101:
-               ret = request_firmware(&fw, filename, &dev->dev);
+               ret = request_firmware(&fw, fw_2101, &dev->dev);
                if (ret != 0) {
-                       err("did not find the firmware file. (%s) "
-                       "Please see linux/Documentation/dvb/ for more details "
-                       "on firmware-problems.", filename);
+                       err(err_str, fw_2101);
                        return ret;
                }
                break;
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev,
                }
                /* init registers */
                switch (dev->descriptor.idProduct) {
+               case USB_PID_PROF_1100:
+                       s6x0_properties.rc_key_map = tbs_rc_keys;
+                       s6x0_properties.rc_key_map_size =
+                                       ARRAY_SIZE(tbs_rc_keys);
+                       break;
                case USB_PID_TEVII_S650:
                        dw2104_properties.rc_key_map = tevii_rc_keys;
                        dw2104_properties.rc_key_map_size =
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
                                                DW210X_READ_MSG);
                                if (reset16[2] == 0x11) {
                                        dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
-                                       dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
                                        break;
                                }
                        }
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = {
        }
 };
 
-static struct dvb_usb_device_properties s630_properties = {
+static struct dvb_usb_device_properties s6x0_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
        .usb_ctrl = DEVICE_SPECIFIC,
        .firmware = "dvb-usb-s630.fw",
        .no_reconnect = 1,
 
-       .i2c_algo = &s630_i2c_algo,
+       .i2c_algo = &s6x0_i2c_algo,
        .rc_key_map = tevii_rc_keys,
        .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
        .rc_interval = 150,
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = {
        .generic_bulk_ctrl_endpoint = 0x81,
        .num_adapters = 1,
        .download_firmware = dw2102_load_firmware,
-       .read_mac_address = s630_read_mac_address,
+       .read_mac_address = s6x0_read_mac_address,
        .adapter = {
                {
-                       .frontend_attach = s630_frontend_attach,
+                       .frontend_attach = s6x0_frontend_attach,
                        .streaming_ctrl = NULL,
-                       .tuner_attach = s630_zl10039_tuner_attach,
+                       .tuner_attach = NULL,
                        .stream = {
                                .type = USB_BULK,
                                .count = 8,
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = {
                        },
                }
        },
-       .num_device_descs = 1,
+       .num_device_descs = 3,
        .devices = {
                {"TeVii S630 USB",
                        {&dw2102_table[6], NULL},
                        {NULL},
                },
+               {"Prof 1100 USB ",
+                       {&dw2102_table[7], NULL},
+                       {NULL},
+               },
+               {"TeVii S660 USB",
+                       {&dw2102_table[8], NULL},
+                       {NULL},
+               },
        }
 };
 
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf,
                        THIS_MODULE, NULL, adapter_nr) ||
            0 == dvb_usb_device_init(intf, &dw3101_properties,
                        THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &s630_properties,
-                       THIS_MODULE, NULL, adapter_nr)) {
+           0 == dvb_usb_device_init(intf, &s6x0_properties,
+                       THIS_MODULE, NULL, adapter_nr))
                return 0;
-       }
+
        return -ENODEV;
 }
 
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit);
 MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
 MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
                                " DVB-C 3101 USB2.0,"
-                               " TeVii S600, S630, S650 USB2.0 devices");
+                               " TeVii S600, S630, S650, S660 USB2.0,"
+                               " Prof 1100 USB2.0 devices");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
index 9cbbe42ca44be982ef46d8e6c1d6fe660edd77aa..ebb7b9fd115b3e1880afd34bbb7782883e681dff 100644 (file)
@@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
        deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
               state->frontend.ops.info.frequency_stepsize);
        /* freq -> oscilator frequency conversion. */
-       /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
-       /* add 400[1/7 MHZ] = 57.142857MHz.   57MHz for the IF,  */
-       /*                                   1/7MHz for center freq shift */
+       /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
        f = freq / state->frontend.ops.info.frequency_stepsize;
-       f += 400;
+       /* add 399[1/7 MHZ] = 57MHz for the IF  */
+       f += 399;
+       /* add center frequency shift if necessary */
+       if (f % 7 == 0)
+               f++;
        pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
        pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
        pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
index 20eadf9318e08eca422c11f68ab96d4b2557a0c6..7a7f1b2b681ccaa38fbc9161aa8b0d726f14952b 100644 (file)
@@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
 
        switch (c->delivery_system) {
        case SYS_DVBS:
-               /* Only QPSK is supported for DVB-S */
-               if (c->modulation != QPSK) {
+               /* Allow QPSK and 8PSK (even for DVB-S) */
+               if (c->modulation != QPSK && c->modulation != PSK_8) {
                        deb_fe("%s: unsupported modulation selected (%d)\n",
                                __func__, c->modulation);
                        return -EOPNOTSUPP;
index 58aac018f109003aaea23322ac22804d8b52020c..a3b8b697349b130f161daf1dc747d40c89ffcdb7 100644 (file)
@@ -526,6 +526,15 @@ config DVB_TUNER_DIB0070
          This device is only used inside a SiP called together with a
          demodulator for now.
 
+config DVB_TUNER_DIB0090
+       tristate "DiBcom DiB0090 silicon base-band tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner DiB0090 from DiBcom.
+         This device is only used inside a SiP called together with a
+         demodulator for now.
+
 comment "SEC control devices for DVB-S"
        depends on DVB_CORE
 
index 823482535d110000b2d9a9c61508b3e1da813ec6..47575cc7b699cea3a431b6d1c29093847402a5e8 100644 (file)
@@ -55,6 +55,7 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
 obj-$(CONFIG_DVB_TDA8261) += tda8261.o
 obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
+obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
 obj-$(CONFIG_DVB_TUA6100) += tua6100.o
 obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
 obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
index 2dc2723b724a15010009710758dfe3a12931865f..24268ef2753d7b33ed1069d7bfa9d81bf8d59cc7 100644 (file)
@@ -62,7 +62,7 @@ struct au8522_register_config {
    The values are as follows from left to right
    0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
 */
-struct au8522_register_config filter_coef[] = {
+static const struct au8522_register_config filter_coef[] = {
        {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
        {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
        {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
@@ -104,7 +104,7 @@ struct au8522_register_config filter_coef[] = {
    0="SIF" 1="ATVRF/ATVRF13"
    Note: the "ATVRF/ATVRF13" mode has never been tested
 */
-struct au8522_register_config lpfilter_coef[] = {
+static const struct au8522_register_config lpfilter_coef[] = {
        {0x060b, {0x21, 0x0b} },
        {0x060c, {0xad, 0xad} },
        {0x060d, {0x70, 0xf0} },
index 2be17b93e0bd7dcf2419b263316971304f30072f..0d12763603b47d7bdcb2f4f008fb1eff875f97ae 100644 (file)
@@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 #define DIB0070_P1G  0x03
 #define DIB0070S_P1A 0x02
 
-enum frontend_tune_state {
-       CT_TUNER_START = 10,
-       CT_TUNER_STEP_0,
-       CT_TUNER_STEP_1,
-       CT_TUNER_STEP_2,
-       CT_TUNER_STEP_3,
-       CT_TUNER_STEP_4,
-       CT_TUNER_STEP_5,
-       CT_TUNER_STEP_6,
-       CT_TUNER_STEP_7,
-       CT_TUNER_STOP,
-};
-
-#define FE_CALLBACK_TIME_NEVER 0xffffffff
-
 struct dib0070_state {
        struct i2c_adapter *i2c;
        struct dvb_frontend *fe;
@@ -71,10 +56,10 @@ struct dib0070_state {
        u16 wbd_ff_offset;
        u8 revision;
 
-       enum frontend_tune_state tune_state;
-       u32 current_rf;
+    enum frontend_tune_state tune_state;
+    u32 current_rf;
 
-       /* for the captrim binary search */
+    /* for the captrim binary search */
        s8 step;
        u16 adc_diff;
 
@@ -85,7 +70,7 @@ struct dib0070_state {
        const struct dib0070_tuning *current_tune_table_index;
        const struct dib0070_lna_match *lna_match;
 
-       u8 wbd_gain_current;
+    u8  wbd_gain_current;
        u16 wbd_offset_3_3[2];
 };
 
@@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 {
        u8 b[2];
        struct i2c_msg msg[2] = {
-               {.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
-               {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
+               { .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
        };
        if (i2c_transfer(state->i2c, msg, 2) != 2) {
                printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 {
        u8 b[3] = { reg, val >> 8, val & 0xff };
-       struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
+       struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
        if (i2c_transfer(state->i2c, &msg, 1) != 1) {
                printk(KERN_WARNING "DiB0070 I2C write failed\n");
                return -EREMOTEIO;
@@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 
 static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
 {
-       struct dib0070_state *state = fe->tuner_priv;
-       u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
-
-       if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
-               tmp |= (0 << 14);
-       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
-               tmp |= (1 << 14);
-       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
-               tmp |= (2 << 14);
-       else
-               tmp |= (3 << 14);
-
-       dib0070_write_reg(state, 0x02, tmp);
-
-       /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
-       if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
-               u16 value = dib0070_read_reg(state, 0x17);
-
-               dib0070_write_reg(state, 0x17, value & 0xfffc);
-               tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
-               dib0070_write_reg(state, 0x01, tmp | (60 << 9));
-
-               dib0070_write_reg(state, 0x17, value);
-       }
+    struct dib0070_state *state = fe->tuner_priv;
+    u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+
+    if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
+       tmp |= (0 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
+       tmp |= (1 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
+       tmp |= (2 << 14);
+    else
+       tmp |= (3 << 14);
+
+    dib0070_write_reg(state, 0x02, tmp);
+
+    /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+       u16 value = dib0070_read_reg(state, 0x17);
+
+       dib0070_write_reg(state, 0x17, value & 0xfffc);
+       tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+       dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+
+       dib0070_write_reg(state, 0x17, value);
+    }
        return 0;
 }
 
@@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
        if (*tune_state == CT_TUNER_STEP_0) {
 
                dib0070_write_reg(state, 0x0f, 0xed10);
-               dib0070_write_reg(state, 0x17, 0x0034);
+               dib0070_write_reg(state, 0x17,    0x0034);
 
                dib0070_write_reg(state, 0x18, 0x0032);
                state->step = state->captrim = state->fcaptrim = 64;
                state->adc_diff = 3000;
                ret = 20;
 
-               *tune_state = CT_TUNER_STEP_1;
+       *tune_state = CT_TUNER_STEP_1;
        } else if (*tune_state == CT_TUNER_STEP_1) {
                state->step /= 2;
                dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
@@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
 
                adc = dib0070_read_reg(state, 0x19);
 
-               dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
+               dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
 
                if (adc >= 400) {
                        adc -= 400;
@@ -193,6 +178,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
                        state->adc_diff = adc;
                        state->fcaptrim = state->captrim;
 
+
+
                }
                state->captrim += (step_sign * state->step);
 
@@ -213,7 +200,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
 static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
 {
        struct dib0070_state *state = fe->tuner_priv;
-       u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
        dprintk("CTRL_LO5: 0x%x", lo5);
        return dib0070_write_reg(state, 0x15, lo5);
 }
@@ -227,99 +214,99 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
                dib0070_write_reg(state, 0x1a, 0x0000);
        } else {
                dib0070_write_reg(state, 0x1b, 0x4112);
-               if (state->cfg->vga_filter != 0) {
-                       dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
-                       dprintk("vga filter register is set to %x", state->cfg->vga_filter);
-               } else
-                       dib0070_write_reg(state, 0x1a, 0x0009);
+       if (state->cfg->vga_filter != 0) {
+               dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+               dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+       } else
+               dib0070_write_reg(state, 0x1a, 0x0009);
        }
 }
 
 EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
 struct dib0070_tuning {
-       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
-       u8 switch_trim;
-       u8 vco_band;
-       u8 hfdiv;
-       u8 vco_multi;
-       u8 presc;
-       u8 wbdmux;
-       u16 tuner_enable;
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 switch_trim;
+    u8 vco_band;
+    u8 hfdiv;
+    u8 vco_multi;
+    u8 presc;
+    u8 wbdmux;
+    u16 tuner_enable;
 };
 
 struct dib0070_lna_match {
-       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
-       u8 lna_band;
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 lna_band;
 };
 
 static const struct dib0070_tuning dib0070s_tuning_table[] = {
-       {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800},    /* UHF */
-       {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
-       {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
-       {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},   /* LBAND */
-       {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
-       {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
-       {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000},        /* SBAND */
+    {     570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {    1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
+    {    1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    {    2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
 };
 
 static const struct dib0070_tuning dib0070_tuning_table[] = {
-       {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000},   /* FM below 92MHz cannot be tuned */
-       {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000},   /* VHF */
-       {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
-       {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
-       {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800},    /* UHF */
-       {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
-       {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
-       {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400},        /* LBAND or everything higher than UHF */
+    {     115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
+    {     179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
+    {     189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
+    {     250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
+    {     569999, 2, 1, 5,  6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     699999, 2, 0, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    { 0xffffffff, 0, 1, 0,  2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
 };
 
 static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
-       {180000, 0},            /* VHF */
-       {188000, 1},
-       {196400, 2},
-       {250000, 3},
-       {550000, 0},            /* UHF */
-       {590000, 1},
-       {666000, 3},
-       {864000, 5},
-       {1500000, 0},           /* LBAND or everything higher than UHF */
-       {1600000, 1},
-       {2000000, 3},
-       {0xffffffff, 7},
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 0 }, /* UHF */
+    {     590000, 1 },
+    {     666000, 3 },
+    {     864000, 5 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
 };
 
 static const struct dib0070_lna_match dib0070_lna[] = {
-       {180000, 0},            /* VHF */
-       {188000, 1},
-       {196400, 2},
-       {250000, 3},
-       {550000, 2},            /* UHF */
-       {650000, 3},
-       {750000, 5},
-       {850000, 6},
-       {864000, 7},
-       {1500000, 0},           /* LBAND or everything higher than UHF */
-       {1600000, 1},
-       {2000000, 3},
-       {0xffffffff, 7},
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 2 }, /* UHF */
+    {     650000, 3 },
+    {     750000, 5 },
+    {     850000, 6 },
+    {     864000, 7 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
 };
 
-#define LPF    100             // define for the loop filter 100kHz by default 16-07-06
+#define LPF    100
 static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
 {
-       struct dib0070_state *state = fe->tuner_priv;
+    struct dib0070_state *state = fe->tuner_priv;
 
-       const struct dib0070_tuning *tune;
-       const struct dib0070_lna_match *lna_match;
+    const struct dib0070_tuning *tune;
+    const struct dib0070_lna_match *lna_match;
 
-       enum frontend_tune_state *tune_state = &state->tune_state;
-       int ret = 10;           /* 1ms is the default delay most of the time */
+    enum frontend_tune_state *tune_state = &state->tune_state;
+    int ret = 10; /* 1ms is the default delay most of the time */
 
-       u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
-       u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
+    u8  band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
+    u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
 
 #ifdef CONFIG_SYS_ISDBT
-       if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
                if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
                     && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
                    || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
@@ -328,172 +315,180 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
                        && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
                        freq += 850;
 #endif
+    if (state->current_rf != freq) {
+
+       switch (state->revision) {
+       case DIB0070S_P1A:
+           tune = dib0070s_tuning_table;
+           lna_match = dib0070_lna;
+           break;
+       default:
+           tune = dib0070_tuning_table;
+           if (state->cfg->flip_chip)
+               lna_match = dib0070_lna_flip_chip;
+           else
+               lna_match = dib0070_lna;
+           break;
+       }
+       while (freq > tune->max_freq) /* find the right one */
+           tune++;
+       while (freq > lna_match->max_freq) /* find the right one */
+           lna_match++;
+
+       state->current_tune_table_index = tune;
+       state->lna_match = lna_match;
+    }
+
+    if (*tune_state == CT_TUNER_START) {
+       dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
        if (state->current_rf != freq) {
+               u8 REFDIV;
+               u32 FBDiv, Rest, FREF, VCOF_kHz;
+               u8 Den;
+
+               state->current_rf = freq;
+               state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+
+
+               dib0070_write_reg(state, 0x17, 0x30);
+
+
+               VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
+
+               switch (band) {
+               case BAND_VHF:
+                       REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+                       break;
+               case BAND_FM:
+                       REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
+                       break;
+               default:
+                       REFDIV = (u8) (state->cfg->clock_khz  / 10000);
+                       break;
+               }
+               FREF = state->cfg->clock_khz / REFDIV;
+
+
 
                switch (state->revision) {
                case DIB0070S_P1A:
-                       tune = dib0070s_tuning_table;
-                       lna_match = dib0070_lna;
+                       FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+                       Rest  = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
                        break;
+
+               case DIB0070_P1G:
+               case DIB0070_P1F:
                default:
-                       tune = dib0070_tuning_table;
-                       if (state->cfg->flip_chip)
-                               lna_match = dib0070_lna_flip_chip;
-                       else
-                               lna_match = dib0070_lna;
+                       FBDiv = (freq / (FREF / 2));
+                       Rest  = 2 * freq - FBDiv * FREF;
                        break;
                }
-               while (freq > tune->max_freq)   /* find the right one */
-                       tune++;
-               while (freq > lna_match->max_freq)      /* find the right one */
-                       lna_match++;
 
-               state->current_tune_table_index = tune;
-               state->lna_match = lna_match;
-       }
+               if (Rest < LPF)
+                       Rest = 0;
+               else if (Rest < 2 * LPF)
+                       Rest = 2 * LPF;
+               else if (Rest > (FREF - LPF)) {
+                       Rest = 0;
+                       FBDiv += 1;
+               } else if (Rest > (FREF - 2 * LPF))
+                       Rest = FREF - 2 * LPF;
+               Rest = (Rest * 6528) / (FREF / 10);
+
+               Den = 1;
+               if (Rest > 0) {
+                       state->lo4 |= (1 << 14) | (1 << 12);
+                       Den = 255;
+               }
+
 
-       if (*tune_state == CT_TUNER_START) {
-               dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
-               if (state->current_rf != freq) {
-                       u8 REFDIV;
-                       u32 FBDiv, Rest, FREF, VCOF_kHz;
-                       u8 Den;
-
-                       state->current_rf = freq;
-                       state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
-
-                       dib0070_write_reg(state, 0x17, 0x30);
-
-                       VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
-
-                       switch (band) {
-                       case BAND_VHF:
-                               REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
-                               break;
-                       case BAND_FM:
-                               REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
-                               break;
-                       default:
-                               REFDIV = (u8) (state->cfg->clock_khz / 10000);
-                               break;
-                       }
-                       FREF = state->cfg->clock_khz / REFDIV;
-
-                       switch (state->revision) {
-                       case DIB0070S_P1A:
-                               FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
-                               Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
-                               break;
-
-                       case DIB0070_P1G:
-                       case DIB0070_P1F:
-                       default:
-                               FBDiv = (freq / (FREF / 2));
-                               Rest = 2 * freq - FBDiv * FREF;
-                               break;
-                       }
-
-                       if (Rest < LPF)
-                               Rest = 0;
-                       else if (Rest < 2 * LPF)
-                               Rest = 2 * LPF;
-                       else if (Rest > (FREF - LPF)) {
-                               Rest = 0;
-                               FBDiv += 1;
-                       } else if (Rest > (FREF - 2 * LPF))
-                               Rest = FREF - 2 * LPF;
-                       Rest = (Rest * 6528) / (FREF / 10);
-
-                       Den = 1;
-                       if (Rest > 0) {
-                               state->lo4 |= (1 << 14) | (1 << 12);
-                               Den = 255;
-                       }
-
-                       dib0070_write_reg(state, 0x11, (u16) FBDiv);
-                       dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
-                       dib0070_write_reg(state, 0x13, (u16) Rest);
-
-                       if (state->revision == DIB0070S_P1A) {
-
-                               if (band == BAND_SBAND) {
-                                       dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-                                       dib0070_write_reg(state, 0x1d, 0xFFFF);
-                               } else
-                                       dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
-                       }
-
-                       dib0070_write_reg(state, 0x20,
-                                         0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
-
-                       dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
-                       dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
-                       dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
-                       dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
-                       dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
-                       dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
-
-                       *tune_state = CT_TUNER_STEP_0;
-               } else {        /* we are already tuned to this frequency - the configuration is correct  */
-                       ret = 50;       /* wakeup time */
-                       *tune_state = CT_TUNER_STEP_5;
+               dib0070_write_reg(state, 0x11, (u16)FBDiv);
+               dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+               dib0070_write_reg(state, 0x13, (u16) Rest);
+
+               if (state->revision == DIB0070S_P1A) {
+
+                       if (band == BAND_SBAND) {
+                               dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+                               dib0070_write_reg(state, 0x1d, 0xFFFF);
+                       } else
+                               dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
                }
-       } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
 
-               ret = dib0070_captrim(state, tune_state);
+               dib0070_write_reg(state, 0x20,
+                       0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
 
-       } else if (*tune_state == CT_TUNER_STEP_4) {
-               const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-               if (tmp != NULL) {
-                       while (freq / 1000 > tmp->freq) /* find the right one */
-                               tmp++;
-                       dib0070_write_reg(state, 0x0f,
-                                         (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
-                                                                                                                               current_tune_table_index->
-                                                                                                                               wbdmux << 0));
-                       state->wbd_gain_current = tmp->wbd_gain_val;
-               } else {
+               dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+               dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+               dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+               dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+               dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+               dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
+
+               *tune_state = CT_TUNER_STEP_0;
+       } else { /* we are already tuned to this frequency - the configuration is correct  */
+               ret = 50; /* wakeup time */
+               *tune_state = CT_TUNER_STEP_5;
+       }
+    } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+
+       ret = dib0070_captrim(state, tune_state);
+
+    } else if (*tune_state == CT_TUNER_STEP_4) {
+       const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+       if (tmp != NULL) {
+               while (freq/1000 > tmp->freq) /* find the right one */
+                       tmp++;
+               dib0070_write_reg(state, 0x0f,
+                       (0 << 15) | (1 << 14) | (3 << 12)
+                       | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
+                       | (state->current_tune_table_index->wbdmux << 0));
+               state->wbd_gain_current = tmp->wbd_gain_val;
+       } else {
                        dib0070_write_reg(state, 0x0f,
                                          (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
                                                                                                                wbdmux << 0));
-                       state->wbd_gain_current = 6;
-               }
+           state->wbd_gain_current = 6;
+       }
 
-               dib0070_write_reg(state, 0x06, 0x3fff);
+       dib0070_write_reg(state, 0x06, 0x3fff);
                dib0070_write_reg(state, 0x07,
                                  (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
-               dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
-               dib0070_write_reg(state, 0x0d, 0x0d80);
+       dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+       dib0070_write_reg(state, 0x0d, 0x0d80);
 
-               dib0070_write_reg(state, 0x18, 0x07ff);
-               dib0070_write_reg(state, 0x17, 0x0033);
 
-               *tune_state = CT_TUNER_STEP_5;
-       } else if (*tune_state == CT_TUNER_STEP_5) {
-               dib0070_set_bandwidth(fe, ch);
-               *tune_state = CT_TUNER_STOP;
-       } else {
-               ret = FE_CALLBACK_TIME_NEVER;   /* tuner finished, time to call again infinite */
-       }
-       return ret;
+       dib0070_write_reg(state, 0x18,   0x07ff);
+       dib0070_write_reg(state, 0x17, 0x0033);
+
+
+       *tune_state = CT_TUNER_STEP_5;
+    } else if (*tune_state == CT_TUNER_STEP_5) {
+       dib0070_set_bandwidth(fe, ch);
+       *tune_state = CT_TUNER_STOP;
+    } else {
+       ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
+    }
+    return ret;
 }
 
+
 static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
 {
-       struct dib0070_state *state = fe->tuner_priv;
-       uint32_t ret;
+    struct dib0070_state *state = fe->tuner_priv;
+    uint32_t ret;
 
-       state->tune_state = CT_TUNER_START;
+    state->tune_state = CT_TUNER_START;
 
-       do {
-               ret = dib0070_tune_digital(fe, p);
-               if (ret != FE_CALLBACK_TIME_NEVER)
-                       msleep(ret / 10);
-               else
-                       break;
-       } while (state->tune_state != CT_TUNER_STOP);
+    do {
+       ret = dib0070_tune_digital(fe, p);
+       if (ret != FE_CALLBACK_TIME_NEVER)
+               msleep(ret/10);
+       else
+           break;
+    } while (state->tune_state != CT_TUNER_STOP);
 
-       return 0;
+    return 0;
 }
 
 static int dib0070_wakeup(struct dvb_frontend *fe)
@@ -512,92 +507,113 @@ static int dib0070_sleep(struct dvb_frontend *fe)
        return 0;
 }
 
-static const u16 dib0070_p1f_defaults[] = {
+u8 dib0070_get_rf_output(struct dvb_frontend *fe)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
+}
+EXPORT_SYMBOL(dib0070_get_rf_output);
+
+int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
+       if (no > 3)
+               no = 3;
+       if (no < 1)
+               no = 1;
+       return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
+}
+EXPORT_SYMBOL(dib0070_set_rf_output);
+
+static const u16 dib0070_p1f_defaults[] =
+
+{
        7, 0x02,
-       0x0008,
-       0x0000,
-       0x0000,
-       0x0000,
-       0x0000,
-       0x0002,
-       0x0100,
+               0x0008,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0002,
+               0x0100,
 
        3, 0x0d,
-       0x0d80,
-       0x0001,
-       0x0000,
+               0x0d80,
+               0x0001,
+               0x0000,
 
        4, 0x11,
-       0x0000,
-       0x0103,
-       0x0000,
-       0x0000,
+               0x0000,
+               0x0103,
+               0x0000,
+               0x0000,
 
        3, 0x16,
-       0x0004 | 0x0040,
-       0x0030,
-       0x07ff,
+               0x0004 | 0x0040,
+               0x0030,
+               0x07ff,
 
        6, 0x1b,
-       0x4112,
-       0xff00,
-       0xc07f,
-       0x0000,
-       0x0180,
-       0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+               0x4112,
+               0xff00,
+               0xc07f,
+               0x0000,
+               0x0180,
+               0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
 
        0,
 };
 
 static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
 {
-       u16 tuner_en = dib0070_read_reg(state, 0x20);
-       u16 offset;
-
-       dib0070_write_reg(state, 0x18, 0x07ff);
-       dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
-       dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
-       msleep(9);
-       offset = dib0070_read_reg(state, 0x19);
-       dib0070_write_reg(state, 0x20, tuner_en);
-       return offset;
+    u16 tuner_en = dib0070_read_reg(state, 0x20);
+    u16 offset;
+
+    dib0070_write_reg(state, 0x18, 0x07ff);
+    dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+    dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
+    msleep(9);
+    offset = dib0070_read_reg(state, 0x19);
+    dib0070_write_reg(state, 0x20, tuner_en);
+    return offset;
 }
 
 static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
 {
-       u8 gain;
-       for (gain = 6; gain < 8; gain++) {
-               state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
-               dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
-       }
+    u8 gain;
+    for (gain = 6; gain < 8; gain++) {
+       state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+       dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
+    }
 }
 
 u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 {
-       struct dib0070_state *state = fe->tuner_priv;
-       const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-       u32 freq = fe->dtv_property_cache.frequency / 1000;
-
-       if (tmp != NULL) {
-               while (freq / 1000 > tmp->freq) /* find the right one */
-                       tmp++;
-               state->wbd_gain_current = tmp->wbd_gain_val;
+    struct dib0070_state *state = fe->tuner_priv;
+    const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+    u32 freq = fe->dtv_property_cache.frequency/1000;
+
+    if (tmp != NULL) {
+       while (freq/1000 > tmp->freq) /* find the right one */
+           tmp++;
+       state->wbd_gain_current = tmp->wbd_gain_val;
        } else
-               state->wbd_gain_current = 6;
+       state->wbd_gain_current = 6;
 
-       return state->wbd_offset_3_3[state->wbd_gain_current - 6];
+    return state->wbd_offset_3_3[state->wbd_gain_current - 6];
 }
-
 EXPORT_SYMBOL(dib0070_wbd_offset);
 
 #define pgm_read_word(w) (*w)
 static int dib0070_reset(struct dvb_frontend *fe)
 {
-       struct dib0070_state *state = fe->tuner_priv;
+    struct dib0070_state *state = fe->tuner_priv;
        u16 l, r, *n;
 
        HARD_RESET(state);
 
+
 #ifndef FORCE_SBAND_TUNER
        if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
                state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
@@ -605,7 +621,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
 #else
 #warning forcing SBAND
 #endif
-       state->revision = DIB0070S_P1A;
+               state->revision = DIB0070S_P1A;
 
        /* P1F or not */
        dprintk("Revision: %x", state->revision);
@@ -620,7 +636,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
        while (l) {
                r = pgm_read_word(n++);
                do {
-                       dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
+                       dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
                        r++;
                } while (--l);
                l = pgm_read_word(n++);
@@ -633,6 +649,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
        else
                r = 2;
 
+
        r |= state->cfg->osc_buffer_state << 3;
 
        dib0070_write_reg(state, 0x10, r);
@@ -643,16 +660,24 @@ static int dib0070_reset(struct dvb_frontend *fe)
                dib0070_write_reg(state, 0x02, r | (1 << 5));
        }
 
-       if (state->revision == DIB0070S_P1A)
-               dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-       else
+    if (state->revision == DIB0070S_P1A)
+       dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+    else
                dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
 
        dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
 
-       dib0070_wbd_offset_calibration(state);
+    dib0070_wbd_offset_calibration(state);
 
-       return 0;
+    return 0;
+}
+
+static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+
+    *frequency = 1000 * state->current_rf;
+    return 0;
 }
 
 static int dib0070_release(struct dvb_frontend *fe)
@@ -664,18 +689,18 @@ static int dib0070_release(struct dvb_frontend *fe)
 
 static const struct dvb_tuner_ops dib0070_ops = {
        .info = {
-                .name = "DiBcom DiB0070",
-                .frequency_min = 45000000,
-                .frequency_max = 860000000,
-                .frequency_step = 1000,
-                },
-       .release = dib0070_release,
-
-       .init = dib0070_wakeup,
-       .sleep = dib0070_sleep,
-       .set_params = dib0070_tune,
-
-//      .get_frequency = dib0070_get_frequency,
+               .name           = "DiBcom DiB0070",
+               .frequency_min  =  45000000,
+               .frequency_max  = 860000000,
+               .frequency_step =      1000,
+       },
+       .release       = dib0070_release,
+
+       .init          = dib0070_wakeup,
+       .sleep         = dib0070_sleep,
+       .set_params    = dib0070_tune,
+
+       .get_frequency = dib0070_get_frequency,
 //      .get_bandwidth = dib0070_get_bandwidth
 };
 
@@ -687,7 +712,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
 
        state->cfg = cfg;
        state->i2c = i2c;
-       state->fe = fe;
+       state->fe  = fe;
        fe->tuner_priv = state;
 
        if (dib0070_reset(fe) != 0)
@@ -699,12 +724,11 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
        fe->tuner_priv = state;
        return fe;
 
- free_mem:
+free_mem:
        kfree(state);
        fe->tuner_priv = NULL;
        return NULL;
 }
-
 EXPORT_SYMBOL(dib0070_attach);
 
 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
index eec9e52ffa753d0454044ca2705697e53b0ca39f..45c31fae3967118c5f6a55ffe6718de54aee2b8a 100644 (file)
@@ -52,6 +52,8 @@ struct dib0070_config {
 extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
 extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
+extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
+extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
 #else
 static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
 {
@@ -62,7 +64,7 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struc
 static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
+       return 0;
 }
 
 static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
new file mode 100644 (file)
index 0000000..6145527
--- /dev/null
@@ -0,0 +1,1522 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "dib0090.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { \
+       if (debug) { \
+               printk(KERN_DEBUG "DiB0090: "); \
+               printk(args); \
+               printk("\n"); \
+       } \
+} while (0)
+
+#define CONFIG_SYS_ISDBT
+#define CONFIG_BAND_CBAND
+#define CONFIG_BAND_VHF
+#define CONFIG_BAND_UHF
+#define CONFIG_DIB0090_USE_PWM_AGC
+
+#define EN_LNA0      0x8000
+#define EN_LNA1      0x4000
+#define EN_LNA2      0x2000
+#define EN_LNA3      0x1000
+#define EN_MIX0      0x0800
+#define EN_MIX1      0x0400
+#define EN_MIX2      0x0200
+#define EN_MIX3      0x0100
+#define EN_IQADC     0x0040
+#define EN_PLL       0x0020
+#define EN_TX        0x0010
+#define EN_BB        0x0008
+#define EN_LO        0x0004
+#define EN_BIAS      0x0001
+
+#define EN_IQANA     0x0002
+#define EN_DIGCLK    0x0080    /* not in the 0x24 reg, only in 0x1b */
+#define EN_CRYSTAL   0x0002
+
+#define EN_UHF          0x22E9
+#define EN_VHF          0x44E9
+#define EN_LBD          0x11E9
+#define EN_SBD          0x44E9
+#define EN_CAB          0x88E9
+
+#define pgm_read_word(w) (*w)
+
+struct dc_calibration;
+
+struct dib0090_tuning {
+       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
+       u8 switch_trim;
+       u8 lna_tune;
+       u8 lna_bias;
+       u16 v2i;
+       u16 mix;
+       u16 load;
+       u16 tuner_enable;
+};
+
+struct dib0090_pll {
+       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
+       u8 vco_band;
+       u8 hfdiv_code;
+       u8 hfdiv;
+       u8 topresc;
+};
+
+struct dib0090_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+       const struct dib0090_config *config;
+
+       u8 current_band;
+       u16 revision;
+       enum frontend_tune_state tune_state;
+       u32 current_rf;
+
+       u16 wbd_offset;
+       s16 wbd_target;         /* in dB */
+
+       s16 rf_gain_limit;      /* take-over-point: where to split between bb and rf gain */
+       s16 current_gain;       /* keeps the currently programmed gain */
+       u8 agc_step;            /* new binary search */
+
+       u16 gain[2];            /* for channel monitoring */
+
+       const u16 *rf_ramp;
+       const u16 *bb_ramp;
+
+       /* for the software AGC ramps */
+       u16 bb_1_def;
+       u16 rf_lt_def;
+       u16 gain_reg[4];
+
+       /* for the captrim/dc-offset search */
+       s8 step;
+       s16 adc_diff;
+       s16 min_adc_diff;
+
+       s8 captrim;
+       s8 fcaptrim;
+
+       const struct dc_calibration *dc;
+       u16 bb6, bb7;
+
+       const struct dib0090_tuning *current_tune_table_index;
+       const struct dib0090_pll *current_pll_table_index;
+
+       u8 tuner_is_tuned;
+       u8 agc_freeze;
+
+       u8 reset;
+};
+
+static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
+{
+       u8 b[2];
+       struct i2c_msg msg[2] = {
+               {.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1},
+               {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
+       };
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "DiB0090 I2C read failed\n");
+               return 0;
+       }
+       return (b[0] << 8) | b[1];
+}
+
+static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
+{
+       u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
+       struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0090 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+#define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
+#define ADC_TARGET -220
+#define GAIN_ALPHA 5
+#define WBD_ALPHA 6
+#define LPF    100
+static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
+{
+       do {
+               dib0090_write_reg(state, r++, *b++);
+       } while (--c);
+}
+
+static u16 dib0090_identify(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       u16 v;
+
+       v = dib0090_read_reg(state, 0x1a);
+
+#ifdef FIRMWARE_FIREFLY
+       /* pll is not locked locked */
+       if (!(v & 0x800))
+               dprintk("FE%d : Identification : pll is not yet locked", fe->id);
+#endif
+
+       /* without PLL lock info */
+       v &= 0x3ff;
+       dprintk("P/V: %04x:", v);
+
+       if ((v >> 8) & 0xf)
+               dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf);
+       else
+               return 0xff;
+
+       v &= 0xff;
+       if (((v >> 5) & 0x7) == 0x1)
+               dprintk("FE%d : MP001 : 9090/8096", fe->id);
+       else if (((v >> 5) & 0x7) == 0x4)
+               dprintk("FE%d : MP005 : Single Sband", fe->id);
+       else if (((v >> 5) & 0x7) == 0x6)
+               dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id);
+       else if (((v >> 5) & 0x7) == 0x7)
+               dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id);
+       else
+               return 0xff;
+
+       /* revision only */
+       if ((v & 0x1f) == 0x3)
+               dprintk("FE%d : P1-D/E/F detected", fe->id);
+       else if ((v & 0x1f) == 0x1)
+               dprintk("FE%d : P1C detected", fe->id);
+       else if ((v & 0x1f) == 0x0) {
+#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
+               dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id);
+               dib0090_p1b_register(fe);
+#else
+               dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id);
+               return 0xff;
+#endif
+       }
+
+       return v;
+}
+
+static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       HARD_RESET(state);
+
+       dib0090_write_reg(state, 0x24, EN_PLL);
+       dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);        /* PLL, DIG_CLK and CRYSTAL remain */
+
+       /* adcClkOutRatio=8->7, release reset */
+       dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
+       if (cfg->clkoutdrive != 0)
+               dib0090_write_reg(state, 0x23,
+                                 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
+                                                                                                                                          clkouttobamse
+                                                                                                                                          << 4) | (0
+                                                                                                                                                   <<
+                                                                                                                                                   2)
+                                 | (0));
+       else
+               dib0090_write_reg(state, 0x23,
+                                 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg->
+                                                                                                                           clkouttobamse << 4) | (0
+                                                                                                                                                  <<
+                                                                                                                                                  2)
+                                 | (0));
+
+       /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */
+       dib0090_write_reg(state, 0x21,
+                         (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv));
+
+}
+
+static int dib0090_wakeup(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (state->config->sleep)
+               state->config->sleep(fe, 0);
+       return 0;
+}
+
+static int dib0090_sleep(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (state->config->sleep)
+               state->config->sleep(fe, 1);
+       return 0;
+}
+
+extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (fast)
+               dib0090_write_reg(state, 0x04, 0);
+       else
+               dib0090_write_reg(state, 0x04, 1);
+}
+EXPORT_SYMBOL(dib0090_dcc_freq);
+
+static const u16 rf_ramp_pwm_cband[] = {
+       0,                      /* max RF gain in 10th of dB */
+       0,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       0,                      /* ramp_max = maximum X used on the ramp */
+       (0 << 10) | 0,          /* 0x2c, LNA 1 = 0dB */
+       (0 << 10) | 0,          /* 0x2d, LNA 1 */
+       (0 << 10) | 0,          /* 0x2e, LNA 2 = 0dB */
+       (0 << 10) | 0,          /* 0x2f, LNA 2 */
+       (0 << 10) | 0,          /* 0x30, LNA 3 = 0dB */
+       (0 << 10) | 0,          /* 0x31, LNA 3 */
+       (0 << 10) | 0,          /* GAIN_4_1, LNA 4 = 0dB */
+       (0 << 10) | 0,          /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_vhf[] = {
+       412,                    /* max RF gain in 10th of dB */
+       132, 307, 127,          /* LNA1,  13.2dB */
+       105, 412, 255,          /* LNA2,  10.5dB */
+       50, 50, 127,            /* LNA3,  5dB */
+       125, 175, 127,          /* LNA4,  12.5dB */
+       0, 0, 127,              /* CBAND, 0dB */
+};
+
+static const u16 rf_ramp_uhf[] = {
+       412,                    /* max RF gain in 10th of dB */
+       132, 307, 127,          /* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
+       105, 412, 255,          /* LNA2  : 10.5 dB */
+       50, 50, 127,            /* LNA3  :  5.0 dB */
+       125, 175, 127,          /* LNA4  : 12.5 dB */
+       0, 0, 127,              /* CBAND :  0.0 dB */
+};
+
+static const u16 rf_ramp_cband[] = {
+       332,                    /* max RF gain in 10th of dB */
+       132, 252, 127,          /* LNA1,  dB */
+       80, 332, 255,           /* LNA2,  dB */
+       0, 0, 127,              /* LNA3,  dB */
+       0, 0, 127,              /* LNA4,  dB */
+       120, 120, 127,          /* LT1 CBAND */
+};
+
+static const u16 rf_ramp_pwm_vhf[] = {
+       404,                    /* max RF gain in 10th of dB */
+       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       1011,                   /* ramp_max = maximum X used on the ramp */
+       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
+       (0 << 10) | 756,        /* 0x2d, LNA 1 */
+       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
+       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
+       (16 << 10) | 290,       /* 0x30, LNA 3 = 5dB */
+       (0 << 10) | 417,        /* 0x31, LNA 3 */
+       (7 << 10) | 0,          /* GAIN_4_1, LNA 4 = 12.5dB */
+       (0 << 10) | 290,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_uhf[] = {
+       404,                    /* max RF gain in 10th of dB */
+       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       1011,                   /* ramp_max = maximum X used on the ramp */
+       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
+       (0 << 10) | 756,        /* 0x2d, LNA 1 */
+       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
+       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
+       (16 << 10) | 0,         /* 0x30, LNA 3 = 5dB */
+       (0 << 10) | 127,        /* 0x31, LNA 3 */
+       (7 << 10) | 127,        /* GAIN_4_1, LNA 4 = 12.5dB */
+       (0 << 10) | 417,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 bb_ramp_boost[] = {
+       550,                    /* max BB gain in 10th of dB */
+       260, 260, 26,           /* BB1, 26dB */
+       290, 550, 29,           /* BB2, 29dB */
+};
+
+static const u16 bb_ramp_pwm_normal[] = {