Merge branch 'origin'
authorLinus Torvalds <torvalds@g5.osdl.org>
Tue, 21 Mar 2006 16:52:18 +0000 (08:52 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 21 Mar 2006 16:52:18 +0000 (08:52 -0800)
Conflicts:
Documentation/video4linux/CARDLIST.cx88
drivers/media/video/cx88/Kconfig
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/saa7134/saa7134-dvb.c

Resolved as in the original merge by Mauro Carvalho Chehab

157 files changed:
.gitignore
Documentation/dvb/avermedia.txt
Documentation/dvb/get_dvb_firmware
Documentation/dvb/readme.txt
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/CARDLIST.tuner
Documentation/video4linux/README.cpia2 [new file with mode: 0644]
Documentation/video4linux/cpia2_overview.txt [new file with mode: 0644]
drivers/media/common/Makefile
drivers/media/common/ir-common.c [deleted file]
drivers/media/common/ir-functions.c [new file with mode: 0644]
drivers/media/common/ir-keymaps.c [new file with mode: 0644]
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_i2c.c
drivers/media/common/saa7146_vbi.c
drivers/media/common/saa7146_video.c
drivers/media/dvb/b2c2/flexcop-common.h
drivers/media/dvb/b2c2/flexcop-i2c.c
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/bt8xx/dst_common.h
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/bt8xx/dvb-bt8xx.h
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dmxdev.h
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/dvb-core/dvb_demux.h
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dvb-usb-init.c
drivers/media/dvb/dvb-usb/dvb-usb-urb.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/bcm3510.c
drivers/media/dvb/frontends/bsbe1.h [new file with mode: 0644]
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/cx24110.h
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/lnbp21.h [new file with mode: 0644]
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda1004x.h
drivers/media/dvb/frontends/zl10353.c [new file with mode: 0644]
drivers/media/dvb/frontends/zl10353.h [new file with mode: 0644]
drivers/media/dvb/frontends/zl10353_priv.h [new file with mode: 0644]
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget.c
drivers/media/dvb/ttpci/budget.h
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/radio/miropcm20-rds-core.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/arv.c
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-driver.c
drivers/media/video/bttv-input.c
drivers/media/video/bttv-risc.c
drivers/media/video/bw-qcam.c
drivers/media/video/bw-qcam.h
drivers/media/video/c-qcam.c
drivers/media/video/cpia.c
drivers/media/video/cpia.h
drivers/media/video/cpia2/Makefile [new file with mode: 0644]
drivers/media/video/cpia2/cpia2.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_core.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_registers.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_usb.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_v4l.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2dev.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2patch.h [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx25840/cx25840-vbi.c
drivers/media/video/cx25840/cx25840.h
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/media/video/msp3400-driver.c
drivers/media/video/msp3400-kthreads.c
drivers/media/video/msp3400.h
drivers/media/video/mxb.c
drivers/media/video/planb.c
drivers/media/video/planb.h
drivers/media/video/pms.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7115.c
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-oss.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda8290.c
drivers/media/video/tuner-core.c
drivers/media/video/tuner-simple.c
drivers/media/video/tuner-types.c
drivers/media/video/tvaudio.c
drivers/media/video/tvp5150.c
drivers/media/video/tvp5150_reg.h
drivers/media/video/v4l2-common.c
drivers/media/video/video-buf-dvb.c
drivers/media/video/video-buf.c
drivers/media/video/videodev.c
drivers/media/video/vino.c
include/linux/dvb/audio.h
include/linux/dvb/video.h
include/linux/videodev2.h
include/media/ir-common.h
include/media/saa7146.h
include/media/tuner-types.h
include/media/tuner.h
include/media/v4l2-common.h
include/media/video-buf-dvb.h
include/media/video-buf.h

index 3f8fb68..53e53f2 100644 (file)
@@ -30,3 +30,5 @@ include/linux/autoconf.h
 include/linux/compile.h
 include/linux/version.h
 
+# stgit generated dirs
+patches-*
index 068070f..8bab846 100644 (file)
@@ -1,4 +1,3 @@
-
 HOWTO: Get An Avermedia DVB-T working under Linux
           ______________________________________________
 
@@ -137,11 +136,8 @@ Getting the card going
    To  power  up  the  card,  load  the  following modules in the
    following order:
 
-     * insmod dvb-core.o
-     * modprobe bttv.o
-     * insmod bt878.o
-     * insmod dvb-bt8xx.o
-     * insmod sp887x.o
+     * modprobe bttv (normally loaded automatically)
+     * modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules)
 
    Insertion  of  these  modules  into  the  running  kernel will
    activate the appropriate DVB device nodes. It is then possible
@@ -302,4 +298,4 @@ Further Update
    Many  thanks to Nigel Pearson for the updates to this document
    since the recent revision of the driver.
 
-   January 29th 2004
+   February 14th 2006
index 75c28a1..bb55f49 100644 (file)
@@ -21,8 +21,9 @@
 use File::Temp qw/ tempdir /;
 use IO::Handle;
 
-@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
-               "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
+@components = ( "sp8870", "sp887x", "tda10045", "tda10046",
+               "tda10046lifeview", "av7110", "dec2000t", "dec2540t",
+               "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
                "or51211", "or51132_qam", "or51132_vsb", "bluebird");
 
 # Check args
@@ -126,6 +127,24 @@ sub tda10046 {
     $outfile;
 }
 
+sub tda10046lifeview {
+    my $sourcefile = "Drv_2.11.02.zip";
+    my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile";
+    my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
+    my $outfile = "dvb-fe-tda10046.fw";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+    checkstandard();
+
+    wgetfile($sourcefile, $url);
+    unzip($sourcefile, $tmpdir);
+    extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp");
+    verify("$tmpdir/fwtmp", $hash);
+    copy("$tmpdir/fwtmp", $outfile);
+
+    $outfile;
+}
+
 sub av7110 {
     my $sourcefile = "dvb-ttpci-01.fw-261d";
     my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
index f5c50b2..0b0380c 100644 (file)
@@ -20,11 +20,23 @@ http://linuxtv.org/downloads/
 
 What's inside this directory:
 
+"avermedia.txt"
+contains detailed information about the
+Avermedia DVB-T cards. See also "bt8xx.txt".
+
+"bt8xx.txt"
+contains detailed information about the
+various bt8xx based "budget" DVB cards.
+
 "cards.txt"
 contains a list of supported hardware.
 
+"ci.txt"
+contains detailed information about the
+CI module as part from TwinHan cards and Clones.
+
 "contributors.txt"
-is the who-is-who of DVB development
+is the who-is-who of DVB development.
 
 "faq.txt"
 contains frequently asked questions and their answers.
@@ -34,19 +46,17 @@ script to download and extract firmware for those devices
 that require it.
 
 "ttusb-dec.txt"
-contains detailed informations about the
+contains detailed information about the
 TT DEC2000/DEC3000 USB DVB hardware.
 
-"bt8xx.txt"
-contains detailed installation instructions for the
-various bt8xx based "budget" DVB cards
-(Nebula, Pinnacle PCTV, Twinhan DST)
-
-"README.dibusb"
-contains detailed information about adapters
-based on DiBcom reference design.
-
 "udev.txt"
 how to get DVB and udev up and running.
 
+"README.dvb-usb"
+contains detailed information about the DVB USB cards.
+
+"README.flexcop"
+contains detailed information about the
+Technisat- and Flexcop B2C2 drivers.
+
 Good luck and have fun!
index 8bea3fb..3b39a91 100644 (file)
@@ -43,3 +43,5 @@
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
  43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
  44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
+ 45 -> KWorld HardwareMpegTV XPert                         [17de:0840]
+ 46 -> DViCO FusionHDTV DVB-T Hybrid                       [18ac:db40,18ac:db44]
index a0c7cad..a302668 100644 (file)
@@ -8,3 +8,4 @@
   7 -> Leadtek Winfast USB II                   (em2800)
   8 -> Kworld USB2800                           (em2800)
   9 -> Pinnacle Dazzle DVC 90                   (em2820/em2840) [2304:0207]
+ 12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
index da4fb89..874ffc4 100644 (file)
@@ -83,3 +83,9 @@
  82 -> MSI TV@Anywhere plus                     [1462:6231]
  83 -> Terratec Cinergy 250 PCI TV              [153b:1160]
  84 -> LifeView FlyDVB Trio                     [5168:0319]
+ 85 -> AverTV DVB-T 777                         [1461:2c05]
+ 86 -> LifeView FlyDVB-T                        [5168:0301]
+ 87 -> ADS Instant TV Duo Cardbus PTV331        [0331:1421]
+ 88 -> Tevion/KWorld DVB-T 220RF                [17de:7201]
+ 89 -> ELSA EX-VISION 700TV                     [1048:226c]
+ 90 -> Kworld ATSC110                           [17de:7350]
index f6d0cf7..603f165 100644 (file)
@@ -69,3 +69,5 @@ tuner=67 - Philips TD1316 Hybrid Tuner
 tuner=68 - Philips TUV1236D ATSC/NTSC dual in
 tuner=69 - Tena TNF 5335 MF
 tuner=70 - Samsung TCPN 2121P30A
+tuner=71 - Xceive xc3028
+tuner=72 - Thomson FE6600
diff --git a/Documentation/video4linux/README.cpia2 b/Documentation/video4linux/README.cpia2
new file mode 100644 (file)
index 0000000..ce8213d
--- /dev/null
@@ -0,0 +1,130 @@
+$Id: README,v 1.7 2005/08/29 23:39:57 sbertin Exp $
+
+1. Introduction
+
+       This is a driver for STMicroelectronics's CPiA2 (second generation
+Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG
+stream at up to vga size. It implements the Video4Linux interface as much as
+possible.  Since the V4L interface does not support compressed formats, only
+an mjpeg enabled application can be used with the camera. We have modified the
+gqcam application to view this stream.
+
+       The driver is implemented as two kernel modules. The cpia2 module
+contains the camera functions and the V4L interface.  The cpia2_usb module
+contains usb specific functions.  The main reason for this was the size of the
+module was getting out of hand, so I separted them.  It is not likely that
+there will be a parallel port version.
+
+FEATURES:
+   - Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos
+     sensors. I only have the vga sensor, so can't test the other.
+   - Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between.
+     VGA and QVGA are the native image sizes for the VGA camera. CIF is done
+     in the coprocessor by scaling QVGA.  All other sizes are done by clipping.
+   - Palette: YCrCb, compressed with MJPEG.
+   - Some compression parameters are settable.
+   - Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA).
+   - Adjust brightness, color, contrast while streaming.
+   - Flicker control settable for 50 or 60 Hz mains frequency.
+
+2. Making and installing the stv672 driver modules:
+
+       Requirements:
+       -------------
+       This should work with 2.4 (2.4.23 and later) and 2.6 kernels, but has
+only been tested on 2.6.  Video4Linux must be either compiled into the kernel or
+available as a module.  Video4Linux2 is automatically detected and made
+available at compile time.
+
+       Compiling:
+       ----------
+       As root, do a make install.  This will compile and install the modules
+into the media/video directory in the module tree. For 2.4 kernels, use
+Makefile_2.4 (aka do make -f Makefile_2.4 install).
+
+       Setup:
+       ------
+       Use 'modprobe cpia2' to load and 'modprobe -r cpia2' to unload. This
+may be done automatically by your distribution.
+
+3. Driver options
+
+       Option          Description
+       ------          -----------
+       video_nr        video device to register (0=/dev/video0, etc)
+                       range -1 to 64.  default is -1 (first available)
+                       If you have more than 1 camera, this MUST be -1.
+       buffer_size     Size for each frame buffer in bytes (default 68k)
+       num_buffers     Number of frame buffers (1-32, default 3)
+       alternate       USB Alternate (2-7, default 7)
+       flicker_freq    Frequency for flicker reduction(50 or 60, default 60)
+       flicker_mode    0 to disable, or 1 to enable flicker reduction.
+                       (default 0). This is only effective if the camera
+                       uses a stv0672 coprocessor.
+
+       Setting the options:
+       --------------------
+       If you are using modules, edit /etc/modules.conf and add an options
+line like this:
+       options cpia2 num_buffers=3 buffer_size=65535
+
+       If the driver is compiled into the kernel, at boot time specify them
+like this:
+       cpia2.num_buffers=3 cpia2.buffer_size=65535
+
+       What buffer size should I use?
+       ------------------------------
+       The maximum image size depends on the alternate you choose, and the
+frame rate achieved by the camera.  If the compression engine is able to
+keep up with the frame rate, the maximum image size is given by the table
+below.
+       The compression engine starts out at maximum compression, and will
+increase image quality until it is close to the size in the table.  As long
+as the compression engine can keep up with the frame rate, after a short time
+the images will all be about the size in the table, regardless of resolution.
+       At low alternate settings, the compression engine may not be able to
+compress the image enough and will reduce the frame rate by producing larger
+images.
+       The default of 68k should be good for most users.  This will handle
+any alternate at frame rates down to 15fps.  For lower frame rates, it may
+be necessary to increase the buffer size to avoid having frames dropped due
+to insufficient space.
+
+                            Image size(bytes)
+       Alternate  bytes/ms   15fps    30fps
+           2         128      8533     4267
+           3         384     25600    12800
+           4         640     42667    21333
+           5         768     51200    25600
+           6         896     59733    29867
+           7        1023     68200    34100
+
+       How many buffers should I use?
+       ------------------------------
+       For normal streaming, 3 should give the best results.  With only 2,
+it is possible for the camera to finish sending one image just after a
+program has started reading the other.  If this happens, the driver must drop
+a frame.  The exception to this is if you have a heavily loaded machine.  In
+this case use 2 buffers.  You are probably not reading at the full frame rate.
+If the camera can send multiple images before a read finishes, it could
+overwrite the third buffer before the read finishes, leading to a corrupt
+image.  Single and double buffering have extra checks to avoid overwriting.
+
+4. Using the camera
+
+       We are providing a modified gqcam application to view the output. In
+order to avoid confusion, here it is called mview.  There is also the qx5view
+program which can also control the lights on the qx5 microscope. MJPEG Tools
+(http://mjpeg.sourceforge.net) can also be used to record from the camera.
+
+5. Notes to developers:
+
+   - This is a driver version stripped of the 2.4 back compatibility
+     and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
+
+6. Thanks:
+
+   - Peter Pregler <Peter_Pregler@email.com>,
+     Scott J. Bertin <scottbertin@yahoo.com>, and
+     Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
+     this one was modelled from.
diff --git a/Documentation/video4linux/cpia2_overview.txt b/Documentation/video4linux/cpia2_overview.txt
new file mode 100644 (file)
index 0000000..a6e5366
--- /dev/null
@@ -0,0 +1,38 @@
+                       Programmer's View of Cpia2
+
+Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
+division of ST Microelectronics).  There are two versions.  The first is the
+STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
+up to CIF, and 15 fps for VGA frames.  The STV0676 is an improved version,
+which can handle up to 30 fps VGA.  Both coprocessors can be attached to two
+CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor.  These will
+be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
+
+The two chipsets operate almost identically.  The core is an 8051 processor,
+running two different versions of firmware.  The 672 runs the VP4 video
+processor code, the 676 runs VP5.  There are a few differences in register
+mappings for the two chips.  In these cases, the symbols defined in the
+header files are marked with VP4 or VP5 as part of the symbol name.
+
+The cameras appear externally as three sets of registers. Setting register
+values is the only way to control the camera.  Some settings are
+interdependant, such as the sequence required to power up the camera. I will
+try to make note of all of these cases.
+
+The register sets are called blocks.  Block 0 is the system block.  This
+section is always powered on when the camera is plugged in.  It contains
+registers that control housekeeping functions such as powering up the video
+processor.  The video processor is the VP block.  These registers control
+how the video from the sensor is processed.  Examples are timing registers,
+user mode (vga, qvga), scaling, cropping, framerates, and so on.  The last
+block is the video compressor (VC).  The video stream sent from the camera is
+compressed as Motion JPEG (JPEGA).  The VC controls all of the compression
+parameters.  Looking at the file cpia2_registers.h, you can get a full view
+of these registers and the possible values for most of them.
+
+One or more registers can be set or read by sending a usb control message to
+the camera.  There are three modes for this.  Block mode requests a number
+of contiguous registers.  Random mode reads or writes random registers with
+a tuple structure containing address/value pairs.  The repeat mode is only
+used by VP4 to load a firmware patch.  It contains a starting address and
+a sequence of bytes to be written into a gpio port.
\ No newline at end of file
index bd458cb..61b8961 100644 (file)
@@ -1,5 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
+ir-common-objs  := ir-functions.o ir-keymaps.o
 
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
deleted file mode 100644 (file)
index 97fa3fc..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/string.h>
-#include <media/ir-common.h>
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static int repeat = 1;
-module_param(repeat, int, 0444);
-MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
-
-static int debug = 0;    /* debug level (0,1,2) */
-module_param(debug, int, 0644);
-
-#define dprintk(level, fmt, arg...)    if (debug >= level) \
-       printk(KERN_DEBUG fmt , ## arg)
-
-/* -------------------------------------------------------------------------- */
-
-/* generic RC5 keytable                                          */
-/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
-/* used by old (black) Hauppauge remotes                         */
-IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 0x00 ] = KEY_KP0,
-       [ 0x01 ] = KEY_KP1,
-       [ 0x02 ] = KEY_KP2,
-       [ 0x03 ] = KEY_KP3,
-       [ 0x04 ] = KEY_KP4,
-       [ 0x05 ] = KEY_KP5,
-       [ 0x06 ] = KEY_KP6,
-       [ 0x07 ] = KEY_KP7,
-       [ 0x08 ] = KEY_KP8,
-       [ 0x09 ] = KEY_KP9,
-
-       [ 0x0b ] = KEY_CHANNEL,         /* channel / program (japan: 11) */
-       [ 0x0c ] = KEY_POWER,           /* standby */
-       [ 0x0d ] = KEY_MUTE,            /* mute / demute */
-       [ 0x0f ] = KEY_TV,              /* display */
-       [ 0x10 ] = KEY_VOLUMEUP,
-       [ 0x11 ] = KEY_VOLUMEDOWN,
-       [ 0x12 ] = KEY_BRIGHTNESSUP,
-       [ 0x13 ] = KEY_BRIGHTNESSDOWN,
-       [ 0x1e ] = KEY_SEARCH,          /* search + */
-       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
-       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
-       [ 0x22 ] = KEY_CHANNEL,         /* alt / channel */
-       [ 0x23 ] = KEY_LANGUAGE,        /* 1st / 2nd language */
-       [ 0x26 ] = KEY_SLEEP,           /* sleeptimer */
-       [ 0x2e ] = KEY_MENU,            /* 2nd controls (USA: menu) */
-       [ 0x30 ] = KEY_PAUSE,
-       [ 0x32 ] = KEY_REWIND,
-       [ 0x33 ] = KEY_GOTO,
-       [ 0x35 ] = KEY_PLAY,
-       [ 0x36 ] = KEY_STOP,
-       [ 0x37 ] = KEY_RECORD,          /* recording */
-       [ 0x3c ] = KEY_TEXT,            /* teletext submode (Japan: 12) */
-       [ 0x3d ] = KEY_SUSPEND,         /* system standby */
-
-};
-EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
-
-/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 18 ] = KEY_KP0,
-       [  5 ] = KEY_KP1,
-       [  6 ] = KEY_KP2,
-       [  7 ] = KEY_KP3,
-       [  9 ] = KEY_KP4,
-       [ 10 ] = KEY_KP5,
-       [ 11 ] = KEY_KP6,
-       [ 13 ] = KEY_KP7,
-       [ 14 ] = KEY_KP8,
-       [ 15 ] = KEY_KP9,
-
-       [  0 ] = KEY_POWER,
-       [  2 ] = KEY_TUNER,             /* TV/FM */
-       [ 30 ] = KEY_VIDEO,
-       [  4 ] = KEY_VOLUMEUP,
-       [  8 ] = KEY_VOLUMEDOWN,
-       [ 12 ] = KEY_CHANNELUP,
-       [ 16 ] = KEY_CHANNELDOWN,
-       [  3 ] = KEY_ZOOM,              /* fullscreen */
-       [ 31 ] = KEY_SUBTITLE,          /* closed caption/teletext */
-       [ 32 ] = KEY_SLEEP,
-       [ 20 ] = KEY_MUTE,
-       [ 43 ] = KEY_RED,
-       [ 44 ] = KEY_GREEN,
-       [ 45 ] = KEY_YELLOW,
-       [ 46 ] = KEY_BLUE,
-       [ 24 ] = KEY_KPPLUS,            /* fine tune + */
-       [ 25 ] = KEY_KPMINUS,           /* fine tune - */
-       [ 33 ] = KEY_KPDOT,
-       [ 19 ] = KEY_KPENTER,
-       [ 34 ] = KEY_BACK,
-       [ 35 ] = KEY_PLAYPAUSE,
-       [ 36 ] = KEY_NEXT,
-       [ 38 ] = KEY_STOP,
-       [ 39 ] = KEY_RECORD
-};
-EXPORT_SYMBOL_GPL(ir_codes_winfast);
-
-IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
-       [ 0x59 ] = KEY_MUTE,
-       [ 0x4a ] = KEY_POWER,
-
-       [ 0x18 ] = KEY_TEXT,
-       [ 0x26 ] = KEY_TV,
-       [ 0x3d ] = KEY_PRINT,
-
-       [ 0x48 ] = KEY_RED,
-       [ 0x04 ] = KEY_GREEN,
-       [ 0x11 ] = KEY_YELLOW,
-       [ 0x00 ] = KEY_BLUE,
-
-       [ 0x2d ] = KEY_VOLUMEUP,
-       [ 0x1e ] = KEY_VOLUMEDOWN,
-
-       [ 0x49 ] = KEY_MENU,
-
-       [ 0x16 ] = KEY_CHANNELUP,
-       [ 0x17 ] = KEY_CHANNELDOWN,
-
-       [ 0x20 ] = KEY_UP,
-       [ 0x21 ] = KEY_DOWN,
-       [ 0x22 ] = KEY_LEFT,
-       [ 0x23 ] = KEY_RIGHT,
-       [ 0x0d ] = KEY_SELECT,
-
-
-
-       [ 0x08 ] = KEY_BACK,
-       [ 0x07 ] = KEY_REFRESH,
-
-       [ 0x2f ] = KEY_ZOOM,
-       [ 0x29 ] = KEY_RECORD,
-
-       [ 0x4b ] = KEY_PAUSE,
-       [ 0x4d ] = KEY_REWIND,
-       [ 0x2e ] = KEY_PLAY,
-       [ 0x4e ] = KEY_FORWARD,
-       [ 0x53 ] = KEY_PREVIOUS,
-       [ 0x4c ] = KEY_STOP,
-       [ 0x54 ] = KEY_NEXT,
-
-       [ 0x69 ] = KEY_KP0,
-       [ 0x6a ] = KEY_KP1,
-       [ 0x6b ] = KEY_KP2,
-       [ 0x6c ] = KEY_KP3,
-       [ 0x6d ] = KEY_KP4,
-       [ 0x6e ] = KEY_KP5,
-       [ 0x6f ] = KEY_KP6,
-       [ 0x70 ] = KEY_KP7,
-       [ 0x71 ] = KEY_KP8,
-       [ 0x72 ] = KEY_KP9,
-
-       [ 0x74 ] = KEY_CHANNEL,
-       [ 0x0a ] = KEY_BACKSPACE,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
-
-/* empty keytable, can be used as placeholder for not-yet created keytables */
-IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
-       [ 42 ] = KEY_COFFEE,
-};
-EXPORT_SYMBOL_GPL(ir_codes_empty);
-
-/* Hauppauge: the newer, gray remotes (seems there are multiple
- * slightly different versions), shipped with cx88+ivtv cards.
- * almost rc5 coding, but some non-standard keys */
-IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 0x00 ] = KEY_KP0,
-       [ 0x01 ] = KEY_KP1,
-       [ 0x02 ] = KEY_KP2,
-       [ 0x03 ] = KEY_KP3,
-       [ 0x04 ] = KEY_KP4,
-       [ 0x05 ] = KEY_KP5,
-       [ 0x06 ] = KEY_KP6,
-       [ 0x07 ] = KEY_KP7,
-       [ 0x08 ] = KEY_KP8,
-       [ 0x09 ] = KEY_KP9,
-
-       [ 0x0a ] = KEY_TEXT,            /* keypad asterisk as well */
-       [ 0x0b ] = KEY_RED,             /* red button */
-       [ 0x0c ] = KEY_RADIO,
-       [ 0x0d ] = KEY_MENU,
-       [ 0x0e ] = KEY_SUBTITLE,        /* also the # key */
-       [ 0x0f ] = KEY_MUTE,
-       [ 0x10 ] = KEY_VOLUMEUP,
-       [ 0x11 ] = KEY_VOLUMEDOWN,
-       [ 0x12 ] = KEY_PREVIOUS,        /* previous channel */
-       [ 0x14 ] = KEY_UP,
-       [ 0x15 ] = KEY_DOWN,
-       [ 0x16 ] = KEY_LEFT,
-       [ 0x17 ] = KEY_RIGHT,
-       [ 0x18 ] = KEY_VIDEO,           /* Videos */
-       [ 0x19 ] = KEY_AUDIO,           /* Music */
-       /* 0x1a: Pictures - presume this means
-          "Multimedia Home Platform" -
-          no "PICTURES" key in input.h
-        */
-       [ 0x1a ] = KEY_MHP,
-
-       [ 0x1b ] = KEY_EPG,             /* Guide */
-       [ 0x1c ] = KEY_TV,
-       [ 0x1e ] = KEY_NEXTSONG,        /* skip >| */
-       [ 0x1f ] = KEY_EXIT,            /* back/exit */
-       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
-       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
-       [ 0x22 ] = KEY_CHANNEL,         /* source (old black remote) */
-       [ 0x24 ] = KEY_PREVIOUSSONG,    /* replay |< */
-       [ 0x25 ] = KEY_ENTER,           /* OK */
-       [ 0x26 ] = KEY_SLEEP,           /* minimize (old black remote) */
-       [ 0x29 ] = KEY_BLUE,            /* blue key */
-       [ 0x2e ] = KEY_GREEN,           /* green button */
-       [ 0x30 ] = KEY_PAUSE,           /* pause */
-       [ 0x32 ] = KEY_REWIND,          /* backward << */
-       [ 0x34 ] = KEY_FASTFORWARD,     /* forward >> */
-       [ 0x35 ] = KEY_PLAY,
-       [ 0x36 ] = KEY_STOP,
-       [ 0x37 ] = KEY_RECORD,          /* recording */
-       [ 0x38 ] = KEY_YELLOW,          /* yellow key */
-       [ 0x3b ] = KEY_SELECT,          /* top right button */
-       [ 0x3c ] = KEY_ZOOM,            /* full */
-       [ 0x3d ] = KEY_POWER,           /* system power (green button) */
-};
-EXPORT_SYMBOL(ir_codes_hauppauge_new);
-
-IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
-       [  2 ] = KEY_KP0,
-       [  1 ] = KEY_KP1,
-       [ 11 ] = KEY_KP2,
-       [ 27 ] = KEY_KP3,
-       [  5 ] = KEY_KP4,
-       [  9 ] = KEY_KP5,
-       [ 21 ] = KEY_KP6,
-       [  6 ] = KEY_KP7,
-       [ 10 ] = KEY_KP8,
-       [ 18 ] = KEY_KP9,
-
-       [  3 ] = KEY_TUNER,             /* TV/FM */
-       [  7 ] = KEY_SEARCH,            /* scan */
-       [ 28 ] = KEY_ZOOM,              /* full screen */
-       [ 30 ] = KEY_POWER,
-       [ 23 ] = KEY_VOLUMEDOWN,
-       [ 31 ] = KEY_VOLUMEUP,
-       [ 20 ] = KEY_CHANNELDOWN,
-       [ 22 ] = KEY_CHANNELUP,
-       [ 24 ] = KEY_MUTE,
-
-       [  0 ] = KEY_LIST,              /* source */
-       [ 19 ] = KEY_INFO,              /* loop */
-       [ 16 ] = KEY_LAST,              /* +100 */
-       [ 13 ] = KEY_CLEAR,             /* reset */
-       [ 12 ] = BTN_RIGHT,             /* fun++ */
-       [  4 ] = BTN_LEFT,              /* fun-- */
-       [ 14 ] = KEY_GOTO,              /* function */
-       [ 15 ] = KEY_STOP,              /* freeze */
-};
-EXPORT_SYMBOL(ir_codes_pixelview);
-
-/* -------------------------------------------------------------------------- */
-
-static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
-{
-       if (KEY_RESERVED == ir->keycode) {
-               printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
-                      dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
-               return;
-       }
-       dprintk(1,"%s: key event code=%d down=%d\n",
-               dev->name,ir->keycode,ir->keypressed);
-       input_report_key(dev,ir->keycode,ir->keypressed);
-       input_sync(dev);
-}
-
-/* -------------------------------------------------------------------------- */
-
-void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-                  int ir_type, IR_KEYTAB_TYPE *ir_codes)
-{
-       int i;
-
-       ir->ir_type = ir_type;
-       if (ir_codes)
-               memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
-
-
-       dev->keycode     = ir->ir_codes;
-       dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
-       dev->keycodemax  = IR_KEYTAB_SIZE;
-       for (i = 0; i < IR_KEYTAB_SIZE; i++)
-               set_bit(ir->ir_codes[i], dev->keybit);
-       clear_bit(0, dev->keybit);
-
-       set_bit(EV_KEY, dev->evbit);
-       if (repeat)
-               set_bit(EV_REP, dev->evbit);
-}
-
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
-{
-       if (ir->keypressed) {
-               ir->keypressed = 0;
-               ir_input_key_event(dev,ir);
-       }
-}
-
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
-                     u32 ir_key, u32 ir_raw)
-{
-       u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
-
-       if (ir->keypressed && ir->keycode != keycode) {
-               ir->keypressed = 0;
-               ir_input_key_event(dev,ir);
-       }
-       if (!ir->keypressed) {
-               ir->ir_key  = ir_key;
-               ir->ir_raw  = ir_raw;
-               ir->keycode = keycode;
-               ir->keypressed = 1;
-               ir_input_key_event(dev,ir);
-       }
-}
-
-/* -------------------------------------------------------------------------- */
-
-u32 ir_extract_bits(u32 data, u32 mask)
-{
-       int mbit, vbit;
-       u32 value;
-
-       value = 0;
-       vbit  = 0;
-       for (mbit = 0; mbit < 32; mbit++) {
-               if (!(mask & ((u32)1 << mbit)))
-                       continue;
-               if (data & ((u32)1 << mbit))
-                       value |= (1 << vbit);
-               vbit++;
-       }
-       return value;
-}
-
-static int inline getbit(u32 *samples, int bit)
-{
-       return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
-}
-
-/* sump raw samples for visual debugging ;) */
-int ir_dump_samples(u32 *samples, int count)
-{
-       int i, bit, start;
-
-       printk(KERN_DEBUG "ir samples: ");
-       start = 0;
-       for (i = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit)
-                       start = 1;
-               if (0 == start)
-                       continue;
-               printk("%s", bit ? "#" : "_");
-       }
-       printk("\n");
-       return 0;
-}
-
-/* decode raw samples, pulse distance coding used by NEC remotes */
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
-{
-       int i,last,bit,len;
-       u32 curBit;
-       u32 value;
-
-       /* find start burst */
-       for (i = len = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit) {
-                       len++;
-               } else {
-                       if (len >= 29)
-                               break;
-                       len = 0;
-               }
-       }
-
-       /* start burst to short */
-       if (len < 29)
-               return 0xffffffff;
-
-       /* find start silence */
-       for (len = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit) {
-                       break;
-               } else {
-                       len++;
-               }
-       }
-
-       /* silence to short */
-       if (len < 7)
-               return 0xffffffff;
-
-       /* go decoding */
-       len   = 0;
-       last = 1;
-       value = 0; curBit = 1;
-       for (; i < count * 32; i++) {
-               bit  = getbit(samples,i);
-               if (last) {
-                       if(bit) {
-                               continue;
-                       } else {
-                               len = 1;
-                       }
-               } else {
-                       if (bit) {
-                               if (len > (low + high) /2)
-                                       value |= curBit;
-                               curBit <<= 1;
-                               if (curBit == 1)
-                                       break;
-                       } else {
-                               len++;
-                       }
-               }
-               last = bit;
-       }
-
-       return value;
-}
-
-/* decode raw samples, biphase coding, used by rc5 for example */
-int ir_decode_biphase(u32 *samples, int count, int low, int high)
-{
-       int i,last,bit,len,flips;
-       u32 value;
-
-       /* find start bit (1) */
-       for (i = 0; i < 32; i++) {
-               bit = getbit(samples,i);
-               if (bit)
-                       break;
-       }
-
-       /* go decoding */
-       len   = 0;
-       flips = 0;
-       value = 1;
-       for (; i < count * 32; i++) {
-               if (len > high)
-                       break;
-               if (flips > 1)
-                       break;
-               last = bit;
-               bit  = getbit(samples,i);
-               if (last == bit) {
-                       len++;
-                       continue;
-               }
-               if (len < low) {
-                       len++;
-                       flips++;
-                       continue;
-               }
-               value <<= 1;
-               value |= bit;
-               flips = 0;
-               len   = 1;
-       }
-       return value;
-}
-
-EXPORT_SYMBOL_GPL(ir_input_init);
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
new file mode 100644 (file)
index 0000000..397cff8
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ *
+ * some common structs and functions to handle infrared remotes via
+ * input layer ...
+ *
+ * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <media/ir-common.h>
+
+/* -------------------------------------------------------------------------- */
+
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_LICENSE("GPL");
+
+static int repeat = 1;
+module_param(repeat, int, 0444);
+MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
+
+static int debug = 0;    /* debug level (0,1,2) */
+module_param(debug, int, 0644);
+
+#define dprintk(level, fmt, arg...)    if (debug >= level) \
+       printk(KERN_DEBUG fmt , ## arg)
+
+/* -------------------------------------------------------------------------- */
+
+static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
+{
+       if (KEY_RESERVED == ir->keycode) {
+               printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
+                      dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
+               return;
+       }
+       dprintk(1,"%s: key event code=%d down=%d\n",
+               dev->name,ir->keycode,ir->keypressed);
+       input_report_key(dev,ir->keycode,ir->keypressed);
+       input_sync(dev);
+}
+
+/* -------------------------------------------------------------------------- */
+
+void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
+                  int ir_type, IR_KEYTAB_TYPE *ir_codes)
+{
+       int i;
+
+       ir->ir_type = ir_type;
+       if (ir_codes)
+               memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
+
+
+       dev->keycode     = ir->ir_codes;
+       dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
+       dev->keycodemax  = IR_KEYTAB_SIZE;
+       for (i = 0; i < IR_KEYTAB_SIZE; i++)
+               set_bit(ir->ir_codes[i], dev->keybit);
+       clear_bit(0, dev->keybit);
+
+       set_bit(EV_KEY, dev->evbit);
+       if (repeat)
+               set_bit(EV_REP, dev->evbit);
+}
+
+void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
+{
+       if (ir->keypressed) {
+               ir->keypressed = 0;
+               ir_input_key_event(dev,ir);
+       }
+}
+
+void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
+                     u32 ir_key, u32 ir_raw)
+{
+       u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
+
+       if (ir->keypressed && ir->keycode != keycode) {
+               ir->keypressed = 0;
+               ir_input_key_event(dev,ir);
+       }
+       if (!ir->keypressed) {
+               ir->ir_key  = ir_key;
+               ir->ir_raw  = ir_raw;
+               ir->keycode = keycode;
+               ir->keypressed = 1;
+               ir_input_key_event(dev,ir);
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+u32 ir_extract_bits(u32 data, u32 mask)
+{
+       int mbit, vbit;
+       u32 value;
+
+       value = 0;
+       vbit  = 0;
+       for (mbit = 0; mbit < 32; mbit++) {
+               if (!(mask & ((u32)1 << mbit)))
+                       continue;
+               if (data & ((u32)1 << mbit))
+                       value |= (1 << vbit);
+               vbit++;
+       }
+       return value;
+}
+
+static int inline getbit(u32 *samples, int bit)
+{
+       return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
+}
+
+/* sump raw samples for visual debugging ;) */
+int ir_dump_samples(u32 *samples, int count)
+{
+       int i, bit, start;
+
+       printk(KERN_DEBUG "ir samples: ");
+       start = 0;
+       for (i = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit)
+                       start = 1;
+               if (0 == start)
+                       continue;
+               printk("%s", bit ? "#" : "_");
+       }
+       printk("\n");
+       return 0;
+}
+
+/* decode raw samples, pulse distance coding used by NEC remotes */
+int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
+{
+       int i,last,bit,len;
+       u32 curBit;
+       u32 value;
+
+       /* find start burst */
+       for (i = len = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit) {
+                       len++;
+               } else {
+                       if (len >= 29)
+                               break;
+                       len = 0;
+               }
+       }
+
+       /* start burst to short */
+       if (len < 29)
+               return 0xffffffff;
+
+       /* find start silence */
+       for (len = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit) {
+                       break;
+               } else {
+                       len++;
+               }
+       }
+
+       /* silence to short */
+       if (len < 7)
+               return 0xffffffff;
+
+       /* go decoding */
+       len   = 0;
+       last = 1;
+       value = 0; curBit = 1;
+       for (; i < count * 32; i++) {
+               bit  = getbit(samples,i);
+               if (last) {
+                       if(bit) {
+                               continue;
+                       } else {
+                               len = 1;
+                       }
+               } else {
+                       if (bit) {
+                               if (len > (low + high) /2)
+                                       value |= curBit;
+                               curBit <<= 1;
+                               if (curBit == 1)
+                                       break;
+                       } else {
+                               len++;
+                       }
+               }
+               last = bit;
+       }
+
+       return value;
+}
+
+/* decode raw samples, biphase coding, used by rc5 for example */
+int ir_decode_biphase(u32 *samples, int count, int low, int high)
+{
+       int i,last,bit,len,flips;
+       u32 value;
+
+       /* find start bit (1) */
+       for (i = 0; i < 32; i++) {
+               bit = getbit(samples,i);
+               if (bit)
+                       break;
+       }
+
+       /* go decoding */
+       len   = 0;
+       flips = 0;
+       value = 1;
+       for (; i < count * 32; i++) {
+               if (len > high)
+                       break;
+               if (flips > 1)
+                       break;
+               last = bit;
+               bit  = getbit(samples,i);
+               if (last == bit) {
+                       len++;
+                       continue;
+               }
+               if (len < low) {
+                       len++;
+                       flips++;
+                       continue;
+               }
+               value <<= 1;
+               value |= bit;
+               flips = 0;
+               len   = 1;
+       }
+       return value;
+}
+
+EXPORT_SYMBOL_GPL(ir_input_init);
+EXPORT_SYMBOL_GPL(ir_input_nokey);
+EXPORT_SYMBOL_GPL(ir_input_keydown);
+
+EXPORT_SYMBOL_GPL(ir_extract_bits);
+EXPORT_SYMBOL_GPL(ir_dump_samples);
+EXPORT_SYMBOL_GPL(ir_decode_biphase);
+EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
new file mode 100644 (file)
index 0000000..a294d5c
--- /dev/null
@@ -0,0 +1,1415 @@
+/*
+
+
+    Keytables for supported remote controls. This file is part of
+    video4linux.
+
+    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.
+
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/input.h>
+#include <media/ir-common.h>
+
+/* empty keytable, can be used as placeholder for not-yet created keytables */
+IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
+       [ 0x2a ] = KEY_COFFEE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_empty);
+
+/* Matt Jesson <dvb@jesson.eclipse.co.uk */
+IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
+       [ 0x28 ] = KEY_0,         //'0' / 'enter'
+       [ 0x22 ] = KEY_1,         //'1'
+       [ 0x12 ] = KEY_2,         //'2' / 'up arrow'
+       [ 0x32 ] = KEY_3,         //'3'
+       [ 0x24 ] = KEY_4,         //'4' / 'left arrow'
+       [ 0x14 ] = KEY_5,         //'5'
+       [ 0x34 ] = KEY_6,         //'6' / 'right arrow'
+       [ 0x26 ] = KEY_7,         //'7'
+       [ 0x16 ] = KEY_8,         //'8' / 'down arrow'
+       [ 0x36 ] = KEY_9,         //'9'
+
+       [ 0x20 ] = KEY_LIST,        // 'source'
+       [ 0x10 ] = KEY_TEXT,        // 'teletext'
+       [ 0x00 ] = KEY_POWER,       // 'power'
+       [ 0x04 ] = KEY_AUDIO,       // 'audio'
+       [ 0x06 ] = KEY_ZOOM,        // 'full screen'
+       [ 0x18 ] = KEY_VIDEO,       // 'display'
+       [ 0x38 ] = KEY_SEARCH,      // 'loop'
+       [ 0x08 ] = KEY_INFO,        // 'preview'
+       [ 0x2a ] = KEY_REWIND,      // 'backward <<'
+       [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
+       [ 0x3a ] = KEY_RECORD,      // 'capture'
+       [ 0x0a ] = KEY_MUTE,        // 'mute'
+       [ 0x2c ] = KEY_RECORD,      // 'record'
+       [ 0x1c ] = KEY_PAUSE,       // 'pause'
+       [ 0x3c ] = KEY_STOP,        // 'stop'
+       [ 0x0c ] = KEY_PLAY,        // 'play'
+       [ 0x2e ] = KEY_RED,         // 'red'
+       [ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
+       [ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
+       [ 0x21 ] = KEY_GREEN,       // 'green'
+       [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
+       [ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
+       [ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
+       [ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt);
+
+/* Attila Kondoros <attila.kondoros@chello.hu> */
+IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
+
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+       [ 0x00 ] = KEY_0,
+       [ 0x17 ] = KEY_LAST,        // +100
+       [ 0x0a ] = KEY_LIST,        // recall
+
+
+       [ 0x1c ] = KEY_TUNER,       // TV/FM
+       [ 0x15 ] = KEY_SEARCH,      // scan
+       [ 0x12 ] = KEY_POWER,       // power
+       [ 0x1f ] = KEY_VOLUMEDOWN,  // vol up
+       [ 0x1b ] = KEY_VOLUMEUP,    // vol down
+       [ 0x1e ] = KEY_CHANNELDOWN, // chn up
+       [ 0x1a ] = KEY_CHANNELUP,   // chn down
+
+       [ 0x11 ] = KEY_VIDEO,       // video
+       [ 0x0f ] = KEY_ZOOM,        // full screen
+       [ 0x13 ] = KEY_MUTE,        // mute/unmute
+       [ 0x10 ] = KEY_TEXT,        // min
+
+       [ 0x0d ] = KEY_STOP,        // freeze
+       [ 0x0e ] = KEY_RECORD,      // record
+       [ 0x1d ] = KEY_PLAYPAUSE,   // stop
+       [ 0x19 ] = KEY_PLAY,        // play
+
+       [ 0x16 ] = KEY_GOTO,        // osd
+       [ 0x14 ] = KEY_REFRESH,     // default
+       [ 0x0c ] = KEY_KPPLUS,      // fine tune >>>>
+       [ 0x18 ] = KEY_KPMINUS      // fine tune <<<<
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp);
+
+/* ---------------------------------------------------------------------- */
+
+IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
+
+       [ 0x1e ] = KEY_POWER,       // power
+       [ 0x07 ] = KEY_MEDIA,       // source
+       [ 0x1c ] = KEY_SEARCH,      // scan
+
+/* FIXME: duplicate keycodes?
+ *
+ * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
+ * The GPIO values are
+ * 6397fb for both "Scan <" and "CH -",
+ * 639ffb for "Scan >" and "CH+",
+ * 6384fb for "Tune <" and "<<<",
+ * 638cfb for "Tune >" and ">>>", regardless of the mask.
+ *
+ *     [ 0x17 ] = KEY_BACK,        // fm scan <<
+ *     [ 0x1f ] = KEY_FORWARD,     // fm scan >>
+ *
+ *     [ 0x04 ] = KEY_LEFT,        // fm tuning <
+ *     [ 0x0c ] = KEY_RIGHT,       // fm tuning >
+ *
+ * For now, these four keys are disabled. Pressing them will generate
+ * the CH+/CH-/<<</>>> events
+ */
+
+       [ 0x03 ] = KEY_TUNER,       // TV/FM
+
+       [ 0x00 ] = KEY_RECORD,
+       [ 0x08 ] = KEY_STOP,
+       [ 0x11 ] = KEY_PLAY,
+
+       [ 0x1a ] = KEY_PLAYPAUSE,   // freeze
+       [ 0x19 ] = KEY_ZOOM,        // zoom
+       [ 0x0f ] = KEY_TEXT,        // min
+
+       [ 0x01 ] = KEY_1,
+       [ 0x0b ] = KEY_2,
+       [ 0x1b ] = KEY_3,
+       [ 0x05 ] = KEY_4,
+       [ 0x09 ] = KEY_5,
+       [ 0x15 ] = KEY_6,
+       [ 0x06 ] = KEY_7,
+       [ 0x0a ] = KEY_8,
+       [ 0x12 ] = KEY_9,
+       [ 0x02 ] = KEY_0,
+       [ 0x10 ] = KEY_LAST,        // +100
+       [ 0x13 ] = KEY_LIST,        // recall
+
+       [ 0x1f ] = KEY_CHANNELUP,   // chn down
+       [ 0x17 ] = KEY_CHANNELDOWN, // chn up
+       [ 0x16 ] = KEY_VOLUMEUP,    // vol down
+       [ 0x14 ] = KEY_VOLUMEDOWN,  // vol up
+
+       [ 0x04 ] = KEY_KPMINUS,     // <<<
+       [ 0x0e ] = KEY_SETUP,       // function
+       [ 0x0c ] = KEY_KPPLUS,      // >>>
+
+       [ 0x0d ] = KEY_GOTO,        // mts
+       [ 0x1d ] = KEY_REFRESH,     // reset
+       [ 0x18 ] = KEY_MUTE         // mute/unmute
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pixelview);
+
+IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+       [ 0x0a ] = KEY_TV,
+       [ 0x0b ] = KEY_AUX,
+       [ 0x0c ] = KEY_DVD,
+       [ 0x0d ] = KEY_POWER,
+       [ 0x0e ] = KEY_MHP,     /* labelled 'Picture' */
+       [ 0x0f ] = KEY_AUDIO,
+       [ 0x10 ] = KEY_INFO,
+       [ 0x11 ] = KEY_F13,     /* 16:9 */
+       [ 0x12 ] = KEY_F14,     /* 14:9 */
+       [ 0x13 ] = KEY_EPG,
+       [ 0x14 ] = KEY_EXIT,
+       [ 0x15 ] = KEY_MENU,
+       [ 0x16 ] = KEY_UP,
+       [ 0x17 ] = KEY_DOWN,
+       [ 0x18 ] = KEY_LEFT,
+       [ 0x19 ] = KEY_RIGHT,
+       [ 0x1a ] = KEY_ENTER,
+       [ 0x1b ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_CHANNELDOWN,
+       [ 0x1d ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+       [ 0x1f ] = KEY_RED,
+       [ 0x20 ] = KEY_GREEN,
+       [ 0x21 ] = KEY_YELLOW,
+       [ 0x22 ] = KEY_BLUE,
+       [ 0x23 ] = KEY_SUBTITLE,
+       [ 0x24 ] = KEY_F15,     /* AD */
+       [ 0x25 ] = KEY_TEXT,
+       [ 0x26 ] = KEY_MUTE,
+       [ 0x27 ] = KEY_REWIND,
+       [ 0x28 ] = KEY_STOP,
+       [ 0x29 ] = KEY_PLAY,
+       [ 0x2a ] = KEY_FASTFORWARD,
+       [ 0x2b ] = KEY_F16,     /* chapter */
+       [ 0x2c ] = KEY_PAUSE,
+       [ 0x2d ] = KEY_PLAY,
+       [ 0x2e ] = KEY_RECORD,
+       [ 0x2f ] = KEY_F17,     /* picture in picture */
+       [ 0x30 ] = KEY_KPPLUS,  /* zoom in */
+       [ 0x31 ] = KEY_KPMINUS, /* zoom out */
+       [ 0x32 ] = KEY_F18,     /* capture */
+       [ 0x33 ] = KEY_F19,     /* web */
+       [ 0x34 ] = KEY_EMAIL,
+       [ 0x35 ] = KEY_PHONE,
+       [ 0x36 ] = KEY_PC
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_nebula);
+
+/* DigitalNow DNTV Live DVB-T Remote */
+IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_ESC,             /* 'go up a level?' */
+       /* Keys 0 to 9 */
+       [ 0x0a ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0b ] = KEY_TUNER,           /* tv/fm */
+       [ 0x0c ] = KEY_SEARCH,          /* scan */
+       [ 0x0d ] = KEY_STOP,
+       [ 0x0e ] = KEY_PAUSE,
+       [ 0x0f ] = KEY_LIST,            /* source */
+
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x11 ] = KEY_REWIND,          /* backward << */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_S,                       /* snap */
+       [ 0x14 ] = KEY_AUDIO,           /* stereo */
+       [ 0x15 ] = KEY_CLEAR,           /* reset */
+       [ 0x16 ] = KEY_PLAY,
+       [ 0x17 ] = KEY_ENTER,
+       [ 0x18 ] = KEY_ZOOM,            /* full screen */
+       [ 0x19 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1c ] = KEY_INFO,            /* preview */
+       [ 0x1d ] = KEY_RECORD,          /* record */
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t);
+
+/* ---------------------------------------------------------------------- */
+
+/* IO-DATA BCTV7E Remote */
+IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
+       [ 0x40 ] = KEY_TV,
+       [ 0x20 ] = KEY_RADIO,           /* FM */
+       [ 0x60 ] = KEY_EPG,
+       [ 0x00 ] = KEY_POWER,
+
+       /* Keys 0 to 9 */
+       [ 0x44 ] = KEY_0,               /* 10 */
+       [ 0x50 ] = KEY_1,
+       [ 0x30 ] = KEY_2,
+       [ 0x70 ] = KEY_3,
+       [ 0x48 ] = KEY_4,
+       [ 0x28 ] = KEY_5,
+       [ 0x68 ] = KEY_6,
+       [ 0x58 ] = KEY_7,
+       [ 0x38 ] = KEY_8,
+       [ 0x78 ] = KEY_9,
+
+       [ 0x10 ] = KEY_L,                       /* Live */
+       [ 0x08 ] = KEY_T,                       /* Time Shift */
+
+       [ 0x18 ] = KEY_PLAYPAUSE,               /* Play */
+
+       [ 0x24 ] = KEY_ENTER,           /* 11 */
+       [ 0x64 ] = KEY_ESC,             /* 12 */
+       [ 0x04 ] = KEY_M,                       /* Multi */
+
+       [ 0x54 ] = KEY_VIDEO,
+       [ 0x34 ] = KEY_CHANNELUP,
+       [ 0x74 ] = KEY_VOLUMEUP,
+       [ 0x14 ] = KEY_MUTE,
+
+       [ 0x4c ] = KEY_S,                       /* SVIDEO */
+       [ 0x2c ] = KEY_CHANNELDOWN,
+       [ 0x6c ] = KEY_VOLUMEDOWN,
+       [ 0x0c ] = KEY_ZOOM,
+
+       [ 0x5c ] = KEY_PAUSE,
+       [ 0x3c ] = KEY_C,                       /* || (red) */
+       [ 0x7c ] = KEY_RECORD,          /* recording */
+       [ 0x1c ] = KEY_STOP,
+
+       [ 0x41 ] = KEY_REWIND,          /* backward << */
+       [ 0x21 ] = KEY_PLAY,
+       [ 0x61 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x01 ] = KEY_NEXT,            /* skip >| */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e);
+
+/* ---------------------------------------------------------------------- */
+
+/* ADS Tech Instant TV DVB-T PCI Remote */
+IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x4d ] = KEY_0,
+       [ 0x57 ] = KEY_1,
+       [ 0x4f ] = KEY_2,
+       [ 0x53 ] = KEY_3,
+       [ 0x56 ] = KEY_4,
+       [ 0x4e ] = KEY_5,
+       [ 0x5e ] = KEY_6,
+       [ 0x54 ] = KEY_7,
+       [ 0x4c ] = KEY_8,
+       [ 0x5c ] = KEY_9,
+
+       [ 0x5b ] = KEY_POWER,
+       [ 0x5f ] = KEY_MUTE,
+       [ 0x55 ] = KEY_GOTO,
+       [ 0x5d ] = KEY_SEARCH,
+       [ 0x17 ] = KEY_EPG,             /* Guide */
+       [ 0x1f ] = KEY_MENU,
+       [ 0x0f ] = KEY_UP,
+       [ 0x46 ] = KEY_DOWN,
+       [ 0x16 ] = KEY_LEFT,
+       [ 0x1e ] = KEY_RIGHT,
+       [ 0x0e ] = KEY_SELECT,          /* Enter */
+       [ 0x5a ] = KEY_INFO,
+       [ 0x52 ] = KEY_EXIT,
+       [ 0x59 ] = KEY_PREVIOUS,
+       [ 0x51 ] = KEY_NEXT,
+       [ 0x58 ] = KEY_REWIND,
+       [ 0x50 ] = KEY_FORWARD,
+       [ 0x44 ] = KEY_PLAYPAUSE,
+       [ 0x07 ] = KEY_STOP,
+       [ 0x1b ] = KEY_RECORD,
+       [ 0x13 ] = KEY_TUNER,           /* Live */
+       [ 0x0a ] = KEY_A,
+       [ 0x12 ] = KEY_B,
+       [ 0x03 ] = KEY_PROG1,           /* 1 */
+       [ 0x01 ] = KEY_PROG2,           /* 2 */
+       [ 0x00 ] = KEY_PROG3,           /* 3 */
+       [ 0x06 ] = KEY_DVD,
+       [ 0x48 ] = KEY_AUX,             /* Photo */
+       [ 0x40 ] = KEY_VIDEO,
+       [ 0x19 ] = KEY_AUDIO,           /* Music */
+       [ 0x0b ] = KEY_CHANNELUP,
+       [ 0x08 ] = KEY_CHANNELDOWN,
+       [ 0x15 ] = KEY_VOLUMEUP,
+       [ 0x1c ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci);
+
+/* ---------------------------------------------------------------------- */
+
+/* MSI TV@nywhere remote */
+IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0c ] = KEY_MUTE,
+       [ 0x0f ] = KEY_SCREEN,          /* Full Screen */
+       [ 0x10 ] = KEY_F,                       /* Funtion */
+       [ 0x11 ] = KEY_T,                       /* Time shift */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_MEDIA,           /* MTS */
+       [ 0x14 ] = KEY_SLOW,
+       [ 0x16 ] = KEY_REWIND,          /* backward << */
+       [ 0x17 ] = KEY_ENTER,           /* Return */
+       [ 0x18 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
+
+/* ---------------------------------------------------------------------- */
+
+/* Cinergy 1400 DVB-T */
+IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_POWER,
+       [ 0x02 ] = KEY_1,
+       [ 0x03 ] = KEY_2,
+       [ 0x04 ] = KEY_3,
+       [ 0x05 ] = KEY_4,
+       [ 0x06 ] = KEY_5,
+       [ 0x07 ] = KEY_6,
+       [ 0x08 ] = KEY_7,
+       [ 0x09 ] = KEY_8,
+       [ 0x0a ] = KEY_9,
+       [ 0x0c ] = KEY_0,
+
+       [ 0x0b ] = KEY_VIDEO,
+       [ 0x0d ] = KEY_REFRESH,
+       [ 0x0e ] = KEY_SELECT,
+       [ 0x0f ] = KEY_EPG,
+       [ 0x10 ] = KEY_UP,
+       [ 0x11 ] = KEY_LEFT,
+       [ 0x12 ] = KEY_OK,
+       [ 0x13 ] = KEY_RIGHT,
+       [ 0x14 ] = KEY_DOWN,
+       [ 0x15 ] = KEY_TEXT,
+       [ 0x16 ] = KEY_INFO,
+
+       [ 0x17 ] = KEY_RED,
+       [ 0x18 ] = KEY_GREEN,
+       [ 0x19 ] = KEY_YELLOW,
+       [ 0x1a ] = KEY_BLUE,
+
+       [ 0x1b ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_VOLUMEUP,
+       [ 0x1d ] = KEY_MUTE,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+       [ 0x1f ] = KEY_CHANNELDOWN,
+
+       [ 0x40 ] = KEY_PAUSE,
+       [ 0x4c ] = KEY_PLAY,
+       [ 0x58 ] = KEY_RECORD,
+       [ 0x54 ] = KEY_PREVIOUS,
+       [ 0x48 ] = KEY_STOP,
+       [ 0x5c ] = KEY_NEXT,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400);
+
+/* ---------------------------------------------------------------------- */
+
+/* AVERTV STUDIO 303 Remote */
+IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
+       [ 0x2a ] = KEY_1,
+       [ 0x32 ] = KEY_2,
+       [ 0x3a ] = KEY_3,
+       [ 0x4a ] = KEY_4,
+       [ 0x52 ] = KEY_5,
+       [ 0x5a ] = KEY_6,
+       [ 0x6a ] = KEY_7,
+       [ 0x72 ] = KEY_8,
+       [ 0x7a ] = KEY_9,
+       [ 0x0e ] = KEY_0,
+
+       [ 0x02 ] = KEY_POWER,
+       [ 0x22 ] = KEY_VIDEO,
+       [ 0x42 ] = KEY_AUDIO,
+       [ 0x62 ] = KEY_ZOOM,
+       [ 0x0a ] = KEY_TV,
+       [ 0x12 ] = KEY_CD,
+       [ 0x1a ] = KEY_TEXT,
+
+       [ 0x16 ] = KEY_SUBTITLE,
+       [ 0x1e ] = KEY_REWIND,
+       [ 0x06 ] = KEY_PRINT,
+
+       [ 0x2e ] = KEY_SEARCH,
+       [ 0x36 ] = KEY_SLEEP,
+       [ 0x3e ] = KEY_SHUFFLE,
+       [ 0x26 ] = KEY_MUTE,
+
+       [ 0x4e ] = KEY_RECORD,
+       [ 0x56 ] = KEY_PAUSE,
+       [ 0x5e ] = KEY_STOP,
+       [ 0x46 ] = KEY_PLAY,
+
+       [ 0x6e ] = KEY_RED,
+       [ 0x0b ] = KEY_GREEN,
+       [ 0x66 ] = KEY_YELLOW,
+       [ 0x03 ] = KEY_BLUE,
+
+       [ 0x76 ] = KEY_LEFT,
+       [ 0x7e ] = KEY_RIGHT,
+       [ 0x13 ] = KEY_DOWN,
+       [ 0x1b ] = KEY_UP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avertv_303);
+
+/* ---------------------------------------------------------------------- */
+
+/* DigitalNow DNTV Live! DVB-T Pro Remote */
+IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
+       [ 0x16 ] = KEY_POWER,
+       [ 0x5b ] = KEY_HOME,
+
+       [ 0x55 ] = KEY_TV,              /* live tv */
+       [ 0x58 ] = KEY_TUNER,           /* digital Radio */
+       [ 0x5a ] = KEY_RADIO,           /* FM radio */
+       [ 0x59 ] = KEY_DVD,             /* dvd menu */
+       [ 0x03 ] = KEY_1,
+       [ 0x01 ] = KEY_2,
+       [ 0x06 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x1d ] = KEY_5,
+       [ 0x1f ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x19 ] = KEY_8,
+       [ 0x1b ] = KEY_9,
+       [ 0x0c ] = KEY_CANCEL,
+       [ 0x15 ] = KEY_0,
+       [ 0x4a ] = KEY_CLEAR,
+       [ 0x13 ] = KEY_BACK,
+       [ 0x00 ] = KEY_TAB,
+       [ 0x4b ] = KEY_UP,
+       [ 0x4e ] = KEY_LEFT,
+       [ 0x4f ] = KEY_OK,
+       [ 0x52 ] = KEY_RIGHT,
+       [ 0x51 ] = KEY_DOWN,
+       [ 0x1e ] = KEY_VOLUMEUP,
+       [ 0x0a ] = KEY_VOLUMEDOWN,
+       [ 0x02 ] = KEY_CHANNELDOWN,
+       [ 0x05 ] = KEY_CHANNELUP,
+       [ 0x11 ] = KEY_RECORD,
+       [ 0x14 ] = KEY_PLAY,
+       [ 0x4c ] = KEY_PAUSE,
+       [ 0x1a ] = KEY_STOP,
+       [ 0x40 ] = KEY_REWIND,
+       [ 0x12 ] = KEY_FASTFORWARD,
+       [ 0x41 ] = KEY_PREVIOUSSONG,    /* replay |< */
+       [ 0x42 ] = KEY_NEXTSONG,        /* skip >| */
+       [ 0x54 ] = KEY_CAMERA,          /* capture */
+       [ 0x50 ] = KEY_LANGUAGE,        /* sap */
+       [ 0x47 ] = KEY_TV2,             /* pip */
+       [ 0x4d ] = KEY_SCREEN,
+       [ 0x43 ] = KEY_SUBTITLE,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x49 ] = KEY_AUDIO,           /* l/r */
+       [ 0x07 ] = KEY_SLEEP,
+       [ 0x08 ] = KEY_VIDEO,           /* a/v */
+       [ 0x0e ] = KEY_PREVIOUS,        /* recall */
+       [ 0x45 ] = KEY_ZOOM,            /* zoom + */
+       [ 0x46 ] = KEY_ANGLE,           /* zoom - */
+       [ 0x56 ] = KEY_RED,
+       [ 0x57 ] = KEY_GREEN,
+       [ 0x5c ] = KEY_YELLOW,
+       [ 0x5d ] = KEY_BLUE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro);
+
+IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_CHANNEL,
+       [ 0x02 ] = KEY_SELECT,
+       [ 0x03 ] = KEY_MUTE,
+       [ 0x04 ] = KEY_POWER,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x08 ] = KEY_CHANNELUP,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0c ] = KEY_CHANNELDOWN,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_0,
+       [ 0x12 ] = KEY_MENU,
+       [ 0x13 ] = KEY_PRINT,
+       [ 0x14 ] = KEY_VOLUMEDOWN,
+       [ 0x16 ] = KEY_PAUSE,
+       [ 0x18 ] = KEY_RECORD,
+       [ 0x19 ] = KEY_REWIND,
+       [ 0x1a ] = KEY_PLAY,
+       [ 0x1b ] = KEY_FORWARD,
+       [ 0x1c ] = KEY_BACKSPACE,
+       [ 0x1e ] = KEY_STOP,
+       [ 0x40 ] = KEY_ZOOM,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_em_terratec);
+
+IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = {
+       [ 0x3a ] = KEY_0,
+       [ 0x31 ] = KEY_1,
+       [ 0x32 ] = KEY_2,
+       [ 0x33 ] = KEY_3,
+       [ 0x34 ] = KEY_4,
+       [ 0x35 ] = KEY_5,
+       [ 0x36 ] = KEY_6,
+       [ 0x37 ] = KEY_7,
+       [ 0x38 ] = KEY_8,
+       [ 0x39 ] = KEY_9,
+
+       [ 0x2f ] = KEY_POWER,
+
+       [ 0x2e ] = KEY_P,
+       [ 0x1f ] = KEY_L,
+       [ 0x2b ] = KEY_I,
+
+       [ 0x2d ] = KEY_ZOOM,
+       [ 0x1e ] = KEY_ZOOM,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x0f ] = KEY_VOLUMEDOWN,
+       [ 0x17 ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_CHANNELDOWN,
+       [ 0x25 ] = KEY_INFO,
+
+       [ 0x3c ] = KEY_MUTE,
+
+       [ 0x3d ] = KEY_LEFT,
+       [ 0x3b ] = KEY_RIGHT,
+
+       [ 0x3f ] = KEY_UP,
+       [ 0x3e ] = KEY_DOWN,
+       [ 0x1a ] = KEY_PAUSE,
+
+       [ 0x1d ] = KEY_MENU,
+       [ 0x19 ] = KEY_PLAY,
+       [ 0x16 ] = KEY_REWIND,
+       [ 0x13 ] = KEY_FORWARD,
+       [ 0x15 ] = KEY_PAUSE,
+       [ 0x0e ] = KEY_REWIND,
+       [ 0x0d ] = KEY_PLAY,
+       [ 0x0b ] = KEY_STOP,
+       [ 0x07 ] = KEY_FORWARD,
+       [ 0x27 ] = KEY_RECORD,
+       [ 0x26 ] = KEY_TUNER,
+       [ 0x29 ] = KEY_TEXT,
+       [ 0x2a ] = KEY_MEDIA,
+       [ 0x18 ] = KEY_EPG,
+       [ 0x27 ] = KEY_RECORD,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb);
+
+IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = {
+       [ 0x0f ] = KEY_0,
+       [ 0x03 ] = KEY_1,
+       [ 0x04 ] = KEY_2,
+       [ 0x05 ] = KEY_3,
+       [ 0x07 ] = KEY_4,
+       [ 0x08 ] = KEY_5,
+       [ 0x09 ] = KEY_6,
+       [ 0x0b ] = KEY_7,
+       [ 0x0c ] = KEY_8,
+       [ 0x0d ] = KEY_9,
+
+       [ 0x0e ] = KEY_MODE,         // Air/Cable
+       [ 0x11 ] = KEY_VIDEO,        // Video
+       [ 0x15 ] = KEY_AUDIO,        // Audio
+       [ 0x00 ] = KEY_POWER,        // Power
+       [ 0x18 ] = KEY_TUNER,        // AV Source
+       [ 0x02 ] = KEY_ZOOM,         // Fullscreen
+       [ 0x1a ] = KEY_LANGUAGE,     // Stereo
+       [ 0x1b ] = KEY_MUTE,         // Mute
+       [ 0x14 ] = KEY_VOLUMEUP,     // Volume +
+       [ 0x17 ] = KEY_VOLUMEDOWN,   // Volume -
+       [ 0x12 ] = KEY_CHANNELUP,    // Channel +
+       [ 0x13 ] = KEY_CHANNELDOWN,  // Channel -
+       [ 0x06 ] = KEY_AGAIN,        // Recall
+       [ 0x10 ] = KEY_ENTER,      // Enter
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_flyvideo);
+
+IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_ZOOM,            // Full Screen
+       [ 0x00 ] = KEY_POWER,           // Power
+
+       [ 0x03 ] = KEY_1,
+       [ 0x04 ] = KEY_2,
+       [ 0x05 ] = KEY_3,
+       [ 0x07 ] = KEY_4,
+       [ 0x08 ] = KEY_5,
+       [ 0x09 ] = KEY_6,
+       [ 0x0b ] = KEY_7,
+       [ 0x0c ] = KEY_8,
+       [ 0x0d ] = KEY_9,
+       [ 0x06 ] = KEY_AGAIN,           // Recall
+       [ 0x0f ] = KEY_0,
+       [ 0x10 ] = KEY_MUTE,            // Mute
+       [ 0x02 ] = KEY_RADIO,           // TV/Radio
+       [ 0x1b ] = KEY_LANGUAGE,                // SAP (Second Audio Program)
+
+       [ 0x14 ] = KEY_VOLUMEUP,                // VOL+
+       [ 0x17 ] = KEY_VOLUMEDOWN,      // VOL-
+       [ 0x12 ] = KEY_CHANNELUP,               // CH+
+       [ 0x13 ] = KEY_CHANNELDOWN,     // CH-
+       [ 0x1d ] = KEY_ENTER,           // Enter
+
+       [ 0x1a ] = KEY_MODE,            // PIP
+       [ 0x18 ] = KEY_TUNER,           // Source
+
+       [ 0x1e ] = KEY_RECORD,          // Record/Pause
+       [ 0x15 ] = KEY_ANGLE,           // Swap (no label on key)
+       [ 0x1c ] = KEY_PAUSE,           // Timeshift/Pause
+       [ 0x19 ] = KEY_BACK,            // Rewind <<
+       [ 0x0a ] = KEY_PLAYPAUSE,               // Play/Pause
+       [ 0x1f ] = KEY_FORWARD,         // Forward >>
+       [ 0x16 ] = KEY_PREVIOUS,                // Back |<<
+       [ 0x11 ] = KEY_STOP,            // Stop
+       [ 0x0e ] = KEY_NEXT,            // End >>|
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_flydvb);
+
+IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_POWER,
+       [ 0x0b ] = KEY_PROG1,           // app
+       [ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
+       [ 0x0d ] = KEY_CHANNELUP,       // channel
+       [ 0x0e ] = KEY_CHANNELDOWN,     // channel-
+       [ 0x0f ] = KEY_VOLUMEUP,
+       [ 0x10 ] = KEY_VOLUMEDOWN,
+       [ 0x11 ] = KEY_TUNER,           // AV
+       [ 0x12 ] = KEY_NUMLOCK,         // -/--
+       [ 0x13 ] = KEY_AUDIO,           // audio
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x15 ] = KEY_UP,
+       [ 0x16 ] = KEY_DOWN,
+       [ 0x17 ] = KEY_LEFT,
+       [ 0x18 ] = KEY_RIGHT,
+       [ 0x19 ] = BTN_LEFT,
+       [ 0x1a ] = BTN_RIGHT,
+       [ 0x1b ] = KEY_WWW,             // text
+       [ 0x1c ] = KEY_REWIND,
+       [ 0x1d ] = KEY_FORWARD,
+       [ 0x1e ] = KEY_RECORD,
+       [ 0x1f ] = KEY_PLAY,
+       [ 0x20 ] = KEY_PREVIOUSSONG,
+       [ 0x21 ] = KEY_NEXTSONG,
+       [ 0x22 ] = KEY_PAUSE,
+       [ 0x23 ] = KEY_STOP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_cinergy);
+
+/* Alfons Geser <a.geser@cox.net>
+ * updates from Job D. R. Borges <jobdrb@ig.com.br> */
+IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = {
+       [ 0x12 ] = KEY_POWER,
+       [ 0x01 ] = KEY_TV,             // DVR
+       [ 0x15 ] = KEY_DVD,            // DVD
+       [ 0x17 ] = KEY_AUDIO,          // music
+                                    // DVR mode / DVD mode / music mode
+
+       [ 0x1b ] = KEY_MUTE,           // mute
+       [ 0x02 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
+       [ 0x1e ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
+       [ 0x16 ] = KEY_ZOOM,           // full screen
+       [ 0x1c ] = KEY_VIDEO,          // video source / eject / delall
+       [ 0x1d ] = KEY_RESTART,        // playback / angle / del
+       [ 0x2f ] = KEY_SEARCH,         // scan / menu / playlist
+       [ 0x30 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
+
+       [ 0x31 ] = KEY_HELP,           // help
+       [ 0x32 ] = KEY_MODE,           // num/memo
+       [ 0x33 ] = KEY_ESC,            // cancel
+
+       [ 0x0c ] = KEY_UP,             // up
+       [ 0x10 ] = KEY_DOWN,           // down
+       [ 0x08 ] = KEY_LEFT,           // left
+       [ 0x04 ] = KEY_RIGHT,          // right
+       [ 0x03 ] = KEY_SELECT,         // select
+
+       [ 0x1f ] = KEY_REWIND,         // rewind
+       [ 0x20 ] = KEY_PLAYPAUSE,      // play/pause
+       [ 0x29 ] = KEY_FORWARD,        // forward
+       [ 0x14 ] = KEY_AGAIN,          // repeat
+       [ 0x2b ] = KEY_RECORD,         // recording
+       [ 0x2c ] = KEY_STOP,           // stop
+       [ 0x2d ] = KEY_PLAY,           // play
+       [ 0x2e ] = KEY_SHUFFLE,        // snapshot / shuffle
+
+       [ 0x00 ] = KEY_0,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+
+       [ 0x2a ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x18 ] = KEY_CHANNELUP,      // CH.tracking up
+       [ 0x19 ] = KEY_CHANNELDOWN,    // CH.tracking down
+
+       [ 0x13 ] = KEY_ENTER,        // enter
+       [ 0x21 ] = KEY_DOT,          // . (decimal dot)
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_eztv);
+
+/* Alex Hermann <gaaf@gmx.net> */
+IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
+       [ 0x28 ] = KEY_1,
+       [ 0x18 ] = KEY_2,
+       [ 0x38 ] = KEY_3,
+       [ 0x24 ] = KEY_4,
+       [ 0x14 ] = KEY_5,
+       [ 0x34 ] = KEY_6,
+       [ 0x2c ] = KEY_7,
+       [ 0x1c ] = KEY_8,
+       [ 0x3c ] = KEY_9,
+       [ 0x22 ] = KEY_0,
+
+       [ 0x20 ] = KEY_TV,              /* TV/FM */
+       [ 0x10 ] = KEY_CD,              /* CD */
+       [ 0x30 ] = KEY_TEXT,            /* TELETEXT */
+       [ 0x00 ] = KEY_POWER,           /* POWER */
+
+       [ 0x08 ] = KEY_VIDEO,           /* VIDEO */
+       [ 0x04 ] = KEY_AUDIO,           /* AUDIO */
+       [ 0x0c ] = KEY_ZOOM,            /* FULL SCREEN */
+
+       [ 0x12 ] = KEY_SUBTITLE,        /* DISPLAY */
+       [ 0x32 ] = KEY_REWIND,          /* LOOP */
+       [ 0x02 ] = KEY_PRINT,           /* PREVIEW */
+
+       [ 0x2a ] = KEY_SEARCH,          /* AUTOSCAN */
+       [ 0x1a ] = KEY_SLEEP,           /* FREEZE */
+       [ 0x3a ] = KEY_SHUFFLE,         /* SNAPSHOT */
+       [ 0x0a ] = KEY_MUTE,            /* MUTE */
+
+       [ 0x26 ] = KEY_RECORD,          /* RECORD */
+       [ 0x16 ] = KEY_PAUSE,           /* PAUSE */
+       [ 0x36 ] = KEY_STOP,            /* STOP */
+       [ 0x06 ] = KEY_PLAY,            /* PLAY */
+
+       [ 0x2e ] = KEY_RED,             /* RED */
+       [ 0x21 ] = KEY_GREEN,           /* GREEN */
+       [ 0x0e ] = KEY_YELLOW,          /* YELLOW */
+       [ 0x01 ] = KEY_BLUE,            /* BLUE */
+
+       [ 0x1e ] = KEY_VOLUMEDOWN,      /* VOLUME- */
+       [ 0x3e ] = KEY_VOLUMEUP,        /* VOLUME+ */
+       [ 0x11 ] = KEY_CHANNELDOWN,     /* CHANNEL/PAGE- */
+       [ 0x31 ] = KEY_CHANNELUP        /* CHANNEL/PAGE+ */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avermedia);
+
+IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = {
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x24 ] = KEY_ZOOM,
+
+       [ 0x01 ] = KEY_DVD,
+       [ 0x23 ] = KEY_RADIO,
+       [ 0x00 ] = KEY_TV,
+
+       [ 0x0a ] = KEY_REWIND,
+       [ 0x08 ] = KEY_PLAYPAUSE,
+       [ 0x0f ] = KEY_FORWARD,
+
+       [ 0x02 ] = KEY_PREVIOUS,
+       [ 0x07 ] = KEY_STOP,
+       [ 0x06 ] = KEY_NEXT,
+
+       [ 0x0c ] = KEY_UP,
+       [ 0x0e ] = KEY_DOWN,
+       [ 0x0b ] = KEY_LEFT,
+       [ 0x0d ] = KEY_RIGHT,
+       [ 0x11 ] = KEY_OK,
+
+       [ 0x03 ] = KEY_MENU,
+       [ 0x09 ] = KEY_SETUP,
+       [ 0x05 ] = KEY_VIDEO,
+       [ 0x22 ] = KEY_CHANNEL,
+
+       [ 0x12 ] = KEY_VOLUMEUP,
+       [ 0x15 ] = KEY_VOLUMEDOWN,
+       [ 0x10 ] = KEY_CHANNELUP,
+       [ 0x13 ] = KEY_CHANNELDOWN,
+
+       [ 0x04 ] = KEY_RECORD,
+
+       [ 0x16 ] = KEY_1,
+       [ 0x17 ] = KEY_2,
+       [ 0x18 ] = KEY_3,
+       [ 0x19 ] = KEY_4,
+       [ 0x1a ] = KEY_5,
+       [ 0x1b ] = KEY_6,
+       [ 0x1c ] = KEY_7,
+       [ 0x1d ] = KEY_8,
+       [ 0x1e ] = KEY_9,
+       [ 0x1f ] = KEY_0,
+
+       [ 0x20 ] = KEY_LANGUAGE,
+       [ 0x21 ] = KEY_SLEEP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr);
+
+/* Michael Tokarev <mjt@tls.msk.ru>
+   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
+   keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at
+   least, and probably other cards too.
+   The "ascii-art picture" below (in comments, first row
+   is the keycode in hex, and subsequent row(s) shows
+   the button labels (several variants when appropriate)
+   helps to descide which keycodes to assign to the buttons.
+ */
+IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
+
+       /*  0x1c            0x12  *
+        * FUNCTION         POWER *
+        *   FM              (|)  *
+        *                        */
+       [ 0x1c ] = KEY_RADIO,   /*XXX*/
+       [ 0x12 ] = KEY_POWER,
+
+       /*  0x01    0x02    0x03  *
+        *   1       2       3    *
+        *                        *
+        *  0x04    0x05    0x06  *
+        *   4       5       6    *
+        *                        *
+        *  0x07    0x08    0x09  *
+        *   7       8       9    *
+        *                        */
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       /*  0x0a    0x00    0x17  *
+        * RECALL    0      +100  *
+        *                  PLUS  *
+        *                        */
+       [ 0x0a ] = KEY_AGAIN,   /*XXX KEY_REWIND? */
+       [ 0x00 ] = KEY_0,
+       [ 0x17 ] = KEY_DIGITS,  /*XXX*/
+
+       /*  0x14            0x10  *
+        *  MENU            INFO  *
+        *  OSD                   */
+       [ 0x14 ] = KEY_MENU,
+       [ 0x10 ] = KEY_INFO,
+
+       /*          0x0b          *
+        *           Up           *
+        *                        *
+        *  0x18    0x16    0x0c  *
+        *  Left     Ok     Right *
+        *                        *
+        *         0x015          *
+        *         Down           *
+        *                        */
+       [ 0x0b ] = KEY_UP,      /*XXX KEY_SCROLLUP? */
+       [ 0x18 ] = KEY_LEFT,    /*XXX KEY_BACK? */
+       [ 0x16 ] = KEY_OK,      /*XXX KEY_SELECT? KEY_ENTER? */
+       [ 0x0c ] = KEY_RIGHT,   /*XXX KEY_FORWARD? */
+       [ 0x15 ] = KEY_DOWN,    /*XXX KEY_SCROLLDOWN? */
+
+       /*  0x11            0x0d  *
+        *  TV/AV           MODE  *
+        *  SOURCE         STEREO *
+        *                        */
+       [ 0x11 ] = KEY_TV,      /*XXX*/
+       [ 0x0d ] = KEY_MODE,    /*XXX there's no KEY_STEREO */
+
+       /*  0x0f    0x1b    0x1a  *
+        *  AUDIO   Vol+    Chan+ *
+        *        TIMESHIFT???    *
+        *                        *
+        *  0x0e    0x1f    0x1e  *
+        *  SLEEP   Vol-    Chan- *
+        *                        */
+       [ 0x0f ] = KEY_AUDIO,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x0e ] = KEY_SLEEP,   /*XXX maybe KEY_PAUSE */
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+
+       /*         0x13     0x19  *
+        *         MUTE   SNAPSHOT*
+        *                        */
+       [ 0x13 ] = KEY_MUTE,
+       [ 0x19 ] = KEY_RECORD,  /*XXX*/
+
+       // 0x1d unused ?
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_manli);
+
+/* Mike Baikov <mike@baikov.com> */
+IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
+
+       [ 0x21 ] = KEY_POWER,
+       [ 0x69 ] = KEY_TV,
+       [ 0x33 ] = KEY_0,
+       [ 0x51 ] = KEY_1,
+       [ 0x31 ] = KEY_2,
+       [ 0x71 ] = KEY_3,
+       [ 0x3b ] = KEY_4,
+       [ 0x58 ] = KEY_5,
+       [ 0x41 ] = KEY_6,
+       [ 0x48 ] = KEY_7,
+       [ 0x30 ] = KEY_8,
+       [ 0x53 ] = KEY_9,
+       [ 0x73 ] = KEY_AGAIN, /* LOOP */
+       [ 0x0a ] = KEY_AUDIO,
+       [ 0x61 ] = KEY_PRINT, /* PREVIEW */
+       [ 0x7a ] = KEY_VIDEO,
+       [ 0x20 ] = KEY_CHANNELUP,
+       [ 0x40 ] = KEY_CHANNELDOWN,
+       [ 0x18 ] = KEY_VOLUMEDOWN,
+       [ 0x50 ] = KEY_VOLUMEUP,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x4a ] = KEY_SEARCH,
+       [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */
+       [ 0x22 ] = KEY_RECORD,
+       [ 0x62 ] = KEY_STOP,
+       [ 0x78 ] = KEY_PLAY,
+       [ 0x39 ] = KEY_REWIND,
+       [ 0x59 ] = KEY_PAUSE,
+       [ 0x19 ] = KEY_FORWARD,
+       [ 0x09 ] = KEY_ZOOM,
+
+       [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */
+       [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */
+       [ 0x3a ] = KEY_F23, /* TIMESHIFT */
+       [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
+
+IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
+       [ 0x03 ] = KEY_POWER,
+       [ 0x6f ] = KEY_MUTE,
+       [ 0x10 ] = KEY_BACKSPACE,       /* Recall */
+
+       [ 0x11 ] = KEY_0,
+       [ 0x04 ] = KEY_1,
+       [ 0x05 ] = KEY_2,
+       [ 0x06 ] = KEY_3,
+       [ 0x08 ] = KEY_4,
+       [ 0x09 ] = KEY_5,
+       [ 0x0a ] = KEY_6,
+       [ 0x0c ] = KEY_7,
+       [ 0x0d ] = KEY_8,
+       [ 0x0e ] = KEY_9,
+       [ 0x12 ] = KEY_DOT,           /* 100+ */
+
+       [ 0x07 ] = KEY_VOLUMEUP,
+       [ 0x0b ] = KEY_VOLUMEDOWN,
+       [ 0x1a ] = KEY_KPPLUS,
+       [ 0x18 ] = KEY_KPMINUS,
+       [ 0x15 ] = KEY_UP,
+       [ 0x1d ] = KEY_DOWN,
+       [ 0x0f ] = KEY_CHANNELUP,
+       [ 0x13 ] = KEY_CHANNELDOWN,
+       [ 0x48 ] = KEY_ZOOM,
+
+       [ 0x1b ] = KEY_VIDEO,           /* Video source */
+       [ 0x49 ] = KEY_LANGUAGE,        /* MTS Select */
+       [ 0x19 ] = KEY_SEARCH,          /* Auto Scan */
+
+       [ 0x4b ] = KEY_RECORD,
+       [ 0x46 ] = KEY_PLAY,
+       [ 0x45 ] = KEY_PAUSE,           /* Pause */
+       [ 0x44 ] = KEY_STOP,
+       [ 0x40 ] = KEY_FORWARD,         /* Forward ? */
+       [ 0x42 ] = KEY_REWIND,          /* Backward ? */
+
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_purpletv);
+
+/* Mapping for the 28 key remote control as seen at
+   http://www.sednacomputer.com/photo/cardbus-tv.jpg
+   Pavel Mihaylov <bin@bash.info> */
+IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_AGAIN,          /* Recall */
+       [ 0x0b ] = KEY_CHANNELUP,
+       [ 0x0c ] = KEY_VOLUMEUP,
+       [ 0x0d ] = KEY_MODE,           /* Stereo */
+       [ 0x0e ] = KEY_STOP,
+       [ 0x0f ] = KEY_PREVIOUSSONG,
+       [ 0x10 ] = KEY_ZOOM,
+       [ 0x11 ] = KEY_TUNER,          /* Source */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_MUTE,
+       [ 0x15 ] = KEY_CHANNELDOWN,
+       [ 0x18 ] = KEY_VOLUMEDOWN,
+       [ 0x19 ] = KEY_SHUFFLE,        /* Snapshot */
+       [ 0x1a ] = KEY_NEXTSONG,
+       [ 0x1b ] = KEY_TEXT,           /* Time Shift */
+       [ 0x1c ] = KEY_RADIO,          /* FM Radio */
+       [ 0x1d ] = KEY_RECORD,
+       [ 0x1e ] = KEY_PAUSE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna);
+
+/* Mark Phalan <phalanm@o2.ie> */
+IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x12 ] = KEY_POWER,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x0e ] = KEY_PAGEUP,
+       [ 0x1d ] = KEY_PAGEDOWN,
+       [ 0x13 ] = KEY_SOUND,
+
+       [ 0x18 ] = KEY_KPPLUSMINUS,     /* CH +/- */
+       [ 0x16 ] = KEY_SUBTITLE,                /* CC */
+       [ 0x0d ] = KEY_TEXT,            /* TTX */
+       [ 0x0b ] = KEY_TV,              /* AIR/CBL */
+       [ 0x11 ] = KEY_PC,              /* PC/TV */
+       [ 0x17 ] = KEY_OK,              /* CH RTN */
+       [ 0x19 ] = KEY_MODE,            /* FUNC */
+       [ 0x0c ] = KEY_SEARCH,          /* AUTOSCAN */
+
+       /* Not sure what to do with these ones! */
+       [ 0x0f ] = KEY_SELECT,          /* SOURCE */
+       [ 0x0a ] = KEY_KPPLUS,          /* +100 */
+       [ 0x14 ] = KEY_EQUAL,           /* SYNC */
+       [ 0x1c ] = KEY_MEDIA,             /* PC/TV */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pv951);
+
+/* generic RC5 keytable                                          */
+/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
+/* used by old (black) Hauppauge remotes                         */
+IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0b ] = KEY_CHANNEL,         /* channel / program (japan: 11) */
+       [ 0x0c ] = KEY_POWER,           /* standby */
+       [ 0x0d ] = KEY_MUTE,            /* mute / demute */
+       [ 0x0f ] = KEY_TV,              /* display */
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x12 ] = KEY_BRIGHTNESSUP,
+       [ 0x13 ] = KEY_BRIGHTNESSDOWN,
+       [ 0x1e ] = KEY_SEARCH,          /* search + */
+       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
+       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
+       [ 0x22 ] = KEY_CHANNEL,         /* alt / channel */
+       [ 0x23 ] = KEY_LANGUAGE,        /* 1st / 2nd language */
+       [ 0x26 ] = KEY_SLEEP,           /* sleeptimer */
+       [ 0x2e ] = KEY_MENU,            /* 2nd controls (USA: menu) */
+       [ 0x30 ] = KEY_PAUSE,
+       [ 0x32 ] = KEY_REWIND,
+       [ 0x33 ] = KEY_GOTO,
+       [ 0x35 ] = KEY_PLAY,
+       [ 0x36 ] = KEY_STOP,
+       [ 0x37 ] = KEY_RECORD,          /* recording */
+       [ 0x3c ] = KEY_TEXT,            /* teletext submode (Japan: 12) */
+       [ 0x3d ] = KEY_SUSPEND,         /* system standby */
+
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
+
+/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
+IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x12 ] = KEY_0,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+
+       [ 0x00 ] = KEY_POWER,
+       [ 0x02 ] = KEY_TUNER,           /* TV/FM */
+       [ 0x1e ] = KEY_VIDEO,
+       [ 0x04 ] = KEY_VOLUMEUP,
+       [ 0x08 ] = KEY_VOLUMEDOWN,
+       [ 0x0c ] = KEY_CHANNELUP,
+       [ 0x10 ] = KEY_CHANNELDOWN,
+       [ 0x03 ] = KEY_ZOOM,            /* fullscreen */
+       [ 0x1f ] = KEY_SUBTITLE,                /* closed caption/teletext */
+       [ 0x20 ] = KEY_SLEEP,
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x2b ] = KEY_RED,
+       [ 0x2c ] = KEY_GREEN,
+       [ 0x2d ] = KEY_YELLOW,
+       [ 0x2e ] = KEY_BLUE,
+       [ 0x18 ] = KEY_KPPLUS,          /* fine tune + */
+       [ 0x19 ] = KEY_KPMINUS,         /* fine tune - */
+       [ 0x21 ] = KEY_DOT,
+       [ 0x13 ] = KEY_ENTER,
+       [ 0x22 ] = KEY_BACK,
+       [ 0x23 ] = KEY_PLAYPAUSE,
+       [ 0x24 ] = KEY_NEXT,
+       [ 0x26 ] = KEY_STOP,
+       [ 0x27 ] = KEY_RECORD
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_winfast);
+
+IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+       [ 0x59 ] = KEY_MUTE,
+       [ 0x4a ] = KEY_POWER,
+
+       [ 0x18 ] = KEY_TEXT,
+       [ 0x26 ] = KEY_TV,
+       [ 0x3d ] = KEY_PRINT,
+
+       [ 0x48 ] = KEY_RED,
+       [ 0x04 ] = KEY_GREEN,
+       [ 0x11 ] = KEY_YELLOW,
+       [ 0x00 ] = KEY_BLUE,
+
+       [ 0x2d ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+
+       [ 0x49 ] = KEY_MENU,
+
+       [ 0x16 ] = KEY_CHANNELUP,
+       [ 0x17 ] = KEY_CHANNELDOWN,
+
+       [ 0x20 ] = KEY_UP,
+       [ 0x21 ] = KEY_DOWN,
+       [ 0x22 ] = KEY_LEFT,
+       [ 0x23 ] = KEY_RIGHT,
+       [ 0x0d ] = KEY_SELECT,
+
+
+
+       [ 0x08 ] = KEY_BACK,
+       [ 0x07 ] = KEY_REFRESH,
+
+       [ 0x2f ] = KEY_ZOOM,
+       [ 0x29 ] = KEY_RECORD,
+
+       [ 0x4b ] = KEY_PAUSE,
+       [ 0x4d ] = KEY_REWIND,
+       [ 0x2e ] = KEY_PLAY,
+       [ 0x4e ] = KEY_FORWARD,
+       [ 0x53 ] = KEY_PREVIOUS,
+       [ 0x4c ] = KEY_STOP,
+       [ 0x54 ] = KEY_NEXT,
+
+       [ 0x69 ] = KEY_0,
+       [ 0x6a ] = KEY_1,
+       [ 0x6b ] = KEY_2,
+       [ 0x6c ] = KEY_3,
+       [ 0x6d ] = KEY_4,
+       [ 0x6e ] = KEY_5,
+       [ 0x6f ] = KEY_6,
+       [ 0x70 ] = KEY_7,
+       [ 0x71 ] = KEY_8,
+       [ 0x72 ] = KEY_9,
+
+       [ 0x74 ] = KEY_CHANNEL,
+       [ 0x0a ] = KEY_BACKSPACE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
+
+/* Hauppauge: the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ * almost rc5 coding, but some non-standard keys */
+IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_TEXT,            /* keypad asterisk as well */
+       [ 0x0b ] = KEY_RED,             /* red button */
+       [ 0x0c ] = KEY_RADIO,
+       [ 0x0d ] = KEY_MENU,
+       [ 0x0e ] = KEY_SUBTITLE,        /* also the # key */
+       [ 0x0f ] = KEY_MUTE,
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x12 ] = KEY_PREVIOUS,        /* previous channel */
+       [ 0x14 ] = KEY_UP,
+       [ 0x15 ] = KEY_DOWN,
+       [ 0x16 ] = KEY_LEFT,
+       [ 0x17 ] = KEY_RIGHT,
+       [ 0x18 ] = KEY_VIDEO,           /* Videos */
+       [ 0x19 ] = KEY_AUDIO,           /* Music */
+       /* 0x1a: Pictures - presume this means
+          "Multimedia Home Platform" -
+          no "PICTURES" key in input.h
+        */
+       [ 0x1a ] = KEY_MHP,
+
+       [ 0x1b ] = KEY_EPG,             /* Guide */
+       [ 0x1c ] = KEY_TV,
+       [ 0x1e ] = KEY_NEXTSONG,        /* skip >| */
+       [ 0x1f ] = KEY_EXIT,            /* back/exit */
+       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
+       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
+       [ 0x22 ] = KEY_CHANNEL,         /* source (old black remote) */
+       [ 0x24 ] = KEY_PREVIOUSSONG,    /* replay |< */
+       [ 0x25 ] = KEY_ENTER,           /* OK */
+       [ 0x26 ] = KEY_SLEEP,           /* minimize (old black remote) */
+       [ 0x29 ] = KEY_BLUE,            /* blue key */
+       [ 0x2e ] = KEY_GREEN,           /* green button */
+       [ 0x30 ] = KEY_PAUSE,           /* pause */
+       [ 0x32 ] = KEY_REWIND,          /* backward << */
+       [ 0x34 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x35 ] = KEY_PLAY,
+       [ 0x36 ] = KEY_STOP,
+       [ 0x37 ] = KEY_RECORD,          /* recording */
+       [ 0x38 ] = KEY_YELLOW,          /* yellow key */
+       [ 0x3b ] = KEY_SELECT,          /* top right button */
+       [ 0x3c ] = KEY_ZOOM,            /* full */
+       [ 0x3d ] = KEY_POWER,           /* system power (green button) */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new);
+
index 04c1938..ee16c04 100644 (file)
@@ -21,7 +21,7 @@
 #include <media/saa7146.h>
 
 LIST_HEAD(saa7146_devices);
-DECLARE_MUTEX(saa7146_devices_lock);
+DEFINE_MUTEX(saa7146_devices_lock);
 
 static int saa7146_num;
 
@@ -402,11 +402,11 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
 
        pci_set_drvdata(pci, dev);
 
-       init_MUTEX(&dev->lock);
+       mutex_init(&dev->lock);
        spin_lock_init(&dev->int_slock);
        spin_lock_init(&dev->slock);
 
-       init_MUTEX(&dev->i2c_lock);
+       mutex_init(&dev->i2c_lock);
 
        dev->module = THIS_MODULE;
        init_waitqueue_head(&dev->i2c_wq);
index f8cf73e..dc7fb20 100644 (file)
@@ -17,18 +17,18 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
        }
 
        /* is it free? */
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        if (vv->resources & bit) {
                DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
                /* no, someone else uses it */
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        vv->resources |= bit;
        DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 1;
 }
 
@@ -40,11 +40,11 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
        if ((fh->resources & bits) != bits)
                BUG();
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        fh->resources  &= ~bits;
        vv->resources &= ~bits;
        DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 
@@ -204,7 +204,7 @@ static int fops_open(struct inode *inode, struct file *file)
 
        DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
 
-       if (down_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
        list_for_each(list,&saa7146_devices) {
@@ -276,7 +276,7 @@ out:
                kfree(fh);
                file->private_data = NULL;
        }
-       up(&saa7146_devices_lock);
+       mutex_unlock(&saa7146_devices_lock);
        return result;
 }
 
@@ -287,7 +287,7 @@ static int fops_release(struct inode *inode, struct file *file)
 
        DEB_EE(("inode:%p, file:%p\n",inode,file));
 
-       if (down_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
        if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
@@ -303,7 +303,7 @@ static int fops_release(struct inode *inode, struct file *file)
        file->private_data = NULL;
        kfree(fh);
 
-       up(&saa7146_devices_lock);
+       mutex_unlock(&saa7146_devices_lock);
 
        return 0;
 }
index 8aabdd8..d9953f7 100644 (file)
@@ -279,7 +279,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
        int address_err = 0;
        int short_delay = 0;
 
-       if (down_interruptible (&dev->i2c_lock))
+       if (mutex_lock_interruptible(&dev->i2c_lock))
                return -ERESTARTSYS;
 
        for(i=0;i<num;i++) {
@@ -366,7 +366,7 @@ out:
                }
        }
 
-       up(&dev->i2c_lock);
+       mutex_unlock(&dev->i2c_lock);
        return err;
 }
 
index 468d3c9..500bd3f 100644 (file)
@@ -410,7 +410,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
                            sizeof(struct saa7146_buf),
                            file);
-       init_MUTEX(&fh->vbi_q.lock);
+       mutex_init(&fh->vbi_q.lock);
 
        init_timer(&fh->vbi_read_timeout);
        fh->vbi_read_timeout.function = vbi_read_timeout;
index 7ebac79..6b42713 100644 (file)
@@ -378,20 +378,20 @@ static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
                err = try_win(dev,&f->fmt.win);
                if (0 != err)
                        return err;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                fh->ov.win    = f->fmt.win;
                fh->ov.nclips = f->fmt.win.clipcount;
                if (fh->ov.nclips > 16)
                        fh->ov.nclips = 16;
                if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EFAULT;
                }
 
                /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
                fh->ov.fh = fh;
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                /* check if our current overlay is active */
                if (IS_OVERLAY_ACTIVE(fh) != 0) {
@@ -516,7 +516,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                return -EINVAL;
        }
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
 
        switch (ctrl->type) {
        case V4L2_CTRL_TYPE_BOOLEAN:
@@ -560,7 +560,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                /* fixme: we can support changing VFLIP and HFLIP here... */
                if (IS_CAPTURE_ACTIVE(fh) != 0) {
                        DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EINVAL;
                }
                vv->hflip = c->value;
@@ -568,7 +568,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
        case V4L2_CID_VFLIP:
                if (IS_CAPTURE_ACTIVE(fh) != 0) {
                        DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EINVAL;
                }
                vv->vflip = c->value;
@@ -577,7 +577,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                return -EINVAL;
        }
        }
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
        if (IS_OVERLAY_ACTIVE(fh) != 0) {
                saa7146_stop_preview(fh);
@@ -939,7 +939,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        }
                }
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
 
                /* ok, accept it */
                vv->ov_fb = *fb;
@@ -948,7 +948,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        vv->ov_fb.fmt.bytesperline =
                                vv->ov_fb.fmt.width*fmt->depth/8;
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                return 0;
        }
@@ -1086,7 +1086,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        }
                }
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
 
                for(i = 0; i < dev->ext_vv_data->num_stds; i++)
                        if (*id & dev->ext_vv_data->stds[i].id)
@@ -1098,7 +1098,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        found = 1;
                }
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                if (vv->ov_suspend != NULL) {
                        saa7146_start_preview(vv->ov_suspend);
@@ -1201,11 +1201,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                DEB_D(("VIDIOCGMBUF \n"));
 
                q = &fh->video_q;
-               down(&q->lock);
+               mutex_lock(&q->lock);
                err = videobuf_mmap_setup(q,gbuffers,gbufsize,
                                          V4L2_MEMORY_MMAP);
                if (err < 0) {
-                       up(&q->lock);
+                       mutex_unlock(&q->lock);
                        return err;
                }
                memset(mbuf,0,sizeof(*mbuf));
@@ -1213,7 +1213,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                mbuf->size   = gbuffers * gbufsize;
                for (i = 0; i < gbuffers; i++)
                        mbuf->offsets[i] = i * gbufsize;
-               up(&q->lock);
+               mutex_unlock(&q->lock);
                return 0;
        }
        default:
@@ -1414,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
                            sizeof(struct saa7146_buf),
                            file);
 
-       init_MUTEX(&fh->video_q.lock);
+       mutex_init(&fh->video_q.lock);
 
        return 0;
 }
index 7d7e161..b3dd060 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/pci.h>
+#include <linux/mutex.h>
 
 #include "flexcop-reg.h"
 
@@ -73,8 +74,7 @@ struct flexcop_device {
        int (*fe_sleep) (struct dvb_frontend *);
 
        struct i2c_adapter i2c_adap;
-       struct semaphore i2c_sem;
-
+       struct mutex i2c_mutex;
        struct module *owner;
 
        /* options and status */
index 56495cb..e0bd2d8 100644 (file)
@@ -135,7 +135,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
        struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
        int i, ret = 0;
 
-       if (down_interruptible(&fc->i2c_sem))
+       if (mutex_lock_interruptible(&fc->i2c_mutex))
                return -ERESTARTSYS;
 
        /* reading */
@@ -161,7 +161,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
        else
                ret = num;
 
-       up(&fc->i2c_sem);
+       mutex_unlock(&fc->i2c_mutex);
 
        return ret;
 }
@@ -180,7 +180,7 @@ int flexcop_i2c_init(struct flexcop_device *fc)
 {
        int ret;
 
-       sema_init(&fc->i2c_sem,1);
+       mutex_init(&fc->i2c_mutex);
 
        memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
        strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
index 356f447..5500f8a 100644 (file)
@@ -344,7 +344,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
        int retval;
 
        retval = 0;
-       if (down_interruptible (&bt->gpio_lock))
+       if (mutex_lock_interruptible(&bt->gpio_lock))
                return -ERESTARTSYS;
        /* special gpio signal */
        switch (cmd) {
@@ -375,7 +375,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
                retval = -EINVAL;
                break;
        }
-       up(&bt->gpio_lock);
+       mutex_unlock(&bt->gpio_lock);
        return retval;
 }
 
index 9faf937..f685bc1 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
+
 #include "bt848.h"
 #include "bttv.h"
 
@@ -108,7 +110,7 @@ struct cards {
 extern int bt878_num;
 
 struct bt878 {
-       struct semaphore  gpio_lock;
+       struct mutex gpio_lock;
        unsigned int nr;
        unsigned int bttv_nr;
        struct i2c_adapter *adapter;
index 0310e3d..1cfa5e5 100644 (file)
@@ -910,7 +910,7 @@ static int dst_get_device_id(struct dst_state *state)
 
 static int dst_probe(struct dst_state *state)
 {
-       sema_init(&state->dst_mutex, 1);
+       mutex_init(&state->dst_mutex);
        if ((rdc_8820_reset(state)) < 0) {
                dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
                return -1;
@@ -962,7 +962,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
 {
        u8 reply;
 
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        if ((dst_comm_init(state)) < 0) {
                dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
                goto error;
@@ -1013,11 +1013,11 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
                dprintk(verbose, DST_INFO, 1, "checksum failure");
                goto error;
        }
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return 0;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 
 }
@@ -1128,7 +1128,7 @@ static int dst_write_tuna(struct dvb_frontend *fe)
                        dst_set_voltage(fe, SEC_VOLTAGE_13);
        }
        state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        if ((dst_comm_init(state)) < 0) {
                dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
                goto error;
@@ -1160,11 +1160,11 @@ static int dst_write_tuna(struct dvb_frontend *fe)
        state->diseq_flags |= ATTEMPT_TUNE;
        retval = dst_get_tuna(state);
 werr:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return retval;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 }
 
index c650b4b..f6b49a8 100644 (file)
@@ -81,7 +81,7 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
 {
        u8 reply;
 
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        dst_comm_init(state);
        msleep(65);
 
@@ -110,11 +110,11 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
                        goto error;
                }
        }
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return 0;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 }
 
index 81557f3..51d4e04 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/smp_lock.h>
 #include <linux/dvb/frontend.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #include "bt878.h"
 
 #include "dst_ca.h"
@@ -121,7 +122,7 @@ struct dst_state {
        u8 vendor[8];
        u8 board_info[8];
 
-       struct semaphore dst_mutex;
+       struct mutex dst_mutex;
 };
 
 struct dst_types {
index ea27b15..baa8227 100644 (file)
@@ -76,13 +76,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
        if (!dvbdmx->dmx.frontend)
                return -EINVAL;
 
-       down(&card->lock);
+       mutex_lock(&card->lock);
        card->nfeeds++;
        rc = card->nfeeds;
        if (card->nfeeds == 1)
                bt878_start(card->bt, card->gpio_mode,
                            card->op_sync_orin, card->irq_err_ignore);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
        return rc;
 }
 
@@ -96,11 +96,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        if (!dvbdmx->dmx.frontend)
                return -EINVAL;
 
-       down(&card->lock);
+       mutex_lock(&card->lock);
        card->nfeeds--;
        if (card->nfeeds == 0)
                bt878_stop(card->bt);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
 
        return 0;
 }
@@ -239,6 +239,20 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
 
 static int pinnsat_pll_init(struct dvb_frontend* fe)
 {
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_gpio_enable(card->bttv_nr, 1, 1);  /* output */
+       bttv_write_gpio(card->bttv_nr, 1, 1);   /* relay on */
+
+       return 0;
+}
+
+static int pinnsat_pll_sleep(struct dvb_frontend* fe)
+{
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_write_gpio(card->bttv_nr, 1, 0);   /* relay off */
+
        return 0;
 }
 
@@ -246,6 +260,7 @@ static struct cx24110_config pctvsat_config = {
        .demod_address = 0x55,
        .pll_init = pinnsat_pll_init,
        .pll_set = cx24108_pll_set,
+       .pll_sleep = pinnsat_pll_sleep,
 };
 
 static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -788,7 +803,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
        if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
                return -ENOMEM;
 
-       init_MUTEX(&card->lock);
+       mutex_init(&card->lock);
        card->bttv_nr = sub->core->nr;
        strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
        card->i2c_adapter = &sub->core->i2c_adap;
@@ -798,14 +813,14 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
                card->gpio_mode = 0x0400c060;
                /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
                              BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                break;
 
        case BTTV_BOARD_DVICO_DVBT_LITE:
                card->gpio_mode = 0x0400C060;
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* 26, 15, 14, 6, 5
                 * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA
                 * DA_APP(parallel) */
@@ -820,15 +835,15 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
        case BTTV_BOARD_NEBULA_DIGITV:
        case BTTV_BOARD_AVDVBT_761:
                card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* A_PWRDN DA_SBR DA_APP (high speed serial) */
                break;
 
        case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
                card->gpio_mode = 0x0400402B;
                card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = 0;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
                break;
 
@@ -852,8 +867,8 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
 
        case BTTV_BOARD_PC_HDTV:
                card->gpio_mode = 0x0100EC7B;
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                break;
 
        default:
@@ -881,7 +896,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
                return -EFAULT;
        }
 
-       init_MUTEX(&card->bt->gpio_lock);
+       mutex_init(&card->bt->gpio_lock);
        card->bt->bttv_nr = sub->core->nr;
 
        if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
index cf035a8..00dd9fa 100644 (file)
@@ -26,6 +26,7 @@
 #define DVB_BT8XX_H
 
 #include <linux/i2c.h>
+#include <linux/mutex.h>
 #include "dvbdev.h"
 #include "dvb_net.h"
 #include "bttv.h"
@@ -38,7 +39,7 @@
 #include "lgdt330x.h"
 
 struct dvb_bt8xx_card {
-       struct semaphore lock;
+       struct mutex lock;
        int nfeeds;
        char card_name[32];
        struct dvb_adapter dvb_adapter;
index c4b4c5b..29b7be5 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/input.h>
 #include <linux/dvb/frontend.h>
+#include <linux/mutex.h>
 
 #include "dmxdev.h"
 #include "dvb_demux.h"
@@ -116,7 +117,7 @@ static struct dvb_frontend_info cinergyt2_fe_info = {
 struct cinergyt2 {
        struct dvb_demux demux;
        struct usb_device *udev;
-       struct semaphore sem;
+       struct mutex sem;
        struct dvb_adapter adapter;
        struct dvb_device *fedev;
        struct dmxdev dmxdev;
@@ -345,14 +346,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (cinergyt2->streaming == 0)
                cinergyt2_start_stream_xfer(cinergyt2);
 
        cinergyt2->streaming++;
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -361,13 +362,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (--cinergyt2->streaming == 0)
                cinergyt2_stop_stream_xfer(cinergyt2);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -483,11 +484,11 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
        int err = -ERESTARTSYS;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if ((err = dvb_generic_open(inode, file))) {
-               up(&cinergyt2->sem);
+               mutex_unlock(&cinergyt2->sem);
                return err;
        }
 
@@ -499,7 +500,7 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
 
        atomic_inc(&cinergyt2->inuse);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -517,7 +518,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
-       if (down_interruptible(&cinergyt2->sem))
+       if (mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
@@ -526,7 +527,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
                cinergyt2_sleep(cinergyt2, 1);
        }
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 
        if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
                warn("delayed unregister in release");
@@ -541,12 +542,12 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        poll_wait(file, &cinergyt2->poll_wq, wait);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 
        return (POLLIN | POLLRDNORM | POLLPRI);
 }
@@ -613,7 +614,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
                if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
                        return -EFAULT;
 
-               if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+               if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                        return -ERESTARTSYS;
 
                param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -629,7 +630,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
                                        (char *) param, sizeof(*param),
                                        NULL, 0);
 
-               up(&cinergyt2->sem);
+               mutex_unlock(&cinergyt2->sem);
 
                return (err < 0) ? err : 0;
        }
@@ -724,7 +725,7 @@ static void cinergyt2_query_rc (void *data)
        struct cinergyt2_rc_event rc_events[12];
        int n, len, i;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return;
 
        len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
@@ -784,7 +785,7 @@ out:
        schedule_delayed_work(&cinergyt2->rc_query_work,
                              msecs_to_jiffies(RC_QUERY_INTERVAL));
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 }
 
 static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
@@ -849,7 +850,7 @@ static void cinergyt2_query (void *data)
        uint8_t lock_bits;
        uint32_t unc;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return;
 
        unc = s->uncorrected_block_count;
@@ -868,7 +869,7 @@ static void cinergyt2_query (void *data)
        schedule_delayed_work(&cinergyt2->query_work,
                              msecs_to_jiffies(QUERY_INTERVAL));
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 }
 
 static int cinergyt2_probe (struct usb_interface *intf,
@@ -885,7 +886,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
        memset (cinergyt2, 0, sizeof (struct cinergyt2));
        usb_set_intfdata (intf, (void *) cinergyt2);
 
-       init_MUTEX(&cinergyt2->sem);
+       mutex_init(&cinergyt2->sem);
        init_waitqueue_head (&cinergyt2->poll_wq);
        INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
 
@@ -967,7 +968,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 {
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (state.event > PM_EVENT_ON) {
@@ -981,7 +982,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
                cinergyt2_sleep(cinergyt2, 1);
        }
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -990,7 +991,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
        struct dvbt_set_parameters_msg *param = &cinergyt2->param;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (!cinergyt2->sleeping) {
@@ -1003,7 +1004,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
 
        cinergyt2_resume_rc(cinergyt2);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
index 7b8373a..4c52c85 100644 (file)
@@ -160,13 +160,6 @@ static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type)
        return NULL;
 }
 
-static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state)
-{
-       spin_lock_irq(&dmxdevdvr->dev->lock);
-       dmxdevdvr->state=state;
-       spin_unlock_irq(&dmxdevdvr->dev->lock);
-}
-
 static int dvb_dvr_open(struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
@@ -175,12 +168,12 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 
        dprintk ("function : %s\n", __FUNCTION__);
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        if ((file->f_flags&O_ACCMODE)==O_RDWR) {
                if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
-                       up(&dmxdev->mutex);
+                       mutex_unlock(&dmxdev->mutex);
                        return -EOPNOTSUPP;
                }
        }
@@ -190,7 +183,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
              dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
              dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
              if (!dmxdev->dvr_buffer.data) {
-                     up(&dmxdev->mutex);
+                     mutex_unlock(&dmxdev->mutex);
                      return -ENOMEM;
              }
        }
@@ -199,20 +192,20 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
                dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
 
                if (!dmxdev->demux->write) {
-                       up(&dmxdev->mutex);
+                       mutex_unlock(&dmxdev->mutex);
                        return -EOPNOTSUPP;
                }
 
                front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
 
                if (!front) {
-                       up(&dmxdev->mutex);
+                       mutex_unlock(&dmxdev->mutex);
                        return -EINVAL;
                }
                dmxdev->demux->disconnect_frontend(dmxdev->demux);
                dmxdev->demux->connect_frontend(dmxdev->demux, front);
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
@@ -221,7 +214,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
@@ -239,7 +232,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
                        vfree(mem);
                }
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
@@ -254,10 +247,10 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
                return -EOPNOTSUPP;
        if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
                return -EINVAL;
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
        ret=dmxdev->demux->write(dmxdev->demux, buf, count);
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
@@ -268,11 +261,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
        struct dmxdev *dmxdev = dvbdev->priv;
        int ret;
 
-       //down(&dmxdev->mutex);
+       //mutex_lock(&dmxdev->mutex);
        ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
                              file->f_flags&O_NONBLOCK,
                              buf, count, ppos);
-       //up(&dmxdev->mutex);
+       //mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
@@ -688,7 +681,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
        if (!dmxdev->filter)
                return -EINVAL;
 
-       if (down_interruptible(&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        for (i=0; i<dmxdev->filternum; i++)
@@ -696,12 +689,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
                        break;
 
        if (i==dmxdev->filternum) {
-               up(&dmxdev->mutex);
+               mutex_unlock(&dmxdev->mutex);
                return -EMFILE;
        }
 
        dmxdevfilter=&dmxdev->filter[i];
-       sema_init(&dmxdevfilter->mutex, 1);
+       mutex_init(&dmxdevfilter->mutex);
        dmxdevfilter->dvbdev=dmxdev->dvbdev;
        file->private_data=dmxdevfilter;
 
@@ -711,18 +704,18 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
        dmxdevfilter->feed.ts=NULL;
        init_timer(&dmxdevfilter->timer);
 
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
 
 static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter)
 {
-       if (down_interruptible(&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
-       if (down_interruptible(&dmxdevfilter->mutex)) {
-               up(&dmxdev->mutex);
+       if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+               mutex_unlock(&dmxdev->mutex);
                return -ERESTARTSYS;
        }
 
@@ -740,8 +733,8 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *d
 
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
        wake_up(&dmxdevfilter->buffer.queue);
-       up(&dmxdevfilter->mutex);
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdevfilter->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
@@ -841,7 +834,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        struct dmxdev_filter *dmxdevfilter= file->private_data;
        int ret=0;
 
-       if (down_interruptible(&dmxdevfilter->mutex))
+       if (mutex_lock_interruptible(&dmxdevfilter->mutex))
                return -ERESTARTSYS;
 
        if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
@@ -851,7 +844,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                                     file->f_flags&O_NONBLOCK,
                                     buf, count, ppos);
 
-       up(&dmxdevfilter->mutex);
+       mutex_unlock(&dmxdevfilter->mutex);
        return ret;
 }
 
@@ -864,58 +857,58 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
        unsigned long arg=(unsigned long) parg;
        int ret=0;
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        switch (cmd) {
        case DMX_START:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
                if (dmxdevfilter->state<DMXDEV_STATE_SET)
                        ret = -EINVAL;
                else
                        ret = dvb_dmxdev_filter_start(dmxdevfilter);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_STOP:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
                ret=dvb_dmxdev_filter_stop(dmxdevfilter);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_FILTER:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
                ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
                                    (struct dmx_sct_filter_params *)parg);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_PES_FILTER:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
                ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
                                               (struct dmx_pes_filter_params *)parg);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_BUFFER_SIZE:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
                ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_GET_EVENT:
@@ -959,7 +952,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
        default:
                ret=-EINVAL;
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
@@ -1030,7 +1023,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
 
        int ret=0;
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        switch (cmd) {
@@ -1042,7 +1035,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
        default:
                ret=-EINVAL;
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
@@ -1106,22 +1099,12 @@ dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
        if (!dmxdev->filter)
                return -ENOMEM;
 
-       dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr));
-       if (!dmxdev->dvr) {
-               vfree(dmxdev->filter);
-               dmxdev->filter = NULL;
-               return -ENOMEM;
-       }
-
-       sema_init(&dmxdev->mutex, 1);
+       mutex_init(&dmxdev->mutex);
        spin_lock_init(&dmxdev->lock);
        for (i=0; i<dmxdev->filternum; i++) {
                dmxdev->filter[i].dev=dmxdev;
                dmxdev->filter[i].buffer.data=NULL;
                dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
-               dmxdev->dvr[i].dev=dmxdev;
-               dmxdev->dvr[i].buffer.data=NULL;
-               dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
        }
 
        dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX);
@@ -1141,8 +1124,6 @@ dvb_dmxdev_release(struct dmxdev *dmxdev)
 
        vfree(dmxdev->filter);
        dmxdev->filter=NULL;
-       vfree(dmxdev->dvr);
-       dmxdev->dvr=NULL;
        dmxdev->demux->close(dmxdev->demux);
 }
 EXPORT_SYMBOL(dvb_dmxdev_release);
index fd72920..fafdf47 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/wait.h>
 #include <linux/fs.h>
 #include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include <linux/dvb/dmx.h>
 
@@ -83,7 +83,7 @@ struct dmxdev_filter {
        struct dmxdev *dev;
        struct dmxdev_buffer buffer;
 
-       struct semaphore mutex;
+       struct mutex mutex;
 
        /* only for sections */
        struct timer_list timer;
@@ -94,19 +94,11 @@ struct dmxdev_filter {
 };
 
 
-struct dmxdev_dvr {
-       int state;
-       struct dmxdev *dev;
-       struct dmxdev_buffer buffer;
-};
-
-
 struct dmxdev {
        struct dvb_device *dvbdev;
        struct dvb_device *dvr_dvbdev;
 
        struct dmxdev_filter *filter;
-       struct dmxdev_dvr *dvr;
        struct dmx_demux *demux;
 
        int filternum;
@@ -117,7 +109,7 @@ struct dmxdev {
        struct dmxdev_buffer dvr_buffer;
 #define DVR_BUFFER_SIZE (10*188*1024)
 
-       struct semaphore mutex;
+       struct mutex mutex;
        spinlock_t lock;
 };
 
index b4c899b..83ec5e0 100644 (file)
@@ -589,18 +589,18 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
        if (pid > DMX_MAX_PID)
                return -EINVAL;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (ts_type & TS_DECODER) {
                if (pes_type >= DMX_TS_PES_OTHER) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -EINVAL;
                }
 
                if (demux->pesfilter[pes_type] &&
                    demux->pesfilter[pes_type] != feed) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -EINVAL;
                }
 
@@ -622,14 +622,14 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
 #else
                feed->buffer = vmalloc(feed->buffer_size);
                if (!feed->buffer) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -ENOMEM;
                }
 #endif
        }
 
        feed->state = DMX_STATE_READY;
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -640,21 +640,21 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
        struct dvb_demux *demux = feed->demux;
        int ret;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 
        if (!demux->start_feed) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -ENODEV;
        }
 
        if ((ret = demux->start_feed(feed)) < 0) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return ret;
        }
 
@@ -662,7 +662,7 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
        ts_feed->is_filtering = 1;
        feed->state = DMX_STATE_GO;
        spin_unlock_irq(&demux->lock);
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -673,16 +673,16 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
        struct dvb_demux *demux = feed->demux;
        int ret;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state < DMX_STATE_GO) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 
        if (!demux->stop_feed) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -ENODEV;
        }
 
@@ -692,7 +692,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
        ts_feed->is_filtering = 0;
        feed->state = DMX_STATE_ALLOCATED;
        spin_unlock_irq(&demux->lock);
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return ret;
 }
@@ -704,11 +704,11 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
        struct dvb_demux *demux = (struct dvb_demux *)dmx;
        struct dvb_demux_feed *feed;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (!(feed = dvb_dmx_feed_alloc(demux))) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EBUSY;
        }
 
@@ -729,7 +729,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
 
        if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
                feed->state = DMX_STATE_FREE;
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EBUSY;
        }
 
@@ -737,7 +737,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
        feed->filter->feed = feed;
        feed->filter->state = DMX_STATE_READY;
 
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -748,11 +748,11 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
        struct dvb_demux *demux = (struct dvb_demux *)dmx;
        struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state == DMX_STATE_FREE) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 #ifndef NOBUFS
@@ -770,7 +770,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
        if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
                demux->pesfilter[feed->pes_type] = NULL;
 
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
        return 0;
 }
 
@@ -785,12 +785,12 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
        struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
        struct dvb_demux_filter *dvbdmxfilter;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
        if (!dvbdmxfilter) {
-               up(&dvbdemux->mutex);
+               mutex_unlock(&dvbdemux->mutex);
                return -EBUSY;
        }
 
@@ -805,7 +805,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
        dvbdmxfeed->filter = dvbdmxfilter;
        spin_unlock_irq(&dvbdemux->lock);
 
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -819,7 +819,7 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
        if (pid > 0x1fff)
                return -EINVAL;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        dvb_demux_feed_add(dvbdmxfeed);
@@ -833,13 +833,13 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
 #else
        dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
        if (!dvbdmxfeed->buffer) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENOMEM;
        }
 #endif
 
        dvbdmxfeed->state = DMX_STATE_READY;
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -871,16 +871,16 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
        int ret;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (feed->is_filtering) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EBUSY;
        }
 
        if (!dvbdmxfeed->filter) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 
@@ -890,14 +890,14 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        dvbdmxfeed->feed.sec.seclen = 0;
 
        if (!dvbdmx->start_feed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENODEV;
        }
 
        prepare_secfilters(dvbdmxfeed);
 
        if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return ret;
        }
 
@@ -906,7 +906,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        dvbdmxfeed->state = DMX_STATE_GO;
        spin_unlock_irq(&dvbdmx->lock);
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -916,11 +916,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
        int ret;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (!dvbdmx->stop_feed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENODEV;
        }
 
@@ -931,7 +931,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
        feed->is_filtering = 0;
        spin_unlock_irq(&dvbdmx->lock);
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return ret;
 }
 
@@ -942,11 +942,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (dvbdmxfilter->feed != dvbdmxfeed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 
@@ -966,7 +966,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
 
        dvbdmxfilter->state = DMX_STATE_FREE;
        spin_unlock_irq(&dvbdmx->lock);
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -977,11 +977,11 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
        struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
        struct dvb_demux_feed *dvbdmxfeed;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EBUSY;
        }
 
@@ -1006,7 +1006,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
        (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
        (*feed)->release_filter = dmx_section_feed_release_filter;
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -1016,11 +1016,11 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
        struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (dvbdmxfeed->state == DMX_STATE_FREE) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 #ifndef NOBUFS
@@ -1033,7 +1033,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
 
        dvbdmxfeed->pid = 0xffff;
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -1071,10 +1071,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
        if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
                return -EINVAL;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
        dvb_dmx_swfilter(dvbdemux, buf, count);
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
 
        if (signal_pending(current))
                return -EINTR;
@@ -1126,11 +1126,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux,
        if (demux->frontend)
                return -EINVAL;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        demux->frontend = frontend;
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -1138,11 +1138,11 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
 {
        struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        demux->frontend = NULL;
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -1215,7 +1215,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
        dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
        dmx->get_pes_pids = dvbdmx_get_pes_pids;
 
-       sema_init(&dvbdemux->mutex, 1);
+       mutex_init(&dvbdemux->mutex);
        spin_lock_init(&dvbdemux->lock);
 
        return 0;
index 0cc8883..2c5f915 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/time.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "demux.h"
 
@@ -125,7 +125,7 @@ struct dvb_demux {
        u8 tsbuf[204];
        int tsbufp;
 
-       struct semaphore mutex;
+       struct mutex mutex;
        spinlock_t lock;
 };
 
index 771f32d..2c3ea8f 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/suspend.h>
 #include <linux/jiffies.h>
 #include <asm/processor.h>
-#include <asm/semaphore.h>
 
 #include "dvb_frontend.h"
 #include "dvbdev.h"
@@ -50,13 +49,13 @@ static int dvb_powerdown_on_sleep = 1;
 
 module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
 MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
-module_param(dvb_shutdown_timeout, int, 0444);
+module_param(dvb_shutdown_timeout, int, 0644);
 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
-module_param(dvb_force_auto_inversion, int, 0444);
+module_param(dvb_force_auto_inversion, int, 0644);
 MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
-module_param(dvb_override_tune_delay, int, 0444);
+module_param(dvb_override_tune_delay, int, 0644);
 MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
-module_param(dvb_powerdown_on_sleep, int, 0444);
+module_param(dvb_powerdown_on_sleep, int, 0644);
 MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)");
 
 #define dprintk if (dvb_frontend_debug) printk
@@ -88,7 +87,7 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola
  * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
  */
 
-static DECLARE_MUTEX(frontend_mutex);
+static DEFINE_MUTEX(frontend_mutex);
 
 struct dvb_frontend_private {
 
@@ -1021,12 +1020,12 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if (down_interruptible (&frontend_mutex))
+       if (mutex_lock_interruptible(&frontend_mutex))
                return -ERESTARTSYS;
 
        fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
        if (fe->frontend_priv == NULL) {
-               up(&frontend_mutex);
+               mutex_unlock(&frontend_mutex);
                return -ENOMEM;
        }
        fepriv = fe->frontend_priv;
@@ -1045,7 +1044,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
        dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
                             fe, DVB_DEVICE_FRONTEND);
 
-       up (&frontend_mutex);
+       mutex_unlock(&frontend_mutex);
        return 0;
 }
 EXPORT_SYMBOL(dvb_register_frontend);
@@ -1055,7 +1054,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        dprintk ("%s\n", __FUNCTION__);
 
-       down (&frontend_mutex);
+       mutex_lock(&frontend_mutex);
        dvb_unregister_device (fepriv->dvbdev);
        dvb_frontend_stop (fe);
        if (fe->ops->release)
@@ -1064,7 +1063,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
                printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
        /* fe is invalid now */
        kfree(fepriv);
-       up (&frontend_mutex);
+       mutex_unlock(&frontend_mutex);
        return 0;
 }
 EXPORT_SYMBOL(dvb_unregister_frontend);
index 70a6d14..d5aee5a 100644 (file)
@@ -104,6 +104,7 @@ struct dvb_frontend {
        struct dvb_adapter *dvb;
        void* demodulator_priv;
        void* frontend_priv;
+       void* misc_priv;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter* dvb,
index 6711eb6..2f0f358 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/uio.h>
 #include <asm/uaccess.h>
 #include <linux/crc32.h>
+#include <linux/mutex.h>
 
 #include "dvb_demux.h"
 #include "dvb_net.h"
@@ -151,8 +152,7 @@ struct dvb_net_priv {
        unsigned char ule_bridged;              /* Whether the ULE_BRIDGED extension header was found. */
        int ule_sndu_remain;                    /* Nr. of bytes still required for current ULE SNDU. */
        unsigned long ts_count;                 /* Current ts cell counter. */
-
-       struct semaphore mutex;
+       struct mutex mutex;
 };
 
 
@@ -889,7 +889,7 @@ static int dvb_net_feed_start(struct net_device *dev)
        unsigned char *mac = (unsigned char *) dev->dev_addr;
 
        dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
-       down(&priv->mutex);
+       mutex_lock(&priv->mutex);
        if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
                printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
 
@@ -974,7 +974,7 @@ static int dvb_net_feed_start(struct net_device *dev)
                ret = -EINVAL;
 
 error:
-       up(&priv->mutex);
+       mutex_unlock(&priv->mutex);
        return ret;
 }
 
@@ -984,7 +984,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
        int i, ret = 0;
 
        dprintk("%s\n", __FUNCTION__);
-       down(&priv->mutex);
+       mutex_lock(&priv->mutex);
        if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
                if (priv->secfeed) {
                        if (priv->secfeed->is_filtering) {
@@ -1026,7 +1026,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
                        printk("%s: no ts feed to stop\n", dev->name);
        } else
                ret = -EINVAL;
-       up(&priv->mutex);
+       mutex_unlock(&priv->mutex);
        return ret;
 }
 
@@ -1208,7 +1208,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
 
        INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
        INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
-       init_MUTEX(&priv->mutex);
+       mutex_init(&priv->mutex);
 
        net->base_addr = pid;
 
index 162f979..e14bf43 100644 (file)
@@ -77,7 +77,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -126,7 +126,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
                }
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index 269d899..2d52b76 100644 (file)
@@ -128,7 +128,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                                break;
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index caa1346..91136c0 100644 (file)
@@ -48,7 +48,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -67,7 +67,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                                break;
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index ce34a55..a1705ec 100644 (file)
@@ -42,8 +42,8 @@ static int dvb_usb_init(struct dvb_usb_device *d)
 {
        int ret = 0;
 
-       sema_init(&d->usb_sem, 1);
-       sema_init(&d->i2c_sem, 1);
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
 
        d->state = DVB_USB_STATE_INIT;
 
index ee82197..9002f35 100644 (file)
@@ -21,7 +21,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
        if (wbuf == NULL || wlen == 0)
                return -EINVAL;
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        deb_xfer(">>> ");
@@ -53,7 +53,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
                }
        }
 
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
        return ret;
 }
 EXPORT_SYMBOL(dvb_usb_generic_rw);
index d4909e5..fead958 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/mutex.h>
 
 #include "dvb_frontend.h"
 #include "dvb_demux.h"
@@ -227,8 +228,8 @@ struct dvb_usb_properties {
  * @feedcount: number of reqested feeds (used for streaming-activation)
  * @pid_filtering: is hardware pid_filtering used or not.
  *
- * @usb_sem: semaphore of USB control messages (reading needs two messages)
- * @i2c_sem: semaphore for i2c-transfers
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
  *
  * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
  * @pll_addr: I2C address of the tuner for programming
@@ -283,10 +284,10 @@ struct dvb_usb_device {
        int pid_filtering;
 
        /* locking */
-       struct semaphore usb_sem;
+       struct mutex usb_mutex;
 
        /* i2c */
-       struct semaphore i2c_sem;
+       struct mutex i2c_mutex;
        struct i2c_adapter i2c_adap;
 
        /* tuner programming information */
index 4a95eca..b2f098a 100644 (file)
@@ -75,7 +75,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
 {
        int ret;
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
@@ -84,7 +84,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
        ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
 
 unlock:
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
 
        return ret;
 }
index 3835235..8ea3834 100644 (file)
@@ -38,7 +38,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
        deb_xfer("out buffer: ");
        debug_dump(outbuf,outlen+1,deb_xfer);
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        if (usb_control_msg(d->udev,
@@ -68,7 +68,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
                memcpy(in,&inbuf[1],inlen);
 
 unlock:
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
 
        return ret;
 }
index c676b1e..a1a894d 100644 (file)
@@ -116,6 +116,12 @@ config DVB_MT352
        help
          A DVB-T tuner module. Say Y when you want to support this frontend.
 
+config DVB_ZL10353
+       tristate "Zarlink ZL10353 based"
+       depends on DVB_CORE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
 config DVB_DIB3000MB
        tristate "DiBcom 3000M-B"
        depends on DVB_CORE
index 1af769c..d09b607 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
 obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
+obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
index caaee89..1708a1d 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/jiffies.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 
 #include "dvb_frontend.h"
 #include "bcm3510.h"
@@ -52,7 +53,7 @@ struct bcm3510_state {
        struct dvb_frontend frontend;
 
        /* demodulator private data */
-       struct semaphore hab_sem;
+       struct mutex hab_mutex;
        u8 firmware_loaded:1;
 
        unsigned long next_status_check;
@@ -213,7 +214,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
        dbufout(ob,olen+2,deb_hab);
        deb_hab("\n");
 
-       if (down_interruptible(&st->hab_sem) < 0)
+       if (mutex_lock_interruptible(&st->hab_mutex) < 0)
                return -EAGAIN;
 
        if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
@@ -226,7 +227,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
 
        memcpy(ibuf,&ib[2],ilen);
 error:
-       up(&st->hab_sem);
+       mutex_unlock(&st->hab_mutex);
        return ret;
 }
 
@@ -796,7 +797,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
        state->frontend.ops = &state->ops;
        state->frontend.demodulator_priv = state;
 
-       sema_init(&state->hab_sem, 1);
+       mutex_init(&state->hab_mutex);
 
        if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
                goto error;
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
new file mode 100644 (file)
index 0000000..78573b2
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSBE1_H
+#define BSBE1_H
+
+static u8 alps_bsbe1_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,   // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,  // 1/2 threshold
+       0x2a, 0x14,  // 2/3 threshold
+       0x2b, 0x0f,  // 3/4 threshold
+       0x2c, 0x09,  // 5/6 threshold
+       0x2d, 0x05,  // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,  // test all FECs
+       0x32, 0x19,  // viterbi and synchro search
+       0x33, 0xfc,  // rs control
+       0x34, 0x93,  // error control
+       0x0f, 0x92,
+       0xff, 0xff
+};
+
+
+static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
+       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
+       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
+       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
+       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
+       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio      ) & 0xf0);
+
+       return 0;
+}
+
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
+{
+       int ret;
+       u8 data[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       if ((params->frequency < 950000) || (params->frequency > 2150000))
+               return -EINVAL;
+
+       div = (params->frequency + (125 - 1)) / 125; // round correctly
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+
+       ret = i2c_transfer(i2c, &msg, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
+static struct stv0299_config alps_bsbe1_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsbe1_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
+       .pll_set = alps_bsbe1_pll_set,
+};
+
+#endif
index d15d32c..f3edf8b 100644 (file)
@@ -371,6 +371,15 @@ static int cx24110_initfe(struct dvb_frontend* fe)
        return 0;
 }
 
+static int cx24110_sleep(struct dvb_frontend *fe)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       if (state->config->pll_sleep)
+                 return state->config->pll_sleep(fe);
+       return 0;
+}
+
 static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
        struct cx24110_state *state = fe->demodulator_priv;
@@ -418,6 +427,9 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
        struct cx24110_state *state = fe->demodulator_priv;
        unsigned long timeout;
 
+       if (cmd->msg_len < 3 || cmd->msg_len > 6)
+               return -EINVAL;  /* not implemented */
+
        for (i = 0; i < cmd->msg_len; i++)
                cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
 
@@ -639,6 +651,7 @@ static struct dvb_frontend_ops cx24110_ops = {
        .release = cx24110_release,
 
        .init = cx24110_initfe,
+       .sleep = cx24110_sleep,
        .set_frontend = cx24110_set_frontend,
        .get_frontend = cx24110_get_frontend,
        .read_status = cx24110_read_status,
index b63ecf2..609ac64 100644 (file)
@@ -35,6 +35,7 @@ struct cx24110_config
        /* PLL maintenance */
        int (*pll_init)(struct dvb_frontend* fe);
        int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+       int (*pll_sleep)(struct dvb_frontend* fe);
 };
 
 extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
index 4dcb605..b6e2c38 100644 (file)
@@ -362,6 +362,63 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
 };
 EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
 
+/*
+ * Philips TD1316 Tuner.
+ */
+static void td1316_bw(u8 *buf, u32 freq, int bandwidth)
+{
+       u8 band;
+
+       /* determine band */
+       if (freq < 161000000)
+               band = 1;
+       else if (freq < 444000000)
+               band = 2;
+       else
+               band = 4;
+
+       buf[3] |= band;
+
+       /* setup PLL filter */
+       if (bandwidth == BANDWIDTH_8_MHZ)
+               buf[3] |= 1 << 3;
+}
+
+struct dvb_pll_desc dvb_pll_philips_td1316 = {
+       .name  = "Philips TD1316",
+       .min   =  87000000,
+       .max   = 895000000,
+       .setbw = td1316_bw,
+       .count = 9,
+       .entries = {
+               {  93834000, 36166000, 166666, 0xca, 0x60},
+               { 123834000, 36166000, 166666, 0xca, 0xa0},
+               { 163834000, 36166000, 166666, 0xca, 0xc0},
+               { 253834000, 36166000, 166666, 0xca, 0x60},
+               { 383834000, 36166000, 166666, 0xca, 0xa0},
+               { 443834000, 36166000, 166666, 0xca, 0xc0},
+               { 583834000, 36166000, 166666, 0xca, 0x60},
+               { 793834000, 36166000, 166666, 0xca, 0xa0},
+               { 858834000, 36166000, 166666, 0xca, 0xe0},
+       },
+};
+EXPORT_SYMBOL(dvb_pll_philips_td1316);
+
+/* FE6600 used on DViCO Hybrid */
+struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
+       .name = "Thomson FE6600",
+       .min =  44250000,
+       .max = 858000000,
+       .count = 4,
+       .entries = {
+               { 250000000, 36213333, 166667, 0xb4, 0x12 },
+               { 455000000, 36213333, 166667, 0xfe, 0x11 },
+               { 775500000, 36213333, 166667, 0xbc, 0x18 },
+               { 999999999, 36213333, 166667, 0xf4, 0x18 },
+       }
+};
+EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
+
 /* ----------------------------------------------------------- */
 /* code                                                        */
 
@@ -391,8 +448,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
        div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
        buf[0] = div >> 8;
        buf[1] = div & 0xff;
-       buf[2] = desc->entries[i].cb1;
-       buf[3] = desc->entries[i].cb2;
+       buf[2] = desc->entries[i].config;
+       buf[3] = desc->entries[i].cb;
 
        if (desc->setbw)
                desc->setbw(buf, freq, bandwidth);
index bb8d4b4..2b84617 100644 (file)
@@ -15,8 +15,8 @@ struct dvb_pll_desc {
                u32 limit;
                u32 offset;
                u32 stepsize;
-               u8  cb1;
-               u8  cb2;
+               u8  config;
+               u8  cb;
        } entries[12];
 };
 
@@ -40,6 +40,9 @@ extern struct dvb_pll_desc dvb_pll_tuv1236d;
 extern struct dvb_pll_desc dvb_pll_tdhu2;
 extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
 extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
+extern struct dvb_pll_desc dvb_pll_philips_td1316;
+
+extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
 
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
                      u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
new file mode 100644 (file)
index 0000000..0dcbe61
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * lnbp21.h - driver for lnb supply and control ic lnbp21
+ *
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _LNBP21_H
+#define _LNBP21_H
+
+/* system register */
+#define LNBP21_OLF     0x01
+#define LNBP21_OTF     0x02
+#define LNBP21_EN      0x04
+#define LNBP21_VSEL    0x08
+#define LNBP21_LLC     0x10
+#define LNBP21_TEN     0x20
+#define LNBP21_ISEL    0x40
+#define LNBP21_PCL     0x80
+
+struct lnbp21 {
+       u8                      config;
+       u8                      override_or;
+       u8                      override_and;
+       struct i2c_adapter      *i2c;
+       void                    (*release_chain)(struct dvb_frontend* fe);
+};
+
+static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+       struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
+
+       switch(voltage) {
+       case SEC_VOLTAGE_OFF:
+               break;
+       case SEC_VOLTAGE_13:
+               lnbp21->config |= LNBP21_EN;
+               break;
+       case SEC_VOLTAGE_18:
+               lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+       struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       if (arg)
+               lnbp21->config |= LNBP21_LLC;
+       else
+               lnbp21->config &= ~LNBP21_LLC;
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void lnbp21_exit(struct dvb_frontend *fe)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+
+       /* LNBP power off */
+       lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free data & call next release routine */
+       fe->ops->release = lnbp21->release_chain;
+       kfree(fe->misc_priv);
+       fe->misc_priv = NULL;
+       if (fe->ops->release)
+               fe->ops->release(fe);
+}
+
+static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+{
+       struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
+
+       if (!lnbp21)
+               return -ENOMEM;
+
+       /* default configuration */
+       lnbp21->config = LNBP21_ISEL;
+
+       /* bits which should be forced to '1' */
+       lnbp21->override_or = override_set;
+
+       /* bits which should be forced to '0' */
+       lnbp21->override_and = ~override_clear;
+
+       /* install release callback */
+       lnbp21->release_chain = fe->ops->release;
+       fe->ops->release = lnbp21_exit;
+
+       /* override frontend ops */
+       fe->ops->set_voltage = lnbp21_set_voltage;
+       fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+
+       lnbp21->i2c = i2c;
+       fe->misc_priv = lnbp21;
+
+       return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+}
+
+#endif
index c63e9a5..8e8df7b 100644 (file)
@@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
        dprintk("%s\n", __FUNCTION__);
 
        result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
-       msleep(1);
+       msleep(20);
        return result;
 }
 
@@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
        const struct firmware *fw;
 
        /* reset + wake up chip */
-       tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+       if (state->config->xtal_freq == TDA10046_XTAL_4M) {
+               tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+       } else {
+               dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
+               tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+       }
        tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
        /* let the clocks recover from sleep */
        msleep(5);
@@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe)
        // tda setup
        tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
        tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87);    // 100 ppm crystal, select HP stream
-       tda1004x_write_byteI(state, TDA1004X_CONFC1, 8);      // disable pulse killer
+       tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88);      // enable pulse killer
 
        switch (state->config->agc_config) {
        case TDA10046_AGC_DEFAULT:
@@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe)
                tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
                tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
                break;
+       case TDA10046_AGC_TDA827X_GPL:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
+               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
+               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+               break;
        }
        tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
        tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
@@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe)
        tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
        tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
        tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+       // tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
        tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
 
        state->initialised = 1;
@@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
                if (status == -1)
                        return -EIO;
                cber |= (status << 8);
+               // The address 0x20 should be read to cope with a TDA10046 bug
                tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
                if (cber != 65535)
@@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
                status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
                if (status == -1)
                        return -EIO;
-               vber |= ((status << 16) & 0x0f);
+               vber |= (status & 0x0f) << 16;
+               // The CVBER_LUT should be read to cope with TDA10046 hardware bug
                tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
 
                // if RS has passed some valid TS packets, then we must be
@@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
        if (tmp < 0)
                return -EIO;
        *ber |= (tmp << 9);
+       // The address 0x20 should be read to cope with a TDA10046 bug
        tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
        dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
@@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
                                tda1004x_disable_tuner_i2c(state);
                        }
                }
+               /* set outputs to tristate */
+               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
                tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
                break;
        }
index 8659c52..cc0c4af 100644 (file)
@@ -35,7 +35,8 @@ enum tda10046_agc {
        TDA10046_AGC_DEFAULT,           /* original configuration */
        TDA10046_AGC_IFO_AUTO_NEG,      /* IF AGC only, automatic, negtive */
        TDA10046_AGC_IFO_AUTO_POS,      /* IF AGC only, automatic, positive */
-       TDA10046_AGC_TDA827X,       /* IF AGC only, special setup for tda827x */
+       TDA10046_AGC_TDA827X,           /* IF AGC only, special setup for tda827x */
+       TDA10046_AGC_TDA827X_GPL,       /* same as above, but GPIOs 0 */
 };
 
 enum tda10046_if {
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
new file mode 100644 (file)
index 0000000..23846c4
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ * 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.=
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "zl10353_priv.h"
+#include "zl10353.h"
+
+struct zl10353_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend frontend;
+       struct dvb_frontend_ops ops;
+
+       struct zl10353_config config;
+};
+
+static int debug_regs = 0;
+
+static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+       int err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
+               return err;
+       }
+       return 0;
+}
+
+int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen)
+{
+       int err, i;
+       for (i = 0; i < ilen - 1; i++)
+               if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
+                       return err;
+
+       return 0;
+}
+
+static int zl10353_read_register(struct zl10353_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[1] = { reg };
+       u8 b1[1] = { 0 };
+       struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
+                                   .flags = 0,
+                                   .buf = b0, .len = 1 },
+                                 { .addr = state->config.demod_address,
+                                   .flags = I2C_M_RD,
+                                   .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk("%s: readreg error (reg=%d, ret==%i)\n",
+                      __FUNCTION__, reg, ret);
+               return ret;
+       }
+
+       return b1[0];
+}
+
+void zl10353_dump_regs(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       char buf[52], buf2[4];
+       int ret;
+       u8 reg;
+
+       /* Dump all registers. */
+       for (reg = 0; ; reg++) {
+               if (reg % 16 == 0) {
+                       if (reg)
+                               printk(KERN_DEBUG "%s\n", buf);
+                       sprintf(buf, "%02x: ", reg);
+               }
+               ret = zl10353_read_register(state, reg);
+               if (ret >= 0)
+                       sprintf(buf2, "%02x ", (u8)ret);
+               else
+                       strcpy(buf2, "-- ");
+               strcat(buf, buf2);
+               if (reg == 0xff)
+                       break;
+       }
+       printk(KERN_DEBUG "%s\n", buf);
+}
+
+static int zl10353_sleep(struct dvb_frontend *fe)
+{
+       static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
+
+       zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
+       return 0;
+}
+
+static int zl10353_set_parameters(struct dvb_frontend *fe,
+                                 struct dvb_frontend_parameters *param)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 pllbuf[6] = { 0x67 };
+
+       /* These settings set "auto-everything" and start the FSM. */
+       zl10353_single_write(fe, 0x55, 0x80);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x01);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x00);
+
+       zl10353_single_write(fe, 0x56, 0x28);
+       zl10353_single_write(fe, 0x89, 0x20);
+       zl10353_single_write(fe, 0x5E, 0x00);
+       zl10353_single_write(fe, 0x65, 0x5A);
+       zl10353_single_write(fe, 0x66, 0xE9);
+       zl10353_single_write(fe, 0x62, 0x0A);
+
+       state->config.pll_set(fe, param, pllbuf + 1);
+       zl10353_write(fe, pllbuf, sizeof(pllbuf));
+
+       zl10353_single_write(fe, 0x70, 0x01);
+       udelay(250);
+       zl10353_single_write(fe, 0xE4, 0x00);
+       zl10353_single_write(fe, 0xE5, 0x2A);
+       zl10353_single_write(fe, 0xE9, 0x02);
+       zl10353_single_write(fe, 0xE7, 0x40);
+       zl10353_single_write(fe, 0xE8, 0x10);
+
+       return 0;
+}
+
+static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       int s6, s7, s8;
+
+       if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
+               return -EREMOTEIO;
+       if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
+               return -EREMOTEIO;
+       if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
+               return -EREMOTEIO;
+
+       *status = 0;
+       if (s6 & (1 << 2))
+               *status |= FE_HAS_CARRIER;
+       if (s6 & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if (s6 & (1 << 5))
+               *status |= FE_HAS_LOCK;
+       if (s7 & (1 << 4))
+               *status |= FE_HAS_SYNC;
+       if (s8 & (1 << 6))
+               *status |= FE_HAS_SIGNAL;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+           (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 _snr;
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+
+       _snr = zl10353_read_register(state, SNR);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int zl10353_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings
+                                        *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 1000;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static int zl10353_init(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
+       int rc = 0;
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+
+       /* Do a "hard" reset if not already done */
+       if (zl10353_read_register(state, 0x50) != 0x03) {
+               rc = zl10353_write(fe, zl10353_reset_attach,
+                                  sizeof(zl10353_reset_attach));
+               if (debug_regs)
+                       zl10353_dump_regs(fe);
+       }
+
+       return 0;
+}
+
+static void zl10353_release(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+
+       kfree(state);
+}
+
+static struct dvb_frontend_ops zl10353_ops;
+
+struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct zl10353_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config, config, sizeof(struct zl10353_config));
+       memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
+
+       /* check if the demod is there */
+       if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+               goto error;
+
+       /* create dvb_frontend */
+       state->frontend.ops = &state->ops;
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops zl10353_ops = {
+
+       .info = {
+               .name                   = "Zarlink ZL10353 DVB-T",
+               .type                   = FE_OFDM,
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = zl10353_release,
+
+       .init = zl10353_init,
+       .sleep = zl10353_sleep,
+
+       .set_frontend = zl10353_set_parameters,
+       .get_tune_settings = zl10353_get_tune_settings,
+
+       .read_status = zl10353_read_status,
+       .read_snr = zl10353_read_snr,
+};
+
+module_param(debug_regs, int, 0644);
+MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
+
+MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
+MODULE_AUTHOR("Chris Pascoe");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(zl10353_attach);
+EXPORT_SYMBOL(zl10353_write);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
new file mode 100644 (file)
index 0000000..5cc4ae7
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  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.=
+ */
+
+#ifndef ZL10353_H
+#define ZL10353_H
+
+#include <linux/dvb/frontend.h>
+
+struct zl10353_config
+{
+       /* demodulator's I2C address */
+       u8 demod_address;
+
+       /* function which configures the PLL buffer (for secondary I2C
+        * connected tuner) or tunes the PLL (for direct connected tuner) */
+       int (*pll_set)(struct dvb_frontend *fe,
+                      struct dvb_frontend_parameters *params, u8 *pllbuf);
+};
+
+extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
+                                          struct i2c_adapter *i2c);
+
+extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen);
+
+#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
new file mode 100644 (file)
index 0000000..b72224b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  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.=
+ */
+
+#ifndef _ZL10353_PRIV_
+#define _ZL10353_PRIV_
+
+#define ID_ZL10353     0x14
+
+enum zl10353_reg_addr {
+       INTERRUPT_0     = 0x00,
+       INTERRUPT_1     = 0x01,
+       INTERRUPT_2     = 0x02,
+       INTERRUPT_3     = 0x03,
+       INTERRUPT_4     = 0x04,
+       INTERRUPT_5     = 0x05,
+       STATUS_6        = 0x06,
+       STATUS_7        = 0x07,
+       STATUS_8        = 0x08,
+       STATUS_9        = 0x09,
+       SNR             = 0x10,
+       CHIP_ID         = 0x7F,
+};
+
+#endif                          /* _ZL10353_PRIV_ */
index 7c6ccb9..aef4f58 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/i2c.h>
 
 #include <asm/system.h>
-#include <asm/semaphore.h>
 
 #include <linux/dvb/frontend.h>
 
@@ -67,6 +66,9 @@
 #include "av7110_ca.h"
 #include "av7110_ipack.h"
 
+#include "bsbe1.h"
+#include "lnbp21.h"
+
 #define TS_WIDTH  376
 #define TS_HEIGHT 512
 #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
@@ -242,10 +244,10 @@ static int arm_thread(void *data)
                if (!av7110->arm_ready)
                        continue;
 
-               if (down_interruptible(&av7110->dcomlock))
+               if (mutex_lock_interruptible(&av7110->dcomlock))
                        break;
                newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
 
                if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
                        printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
@@ -253,10 +255,10 @@ static int arm_thread(void *data)
 
                        recover_arm(av7110);
 
-                       if (down_interruptible(&av7110->dcomlock))
+                       if (mutex_lock_interruptible(&av7110->dcomlock))
                                break;
                        newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                }
                av7110->arm_loops = newloops;
                av7110->arm_errors = 0;
@@ -741,7 +743,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
        int ret = 0;
        dprintk(4, "%p\n", av7110);
 
-       if (down_interruptible(&av7110->pid_mutex))
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
                return -ERESTARTSYS;
 
        if (!(vpid & 0x8000))
@@ -760,7 +762,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
                ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
        }
 
-       up(&av7110->pid_mutex);
+       mutex_unlock(&av7110->pid_mutex);
        return ret;
 }
 
@@ -1673,105 +1675,6 @@ static struct stv0299_config alps_bsru6_config = {
 };
 
 
-static u8 alps_bsbe1_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x92,
-       0xff, 0xff
-};
-
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
-
-       ret = i2c_transfer(i2c, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static struct stv0299_config alps_bsbe1_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsbe1_pll_set,
-};
-
-static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
-       int ret;
-       u8 data[1];
-       struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       switch(voltage) {
-       case SEC_VOLTAGE_OFF:
-               data[0] = 0x00;
-               break;
-       case SEC_VOLTAGE_13:
-               data[0] = 0x44;
-               break;
-       case SEC_VOLTAGE_18:
-               data[0] = 0x4c;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-
 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct av7110* av7110 = fe->dvb->priv;
@@ -2096,7 +1999,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
        if (av7110->playing)
                return 0;
 
-       if (down_interruptible(&av7110->pid_mutex))
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
                return -ERESTARTSYS;
 
        if (synced) {
@@ -2118,7 +2021,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
        if (!ret)
                av7110->fe_synced = synced;
 
-       up(&av7110->pid_mutex);
+       mutex_unlock(&av7110->pid_mutex);
        return ret;
 }
 
@@ -2374,9 +2277,15 @@ static int frontend_init(struct av7110 *av7110)
                        /* ALPS BSBE1 */
                        av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
                        if (av7110->fe) {
-                               av7110->fe->ops->set_voltage = lnbp21_set_voltage;
-                               av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
-                               av7110->recover = dvb_s_recover;
+                               if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
+                                       printk("dvb-ttpci: LNBP21 not found!\n");
+                                       if (av7110->fe->ops->release)
+                                               av7110->fe->ops->release(av7110->fe);
+                                       av7110->fe = NULL;
+                               } else {
+                                       av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
+                                       av7110->recover = dvb_s_recover;
+                               }
                        }
                        break;
                }
@@ -2714,16 +2623,16 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
        tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
        tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
 
-       sema_init(&av7110->pid_mutex, 1);
+       mutex_init(&av7110->pid_mutex);
 
        /* locks for data transfers from/to AV7110 */
        spin_lock_init(&av7110->debilock);
-       sema_init(&av7110->dcomlock, 1);
+       mutex_init(&av7110->dcomlock);
        av7110->debitype = -1;
 
        /* default OSD window */
        av7110->osdwin = 1;
-       sema_init(&av7110->osd_sema, 1);
+       mutex_init(&av7110->osd_mutex);
 
        /* ARM "watchdog" */
        init_waitqueue_head(&av7110->arm_wait);
index fafd25f..3e2e121 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/dvb/ca.h>
 #include <linux/dvb/osd.h>
 #include <linux/dvb/net.h>
+#include <linux/mutex.h>
 
 #include "dvbdev.h"
 #include "demux.h"
@@ -127,7 +128,7 @@ struct av7110 {
        /* DEBI and polled command interface */
 
        spinlock_t              debilock;
-       struct semaphore        dcomlock;
+       struct mutex            dcomlock;
        volatile int            debitype;
        volatile int            debilen;
 
@@ -146,7 +147,7 @@ struct av7110 {
 
        int                     osdwin;      /* currently active window */
        u16                     osdbpp[8];
-       struct semaphore        osd_sema;
+       struct mutex            osd_mutex;
 
        /* CA */
 
@@ -172,7 +173,7 @@ struct av7110 {
        struct tasklet_struct   vpe_tasklet;
 
        int                     fe_synced;
-       struct semaphore        pid_mutex;
+       struct mutex            pid_mutex;
 
        int                     video_blank;
        struct video_status     videostate;
index 0bb6e74..75736f2 100644 (file)
@@ -327,10 +327,10 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
        start = jiffies;
        for (;;) {
                err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (down_interruptible(&av7110->dcomlock))
+               if (mutex_lock_interruptible(&av7110->dcomlock))
                        return -ERESTARTSYS;
                stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                if ((stat & flags) == 0)
                        break;
                if (err) {
@@ -487,11 +487,11 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
                dprintk(1, "arm not ready.\n");
                return -1;
        }
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        ret = __av7110_send_fw_cmd(av7110, buf, length);
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        if (ret && ret!=-ERESTARTSYS)
                printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
                       __FUNCTION__, ret);
@@ -563,11 +563,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                return -1;
        }
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
                return err;
        }
@@ -579,7 +579,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                        break;
                if (err) {
                        printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
 #ifdef _NOHANDSHAKE
@@ -595,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                        break;
                if (err) {
                        printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -606,12 +606,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
        stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
        if (stat & GPMQOver) {
                printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                return -1;
        }
        else if (stat & OSDQOver) {
                printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                return -1;
        }
 #endif
@@ -619,7 +619,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
        for (i = 0; i < reply_buf_len; i++)
                reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
 
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        return 0;
 }
 
@@ -735,7 +735,7 @@ static int FlushText(struct av7110 *av7110)
        unsigned long start;
        int err;
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
        start = jiffies;
        while (1) {
@@ -745,12 +745,12 @@ static int FlushText(struct av7110 *av7110)
                if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
        }
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        return 0;
 }
 
@@ -761,7 +761,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
        int length = strlen(buf) + 1;
        u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        start = jiffies;
@@ -772,7 +772,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
                if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -786,7 +786,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
                if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -798,7 +798,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
        if (length & 1)
                wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
        ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        if (ret && ret!=-ERESTARTSYS)
                printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
        return ret;
@@ -1062,7 +1062,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
 {
        int ret;
 
-       if (down_interruptible(&av7110->osd_sema))
+       if (mutex_lock_interruptible(&av7110->osd_mutex))
                return -ERESTARTSYS;
 
        switch (dc->cmd) {
@@ -1198,7 +1198,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
                break;
        }
 
-       up(&av7110->osd_sema);
+       mutex_unlock(&av7110->osd_mutex);
        if (ret==-ERESTARTSYS)
                dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
        else if (ret)
index 1465c04..9dd4745 100644 (file)
@@ -1000,6 +1000,7 @@ static u8 read_pwm(struct budget_av *budget_av)
 
 #define SUBID_DVBS_TV_STAR     0x0014
 #define SUBID_DVBS_TV_STAR_CI  0x0016
+#define SUBID_DVBS_EASYWATCH   0x001e
 #define SUBID_DVBC_KNC1                0x0020
 #define SUBID_DVBC_KNC1_PLUS   0x0021
 #define SUBID_DVBC_CINERGY1200 0x1156
@@ -1038,6 +1039,7 @@ static void frontend_init(struct budget_av *budget_av)
        case SUBID_DVBS_TV_STAR:
        case SUBID_DVBS_TV_STAR_CI:
        case SUBID_DVBS_CYNERGY1200N:
+       case SUBID_DVBS_EASYWATCH:
                fe = stv0299_attach(&philips_sd1878_config,
                                &budget_av->budget.i2c_adap);
                break;
@@ -1285,6 +1287,7 @@ MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
+MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
@@ -1300,6 +1303,7 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
+       MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
        MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
        MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
        MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
index b9b3cd9..09b972b 100644 (file)
@@ -42,6 +42,8 @@
 #include "stv0299.h"
 #include "stv0297.h"
 #include "tda1004x.h"
+#include "lnbp21.h"
+#include "bsbe1.h"
 
 #define DEBIADDR_IR            0x1234
 #define DEBIADDR_CICONTROL     0x0000
@@ -1069,6 +1071,20 @@ static void frontend_init(struct budget_ci *budget_ci)
                        break;
                }
                break;
+
+       case 0x1017:            // TT S-1500 PCI
+               budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
+                       if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
+                               printk("%s: No LNBP21 found!\n", __FUNCTION__);
+                               if (budget_ci->budget.dvb_frontend->ops->release)
+                                       budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
+                               budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+
+               break;
        }
 
        if (budget_ci->budget.dvb_frontend == NULL) {
@@ -1146,6 +1162,7 @@ static int budget_ci_detach(struct saa7146_dev *dev)
 
 static struct saa7146_extension budget_extension;
 
+MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T         PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
@@ -1157,6 +1174,7 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
        MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
        MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
+       MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
        {
         .vendor = 0,
         }
index 238c77b..bfb8092 100644 (file)
@@ -41,6 +41,7 @@
 #include "l64781.h"
 #include "tda8083.h"
 #include "s5h1420.h"
+#include "lnbp21.h"
 
 static void Set22K (struct budget *budget, int state)
 {
@@ -184,64 +185,6 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m
        return 0;
 }
 
-static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u8 buf;
-       struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       switch(voltage) {
-       case SEC_VOLTAGE_13:
-               buf = (buf & 0xf7) | 0x04;
-               break;
-
-       case SEC_VOLTAGE_18:
-               buf = (buf & 0xf7) | 0x0c;
-               break;
-
-       case SEC_VOLTAGE_OFF:
-               buf = buf & 0xf0;
-               break;
-       }
-
-       msg.flags = 0;
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       return 0;
-}
-
-static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u8 buf;
-       struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       if (arg) {
-               buf = buf | 0x10;
-       } else {
-               buf = buf & 0xef;
-       }
-
-       msg.flags = 0;
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       return 0;
-}
-
-static int lnbp21_init(struct budget* budget)
-{
-       u8 buf = 0x00;
-       struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -374,79 +317,6 @@ static struct stv0299_config alps_bsru6_config = {
        .pll_set = alps_bsru6_pll_set,
 };
 
-static u8 alps_bsbe1_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,  /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,  /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,  /* DAC not used, set to high impendance mode */
-       0x07, 0x00,  /* DAC LSB */
-       0x08, 0x40,  /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,  /* FIFO */
-       0x0c, 0x51,  /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,  /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,  /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,  // AGC2 0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,  // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
-       0x29, 0x1e, // 1/2 threshold
-       0x2a, 0x14, // 2/3 threshold
-       0x2b, 0x0f, // 3/4 threshold
-       0x2c, 0x09, // 5/6 threshold
-       0x2d, 0x05, // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f, // test all FECs
-       0x32, 0x19, // viterbi and synchro search
-       0x33, 0xfc, // rs control
-       0x34, 0x93, // error control
-       0x0f, 0x92, // 0x80 = inverse AGC
-       0xff, 0xff
-};
-
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
-
-       ret = i2c_transfer(i2c, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static struct stv0299_config alps_bsbe1_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .min_delay_ms = 100,
-       .set_symb