Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (255 commits)
  [media] radio-aimslab.c: Fix gcc 4.5+ bug
  [media] cx25821: Fix compilation breakage due to BKL dependency
  [media] v4l2-compat-ioctl32: fix compile warning
  [media] zoran: fix compiler warning
  [media] tda18218: fix compile warning
  [media] ngene: fix compile warning
  [media] DVB: IR support for TechnoTrend CT-3650
  [media] cx23885, cimax2.c: Fix case of two CAM insertion irq
  [media] ir-nec-decoder: fix repeat key issue
  [media] staging: se401 depends on USB
  [media] staging: usbvideo/vicam depends on USB
  [media] soc_camera: Add the ability to bind regulators to soc_camedra devices
  [media] V4L2: Add a v4l2-subdev (soc-camera) driver for OmniVision OV2640 sensor
  [media] v4l: soc-camera: switch to .unlocked_ioctl
  [media] v4l: ov772x: simplify pointer dereference
  [media] ov9640: fix OmniVision OV9640 sensor driver's priv data retrieving
  [media] ov9640: use macro to request OmniVision OV9640 sensor private data
  [media] ivtv-i2c: Fix two warnings
  [media] staging/lirc: Update lirc TODO files
  [media] cx88: Remove the obsolete i2c_adapter.id field
  ...
This commit is contained in:
Linus Torvalds 2011-01-06 18:32:12 -08:00
commit 9e9bc97367
500 changed files with 17757 additions and 28845 deletions

View File

@ -34,8 +34,7 @@
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>V4L2 ioctl request code as defined in the <link
linkend="videodev">videodev.h</link> header file, for example
<para>V4L2 ioctl request code as defined in the <filename>videodev2.h</filename> header file, for example
VIDIOC_QUERYCAP.</para>
</listitem>
</varlistentry>
@ -57,7 +56,7 @@ file descriptor. An ioctl <parameter>request</parameter> has encoded
in it whether the argument is an input, output or read/write
parameter, and the size of the argument <parameter>argp</parameter> in
bytes. Macros and defines specifying V4L2 ioctl requests are located
in the <link linkend="videodev">videodev.h</link> header file.
in the <filename>videodev2.h</filename> header file.
Applications should use their own copy, not include the version in the
kernel sources on the system they compile on. All V4L2 ioctl requests,
their respective function and parameters are specified in <xref

View File

@ -142,8 +142,8 @@ leftmost pixel of the second row from the top, and so on. The last row
has just as many pad bytes after it as the other rows.</para>
<para>In V4L2 each format has an identifier which looks like
<constant>PIX_FMT_XXX</constant>, defined in the <link
linkend="videodev">videodev.h</link> header file. These identifiers
<constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename>
header file. These identifiers
represent <link linkend="v4l2-fourcc">four character codes</link>
which are also listed below, however they are not the same as those
used in the Windows world.</para>

View File

@ -1,3 +1,3 @@
obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
pcmcia/ spi/ timers/ video4linux/ vm/ watchdog/src/
pcmcia/ spi/ timers/ vm/ watchdog/src/

View File

@ -46,7 +46,7 @@ and run
Other LG firmware can be extracted manually from US280D.sys
only found in windows/system32/driver.
dd if=US280D.sys ibs=1 skip=42616 count=3668 of=dvb-usb-lme2510-lg.fw
dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
for DM04 LME2510C (LG Tuner)
---------------------------

View File

@ -97,36 +97,38 @@ Who: Pavel Machek <pavel@ucw.cz>
---------------------------
What: Video4Linux API 1 ioctls and from Video devices.
When: kernel 2.6.38
Files: include/linux/videodev.h
Check: include/linux/videodev.h
Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
series. The old API have lots of drawbacks and don't provide enough
means to work with all video and audio standards. The newer API is
already available on the main drivers and should be used instead.
Newer drivers should use v4l_compat_translate_ioctl function to handle
old calls, replacing to newer ones.
Decoder iocts are using internally to allow video drivers to
communicate with video decoders. This should also be improved to allow
V4L2 calls being translated into compatible internal ioctls.
Compatibility ioctls will be provided, for a while, via
v4l1-compat module.
Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: Video4Linux obsolete drivers using V4L1 API
When: kernel 2.6.38
Files: drivers/staging/cpia/* drivers/staging/stradis/*
Check: drivers/staging/cpia/cpia.c drivers/staging/stradis/stradis.c
When: kernel 2.6.39
Files: drivers/staging/se401/* drivers/staging/usbvideo/*
Check: drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
Why: There are some drivers still using V4L1 API, despite all efforts we've done
to migrate. Those drivers are for obsolete hardware that the old maintainer
didn't care (or not have the hardware anymore), and that no other developer
could find any hardware to buy. They probably have no practical usage today,
and people with such old hardware could probably keep using an older version
of the kernel. Those drivers will be moved to staging on 2.6.37 and, if nobody
care enough to port and test them with V4L2 API, they'll be removed on 2.6.38.
of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: Video4Linux: Remove obsolete ioctl's
When: kernel 2.6.39
Files: include/media/videodev2.h
Why: Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
type of R/W arguments. They were fixed, but the old ioctl names are
still there, maintained to avoid breaking binary compatibility:
#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
There's no sense on preserving those forever, as it is very doubtful
that someone would try to use a such old binary with a modern kernel.
Removing them will allow us to remove some magic done at the V4L ioctl
handler.
Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------

View File

@ -155,7 +155,6 @@ Code Seq#(hex) Include File Comments
'Q' all linux/soundcard.h
'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict!
'R' 01-0F media/rds.h conflict!
'R' C0-DF net/bluetooth/rfcomm.h
'S' all linux/cdrom.h conflict!
'S' 80-81 scsi/scsi_ioctl.h conflict!
@ -194,7 +193,6 @@ Code Seq#(hex) Include File Comments
<http://lrcwww.epfl.ch/>
'b' 00-FF conflict! bit3 vme host bridge
<mailto:natalia@nikhefk.nikhef.nl>
'b' 00-0F media/bt819.h conflict!
'c' all linux/cm4000_cs.h conflict!
'c' 00-7F linux/comstats.h conflict!
'c' 00-7F linux/coda.h conflict!
@ -260,14 +258,11 @@ Code Seq#(hex) Include File Comments
't' 80-8F linux/isdn_ppp.h
't' 90 linux/toshiba.h
'u' 00-1F linux/smb_fs.h gone
'v' all linux/videodev.h conflict!
'v' 00-1F linux/ext2_fs.h conflict!
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
'v' C0-CF drivers/media/video/ov511.h conflict!
'v' C0-DF media/pwc-ioctl.h conflict!
'v' C0-FF linux/meye.h conflict!
'v' C0-CF drivers/media/video/zoran/zoran.h conflict!
'v' D0-DF drivers/media/video/cpia2/cpia2dev.h conflict!
'w' all CERN SCI driver
'y' 00-1F packet based user level communications
@ -278,7 +273,6 @@ Code Seq#(hex) Include File Comments
<mailto:oe@port.de>
'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
0x80 00-1F linux/fb.h
0x88 00-3F media/ovcamchip.h
0x89 00-06 arch/x86/include/asm/sockios.h
0x89 0B-DF linux/sockios.h
0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range

View File

@ -1,5 +1,5 @@
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868,eb1a:2875]
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
@ -9,7 +9,7 @@
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
11 -> Terratec Hybrid XS (em2880)
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
@ -53,7 +53,7 @@
52 -> DNT DA2 Hybrid (em2881)
53 -> Pinnacle Hybrid Pro (em2881)
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e]
55 -> Terratec Cinnergy Hybrid T USB XS (em2882) (em2882) [0ccd:005e,0ccd:0042]
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]

View File

@ -180,3 +180,5 @@
179 -> Beholder BeholdTV A7 [5ace:7090]
180 -> Avermedia PCI M733A [1461:4155,1461:4255]
181 -> TechoTrend TT-budget T-3000 [13c2:2804]
182 -> Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid [17de:b136]
183 -> Compro VideoMate Vista M1F [185b:c900]

View File

@ -1,8 +0,0 @@
# kbuild trick to avoid linker error. Can be omitted if a module is built.
obj- := dummy.o
# List of programs to build
hostprogs-y := v4lgrab
# Tell kbuild to always build the programs
always := $(hostprogs-y)

View File

@ -1,191 +0,0 @@
This is a driver for the CPiA PPC2 driven parallel connected
Camera. For example the Creative WebcamII is CPiA driven.
) [1]Peter Pregler, Linz 2000, published under the [2]GNU GPL
---------------------------------------------------------------------------
USAGE:
General:
========
1) Make sure you have created the video devices (/dev/video*):
- if you have a recent MAKEDEV do a 'cd /dev;./MAKEDEV video'
- otherwise do a:
cd /dev
mknod video0 c 81 0
ln -s video0 video
2) Compile the kernel (see below for the list of options to use),
configure your parport and reboot.
3) If all worked well you should get messages similar
to the following (your versions may be different) on the console:
V4L-Driver for Vision CPiA based cameras v0.7.4
parport0: read2 timeout.
parport0: Multimedia device, VLSI Vision Ltd PPC2
Parallel port driver for Vision CPiA based camera
CPIA Version: 1.20 (2.0)
CPIA PnP-ID: 0553:0002:0100
VP-Version: 1.0 0100
1 camera(s) found
As modules:
===========
Make sure you have selected the following kernel options (you can
select all stuff as modules):
The cpia-stuff is in the section 'Character devices -> Video For Linux'.
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_1284=y
CONFIG_VIDEO_DEV=m
CONFIG_VIDEO_CPIA=m
CONFIG_VIDEO_CPIA_PP=m
For autoloading of all those modules you need to tell module-init-tools
some stuff. Add the following line to your module-init-tools config-file
(e.g. /etc/modprobe.conf or wherever your distribution does store that
stuff):
options parport_pc io=0x378 irq=7 dma=3
alias char-major-81 cpia_pp
The first line tells the dma/irq channels to use. Those _must_ match
the settings of your BIOS. Do NOT simply use the values above. See
Documentation/parport.txt for more information about this. The second
line associates the video-device file with the driver. Of cause you
can also load the modules once upon boot (usually done in /etc/modules).
Linked into the kernel:
=======================
Make sure you have selected the following kernel options. Note that
you cannot compile the parport-stuff as modules and the cpia-driver
statically (the other way round is okay though).
The cpia-stuff is in the section 'Character devices -> Video For Linux'.
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_1284=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_CPIA=y
CONFIG_VIDEO_CPIA_PP=y
To use DMA/irq you will need to tell the kernel upon boot time the
hardware configuration of the parport. You can give the boot-parameter
at the LILO-prompt or specify it in lilo.conf. I use the following
append-line in lilo.conf:
append="parport=0x378,7,3"
See Documentation/parport.txt for more information about the
configuration of the parport and the values given above. Do not simply
use the values given above.
---------------------------------------------------------------------------
FEATURES:
- mmap/read v4l-interface (but no overlay)
- image formats: CIF/QCIF, SIF/QSIF, various others used by isabel;
note: all sizes except CIF/QCIF are implemented by clipping, i.e.
pixels are not uploaded from the camera
- palettes: VIDEO_PALETTE_GRAY, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB555,
VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32, VIDEO_PALETTE_YUYV,
VIDEO_PALETTE_UYVY, VIDEO_PALETTE_YUV422
- state information (color balance, exposure, ...) is preserved between
device opens
- complete control over camera via proc-interface (_all_ camera settings are
supported), there is also a python-gtk application available for this [3]
- works under SMP (but the driver is completely serialized and synchronous)
so you get no benefit from SMP, but at least it does not crash your box
- might work for non-Intel architecture, let us know about this
---------------------------------------------------------------------------
TESTED APPLICATIONS:
- a simple test application based on Xt is available at [3]
- another test-application based on gqcam-0.4 (uses GTK)
- gqcam-0.6 should work
- xawtv-3.x (also the webcam software)
- xawtv-2.46
- w3cam (cgi-interface and vidcat, e.g. you may try out 'vidcat |xv
-maxpect -root -quit +noresetroot -rmode 5 -')
- vic, the MBONE video conferencing tool (version 2.8ucl4-1)
- isabel 3R4beta (barely working, but AFAICT all the problems are on
their side)
- camserv-0.40
See [3] for pointers to v4l-applications.
---------------------------------------------------------------------------
KNOWN PROBLEMS:
- some applications do not handle the image format correctly, you will
see strange horizontal stripes instead of a nice picture -> make sure
your application does use a supported image size or queries the driver
for the actually used size (reason behind this: the camera cannot
provide any image format, so if size NxM is requested the driver will
use a format to the closest fitting N1xM1, the application should now
query for this granted size, most applications do not).
- all the todo ;)
- if there is not enough light and the picture is too dark try to
adjust the SetSensorFPS setting, automatic frame rate adjustment
has its price
- do not try out isabel 3R4beta (built 135), you will be disappointed
---------------------------------------------------------------------------
TODO:
- multiple camera support (struct camera or something) - This should work,
but hasn't been tested yet.
- architecture independence?
- SMP-safe asynchronous mmap interface
- nibble mode for old parport interfaces
- streaming capture, this should give a performance gain
---------------------------------------------------------------------------
IMPLEMENTATION NOTES:
The camera can act in two modes, streaming or grabbing. Right now a
polling grab-scheme is used. Maybe interrupt driven streaming will be
used for a asynchronous mmap interface in the next major release of the
driver. This might give a better frame rate.
---------------------------------------------------------------------------
THANKS (in no particular order):
- Scott J. Bertin <sbertin@mindspring.com> for cleanups, the proc-filesystem
and much more
- Henry Bruce <whb@vvl.co.uk> for providing developers information about
the CPiA chip, I wish all companies would treat Linux as seriously
- Karoly Erdei <Karoly.Erdei@risc.uni-linz.ac.at> and RISC-Linz for being
my boss ;) resp. my employer and for providing me the hardware and
allow me to devote some working time to this project
- Manuel J. Petit de Gabriel <mpetit@dit.upm.es> for providing help
with Isabel (http://isabel.dit.upm.es/)
- Bas Huisman <bhuism@cs.utwente.nl> for writing the initial parport code
- Jarl Totland <Jarl.Totland@bdc.no> for setting up the mailing list
and maintaining the web-server[3]
- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
1.02 firmware
- special kudos to all the tester whose machines crashed and/or
will crash. :)
---------------------------------------------------------------------------
REFERENCES
1. http://www.risc.uni-linz.ac.at/
mailto:Peter_Pregler@email.com
2. see the file COPYING in the top directory of the kernel tree
3. http://webcam.sourceforge.net/

View File

@ -322,76 +322,11 @@ your IRQs and make sure the card has its own interrupts.
4. Programming interface
This driver conforms to video4linux and video4linux2, both can be used to
use the driver. Since video4linux didn't provide adequate calls to fully
use the cards' features, we've introduced several programming extensions,
which are currently officially accepted in the 2.4.x branch of the kernel.
These extensions are known as the v4l/mjpeg extensions. See zoran.h for
details (structs/ioctls).
Information - video4linux:
http://linux.bytesex.org/v4l2/API.html
Documentation/video4linux/API.html
/usr/include/linux/videodev.h
Information - video4linux/mjpeg extensions:
./zoran.h
(also see below)
Information - video4linux2:
http://linuxtv.org
http://v4l2spec.bytesex.org/
/usr/include/linux/videodev2.h
More information on the video4linux/mjpeg extensions, by Serguei
Miridonovi and Rainer Johanni:
--
The ioctls for that interface are as follows:
BUZIOC_G_PARAMS
BUZIOC_S_PARAMS
Get and set the parameters of the buz. The user should always do a
BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
settings, change what he likes and then make a BUZIOC_S_PARAMS call.
BUZIOC_REQBUFS
Before being able to capture/playback, the user has to request
the buffers he is wanting to use. Fill the structure
zoran_requestbuffers with the size (recommended: 256*1024) and
the number (recommended 32 up to 256). There are no such restrictions
as for the Video for Linux buffers, you should LEAVE SUFFICIENT
MEMORY for your system however, else strange things will happen ....
On return, the zoran_requestbuffers structure contains number and
size of the actually allocated buffers.
You should use these numbers for doing a mmap of the buffers
into the user space.
The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
maps the MJPEG buffer instead of the V4L buffers.
BUZIOC_QBUF_CAPT
BUZIOC_QBUF_PLAY
Queue a buffer for capture or playback. The first call also starts
streaming capture. When streaming capture is going on, you may
only queue further buffers or issue syncs until streaming
capture is switched off again with a argument of -1 to
a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
BUZIOC_SYNC
Issue this ioctl when all buffers are queued. This ioctl will
block until the first buffer becomes free for saving its
data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
BUZIOC_G_STATUS
Get the status of the input lines (video source connected/norm).
This driver conforms to video4linux2. Support for V4L1 and for the custom
zoran ioctls has been removed in kernel 2.6.38.
For programming example, please, look at lavrec.c and lavplay.c code in
lavtools-1.2p2 package (URL: http://www.cicese.mx/)
and the 'examples' directory in the original Buz driver distribution.
the MJPEG-tools (http://mjpeg.sf.net/).
Additional notes for software developers:
@ -402,9 +337,6 @@ Additional notes for software developers:
standard is "more constant" for current country than geometry
settings of a variety of TV capture cards which may work in ITU or
square pixel format.
--
Please note that lavplay/lavrec are also included in the MJPEG-tools
(http://mjpeg.sf.net/).
===========================

View File

@ -464,10 +464,6 @@ Siemens
-------
Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
Stradis
-------
SDM275,SDM250,SDM026,SDM025 (SAA7146, IBMMPEG2): MPEG2 decoder only
Powercolor
----------
MTV878

View File

@ -366,6 +366,7 @@ t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
pac207 2001:f115 D-Link DSB-C120
sq905c 2770:9050 Disney pix micro (CIF)
sq905c 2770:9051 Lego Bionicle
sq905c 2770:9052 Disney pix micro 2 (VGA)
sq905c 2770:905c All 11 known cameras with this ID
sq905 2770:9120 All 24 known cameras with this ID

View File

@ -45,8 +45,6 @@ module argument syntax (<param>=<value> when passing the option to the
module or meye.<param>=<value> on the kernel boot line when meye is
statically linked into the kernel). Those options are:
forcev4l1: force use of V4L1 API instead of V4L2
gbuffers: number of capture buffers, default is 2 (32 max)
gbufsize: size of each capture buffer, default is 614400
@ -79,9 +77,8 @@ Usage:
Private API:
------------
The driver supports frame grabbing with the video4linux API
(either v4l1 or v4l2), so all video4linux tools (like xawtv)
should work with this driver.
The driver supports frame grabbing with the video4linux API,
so all video4linux tools (like xawtv) should work with this driver.
Besides the video4linux interface, the driver has a private interface
for accessing the Motion Eye extended parameters (camera sharpness,
@ -123,7 +120,4 @@ Private API:
Bugs / Todo:
------------
- the driver could be much cleaned up by removing the v4l1 support.
However, this means all v4l1-only applications will stop working.
- 'motioneye' still uses the meye private v4l1 API extensions.

View File

@ -1,201 +0,0 @@
/* Simple Video4Linux image grabber. */
/*
* Video4Linux Driver Test/Example Framegrabbing Program
*
* Compile with:
* gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
* Use as:
* v4lgrab >image.ppm
*
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
* with minor modifications (Dave Forrest, drf5n@virginia.edu).
*
*
* For some cameras you may need to pre-load libv4l to perform
* the necessary decompression, e.g.:
*
* export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
* ./v4lgrab >image.ppm
*
* see http://hansdegoede.livejournal.com/3636.html for details.
*
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev.h>
#define VIDEO_DEV "/dev/video0"
/* Stole this from tvset.c */
#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
{ \
switch (format) \
{ \
case VIDEO_PALETTE_GREY: \
switch (depth) \
{ \
case 4: \
case 6: \
case 8: \
(r) = (g) = (b) = (*buf++ << 8);\
break; \
\
case 16: \
(r) = (g) = (b) = \
*((unsigned short *) buf); \
buf += 2; \
break; \
} \
break; \
\
\
case VIDEO_PALETTE_RGB565: \
{ \
unsigned short tmp = *(unsigned short *)buf; \
(r) = tmp&0xF800; \
(g) = (tmp<<5)&0xFC00; \
(b) = (tmp<<11)&0xF800; \
buf += 2; \
} \
break; \
\
case VIDEO_PALETTE_RGB555: \
(r) = (buf[0]&0xF8)<<8; \
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
buf += 2; \
break; \
\
case VIDEO_PALETTE_RGB24: \
(r) = buf[0] << 8; (g) = buf[1] << 8; \
(b) = buf[2] << 8; \
buf += 3; \
break; \
\
default: \
fprintf(stderr, \
"Format %d not yet supported\n", \
format); \
} \
}
static int get_brightness_adj(unsigned char *image, long size, int *brightness) {
long i, tot = 0;
for (i=0;i<size*3;i++)
tot += image[i];
*brightness = (128 - tot/(size*3))/3;
return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130);
}
int main(int argc, char ** argv)
{
int fd = open(VIDEO_DEV, O_RDONLY), f;
struct video_capability cap;
struct video_window win;
struct video_picture vpic;
unsigned char *buffer, *src;
int bpp = 24, r = 0, g = 0, b = 0;
unsigned int i, src_depth = 16;
if (fd < 0) {
perror(VIDEO_DEV);
exit(1);
}
if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
perror("VIDIOGCAP");
fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
close(fd);
exit(1);
}
if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
perror("VIDIOCGWIN");
close(fd);
exit(1);
}
if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
perror("VIDIOCGPICT");
close(fd);
exit(1);
}
if (cap.type & VID_TYPE_MONOCHROME) {
vpic.depth=8;
vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
vpic.depth=6;
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
vpic.depth=4;
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
fprintf(stderr, "Unable to find a supported capture format.\n");
close(fd);
exit(1);
}
}
}
} else {
vpic.depth=24;
vpic.palette=VIDEO_PALETTE_RGB24;
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
vpic.palette=VIDEO_PALETTE_RGB565;
vpic.depth=16;
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
vpic.palette=VIDEO_PALETTE_RGB555;
vpic.depth=15;
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
fprintf(stderr, "Unable to find a supported capture format.\n");
return -1;
}
}
}
}
buffer = malloc(win.width * win.height * bpp);
if (!buffer) {
fprintf(stderr, "Out of memory.\n");
exit(1);
}
do {
int newbright;
read(fd, buffer, win.width * win.height * bpp);
f = get_brightness_adj(buffer, win.width * win.height, &newbright);
if (f) {
vpic.brightness += (newbright << 8);
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
perror("VIDIOSPICT");
break;
}
}
} while (f);
fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);
src = buffer;
for (i = 0; i < win.width * win.height; i++) {
READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
fputc(r>>8, stdout);
fputc(g>>8, stdout);
fputc(b>>8, stdout);
}
close(fd);
return 0;
}

View File

@ -247,8 +247,6 @@ calls. The relevant helper functions are:
int nonblocking);
int videobuf_streamon(struct videobuf_queue *q);
int videobuf_streamoff(struct videobuf_queue *q);
int videobuf_cgmbuf(struct videobuf_queue *q, struct video_mbuf *mbuf,
int count);
So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
vidioc_reqbufs() callback which, in turn, usually only needs to locate the
@ -258,10 +256,7 @@ boilerplate in a lot of V4L2 drivers.
The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
complex, of course, since they will also need to deal with starting and
stopping the capture engine. videobuf_cgmbuf(), called from the driver's
vidiocgmbuf() function, only exists if the V4L1 compatibility module has
been selected with CONFIG_VIDEO_V4L1_COMPAT, so its use must be surrounded
with #ifdef directives.
stopping the capture engine.
Buffer allocation

View File

@ -5754,12 +5754,6 @@ M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
F: drivers/net/starfire*
STRADIS MPEG-2 DECODER DRIVER
M: Nathan Laredo <laredo@gnu.org>
W: http://www.stradis.com/
S: Maintained
F: drivers/media/video/stradis.c
SUN3/3X
M: Sam Creasey <sammy@sammy.net>
W: http://sammy.net/sun3/

View File

@ -294,24 +294,6 @@ config INPUT_SGI_BTNS
To compile this driver as a module, choose M here: the
module will be called sgi_btns.
config INPUT_WINBOND_CIR
tristate "Winbond IR remote control"
depends on X86 && PNP
select NEW_LEDS
select LEDS_CLASS
select LEDS_TRIGGERS
select BITREVERSE
help
Say Y here if you want to use the IR remote functionality found
in some Winbond SuperI/O chips. Currently only the WPCD376I
chip is supported (included in some Intel Media series motherboards).
IR Receive and wake-on-IR from suspend and power-off is currently
supported.
To compile this driver as a module, choose M here: the module will be
called winbond_cir.
config HP_SDC_RTC
tristate "HP SDC Real Time Clock"
depends on (GSC || HP300) && SERIO

View File

@ -38,7 +38,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o

View File

@ -1,356 +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/string.h>
#include <linux/jiffies.h>
#include <media/ir-common.h>
#include "ir-core-priv.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 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 down=%d\n",
dev->name, ir->ir_key, ir->keypressed);
return;
}
IR_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);
}
/* -------------------------------------------------------------------------- */
int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
const u64 ir_type)
{
ir->ir_type = ir_type;
if (repeat)
set_bit(EV_REP, dev->evbit);
return 0;
}
EXPORT_SYMBOL_GPL(ir_input_init);
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);
}
}
EXPORT_SYMBOL_GPL(ir_input_nokey);
void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
u32 ir_key)
{
u32 keycode = ir_g_keycode_from_table(dev, 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->keycode = keycode;
ir->keypressed = 1;
ir_input_key_event(dev,ir);
}
}
EXPORT_SYMBOL_GPL(ir_input_keydown);
/* -------------------------------------------------------------------------- */
/* extract mask bits out of data and pack them into the result */
u32 ir_extract_bits(u32 data, u32 mask)
{
u32 vbit = 1, value = 0;
do {
if (mask&1) {
if (data&1)
value |= vbit;
vbit<<=1;
}
data>>=1;
} while (mask>>=1);
return value;
}
EXPORT_SYMBOL_GPL(ir_extract_bits);
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;
}
EXPORT_SYMBOL_GPL(ir_dump_samples);
/* 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;
}
EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
/* 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_decode_biphase);
/* RC5 decoding stuff, moved from bttv-input.c to share it with
* saa7134 */
/* decode raw bit pattern to RC5 code */
u32 ir_rc5_decode(unsigned int code)
{
unsigned int org_code = code;
unsigned int pair;
unsigned int rc5 = 0;
int i;
for (i = 0; i < 14; ++i) {
pair = code & 0x3;
code >>= 2;
rc5 <<= 1;
switch (pair) {
case 0:
case 2:
break;
case 1:
rc5 |= 1;
break;
case 3:
IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
return 0;
}
}
IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
"instr=%x\n", rc5, org_code, RC5_START(rc5),
RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
return rc5;
}
EXPORT_SYMBOL_GPL(ir_rc5_decode);
void ir_rc5_timer_end(unsigned long data)
{
struct card_ir *ir = (struct card_ir *)data;
struct timeval tv;
unsigned long current_jiffies, timeout;
u32 gap;
u32 rc5 = 0;
/* get time */
current_jiffies = jiffies;
do_gettimeofday(&tv);
/* avoid overflow with gap >1s */
if (tv.tv_sec - ir->base_time.tv_sec > 1) {
gap = 200000;
} else {
gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
tv.tv_usec - ir->base_time.tv_usec;
}
/* signal we're ready to start a new code */
ir->active = 0;
/* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
if (gap < 28000) {
IR_dprintk(1, "ir-common: spurious timer_end\n");
return;
}
if (ir->last_bit < 20) {
/* ignore spurious codes (caused by light/other remotes) */
IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
} else {
ir->code = (ir->code << ir->shift_by) | 1;
rc5 = ir_rc5_decode(ir->code);
/* two start bits? */
if (RC5_START(rc5) != ir->start) {
IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
/* right address? */
} else if (RC5_ADDR(rc5) == ir->addr) {
u32 toggle = RC5_TOGGLE(rc5);
u32 instr = RC5_INSTR(rc5);
/* Good code, decide if repeat/repress */
if (toggle != RC5_TOGGLE(ir->last_rc5) ||
instr != RC5_INSTR(ir->last_rc5)) {
IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
toggle);
ir_input_nokey(ir->dev, &ir->ir);
ir_input_keydown(ir->dev, &ir->ir, instr);
}
/* Set/reset key-up timer */
timeout = current_jiffies +
msecs_to_jiffies(ir->rc5_key_timeout);
mod_timer(&ir->timer_keyup, timeout);
/* Save code for repeat test */
ir->last_rc5 = rc5;
}
}
}
EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
void ir_rc5_timer_keyup(unsigned long data)
{
struct card_ir *ir = (struct card_ir *)data;
IR_dprintk(1, "ir-common: key released\n");
ir_input_nokey(ir->dev, &ir->ir);
}
EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);

View File

@ -1,710 +0,0 @@
/* ir-keytable.c - handle IR scancode->keycode tables
*
* Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/input.h>
#include <linux/slab.h>
#include "ir-core-priv.h"
/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
#define IR_TAB_MIN_SIZE 256
#define IR_TAB_MAX_SIZE 8192
/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
#define IR_KEYPRESS_TIMEOUT 250
/**
* ir_create_table() - initializes a scancode table
* @rc_tab: the ir_scancode_table to initialize
* @name: name to assign to the table
* @ir_type: ir type to assign to the new table
* @size: initial size of the table
* @return: zero on success or a negative error code
*
* This routine will initialize the ir_scancode_table and will allocate
* memory to hold at least the specified number elements.
*/
static int ir_create_table(struct ir_scancode_table *rc_tab,
const char *name, u64 ir_type, size_t size)
{
rc_tab->name = name;
rc_tab->ir_type = ir_type;
rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode));
rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL);
if (!rc_tab->scan)
return -ENOMEM;
IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
rc_tab->size, rc_tab->alloc);
return 0;
}
/**
* ir_free_table() - frees memory allocated by a scancode table
* @rc_tab: the table whose mappings need to be freed
*
* This routine will free memory alloctaed for key mappings used by given
* scancode table.
*/
static void ir_free_table(struct ir_scancode_table *rc_tab)
{
rc_tab->size = 0;
kfree(rc_tab->scan);
rc_tab->scan = NULL;
}
/**
* ir_resize_table() - resizes a scancode table if necessary
* @rc_tab: the ir_scancode_table to resize
* @gfp_flags: gfp flags to use when allocating memory
* @return: zero on success or a negative error code
*
* This routine will shrink the ir_scancode_table if it has lots of
* unused entries and grow it if it is full.
*/
static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags)
{
unsigned int oldalloc = rc_tab->alloc;
unsigned int newalloc = oldalloc;
struct ir_scancode *oldscan = rc_tab->scan;
struct ir_scancode *newscan;
if (rc_tab->size == rc_tab->len) {
/* All entries in use -> grow keytable */
if (rc_tab->alloc >= IR_TAB_MAX_SIZE)
return -ENOMEM;
newalloc *= 2;
IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
}
if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
/* Less than 1/3 of entries in use -> shrink keytable */
newalloc /= 2;
IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
}
if (newalloc == oldalloc)
return 0;
newscan = kmalloc(newalloc, gfp_flags);
if (!newscan) {
IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
return -ENOMEM;
}
memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode));
rc_tab->scan = newscan;
rc_tab->alloc = newalloc;
rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
kfree(oldscan);
return 0;
}
/**
* ir_update_mapping() - set a keycode in the scancode->keycode table
* @dev: the struct input_dev device descriptor
* @rc_tab: scancode table to be adjusted
* @index: index of the mapping that needs to be updated
* @keycode: the desired keycode
* @return: previous keycode assigned to the mapping
*
* This routine is used to update scancode->keycopde mapping at given
* position.
*/
static unsigned int ir_update_mapping(struct input_dev *dev,
struct ir_scancode_table *rc_tab,
unsigned int index,
unsigned int new_keycode)
{
int old_keycode = rc_tab->scan[index].keycode;
int i;
/* Did the user wish to remove the mapping? */
if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
index, rc_tab->scan[index].scancode);
rc_tab->len--;
memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1],
(rc_tab->len - index) * sizeof(struct ir_scancode));
} else {
IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
index,
old_keycode == KEY_RESERVED ? "New" : "Replacing",
rc_tab->scan[index].scancode, new_keycode);
rc_tab->scan[index].keycode = new_keycode;
__set_bit(new_keycode, dev->keybit);
}
if (old_keycode != KEY_RESERVED) {
/* A previous mapping was updated... */
__clear_bit(old_keycode, dev->keybit);
/* ... but another scancode might use the same keycode */
for (i = 0; i < rc_tab->len; i++) {
if (rc_tab->scan[i].keycode == old_keycode) {
__set_bit(old_keycode, dev->keybit);
break;
}
}
/* Possibly shrink the keytable, failure is not a problem */
ir_resize_table(rc_tab, GFP_ATOMIC);
}
return old_keycode;
}
/**
* ir_locate_scancode() - set a keycode in the scancode->keycode table
* @ir_dev: the struct ir_input_dev device descriptor
* @rc_tab: scancode table to be searched
* @scancode: the desired scancode
* @resize: controls whether we allowed to resize the table to
* accomodate not yet present scancodes
* @return: index of the mapping containing scancode in question
* or -1U in case of failure.
*
* This routine is used to locate given scancode in ir_scancode_table.
* If scancode is not yet present the routine will allocate a new slot
* for it.
*/
static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
struct ir_scancode_table *rc_tab,
unsigned int scancode,
bool resize)
{
unsigned int i;
/*
* Unfortunately, some hardware-based IR decoders don't provide
* all bits for the complete IR code. In general, they provide only
* the command part of the IR code. Yet, as it is possible to replace
* the provided IR with another one, it is needed to allow loading
* IR tables from other remotes. So,
*/
if (ir_dev->props && ir_dev->props->scanmask)
scancode &= ir_dev->props->scanmask;
/* First check if we already have a mapping for this ir command */
for (i = 0; i < rc_tab->len; i++) {
if (rc_tab->scan[i].scancode == scancode)
return i;
/* Keytable is sorted from lowest to highest scancode */
if (rc_tab->scan[i].scancode >= scancode)
break;
}
/* No previous mapping found, we might need to grow the table */
if (rc_tab->size == rc_tab->len) {
if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC))
return -1U;
}
/* i is the proper index to insert our new keycode */
if (i < rc_tab->len)
memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
(rc_tab->len - i) * sizeof(struct ir_scancode));
rc_tab->scan[i].scancode = scancode;
rc_tab->scan[i].keycode = KEY_RESERVED;
rc_tab->len++;
return i;
}
/**
* ir_setkeycode() - set a keycode in the scancode->keycode table
* @dev: the struct input_dev device descriptor
* @scancode: the desired scancode
* @keycode: result
* @return: -EINVAL if the keycode could not be inserted, otherwise zero.
*
* This routine is used to handle evdev EVIOCSKEY ioctl.
*/
static int ir_setkeycode(struct input_dev *dev,
const struct input_keymap_entry *ke,
unsigned int *old_keycode)
{
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
unsigned int index;
unsigned int scancode;
int retval;
unsigned long flags;
spin_lock_irqsave(&rc_tab->lock, flags);
if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
index = ke->index;
if (index >= rc_tab->len) {
retval = -EINVAL;
goto out;
}
} else {
retval = input_scancode_to_scalar(ke, &scancode);
if (retval)
goto out;
index = ir_establish_scancode(ir_dev, rc_tab, scancode, true);
if (index >= rc_tab->len) {
retval = -ENOMEM;
goto out;
}
}
*old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode);
out:
spin_unlock_irqrestore(&rc_tab->lock, flags);
return retval;
}
/**
* ir_setkeytable() - sets several entries in the scancode->keycode table
* @dev: the struct input_dev device descriptor
* @to: the struct ir_scancode_table to copy entries to
* @from: the struct ir_scancode_table to copy entries from
* @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*
* This routine is used to handle table initialization.
*/
static int ir_setkeytable(struct ir_input_dev *ir_dev,
const struct ir_scancode_table *from)
{
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
unsigned int i, index;
int rc;
rc = ir_create_table(&ir_dev->rc_tab,
from->name, from->ir_type, from->size);
if (rc)
return rc;
IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
rc_tab->size, rc_tab->alloc);
for (i = 0; i < from->size; i++) {
index = ir_establish_scancode(ir_dev, rc_tab,
from->scan[i].scancode, false);
if (index >= rc_tab->len) {
rc = -ENOMEM;
break;
}
ir_update_mapping(ir_dev->input_dev, rc_tab, index,
from->scan[i].keycode);
}
if (rc)
ir_free_table(rc_tab);
return rc;
}
/**
* ir_lookup_by_scancode() - locate mapping by scancode
* @rc_tab: the &struct ir_scancode_table to search
* @scancode: scancode to look for in the table
* @return: index in the table, -1U if not found
*
* This routine performs binary search in RC keykeymap table for
* given scancode.
*/
static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab,
unsigned int scancode)
{
int start = 0;
int end = rc_tab->len - 1;
int mid;
while (start <= end) {
mid = (start + end) / 2;
if (rc_tab->scan[mid].scancode < scancode)
start = mid + 1;
else if (rc_tab->scan[mid].scancode > scancode)
end = mid - 1;
else
return mid;
}
return -1U;
}
/**
* ir_getkeycode() - get a keycode from the scancode->keycode table
* @dev: the struct input_dev device descriptor
* @scancode: the desired scancode
* @keycode: used to return the keycode, if found, or KEY_RESERVED
* @return: always returns zero.
*
* This routine is used to handle evdev EVIOCGKEY ioctl.
*/
static int ir_getkeycode(struct input_dev *dev,
struct input_keymap_entry *ke)
{
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
struct ir_scancode *entry;
unsigned long flags;
unsigned int index;
unsigned int scancode;
int retval;
spin_lock_irqsave(&rc_tab->lock, flags);
if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
index = ke->index;
} else {
retval = input_scancode_to_scalar(ke, &scancode);
if (retval)
goto out;
index = ir_lookup_by_scancode(rc_tab, scancode);
}
if (index >= rc_tab->len) {
if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
IR_dprintk(1, "unknown key for scancode 0x%04x\n",
scancode);
retval = -EINVAL;
goto out;
}
entry = &rc_tab->scan[index];
ke->index = index;
ke->keycode = entry->keycode;
ke->len = sizeof(entry->scancode);
memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
retval = 0;
out:
spin_unlock_irqrestore(&rc_tab->lock, flags);
return retval;
}
/**
* ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
* @input_dev: the struct input_dev descriptor of the device
* @scancode: the scancode that we're seeking
*
* This routine is used by the input routines when a key is pressed at the
* IR. The scancode is received and needs to be converted into a keycode.
* If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
* corresponding keycode from the table.
*/
u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
{
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
unsigned int keycode;
unsigned int index;
unsigned long flags;
spin_lock_irqsave(&rc_tab->lock, flags);
index = ir_lookup_by_scancode(rc_tab, scancode);
keycode = index < rc_tab->len ?
rc_tab->scan[index].keycode : KEY_RESERVED;
spin_unlock_irqrestore(&rc_tab->lock, flags);
if (keycode != KEY_RESERVED)
IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
dev->name, scancode, keycode);
return keycode;
}
EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
/**
* ir_keyup() - generates input event to cleanup a key press
* @ir: the struct ir_input_dev descriptor of the device
*
* This routine is used to signal that a key has been released on the
* remote control. It reports a keyup input event via input_report_key().
*/
void ir_keyup(struct ir_input_dev *ir)
{
if (!ir->keypressed)
return;
IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
input_report_key(ir->input_dev, ir->last_keycode, 0);
input_sync(ir->input_dev);
ir->keypressed = false;
}
EXPORT_SYMBOL_GPL(ir_keyup);
/**
* ir_timer_keyup() - generates a keyup event after a timeout
* @cookie: a pointer to struct ir_input_dev passed to setup_timer()
*
* This routine will generate a keyup event some time after a keydown event
* is generated when no further activity has been detected.
*/
static void ir_timer_keyup(unsigned long cookie)
{
struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
unsigned long flags;
/*
* ir->keyup_jiffies is used to prevent a race condition if a
* hardware interrupt occurs at this point and the keyup timer
* event is moved further into the future as a result.
*
* The timer will then be reactivated and this function called
* again in the future. We need to exit gracefully in that case
* to allow the input subsystem to do its auto-repeat magic or
* a keyup event might follow immediately after the keydown.
*/
spin_lock_irqsave(&ir->keylock, flags);
if (time_is_before_eq_jiffies(ir->keyup_jiffies))
ir_keyup(ir);
spin_unlock_irqrestore(&ir->keylock, flags);
}
/**
* ir_repeat() - notifies the IR core that a key is still pressed
* @dev: the struct input_dev descriptor of the device
*
* This routine is used by IR decoders when a repeat message which does
* not include the necessary bits to reproduce the scancode has been
* received.
*/
void ir_repeat(struct input_dev *dev)
{
unsigned long flags;
struct ir_input_dev *ir = input_get_drvdata(dev);
spin_lock_irqsave(&ir->keylock, flags);
input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode);
if (!ir->keypressed)
goto out;
ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
out:
spin_unlock_irqrestore(&ir->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_repeat);
/**
* ir_keydown() - generates input event for a key press
* @dev: the struct input_dev descriptor of the device
* @scancode: the scancode that we're seeking
* @toggle: the toggle value (protocol dependent, if the protocol doesn't
* support toggle values, this should be set to zero)
*
* This routine is used by the input routines when a key is pressed at the
* IR. It gets the keycode for a scancode and reports an input event via
* input_report_key().
*/
void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
{
unsigned long flags;
struct ir_input_dev *ir = input_get_drvdata(dev);
u32 keycode = ir_g_keycode_from_table(dev, scancode);
spin_lock_irqsave(&ir->keylock, flags);
input_event(dev, EV_MSC, MSC_SCAN, scancode);
/* Repeat event? */
if (ir->keypressed &&
ir->last_scancode == scancode &&
ir->last_toggle == toggle)
goto set_timer;
/* Release old keypress */
ir_keyup(ir);
ir->last_scancode = scancode;
ir->last_toggle = toggle;
ir->last_keycode = keycode;
if (keycode == KEY_RESERVED)
goto out;
/* Register a keypress */
ir->keypressed = true;
IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
dev->name, keycode, scancode);
input_report_key(dev, ir->last_keycode, 1);
input_sync(dev);
set_timer:
ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
out:
spin_unlock_irqrestore(&ir->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_keydown);
static int ir_open(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
return ir_dev->props->open(ir_dev->props->priv);
}
static void ir_close(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
ir_dev->props->close(ir_dev->props->priv);
}
/**
* __ir_input_register() - sets the IR keycode table and add the handlers
* for keymap table get/set
* @input_dev: the struct input_dev descriptor of the device
* @rc_tab: the struct ir_scancode_table table of scancode/keymap
*
* This routine is used to initialize the input infrastructure
* to work with an IR.
* It will register the input/evdev interface for the device and
* register the syfs code for IR class
*/
int __ir_input_register(struct input_dev *input_dev,
const struct ir_scancode_table *rc_tab,
struct ir_dev_props *props,
const char *driver_name)
{
struct ir_input_dev *ir_dev;
int rc;
if (rc_tab->scan == NULL || !rc_tab->size)
return -EINVAL;
ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
if (!ir_dev)
return -ENOMEM;
ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name);
if (!ir_dev->driver_name) {
rc = -ENOMEM;
goto out_dev;
}
input_dev->getkeycode_new = ir_getkeycode;
input_dev->setkeycode_new = ir_setkeycode;
input_set_drvdata(input_dev, ir_dev);
ir_dev->input_dev = input_dev;
spin_lock_init(&ir_dev->rc_tab.lock);
spin_lock_init(&ir_dev->keylock);
setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
if (props) {
ir_dev->props = props;
if (props->open)
input_dev->open = ir_open;
if (props->close)
input_dev->close = ir_close;
}
set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_REP, input_dev->evbit);
set_bit(EV_MSC, input_dev->evbit);
set_bit(MSC_SCAN, input_dev->mscbit);
rc = ir_setkeytable(ir_dev, rc_tab);
if (rc)
goto out_name;
rc = ir_register_class(input_dev);
if (rc < 0)
goto out_table;
if (ir_dev->props)
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_register(input_dev);
if (rc < 0)
goto out_event;
}
rc = ir_register_input(input_dev);
if (rc < 0)
goto out_event;
IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
driver_name, rc_tab->name,
(ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
" in raw mode" : "");
/*
* Default delay of 250ms is too short for some protocols, expecially
* since the timeout is currently set to 250ms. Increase it to 500ms,
* to avoid wrong repetition of the keycodes.
*/
input_dev->rep[REP_DELAY] = 500;
return 0;
out_event:
ir_unregister_class(input_dev);
out_table:
ir_free_table(&ir_dev->rc_tab);
out_name:
kfree(ir_dev->driver_name);
out_dev:
kfree(ir_dev);
return rc;
}
EXPORT_SYMBOL_GPL(__ir_input_register);
/**
* ir_input_unregister() - unregisters IR and frees resources
* @input_dev: the struct input_dev descriptor of the device
* This routine is used to free memory and de-register interfaces.
*/
void ir_input_unregister(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
if (!ir_dev)
return;
IR_dprintk(1, "Freed keycode table\n");
del_timer_sync(&ir_dev->timer_keyup);
if (ir_dev->props)
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(input_dev);
ir_free_table(&ir_dev->rc_tab);
ir_unregister_class(input_dev);
kfree(ir_dev->driver_name);
kfree(ir_dev);
}
EXPORT_SYMBOL_GPL(ir_input_unregister);
int ir_core_debug; /* ir_debug level (0,1,2) */
EXPORT_SYMBOL_GPL(ir_core_debug);
module_param_named(debug, ir_core_debug, int, 0644);
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_LICENSE("GPL");

View File

@ -1,362 +0,0 @@
/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
*
* Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/device.h>
#include "ir-core-priv.h"
#define IRRCV_NUM_DEVICES 256
/* bit array to represent IR sysfs device number */
static unsigned long ir_core_dev_number;
/* class for /sys/class/rc */
static char *ir_devnode(struct device *dev, mode_t *mode)
{
return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
}
static struct class ir_input_class = {
.name = "rc",
.devnode = ir_devnode,
};
static struct {
u64 type;
char *name;
} proto_names[] = {
{ IR_TYPE_UNKNOWN, "unknown" },
{ IR_TYPE_RC5, "rc-5" },
{ IR_TYPE_NEC, "nec" },
{ IR_TYPE_RC6, "rc-6" },
{ IR_TYPE_JVC, "jvc" },
{ IR_TYPE_SONY, "sony" },
{ IR_TYPE_RC5_SZ, "rc-5-sz" },
{ IR_TYPE_LIRC, "lirc" },
};
#define PROTO_NONE "none"
/**
* show_protocols() - shows the current IR protocol(s)
* @d: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the output buffer
*
* This routine is a callback routine for input read the IR protocol type(s).
* it is trigged by reading /sys/class/rc/rc?/protocols.
* It returns the protocol names of supported protocols.
* Enabled protocols are printed in brackets.
*/
static ssize_t show_protocols(struct device *d,
struct device_attribute *mattr, char *buf)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
u64 allowed, enabled;
char *tmp = buf;
int i;
/* Device is being removed */
if (!ir_dev)
return -EINVAL;
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
enabled = ir_dev->rc_tab.ir_type;
allowed = ir_dev->props->allowed_protos;
} else if (ir_dev->raw) {
enabled = ir_dev->raw->enabled_protocols;
allowed = ir_raw_get_allowed_protocols();
} else
return sprintf(tmp, "[builtin]\n");
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
(long long)allowed,
(long long)enabled);
for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
if (allowed & enabled & proto_names[i].type)
tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
else if (allowed & proto_names[i].type)
tmp += sprintf(tmp, "%s ", proto_names[i].name);
}
if (tmp != buf)
tmp--;
*tmp = '\n';
return tmp + 1 - buf;
}
/**
* store_protocols() - changes the current IR protocol(s)
* @d: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the input buffer
* @len: length of the input buffer
*
* This routine is a callback routine for changing the IR protocol type.
* It is trigged by writing to /sys/class/rc/rc?/protocols.
* Writing "+proto" will add a protocol to the list of enabled protocols.
* Writing "-proto" will remove a protocol from the list of enabled protocols.
* Writing "proto" will enable only "proto".
* Writing "none" will disable all protocols.
* Returns -EINVAL if an invalid protocol combination or unknown protocol name
* is used, otherwise @len.
*/
static ssize_t store_protocols(struct device *d,
struct device_attribute *mattr,
const char *data,
size_t len)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
bool enable, disable;
const char *tmp;
u64 type;
u64 mask;
int rc, i, count = 0;
unsigned long flags;
/* Device is being removed */
if (!ir_dev)
return -EINVAL;
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
type = ir_dev->rc_tab.ir_type;
else if (ir_dev->raw)
type = ir_dev->raw->enabled_protocols;
else {
IR_dprintk(1, "Protocol switching not supported\n");
return -EINVAL;
}
while ((tmp = strsep((char **) &data, " \n")) != NULL) {
if (!*tmp)
break;
if (*tmp == '+') {
enable = true;
disable = false;
tmp++;
} else if (*tmp == '-') {
enable = false;
disable = true;
tmp++;
} else {
enable = false;
disable = false;
}
if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
tmp += sizeof(PROTO_NONE);
mask = 0;
count++;
} else {
for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
tmp += strlen(proto_names[i].name);
mask = proto_names[i].type;
break;
}
}
if (i == ARRAY_SIZE(proto_names)) {
IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
return -EINVAL;
}
count++;
}
if (enable)
type |= mask;
else if (disable)
type &= ~mask;
else
type = mask;
}
if (!count) {
IR_dprintk(1, "Protocol not specified\n");
return -EINVAL;
}
if (ir_dev->props && ir_dev->props->change_protocol) {
rc = ir_dev->props->change_protocol(ir_dev->props->priv,
type);
if (rc < 0) {
IR_dprintk(1, "Error setting protocols to 0x%llx\n",
(long long)type);
return -EINVAL;
}
}
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
ir_dev->rc_tab.ir_type = type;
spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
} else {
ir_dev->raw->enabled_protocols = type;
}
IR_dprintk(1, "Current protocol(s): 0x%llx\n",
(long long)type);
return len;
}
#define ADD_HOTPLUG_VAR(fmt, val...) \
do { \
int err = add_uevent_var(env, fmt, val); \
if (err) \
return err; \
} while (0)
static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(device);
if (ir_dev->rc_tab.name)
ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
if (ir_dev->driver_name)
ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
return 0;
}
/*
* Static device attribute struct with the sysfs attributes for IR's
*/
static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
show_protocols, store_protocols);
static struct attribute *rc_dev_attrs[] = {
&dev_attr_protocols.attr,
NULL,
};
static struct attribute_group rc_dev_attr_grp = {
.attrs = rc_dev_attrs,
};
static const struct attribute_group *rc_dev_attr_groups[] = {
&rc_dev_attr_grp,
NULL
};
static struct device_type rc_dev_type = {
.groups = rc_dev_attr_groups,
.uevent = rc_dev_uevent,
};
/**
* ir_register_class() - creates the sysfs for /sys/class/rc/rc?
* @input_dev: the struct input_dev descriptor of the device
*
* This routine is used to register the syfs code for IR class
*/
int ir_register_class(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
int devno = find_first_zero_bit(&ir_core_dev_number,
IRRCV_NUM_DEVICES);
if (unlikely(devno < 0))
return devno;
ir_dev->dev.type = &rc_dev_type;
ir_dev->devno = devno;
ir_dev->dev.class = &ir_input_class;
ir_dev->dev.parent = input_dev->dev.parent;
input_dev->dev.parent = &ir_dev->dev;
dev_set_name(&ir_dev->dev, "rc%d", devno);
dev_set_drvdata(&ir_dev->dev, ir_dev);
return device_register(&ir_dev->dev);
};
/**
* ir_register_input - registers ir input device with input subsystem
* @input_dev: the struct input_dev descriptor of the device
*/
int ir_register_input(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
int rc;
const char *path;
rc = input_register_device(input_dev);
if (rc < 0) {
device_del(&ir_dev->dev);
return rc;
}
__module_get(THIS_MODULE);
path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
printk(KERN_INFO "%s: %s as %s\n",
dev_name(&ir_dev->dev),
input_dev->name ? input_dev->name : "Unspecified device",
path ? path : "N/A");
kfree(path);
set_bit(ir_dev->devno, &ir_core_dev_number);
return 0;
}
/**
* ir_unregister_class() - removes the sysfs for sysfs for
* /sys/class/rc/rc?
* @input_dev: the struct input_dev descriptor of the device
*
* This routine is used to unregister the syfs code for IR class
*/
void ir_unregister_class(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
input_set_drvdata(input_dev, NULL);
clear_bit(ir_dev->devno, &ir_core_dev_number);
input_unregister_device(input_dev);
device_del(&ir_dev->dev);
module_put(THIS_MODULE);
}
/*
* Init/exit code for the module. Basically, creates/removes /sys/class/rc
*/
static int __init ir_core_init(void)
{
int rc = class_register(&ir_input_class);
if (rc) {
printk(KERN_ERR "ir_core: unable to register rc class\n");
return rc;
}
/* Initialize/load the decoders/keymap code that will be used */
ir_raw_init();
ir_rcmap_init();
return 0;
}
static void __exit ir_core_exit(void)
{
class_unregister(&ir_input_class);
ir_rcmap_cleanup();
}
module_init(ir_core_init);
module_exit(ir_core_exit);

View File

@ -1,73 +0,0 @@
/* tbs-nec.h - Keytable for tbs_nec Remote Controller
*
* keymap imported from ir-keymaps.c
*
* Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <media/rc-map.h>
static struct ir_scancode tbs_nec[] = {
{ 0x04, KEY_POWER2}, /*power*/
{ 0x14, KEY_MUTE}, /*mute*/
{ 0x07, KEY_1},
{ 0x06, KEY_2},
{ 0x05, KEY_3},
{ 0x0b, KEY_4},
{ 0x0a, KEY_5},
{ 0x09, KEY_6},
{ 0x0f, KEY_7},
{ 0x0e, KEY_8},
{ 0x0d, KEY_9},
{ 0x12, KEY_0},
{ 0x16, KEY_CHANNELUP}, /*ch+*/
{ 0x11, KEY_CHANNELDOWN},/*ch-*/
{ 0x13, KEY_VOLUMEUP}, /*vol+*/
{ 0x0c, KEY_VOLUMEDOWN},/*vol-*/
{ 0x03, KEY_RECORD}, /*rec*/
{ 0x18, KEY_PAUSE}, /*pause*/
{ 0x19, KEY_OK}, /*ok*/
{ 0x1a, KEY_CAMERA}, /* snapshot */
{ 0x01, KEY_UP},
{ 0x10, KEY_LEFT},
{ 0x02, KEY_RIGHT},
{ 0x08, KEY_DOWN},
{ 0x15, KEY_FAVORITES},
{ 0x17, KEY_SUBTITLE},
{ 0x1d, KEY_ZOOM},
{ 0x1f, KEY_EXIT},
{ 0x1e, KEY_MENU},
{ 0x1c, KEY_EPG},
{ 0x00, KEY_PREVIOUS},
{ 0x1b, KEY_MODE},
};
static struct rc_keymap tbs_nec_map = {
.map = {
.scan = tbs_nec,
.size = ARRAY_SIZE(tbs_nec),
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TBS_NEC,
}
};
static int __init init_rc_map_tbs_nec(void)
{
return ir_register_map(&tbs_nec_map);
}
static void __exit exit_rc_map_tbs_nec(void)
{
ir_unregister_map(&tbs_nec_map);
}
module_init(init_rc_map_tbs_nec)
module_exit(exit_rc_map_tbs_nec)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");

View File

@ -1,82 +0,0 @@
/* tt-1500.h - Keytable for tt_1500 Remote Controller
*
* keymap imported from ir-keymaps.c
*
* Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <media/rc-map.h>
/* for the Technotrend 1500 bundled remotes (grey and black): */
static struct ir_scancode tt_1500[] = {
{ 0x01, KEY_POWER },
{ 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
{ 0x03, KEY_1 },
{ 0x04, KEY_2 },
{ 0x05, KEY_3 },
{ 0x06, KEY_4 },
{ 0x07, KEY_5 },
{ 0x08, KEY_6 },
{ 0x09, KEY_7 },
{ 0x0a, KEY_8 },
{ 0x0b, KEY_9 },
{ 0x0c, KEY_0 },
{ 0x0d, KEY_UP },
{ 0x0e, KEY_LEFT },
{ 0x0f, KEY_OK },
{ 0x10, KEY_RIGHT },
{ 0x11, KEY_DOWN },
{ 0x12, KEY_INFO },
{ 0x13, KEY_EXIT },
{ 0x14, KEY_RED },
{ 0x15, KEY_GREEN },
{ 0x16, KEY_YELLOW },
{ 0x17, KEY_BLUE },
{ 0x18, KEY_MUTE },
{ 0x19, KEY_TEXT },
{ 0x1a, KEY_MODE }, /* ? TV/Radio */
{ 0x21, KEY_OPTION },
{ 0x22, KEY_EPG },
{ 0x23, KEY_CHANNELUP },
{ 0x24, KEY_CHANNELDOWN },
{ 0x25, KEY_VOLUMEUP },
{ 0x26, KEY_VOLUMEDOWN },
{ 0x27, KEY_SETUP },
{ 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
{ 0x3b, KEY_PLAY },
{ 0x3c, KEY_STOP },
{ 0x3d, KEY_REWIND },
{ 0x3e, KEY_PAUSE },
{ 0x3f, KEY_FORWARD },
};
static struct rc_keymap tt_1500_map = {
.map = {
.scan = tt_1500,
.size = ARRAY_SIZE(tt_1500),
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TT_1500,
}
};
static int __init init_rc_map_tt_1500(void)
{
return ir_register_map(&tt_1500_map);
}
static void __exit exit_rc_map_tt_1500(void)
{
ir_unregister_map(&tt_1500_map);
}
module_init(init_rc_map_tt_1500)
module_exit(exit_rc_map_tt_1500)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");

View File

@ -1,107 +0,0 @@
/* ir-raw-event.c - handle IR Pulse/Space event
*
* Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <media/ir-core.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
/* Used to handle IR raw handler extensions */
static LIST_HEAD(rc_map_list);
static DEFINE_SPINLOCK(rc_map_lock);
static struct rc_keymap *seek_rc_map(const char *name)
{
struct rc_keymap *map = NULL;
spin_lock(&rc_map_lock);
list_for_each_entry(map, &rc_map_list, list) {
if (!strcmp(name, map->map.name)) {
spin_unlock(&rc_map_lock);
return map;
}
}
spin_unlock(&rc_map_lock);
return NULL;
}
struct ir_scancode_table *get_rc_map(const char *name)
{
struct rc_keymap *map;
map = seek_rc_map(name);
#ifdef MODULE
if (!map) {
int rc = request_module(name);
if (rc < 0) {
printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
return NULL;
}
msleep(20); /* Give some time for IR to register */
map = seek_rc_map(name);
}
#endif
if (!map) {
printk(KERN_ERR "IR keymap %s not found\n", name);
return NULL;
}
printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
return &map->map;
}
EXPORT_SYMBOL_GPL(get_rc_map);
int ir_register_map(struct rc_keymap *map)
{
spin_lock(&rc_map_lock);
list_add_tail(&map->list, &rc_map_list);
spin_unlock(&rc_map_lock);
return 0;
}
EXPORT_SYMBOL_GPL(ir_register_map);
void ir_unregister_map(struct rc_keymap *map)
{
spin_lock(&rc_map_lock);
list_del(&map->list);
spin_unlock(&rc_map_lock);
}
EXPORT_SYMBOL_GPL(ir_unregister_map);
static struct ir_scancode empty[] = {
{ 0x2a, KEY_COFFEE },
};
static struct rc_keymap empty_map = {
.map = {
.scan = empty,
.size = ARRAY_SIZE(empty),
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EMPTY,
}
};
int ir_rcmap_init(void)
{
return ir_register_map(&empty_map);
}
void ir_rcmap_cleanup(void)
{
ir_unregister_map(&empty_map);
}

View File

@ -40,35 +40,6 @@ config VIDEO_V4L2_COMMON
depends on (I2C || I2C=n) && VIDEO_DEV
default (I2C || I2C=n) && VIDEO_DEV
config VIDEO_ALLOW_V4L1
bool "Enable Video For Linux API 1 (DEPRECATED)"
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
default VIDEO_DEV && VIDEO_V4L2_COMMON
---help---
Enables drivers based on the legacy V4L1 API.
This api were developed to be used at Kernel 2.2 and 2.4, but
lacks support for several video standards. There are several
drivers at kernel that still depends on it.
If you are unsure as to whether this is required, answer Y.
config VIDEO_V4L1_COMPAT
bool "Enable Video For Linux API 1 compatible Layer" if !VIDEO_ALLOW_V4L1
depends on VIDEO_DEV
default y
---help---
Enables a compatibility API used by most V4L2 devices to allow
its usage with legacy applications that supports only V4L1 api.
Documentation for the original API is included in the file
<Documentation/video4linux/API.html>.
User tools for this are available from
<ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
If you are unsure as to whether this is required, answer Y.
#
# DVB Core
#
@ -99,7 +70,7 @@ config VIDEO_MEDIA
comment "Multimedia drivers"
source "drivers/media/common/Kconfig"
source "drivers/media/IR/Kconfig"
source "drivers/media/rc/Kconfig"
#
# Tuner drivers for DVB and V4L
@ -121,26 +92,4 @@ source "drivers/media/radio/Kconfig"
source "drivers/media/dvb/Kconfig"
config DAB
boolean "DAB adapters"
---help---
Allow selecting support for Digital Audio Broadcasting (DAB)
Receiver adapters.
if DAB
config USB_DABUSB
tristate "DABUSB driver"
depends on USB
---help---
A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
brought to you by the DAB-Team
<http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
as an example for URB-based bulk, control, and isochronous
transactions. URB's are explained in
<Documentation/usb/URB.txt>.
To compile this driver as a module, choose M here: the
module will be called dabusb.
endif # DAB
endif # MEDIA_SUPPORT

View File

@ -2,7 +2,7 @@
# Makefile for the kernel multimedia device drivers.
#
obj-y += common/ IR/ video/
obj-y += common/ rc/ video/
obj-$(CONFIG_VIDEO_DEV) += radio/
obj-$(CONFIG_DVB_CORE) += dvb/

View File

@ -1129,35 +1129,6 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh,
core, g_chip_ident, chip);
}
#ifdef CONFIG_VIDEO_V4L1_COMPAT
static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
{
struct saa7146_fh *fh = __fh;
struct videobuf_queue *q = &fh->video_q;
int err, i;
/* fixme: number of capture buffers and sizes for v4l apps */
int gbuffers = 2;
int gbufsize = 768 * 576 * 4;
DEB_D(("VIDIOCGMBUF \n"));
q = &fh->video_q;
err = videobuf_mmap_setup(q, gbuffers, gbufsize,
V4L2_MEMORY_MMAP);
if (err < 0)
return err;
gbuffers = err;
memset(mbuf, 0, sizeof(*mbuf));
mbuf->frames = gbuffers;
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
return 0;
}
#endif
const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@ -1186,9 +1157,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_parm = vidioc_g_parm,
#ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidiocgmbuf,
#endif
};
/*********************************************************************************/

View File

@ -52,13 +52,12 @@ static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
msg.addr = priv->config->i2c_address;
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, data);
dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -EIO : 0;
@ -78,14 +77,13 @@ static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
__func__, reg, ret);
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
*p_data = b1[0];
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
dprintk("%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, b1[0]);
return 0;
}

View File

@ -28,7 +28,7 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
/* write multiple registers */
static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
{
int ret;
int ret = 0;
u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
struct i2c_msg msg[1] = {
{

View File

@ -1,7 +1,6 @@
config DVB_DM1105
tristate "SDMC DM1105 based PCI cards"
depends on DVB_CORE && PCI && I2C
depends on INPUT
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
@ -9,7 +8,7 @@ config DVB_DM1105
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_DS3000 if !DVB_FE_CUSTOMISE
depends on VIDEO_IR
depends on RC_CORE
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002

View File

@ -26,9 +26,8 @@
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <media/ir-core.h>
#include <media/rc-core.h>
#include "demux.h"
#include "dmxdev.h"
@ -266,7 +265,7 @@ static void dm1105_card_list(struct pci_dev *pci)
/* infrared remote control */
struct infrared {
struct input_dev *input_dev;
struct rc_dev *dev;
char input_phys[32];
struct work_struct work;
u32 ir_command;
@ -532,7 +531,7 @@ static void dm1105_emit_key(struct work_struct *work)
data = (ircom >> 8) & 0x7f;
ir_keydown(ir->input_dev, data, 0);
rc_keydown(ir->dev, data, 0);
}
/* work handler */
@ -593,46 +592,47 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{
struct input_dev *input_dev;
char *ir_codes = RC_MAP_DM1105_NEC;
struct rc_dev *dev;
int err = -ENOMEM;
input_dev = input_allocate_device();
if (!input_dev)
dev = rc_allocate_device();
if (!dev)
return -ENOMEM;
dm1105->ir.input_dev = input_dev;
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
input_dev->name = "DVB on-card IR receiver";
input_dev->phys = dm1105->ir.input_phys;
input_dev->id.bustype = BUS_PCI;
input_dev->id.version = 1;
dev->driver_name = MODULE_NAME;
dev->map_name = RC_MAP_DM1105_NEC;
dev->driver_type = RC_DRIVER_SCANCODE;
dev->input_name = "DVB on-card IR receiver";
dev->input_phys = dm1105->ir.input_phys;
dev->input_id.bustype = BUS_PCI;
dev->input_id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
input_dev->id.product = dm1105->pdev->subsystem_device;
dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
dev->input_id.product = dm1105->pdev->subsystem_device;
} else {
input_dev->id.vendor = dm1105->pdev->vendor;
input_dev->id.product = dm1105->pdev->device;
dev->input_id.vendor = dm1105->pdev->vendor;
dev->input_id.product = dm1105->pdev->device;
}
input_dev->dev.parent = &dm1105->pdev->dev;
dev->dev.parent = &dm1105->pdev->dev;
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
err = rc_register_device(dev);
if (err < 0) {
input_free_device(input_dev);
rc_free_device(dev);
return err;
}
dm1105->ir.dev = dev;
return 0;
}
void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
{
ir_input_unregister(dm1105->ir.input_dev);
rc_unregister_device(dm1105->ir.dev);
}
static int __devinit dm1105_hw_init(struct dm1105_dev *dev)

View File

@ -572,13 +572,13 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
dmx_output_t otype;
int ret;
int ts_type;
enum dmx_ts_pes ts_pes;
dmx_pes_type_t ts_pes;
struct dmx_ts_feed *tsfeed;
feed->ts = NULL;
otype = para->output;
ts_pes = (enum dmx_ts_pes)para->pes_type;
ts_pes = para->pes_type;
if (ts_pes < DMX_PES_OTHER)
ts_type = TS_DECODER;

View File

@ -1,6 +1,6 @@
config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB && I2C && IR_CORE
depends on DVB_CORE && USB && I2C && RC_CORE
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.

View File

@ -37,7 +37,7 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
return 0;
}
static struct ir_scancode ir_codes_a800_table[] = {
static struct rc_map_table rc_map_a800_table[] = {
{ 0x0201, KEY_PROG1 }, /* SOURCE */
{ 0x0200, KEY_POWER }, /* POWER */
{ 0x0205, KEY_1 }, /* 1 */
@ -148,8 +148,8 @@ static struct dvb_usb_device_properties a800_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_a800_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table),
.rc_map_table = rc_map_a800_table,
.rc_map_size = ARRAY_SIZE(rc_map_a800_table),
.rc_query = a800_rc_query,
},

View File

@ -33,7 +33,7 @@ MODULE_PARM_DESC(debug,
#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
struct ir_scancode ir_codes_af9005_table[] = {
struct rc_map_table rc_map_af9005_table[] = {
{0x01b7, KEY_POWER},
{0x01a7, KEY_VOLUMEUP},
@ -74,7 +74,7 @@ struct ir_scancode ir_codes_af9005_table[] = {
{0x00d5, KEY_GOTO}, /* marked jump on the remote */
};
int ir_codes_af9005_table_size = ARRAY_SIZE(ir_codes_af9005_table);
int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
static int repeatable_keys[] = {
KEY_VOLUMEUP,
@ -130,10 +130,10 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
deb_decode("code != inverted code\n");
return 0;
}
for (i = 0; i < ir_codes_af9005_table_size; i++) {
if (rc5_custom(&ir_codes_af9005_table[i]) == cust
&& rc5_data(&ir_codes_af9005_table[i]) == dat) {
*event = ir_codes_af9005_table[i].keycode;
for (i = 0; i < rc_map_af9005_table_size; i++) {
if (rc5_custom(&rc_map_af9005_table[i]) == cust
&& rc5_data(&rc_map_af9005_table[i]) == dat) {
*event = rc_map_af9005_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
deb_decode
("key pressed, event %x\n", *event);
@ -146,8 +146,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
return 0;
}
EXPORT_SYMBOL(ir_codes_af9005_table);
EXPORT_SYMBOL(ir_codes_af9005_table_size);
EXPORT_SYMBOL(rc_map_af9005_table);
EXPORT_SYMBOL(rc_map_af9005_table_size);
EXPORT_SYMBOL(af9005_rc_decode);
MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");

View File

@ -1027,8 +1027,8 @@ static struct dvb_usb_device_properties af9005_properties = {
.rc.legacy = {
.rc_interval = 200,
.rc_key_map = NULL,
.rc_key_map_size = 0,
.rc_map_table = NULL,
.rc_map_size = 0,
.rc_query = af9005_rc_query,
},
@ -1070,14 +1070,14 @@ static int __init af9005_usb_module_init(void)
return result;
}
rc_decode = symbol_request(af9005_rc_decode);
rc_keys = symbol_request(ir_codes_af9005_table);
rc_keys_size = symbol_request(ir_codes_af9005_table_size);
rc_keys = symbol_request(rc_map_af9005_table);
rc_keys_size = symbol_request(rc_map_af9005_table_size);
if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
err("af9005_rc_decode function not found, disabling remote");
af9005_properties.rc.legacy.rc_query = NULL;
} else {
af9005_properties.rc.legacy.rc_key_map = rc_keys;
af9005_properties.rc.legacy.rc_key_map_size = *rc_keys_size;
af9005_properties.rc.legacy.rc_map_table = rc_keys;
af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
}
return 0;
@ -1089,9 +1089,9 @@ static void __exit af9005_usb_module_exit(void)
if (rc_decode != NULL)
symbol_put(af9005_rc_decode);
if (rc_keys != NULL)
symbol_put(ir_codes_af9005_table);
symbol_put(rc_map_af9005_table);
if (rc_keys_size != NULL)
symbol_put(ir_codes_af9005_table_size);
symbol_put(rc_map_af9005_table_size);
/* deregister this driver from the USB subsystem */
usb_deregister(&af9005_usb_driver);
}

View File

@ -3490,7 +3490,7 @@ extern u8 regmask[8];
/* remote control decoder */
extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
u32 * event, int *state);
extern struct ir_scancode ir_codes_af9005_table[];
extern int ir_codes_af9005_table_size;
extern struct rc_map_table rc_map_af9005_table[];
extern int rc_map_af9005_table_size;
#endif

View File

@ -1041,13 +1041,13 @@ static int af9015_rc_query(struct dvb_usb_device *d)
priv->rc_keycode = buf[12] << 16 |
buf[13] << 8 | buf[14];
}
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
priv->rc_keycode = 0; /* clear just for sure */
}
} else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__);
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
deb_rc("%s: no key press\n", __func__);
}
@ -1344,13 +1344,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
.protocol = IR_TYPE_NEC,
.protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
.rc_props = {
.allowed_protos = IR_TYPE_NEC,
},
.allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@ -1474,13 +1472,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
.protocol = IR_TYPE_NEC,
.protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
.rc_props = {
.allowed_protos = IR_TYPE_NEC,
},
.allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@ -1588,13 +1584,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
.protocol = IR_TYPE_NEC,
.protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
.rc_props = {
.allowed_protos = IR_TYPE_NEC,
},
.allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,

View File

@ -394,7 +394,7 @@ static int anysee_rc_query(struct dvb_usb_device *d)
if (ircode[0]) {
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
}
return 0;
@ -476,7 +476,7 @@ static struct dvb_usb_device_properties anysee_properties = {
.rc.core = {
.rc_codes = RC_MAP_ANYSEE,
.protocol = IR_TYPE_OTHER,
.protocol = RC_TYPE_OTHER,
.module_name = "anysee",
.rc_query = anysee_rc_query,
.rc_interval = 250, /* windows driver uses 500ms */

View File

@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
}
/* keys for the enclosed remote control */
static struct ir_scancode ir_codes_az6027_table[] = {
static struct rc_map_table rc_map_az6027_table[] = {
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
};
@ -1089,6 +1089,7 @@ static struct usb_device_id az6027_usb_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
{ },
};
@ -1126,15 +1127,15 @@ static struct dvb_usb_device_properties az6027_properties = {
.read_mac_address = az6027_read_mac_addr,
*/
.rc.legacy = {
.rc_key_map = ir_codes_az6027_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table),
.rc_map_table = rc_map_az6027_table,
.rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
.rc_interval = 400,
.rc_query = az6027_rc_query,
},
.i2c_algo = &az6027_i2c_algo,
.num_device_descs = 5,
.num_device_descs = 6,
.devices = {
{
.name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
@ -1156,6 +1157,10 @@ static struct dvb_usb_device_properties az6027_properties = {
.name = "Technisat SkyStar USB 2 HD CI",
.cold_ids = { &az6027_usb_table[4], NULL },
.warm_ids = { NULL },
}, {
.name = "Elgato EyeTV Sat",
.cold_ids = { &az6027_usb_table[5], NULL },
.warm_ids = { NULL },
},
{ NULL },
}

View File

@ -84,7 +84,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
return 0;
}
static struct ir_scancode ir_codes_cinergyt2_table[] = {
static struct rc_map_table rc_map_cinergyt2_table[] = {
{ 0x0401, KEY_POWER },
{ 0x0402, KEY_1 },
{ 0x0403, KEY_2 },
@ -219,8 +219,8 @@ static struct dvb_usb_device_properties cinergyt2_properties = {
.rc.legacy = {
.rc_interval = 50,
.rc_key_map = ir_codes_cinergyt2_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table),
.rc_map_table = rc_map_cinergyt2_table,
.rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
.rc_query = cinergyt2_rc_query,
},

View File

@ -385,7 +385,7 @@ static int cxusb_d680_dmb_streaming_ctrl(
static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
@ -394,7 +394,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[2] &&
rc5_data(&keymap[i]) == ircode[3]) {
*event = keymap[i].keycode;
@ -410,7 +410,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
@ -422,7 +422,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
return 0;
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[1] &&
rc5_data(&keymap[i]) == ircode[2]) {
*event = keymap[i].keycode;
@ -438,7 +438,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[2];
int i;
@ -448,7 +448,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
return 0;
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[0] &&
rc5_data(&keymap[i]) == ircode[1]) {
*event = keymap[i].keycode;
@ -461,7 +461,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
}
static struct ir_scancode ir_codes_dvico_mce_table[] = {
static struct rc_map_table rc_map_dvico_mce_table[] = {
{ 0xfe02, KEY_TV },
{ 0xfe0e, KEY_MP3 },
{ 0xfe1a, KEY_DVD },
@ -509,7 +509,7 @@ static struct ir_scancode ir_codes_dvico_mce_table[] = {
{ 0xfe4e, KEY_POWER },
};
static struct ir_scancode ir_codes_dvico_portable_table[] = {
static struct rc_map_table rc_map_dvico_portable_table[] = {
{ 0xfc02, KEY_SETUP }, /* Profile */
{ 0xfc43, KEY_POWER2 },
{ 0xfc06, KEY_EPG },
@ -548,7 +548,7 @@ static struct ir_scancode ir_codes_dvico_portable_table[] = {
{ 0xfc00, KEY_UNKNOWN }, /* HD */
};
static struct ir_scancode ir_codes_d680_dmb_table[] = {
static struct rc_map_table rc_map_d680_dmb_table[] = {
{ 0x0038, KEY_UNKNOWN }, /* TV/AV */
{ 0x080c, KEY_ZOOM },
{ 0x0800, KEY_0 },
@ -923,7 +923,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
return -EIO;
/* try to determine if there is no IR decoder on the I2C bus */
for (i = 0; adap->dev->props.rc.legacy.rc_key_map != NULL && i < 5; i++) {
for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
msleep(20);
if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
goto no_IR;
@ -931,7 +931,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
continue;
if (ircode[2] + ircode[3] != 0xff) {
no_IR:
adap->dev->props.rc.legacy.rc_key_map = NULL;
adap->dev->props.rc.legacy.rc_map_table = NULL;
info("No IR receiver detected on this device.");
break;
}
@ -1453,8 +1453,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_portable_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
.rc_map_table = rc_map_dvico_portable_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@ -1506,8 +1506,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
.rc.legacy = {
.rc_interval = 150,
.rc_key_map = ir_codes_dvico_mce_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
.rc_map_table = rc_map_dvico_mce_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@ -1567,8 +1567,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_portable_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
.rc_map_table = rc_map_dvico_portable_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@ -1619,8 +1619,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_portable_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
.rc_map_table = rc_map_dvico_portable_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@ -1670,8 +1670,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_mce_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
.rc_map_table = rc_map_dvico_mce_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@ -1720,8 +1720,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_portable_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
.rc_map_table = rc_map_dvico_portable_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@ -1772,8 +1772,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_portable_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
.rc_map_table = rc_map_dvico_portable_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@ -1865,8 +1865,8 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_dvico_mce_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
.rc_map_table = rc_map_dvico_mce_table,
.rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@ -1915,8 +1915,8 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_d680_dmb_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
.rc_map_table = rc_map_d680_dmb_table,
.rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},
@ -1966,8 +1966,8 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_d680_dmb_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
.rc_map_table = rc_map_d680_dmb_table,
.rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},

View File

@ -60,7 +60,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
extern struct i2c_algorithm dib0700_i2c_algo;
extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc, int *cold);
extern int dib0700_change_protocol(void *priv, u64 ir_type);
extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
extern int dib0700_device_count;
extern int dvb_usb_dib0700_ir_proto;

View File

@ -471,19 +471,19 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4);
}
int dib0700_change_protocol(void *priv, u64 ir_type)
int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
{
struct dvb_usb_device *d = priv;
struct dvb_usb_device *d = rc->priv;
struct dib0700_state *st = d->priv;
u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
int new_proto, ret;
/* Set the IR mode */
if (ir_type == IR_TYPE_RC5)
if (rc_type == RC_TYPE_RC5)
new_proto = 1;
else if (ir_type == IR_TYPE_NEC)
else if (rc_type == RC_TYPE_NEC)
new_proto = 0;
else if (ir_type == IR_TYPE_RC6) {
else if (rc_type == RC_TYPE_RC6) {
if (st->fw_version < 0x10200)
return -EINVAL;
@ -499,7 +499,7 @@ int dib0700_change_protocol(void *priv, u64 ir_type)
return ret;
}
d->props.rc.core.protocol = ir_type;
d->props.rc.core.protocol = rc_type;
return ret;
}
@ -535,7 +535,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if (d == NULL)
return;
if (d->rc_input_dev == NULL) {
if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
usb_free_urb(purb);
return;
@ -562,7 +562,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
purb->actual_length);
switch (d->props.rc.core.protocol) {
case IR_TYPE_NEC:
case RC_TYPE_NEC:
toggle = 0;
/* NEC protocol sends repeat code as 0 0 0 FF */
@ -600,7 +600,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
goto resubmit;
}
ir_keydown(d->rc_input_dev, keycode, toggle);
rc_keydown(d->rc_dev, keycode, toggle);
resubmit:
/* Clean the buffer before we requeue */

View File

@ -510,7 +510,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = 0;
switch (d->props.rc.core.protocol) {
case IR_TYPE_NEC:
case RC_TYPE_NEC:
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
(key[3] == 0xff))
@ -520,13 +520,13 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = keycode;
}
ir_keydown(d->rc_input_dev, keycode, 0);
rc_keydown(d->rc_dev, keycode, 0);
break;
default:
/* RC-5 protocol changes toggle bit on new keypress */
keycode = key[3-2] << 8 | key[3-3];
toggle = key[3-1];
ir_keydown(d->rc_input_dev, keycode, toggle);
rc_keydown(d->rc_dev, keycode, toggle);
break;
}
@ -1924,12 +1924,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -1960,12 +1958,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2021,12 +2017,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2065,12 +2059,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2143,12 +2135,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2189,12 +2179,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2259,12 +2247,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2308,12 +2294,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2379,12 +2363,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@ -2417,12 +2399,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@ -2487,12 +2467,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@ -2533,12 +2511,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 2,
@ -2584,12 +2560,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@ -2623,12 +2597,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
.rc_props = {
.allowed_protos = IR_TYPE_RC5 |
IR_TYPE_RC6 |
IR_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
.allowed_protos = RC_TYPE_RC5 |
RC_TYPE_RC6 |
RC_TYPE_NEC,
.change_protocol = dib0700_change_protocol,
},
},
};

View File

@ -327,7 +327,7 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
/*
* common remote control stuff
*/
struct ir_scancode ir_codes_dibusb_table[] = {
struct rc_map_table rc_map_dibusb_table[] = {
/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
@ -456,7 +456,7 @@ struct ir_scancode ir_codes_dibusb_table[] = {
{ 0x804e, KEY_ENTER },
{ 0x804f, KEY_VOLUMEDOWN },
};
EXPORT_SYMBOL(ir_codes_dibusb_table);
EXPORT_SYMBOL(rc_map_dibusb_table);
int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{

View File

@ -213,8 +213,8 @@ static struct dvb_usb_device_properties dibusb1_1_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_dibusb_table,
.rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_map_table = rc_map_dibusb_table,
.rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@ -299,8 +299,8 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_dibusb_table,
.rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_map_table = rc_map_dibusb_table,
.rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@ -365,8 +365,8 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_dibusb_table,
.rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_map_table = rc_map_dibusb_table,
.rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@ -424,8 +424,8 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_dibusb_table,
.rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_map_table = rc_map_dibusb_table,
.rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},

View File

@ -83,8 +83,8 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = ir_codes_dibusb_table,
.rc_key_map_size = 111, /* FIXME */
.rc_map_table = rc_map_dibusb_table,
.rc_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query,
},

View File

@ -124,7 +124,7 @@ extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
#define DEFAULT_RC_INTERVAL 150
//#define DEFAULT_RC_INTERVAL 100000
extern struct ir_scancode ir_codes_dibusb_table[];
extern struct rc_map_table rc_map_dibusb_table[];
extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);

View File

@ -161,7 +161,7 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
static struct ir_scancode ir_codes_digitv_table[] = {
static struct rc_map_table rc_map_digitv_table[] = {
{ 0x5f55, KEY_0 },
{ 0x6f55, KEY_1 },
{ 0x9f55, KEY_2 },
@ -237,10 +237,10 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
/* if something is inside the buffer, simulate key press */
if (key[1] != 0)
{
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
if (rc5_custom(&d->props.rc.legacy.rc_key_map[i]) == key[1] &&
rc5_data(&d->props.rc.legacy.rc_key_map[i]) == key[2]) {
*event = d->props.rc.legacy.rc_key_map[i].keycode;
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
*event = d->props.rc.legacy.rc_map_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
return 0;
}
@ -312,8 +312,8 @@ static struct dvb_usb_device_properties digitv_properties = {
.rc.legacy = {
.rc_interval = 1000,
.rc_key_map = ir_codes_digitv_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table),
.rc_map_table = rc_map_digitv_table,
.rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
.rc_query = digitv_rc_query,
},

View File

@ -57,7 +57,7 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
/* remote control */
/* key list for the tiny remote control (Yakumo, don't know about the others) */
static struct ir_scancode ir_codes_dtt200u_table[] = {
static struct rc_map_table rc_map_dtt200u_table[] = {
{ 0x8001, KEY_MUTE },
{ 0x8002, KEY_CHANNELDOWN },
{ 0x8003, KEY_VOLUMEDOWN },
@ -163,8 +163,8 @@ static struct dvb_usb_device_properties dtt200u_properties = {
.rc.legacy = {
.rc_interval = 300,
.rc_key_map = ir_codes_dtt200u_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
.rc_map_table = rc_map_dtt200u_table,
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@ -210,8 +210,8 @@ static struct dvb_usb_device_properties wt220u_properties = {
.rc.legacy = {
.rc_interval = 300,
.rc_key_map = ir_codes_dtt200u_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
.rc_map_table = rc_map_dtt200u_table,
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@ -257,8 +257,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
.rc.legacy = {
.rc_interval = 300,
.rc_key_map = ir_codes_dtt200u_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
.rc_map_table = rc_map_dtt200u_table,
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@ -304,8 +304,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
.rc.legacy = {
.rc_interval = 300,
.rc_key_map = ir_codes_dtt200u_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
.rc_map_table = rc_map_dtt200u_table,
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},

View File

@ -301,6 +301,7 @@
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
#define USB_PID_ELGATO_EYETV_DTT 0x0021
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
#define USB_PID_ELGATO_EYETV_SAT 0x002a
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
#define USB_PID_FRIIO_WHITE 0x0001

View File

@ -13,11 +13,11 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* See if we can match the raw key code. */
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
*keycode = keymap[i].keycode;
return 0;
@ -28,7 +28,7 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
* otherwise, input core won't let legacy_dvb_usb_setkeycode
* to work
*/
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
*keycode = KEY_RESERVED;
@ -43,18 +43,18 @@ static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* Search if it is replacing an existing keycode */
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
keymap[i].keycode = keycode;
return 0;
}
/* Search if is there a clean entry. If so, use it */
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
keymap[i].scancode = scancode;
@ -106,10 +106,10 @@ static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
input_event(d->rc_input_dev, EV_KEY, event, 1);
input_sync(d->rc_input_dev);
input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
input_sync(d->rc_input_dev);
input_event(d->input_dev, EV_KEY, event, 1);
input_sync(d->input_dev);
input_event(d->input_dev, EV_KEY, d->last_event, 0);
input_sync(d->input_dev);
break;
default:
break;
@ -154,20 +154,32 @@ static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
}
static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
struct input_dev *input_dev)
static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i, err, rc_interval;
struct input_dev *input_dev;
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
input_dev->dev.parent = &d->udev->dev;
d->input_dev = input_dev;
d->rc_dev = NULL;
input_dev->getkeycode = legacy_dvb_usb_getkeycode;
input_dev->setkeycode = legacy_dvb_usb_setkeycode;
/* set the bits for the keys */
deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
deb_rc("setting bit for event %d item %d\n",
d->props.rc.legacy.rc_key_map[i].keycode, i);
set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
d->props.rc.legacy.rc_map_table[i].keycode, i);
set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
}
/* setting these two values to non-zero, we have to manage key repeats */
@ -221,18 +233,34 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
msecs_to_jiffies(d->props.rc.core.rc_interval));
}
static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
struct input_dev *input_dev)
static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int err, rc_interval;
struct rc_dev *dev;
d->props.rc.core.rc_props.priv = d;
err = ir_input_register(input_dev,
d->props.rc.core.rc_codes,
&d->props.rc.core.rc_props,
d->props.rc.core.module_name);
if (err < 0)
dev = rc_allocate_device();
if (!dev)
return -ENOMEM;
dev->driver_name = d->props.rc.core.module_name;
dev->map_name = d->props.rc.core.rc_codes;
dev->change_protocol = d->props.rc.core.change_protocol;
dev->allowed_protos = d->props.rc.core.allowed_protos;
dev->driver_type = RC_DRIVER_SCANCODE;
usb_to_input_id(d->udev, &dev->input_id);
dev->input_name = "IR-receiver inside an USB DVB receiver";
dev->input_phys = d->rc_phys;
dev->dev.parent = &d->udev->dev;
dev->priv = d;
err = rc_register_device(dev);
if (err < 0) {
rc_free_device(dev);
return err;
}
d->input_dev = NULL;
d->rc_dev = dev;
if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
return 0;
@ -251,13 +279,12 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
struct input_dev *input_dev;
int err;
if (dvb_usb_disable_rc_polling)
return 0;
if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
d->props.rc.mode = DVB_RC_LEGACY;
else if (d->props.rc.core.rc_codes)
d->props.rc.mode = DVB_RC_CORE;
@ -267,26 +294,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
input_dev->dev.parent = &d->udev->dev;
/* Start the remote-control polling. */
if (d->props.rc.legacy.rc_interval < 40)
d->props.rc.legacy.rc_interval = 100; /* default */
d->rc_input_dev = input_dev;
if (d->props.rc.mode == DVB_RC_LEGACY)
err = legacy_dvb_usb_remote_init(d, input_dev);
err = legacy_dvb_usb_remote_init(d);
else
err = rc_core_dvb_usb_remote_init(d, input_dev);
err = rc_core_dvb_usb_remote_init(d);
if (err)
return err;
@ -301,9 +316,9 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work();
if (d->props.rc.mode == DVB_RC_LEGACY)
input_unregister_device(d->rc_input_dev);
input_unregister_device(d->input_dev);
else
ir_input_unregister(d->rc_input_dev);
rc_unregister_device(d->rc_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
@ -316,7 +331,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
u8 keybuf[5], u32 *event, int *state)
{
int i;
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
switch (keybuf[0]) {
@ -329,7 +344,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
break;
}
/* See if we can match the raw key code. */
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (rc5_custom(&keymap[i]) == keybuf[1] &&
rc5_data(&keymap[i]) == keybuf[3]) {
*event = keymap[i].keycode;

View File

@ -14,7 +14,7 @@
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/mutex.h>
#include <media/ir-core.h>
#include <media/rc-core.h>
#include "dvb_frontend.h"
#include "dvb_demux.h"
@ -75,17 +75,17 @@ struct dvb_usb_device_description {
struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
};
static inline u8 rc5_custom(struct ir_scancode *key)
static inline u8 rc5_custom(struct rc_map_table *key)
{
return (key->scancode >> 8) & 0xff;
}
static inline u8 rc5_data(struct ir_scancode *key)
static inline u8 rc5_data(struct rc_map_table *key)
{
return key->scancode & 0xff;
}
static inline u8 rc5_scan(struct ir_scancode *key)
static inline u8 rc5_scan(struct rc_map_table *key)
{
return key->scancode & 0xffff;
}
@ -159,9 +159,9 @@ struct dvb_usb_adapter_properties {
/**
* struct dvb_rc_legacy - old properties of remote controller
* @rc_key_map: a hard-wired array of struct ir_scancode (NULL to disable
* @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
* remote control handling).
* @rc_key_map_size: number of items in @rc_key_map.
* @rc_map_size: number of items in @rc_map_table.
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
*/
@ -170,8 +170,8 @@ struct dvb_rc_legacy {
#define REMOTE_NO_KEY_PRESSED 0x00
#define REMOTE_KEY_PRESSED 0x01
#define REMOTE_KEY_REPEAT 0x02
struct ir_scancode *rc_key_map;
int rc_key_map_size;
struct rc_map_table *rc_map_table;
int rc_map_size;
int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
int rc_interval;
};
@ -180,18 +180,20 @@ struct dvb_rc_legacy {
* struct dvb_rc properties of remote controller, using rc-core
* @rc_codes: name of rc codes table
* @protocol: type of protocol(s) currently used by the driver
* @allowed_protos: protocol(s) supported by the driver
* @change_protocol: callback to change protocol
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
* @rc_props: remote controller properties
* @bulk_mode: device supports bulk mode for RC (disable polling mode)
*/
struct dvb_rc {
char *rc_codes;
u64 protocol;
u64 allowed_protos;
int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
char *module_name;
int (*rc_query) (struct dvb_usb_device *d);
int rc_interval;
struct ir_dev_props rc_props;
bool bulk_mode; /* uses bulk mode */
};
@ -385,7 +387,8 @@ struct dvb_usb_adapter {
*
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
*
* @rc_input_dev: input device for the remote control.
* @rc_dev: rc device for the remote control (rc-core mode)
* @input_dev: input device for the remote control (legacy mode)
* @rc_query_work: struct work_struct frequent rc queries
* @last_event: last triggered event
* @last_state: last state (no, pressed, repeat)
@ -418,7 +421,8 @@ struct dvb_usb_device {
struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
/* remote control */
struct input_dev *rc_input_dev;
struct rc_dev *rc_dev;
struct input_dev *input_dev;
char rc_phys[64];
struct delayed_work rc_query_work;
u32 last_event;

View File

@ -73,8 +73,8 @@
"Please see linux/Documentation/dvb/ for more details " \
"on firmware-problems."
struct ir_codes_dvb_usb_table_table {
struct ir_scancode *rc_keys;
struct rc_map_dvb_usb_table_table {
struct rc_map_table *rc_keys;
int rc_keys_size;
};
@ -948,7 +948,7 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
static struct ir_scancode ir_codes_dw210x_table[] = {
static struct rc_map_table rc_map_dw210x_table[] = {
{ 0xf80a, KEY_Q }, /*power*/
{ 0xf80c, KEY_M }, /*mute*/
{ 0xf811, KEY_1 },
@ -982,7 +982,7 @@ static struct ir_scancode ir_codes_dw210x_table[] = {
{ 0xf81b, KEY_B }, /*recall*/
};
static struct ir_scancode ir_codes_tevii_table[] = {
static struct rc_map_table rc_map_tevii_table[] = {
{ 0xf80a, KEY_POWER },
{ 0xf80c, KEY_MUTE },
{ 0xf811, KEY_1 },
@ -1032,7 +1032,7 @@ static struct ir_scancode ir_codes_tevii_table[] = {
{ 0xf858, KEY_SWITCHVIDEOMODE },
};
static struct ir_scancode ir_codes_tbs_table[] = {
static struct rc_map_table rc_map_tbs_table[] = {
{ 0xf884, KEY_POWER },
{ 0xf894, KEY_MUTE },
{ 0xf887, KEY_1 },
@ -1067,16 +1067,16 @@ static struct ir_scancode ir_codes_tbs_table[] = {
{ 0xf89b, KEY_MODE }
};
static struct ir_codes_dvb_usb_table_table keys_tables[] = {
{ ir_codes_dw210x_table, ARRAY_SIZE(ir_codes_dw210x_table) },
{ ir_codes_tevii_table, ARRAY_SIZE(ir_codes_tevii_table) },
{ ir_codes_tbs_table, ARRAY_SIZE(ir_codes_tbs_table) },
static struct rc_map_dvb_usb_table_table keys_tables[] = {
{ rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
{ rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
{ rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
};
static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
int keymap_size = d->props.rc.legacy.rc_key_map_size;
struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int keymap_size = d->props.rc.legacy.rc_map_size;
u8 key[2];
struct i2c_msg msg = {
.addr = DW2102_RC_QUERY,
@ -1185,14 +1185,14 @@ static int dw2102_load_firmware(struct usb_device *dev,
/* init registers */
switch (dev->descriptor.idProduct) {
case USB_PID_PROF_1100:
s6x0_properties.rc.legacy.rc_key_map = ir_codes_tbs_table;
s6x0_properties.rc.legacy.rc_key_map_size =
ARRAY_SIZE(ir_codes_tbs_table);
s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
s6x0_properties.rc.legacy.rc_map_size =
ARRAY_SIZE(rc_map_tbs_table);
break;
case USB_PID_TEVII_S650:
dw2104_properties.rc.legacy.rc_key_map = ir_codes_tevii_table;
dw2104_properties.rc.legacy.rc_key_map_size =
ARRAY_SIZE(ir_codes_tevii_table);
dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
dw2104_properties.rc.legacy.rc_map_size =
ARRAY_SIZE(rc_map_tevii_table);
case USB_PID_DW2104:
reset = 1;
dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
@ -1257,8 +1257,8 @@ static struct dvb_usb_device_properties dw2102_properties = {
.i2c_algo = &dw2102_serit_i2c_algo,
.rc.legacy = {
.rc_key_map = ir_codes_dw210x_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
.rc_map_table = rc_map_dw210x_table,
.rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@ -1310,8 +1310,8 @@ static struct dvb_usb_device_properties dw2104_properties = {
.i2c_algo = &dw2104_i2c_algo,
.rc.legacy = {
.rc_key_map = ir_codes_dw210x_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
.rc_map_table = rc_map_dw210x_table,
.rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@ -1359,8 +1359,8 @@ static struct dvb_usb_device_properties dw3101_properties = {
.i2c_algo = &dw3101_i2c_algo,
.rc.legacy = {
.rc_key_map = ir_codes_dw210x_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
.rc_map_table = rc_map_dw210x_table,
.rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@ -1404,8 +1404,8 @@ static struct dvb_usb_device_properties s6x0_properties = {
.i2c_algo = &s6x0_i2c_algo,
.rc.legacy = {
.rc_key_map = ir_codes_tevii_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table),
.rc_map_table = rc_map_tevii_table,
.rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@ -1468,8 +1468,8 @@ static int dw2102_probe(struct usb_interface *intf,
/* fill only different fields */
p7500->firmware = "dvb-usb-p7500.fw";
p7500->devices[0] = d7500;
p7500->rc.legacy.rc_key_map = ir_codes_tbs_table;
p7500->rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table);
p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
p7500->adapter->frontend_attach = prof_7500_frontend_attach;
if (0 == dvb_usb_device_init(intf, &dw2102_properties,

View File

@ -24,6 +24,33 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
{
return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
}
static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
{
return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
}
static void gp8psk_info(struct dvb_usb_device *d)
{
u8 fpga_vers, fw_vers[6];
if (!gp8psk_get_fw_version(d, fw_vers))
info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i",
fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
else
info("failed to get FW version");
if (!gp8psk_get_fpga_version(d, &fpga_vers))
info("FPGA Version = %i", fpga_vers);
else
info("failed to get FPGA version");
}
int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
{
int ret = 0,try = 0;
@ -146,6 +173,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
return -EINVAL;
gp8psk_info(d);
}
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)

View File

@ -25,7 +25,6 @@ extern int dvb_usb_gp8psk_debug;
#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
/* gp8psk commands */
/* Twinhan Vendor requests */
#define TH_COMMAND_IN 0xC0
@ -49,8 +48,10 @@ extern int dvb_usb_gp8psk_debug;
#define SET_DVB_MODE 0x8E
#define SET_DN_SWITCH 0x8F
#define GET_SIGNAL_LOCK 0x90 /* in */
#define GET_FW_VERS 0x92
#define GET_SERIAL_NUMBER 0x93 /* in */
#define USE_EXTRA_VOLT 0x94
#define GET_FPGA_VERS 0x95
#define CW3K_INIT 0x9d
/* PSK_configuration bits */
@ -88,6 +89,11 @@ extern int dvb_usb_gp8psk_debug;
#define PRODUCT_STRING_READ 0x0D
#define FW_BCD_VERSION_READ 0x14
/* firmware revision id's */
#define GP8PSK_FW_REV1 0x020604
#define GP8PSK_FW_REV2 0x020704
#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,

View File

@ -61,7 +61,7 @@
#define DVB_USB_LOG_PREFIX "LME2510(C)"
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/ir-core.h>
#include <media/rc-core.h>
#include "dvb-usb.h"
#include "lmedm04.h"
@ -112,7 +112,6 @@ struct lme2510_state {
u8 i2c_tuner_gate_r;
u8 i2c_tuner_addr;
u8 stream_on;
u8 one_tune;
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
@ -125,7 +124,7 @@ static int lme2510_bulk_write(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
snd, len , &actual_l, 500);
snd, len , &actual_l, 100);
return ret;
}
@ -135,7 +134,7 @@ static int lme2510_bulk_read(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
rev, len , &actual_l, 500);
rev, len , &actual_l, 200);
return ret;
}
@ -167,7 +166,7 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
msleep(12);
msleep(10);
ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
@ -182,15 +181,13 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
return (ret < 0) ? -ENODEV : 0;
}
static int lme2510_usb_talk_restart(struct dvb_usb_device *d,
u8 *wbuf, int wlen, u8 *rbuf, int rlen) {
static int lme2510_stream_restart(struct dvb_usb_device *d)
{
static u8 stream_on[] = LME_ST_ON_W;
int ret;
u8 rbuff[10];
/*Send Normal Command*/
ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
/*Restart Stream Command*/
ret |= lme2510_usb_talk(d, stream_on, sizeof(stream_on),
ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
rbuff, sizeof(rbuff));
return ret;
}
@ -201,7 +198,7 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
deb_info(1, "INT Key Keypress =%04x", keypress);
if (keypress > 0)
ir_keydown(d->rc_input_dev, keypress, 0);
rc_keydown(d->rc_dev, keypress, 0);
return 0;
}
@ -254,11 +251,16 @@ static void lme2510_int_response(struct urb *lme_urb)
case TUNER_S7395:
/* Tweak for earlier firmware*/
if (ibuf[1] == 0x03) {
if (ibuf[2] > 1)
st->signal_lock = ibuf[2];
st->signal_level = ibuf[3];
st->signal_sn = ibuf[4];
} else {
st->signal_level = ibuf[4];
st->signal_sn = ibuf[5];
st->signal_lock =
(st->signal_lock & 0xf7) +
((ibuf[2] & 0x01) << 0x03);
}
break;
default:
@ -341,11 +343,10 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x10)) {
lme2510_usb_talk_restart(d,
wbuf, wlen, rbuf, rlen);
lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
msleep(80);
msleep(80);
}
}
break;
@ -355,15 +356,12 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x8)) {
lme2510_usb_talk_restart(d,
wbuf, wlen, rbuf, rlen);
lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
}
if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
msleep(5);
}
break;
default:
@ -385,18 +383,16 @@ static int lme2510_msg(struct dvb_usb_device *d,
rbuf[0] = 0x55;
rbuf[1] = st->signal_sn;
break;
/*DiSEqC functions as per TDA10086*/
case 0x36:
case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
case 0x4c:
case 0x4d:
if (wbuf[2] == 0x1c)
lme2510_usb_talk_restart(d,
wbuf, wlen, rbuf, rlen);
case 0x15:
case 0x16:
case 0x17:
case 0x18:
rbuf[0] = 0x55;
rbuf[1] = 0x00;
break;
default:
lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
st->i2c_talk_onoff = 1;
break;
}
break;
@ -413,39 +409,22 @@ static int lme2510_msg(struct dvb_usb_device *d,
break;
case 0x24:
rbuf[0] = 0x55;
rbuf[1] = (st->signal_level & 0x80)
? 0 : st->signal_lock;
rbuf[1] = st->signal_lock;
break;
case 0x6:
if (wbuf[2] == 0xd0)
lme2510_usb_talk(d,
wbuf, wlen, rbuf, rlen);
break;
case 0x1:
if (st->one_tune > 0)
break;
st->one_tune++;
st->i2c_talk_onoff = 1;
/*DiSEqC functions as per STV0288*/
case 0x5:
case 0x7:
case 0x8:
case 0x9:
case 0xa:
case 0xb:
if (wbuf[2] == 0xd0)
lme2510_usb_talk_restart(d,
wbuf, wlen, rbuf, rlen);
break;
default:
case 0x2e:
case 0x26:
case 0x27:
rbuf[0] = 0x55;
rbuf[1] = 0x00;
break;
default:
lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
st->i2c_talk_onoff = 1;
break;
}
break;
default:
break;
}
deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
@ -548,35 +527,26 @@ static int lme2510_identify_state(struct usb_device *udev,
static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct lme2510_state *st = adap->dev->priv;
static u8 stream_on[] = LME_ST_ON_W;
static u8 clear_reg_3[] = LME_CLEAR_PID;
static u8 rbuf[1];
static u8 timeout;
int ret = 0, len = 2, rlen = sizeof(rbuf);
int ret = 0, rlen = sizeof(rbuf);
deb_info(1, "STM (%02x)", onoff);
if (onoff == 1) {
st->i2c_talk_onoff = 0;
timeout = 0;
/* wait for i2C to be free */
while (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) {
timeout++;
if (timeout > 5)
return -ENODEV;
}
msleep(100);
ret |= lme2510_usb_talk(adap->dev,
stream_on, len, rbuf, rlen);
/* Streaming is started by FE_HAS_LOCK */
if (onoff == 1)
st->stream_on = 1;
st->one_tune = 0;
mutex_unlock(&adap->dev->i2c_mutex);
} else {
else {
deb_info(1, "STM Steam Off");
/* mutex is here only to avoid collision with I2C */
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
mutex_unlock(&adap->dev->i2c_mutex);
}
return (ret < 0) ? -ENODEV : 0;
@ -585,41 +555,40 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int lme2510_int_service(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap->dev;
struct input_dev *input_dev;
char *ir_codes = RC_MAP_LME2510;
int ret = 0;
struct rc_dev *rc;
int ret;
info("STA Configuring Remote");
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
input_dev = input_allocate_device();
if (!input_dev)
rc = rc_allocate_device();
if (!rc)
return -ENOMEM;
input_dev->name = "LME2510 Remote Control";
input_dev->phys = d->rc_phys;
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
usb_to_input_id(d->udev, &input_dev->id);
ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
rc->input_name = "LME2510 Remote Control";
rc->input_phys = d->rc_phys;
rc->map_name = RC_MAP_LME2510;
rc->driver_name = "LME 2510";
usb_to_input_id(d->udev, &rc->input_id);
ret = rc_register_device(rc);
if (ret) {
input_free_device(input_dev);
rc_free_device(rc);
return ret;
}
d->rc_dev = rc;
d->rc_input_dev = input_dev;
/* Start the Interupt */
ret = lme2510_int_read(adap);
if (ret < 0) {
ir_input_unregister(input_dev);
input_free_device(input_dev);
rc_unregister_device(rc);
info("INT Unable to start Interupt Service");
return -ENODEV;
}
return (ret < 0) ? -ENODEV : 0;
return 0;
}
static u8 check_sum(u8 *p, u8 len)
@ -668,6 +637,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
ret |= (data[0] == 0x88) ? 0 : -1;
}
}
usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
@ -701,10 +671,11 @@ static void lme_coldreset(struct usb_device *dev)
info("FRM Firmware Cold Reset");
ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
ret |= lme2510_bulk_read(dev, data, len_in, 1);
return;
}
static void lme_firmware_switch(struct usb_device *udev, int cold)
static int lme_firmware_switch(struct usb_device *udev, int cold)
{
const struct firmware *fw = NULL;
char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
@ -712,8 +683,10 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
char *firm_msg[] = {"Loading", "Switching to"};
int ret;
cold = (cold > 0) ? (cold & 1) : 0;
if (udev->descriptor.idProduct == 0x1122)
return;
return 0;
switch (dvb_usb_lme2510_firmware) {
case 0:
@ -740,22 +713,28 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
cold = 0;
break;
}
release_firmware(fw);
if (cold)
if (cold) {
lme_coldreset(udev);
return;
return -ENODEV;
}
return ret;
}
static int lme2510_kill_urb(struct usb_data_stream *stream)
{
int i;
for (i = 0; i < stream->urbs_submitted; i++) {
deb_info(3, "killing URB no. %d.", i);
/* stop the URB */
usb_kill_urb(stream->urb_list[i]);
}
stream->urbs_submitted = 0;
return 0;
}
@ -783,18 +762,13 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct lme2510_state *st = adap->dev->priv;
static u8 voltage_low[] = LME_VOLTAGE_L;
static u8 voltage_high[] = LME_VOLTAGE_H;
static u8 lnb_on[] = LNB_ON;
static u8 lnb_off[] = LNB_OFF;
static u8 rbuf[1];
int ret = 0, len = 3, rlen = 1;
if (st->stream_on == 1)
return 0;
ret |= lme2510_usb_talk(adap->dev, lnb_on, len, rbuf, rlen);
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
switch (voltage) {
case SEC_VOLTAGE_18:
@ -803,94 +777,143 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
break;
case SEC_VOLTAGE_OFF:
ret |= lme2510_usb_talk(adap->dev,
lnb_off, len, rbuf, rlen);
case SEC_VOLTAGE_13:
default:
ret |= lme2510_usb_talk(adap->dev,
voltage_low, len, rbuf, rlen);
break;
}
mutex_unlock(&adap->dev->i2c_mutex);
};
st->i2c_talk_onoff = 1;
return (ret < 0) ? -ENODEV : 0;
}
static int lme_name(struct dvb_usb_adapter *adap)
{
struct lme2510_state *st = adap->dev->priv;
const char *desc = adap->dev->desc->name;
char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"};
char *name = adap->fe->ops.info.name;
strlcpy(name, desc, 128);
strlcat(name, fe_name[st->tuner_config], 128);
return 0;
}
static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
{
int ret = 0;
struct lme2510_state *st = adap->dev->priv;
/* Interupt Start */
ret = lme2510_int_service(adap);
if (ret < 0) {
info("INT Unable to start Interupt Service");
return -ENODEV;
}
int ret = 0;
st->i2c_talk_onoff = 1;
st->i2c_gate = 4;
st->i2c_gate = 4;
adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
&adap->dev->i2c_adap);
if (adap->fe) {
info("TUN Found Frontend TDA10086");
memcpy(&adap->fe->ops.info.name,
&"DM04_LG_TDQY-P001F DVB-S", 24);
adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 4;
st->i2c_tuner_addr = 0xc0;
if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
&adap->dev->i2c_adap, 1)) {
info("TUN TDA8263 Found");
st->tuner_config = TUNER_LG;
if (dvb_usb_lme2510_firmware != 1) {
dvb_usb_lme2510_firmware = 1;
lme_firmware_switch(adap->dev->udev, 1);
}
return 0;
}
kfree(adap->fe);
adap->fe = NULL;
st->tuner_config = TUNER_LG;
if (dvb_usb_lme2510_firmware != 1) {
dvb_usb_lme2510_firmware = 1;
ret = lme_firmware_switch(adap->dev->udev, 1);
} else /*stops LG/Sharp multi tuner problems*/
dvb_usb_lme2510_firmware = 0;
goto end;
}
st->i2c_gate = 5;
adap->fe = dvb_attach(stv0288_attach, &lme_config,
&adap->dev->i2c_adap);
if (adap->fe) {
info("FE Found Stv0288");
memcpy(&adap->fe->ops.info.name,
&"DM04_SHARP:BS2F7HZ7395", 22);
adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
&adap->dev->i2c_adap)) {
st->tuner_config = TUNER_S7395;
info("TUN Sharp IX2505V silicon tuner");
if (dvb_usb_lme2510_firmware != 0) {
dvb_usb_lme2510_firmware = 0;
lme_firmware_switch(adap->dev->udev, 1);
}
return 0;
st->tuner_config = TUNER_S7395;
if (dvb_usb_lme2510_firmware != 0) {
dvb_usb_lme2510_firmware = 0;
ret = lme_firmware_switch(adap->dev->udev, 1);
}
kfree(adap->fe);
adap->fe = NULL;
} else {
info("DM04 Not Supported");
return -ENODEV;
}
info("DM04 Not Supported");
return -ENODEV;
end: if (ret) {
kfree(adap->fe);
adap->fe = NULL;
return -ENODEV;
}
adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
ret = lme_name(adap);
return ret;
}
static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
{
struct lme2510_state *st = adap->dev->priv;
char *tun_msg[] = {"", "TDA8263", "IX2505V"};
int ret = 0;
switch (st->tuner_config) {
case TUNER_LG:
if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
&adap->dev->i2c_adap, 1))
ret = st->tuner_config;
break;
case TUNER_S7395:
if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
&adap->dev->i2c_adap))
ret = st->tuner_config;
break;
default:
break;
}
if (ret)
info("TUN Found %s tuner", tun_msg[ret]);
else {
info("TUN No tuner found --- reseting device");
lme_coldreset(adap->dev->udev);
return -ENODEV;
}
/* Start the Interupt & Remote*/
ret = lme2510_int_service(adap);
return ret;
}
static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
{
struct lme2510_state *st = d->priv;
static u8 lnb_on[] = LNB_ON;
static u8 lnb_off[] = LNB_OFF;
static u8 rbuf[1];
int ret, len = 3, rlen = 1;
ret = mutex_lock_interruptible(&d->i2c_mutex);
if (onoff)
ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
else
ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
st->i2c_talk_onoff = 1;
return 0;
mutex_unlock(&d->i2c_mutex);
return ret;
}
/* DVB USB Driver stuff */
@ -951,6 +974,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
{
.streaming_ctrl = lme2510_streaming_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
.tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
@ -971,7 +995,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
.generic_bulk_ctrl_endpoint = 0,
.num_device_descs = 1,
.devices = {
{ "DM04 LME2510 DVB-S USB 2.0",
{ "DM04_LME2510_DVB-S",
{ &lme2510_table[0], NULL },
},
@ -989,6 +1013,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
{
.streaming_ctrl = lme2510_streaming_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
.tuner_attach = dm04_lme2510_tuner,
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
@ -1009,7 +1034,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
.generic_bulk_ctrl_endpoint = 0,
.num_device_descs = 1,
.devices = {
{ "DM04 LME2510C USB2.0",
{ "DM04_LME2510C_DVB-S",
{ &lme2510_table[1], NULL },
},
}
@ -1036,7 +1061,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
usb_free_coherent(d->udev, 5000, st->buffer,
st->lme_urb->transfer_dma);
info("Interupt Service Stopped");
ir_input_unregister(d->rc_input_dev);
rc_unregister_device(d->rc_dev);
info("Remote Stopped");
}
return buffer;
@ -1055,7 +1080,7 @@ void lme2510_exit(struct usb_interface *intf)
}
static struct usb_driver lme2510_driver = {
.name = "LME2510C_DVBS",
.name = "LME2510C_DVB-S",
.probe = lme2510_probe,
.disconnect = lme2510_exit,
.id_table = lme2510_table,
@ -1083,6 +1108,6 @@ module_init(lme2510_module_init);
module_exit(lme2510_module_exit);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
MODULE_VERSION("1.60");
MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
MODULE_VERSION("1.74");
MODULE_LICENSE("GPL");

View File

@ -142,9 +142,9 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
goto unlock;
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
if (rc5_data(&d->props.rc.legacy.rc_key_map[i]) == rc_state[1]) {
*event = d->props.rc.legacy.rc_key_map[i].keycode;
for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
*event = d->props.rc.legacy.rc_map_table[i].keycode;
switch(rc_state[0]) {
case 0x80:
@ -589,7 +589,7 @@ static struct m920x_inits pinnacle310e_init[] = {
};
/* ir keymaps */
static struct ir_scancode ir_codes_megasky_table[] = {
static struct rc_map_table rc_map_megasky_table[] = {
{ 0x0012, KEY_POWER },
{ 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
{ 0x0002, KEY_CHANNELUP },
@ -608,7 +608,7 @@ static struct ir_scancode ir_codes_megasky_table[] = {
{ 0x000e, KEY_COFFEE }, /* "MTS" */
};
static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
static struct rc_map_table rc_map_tvwalkertwin_table[] = {
{ 0x0001, KEY_ZOOM }, /* Full Screen */
{ 0x0002, KEY_CAMERA }, /* snapshot */
{ 0x0003, KEY_MUTE },
@ -628,7 +628,7 @@ static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
{ 0x001e, KEY_VOLUMEUP },
};
static struct ir_scancode ir_codes_pinnacle310e_table[] = {
static struct rc_map_table rc_map_pinnacle310e_table[] = {
{ 0x16, KEY_POWER },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
@ -786,8 +786,8 @@ static struct dvb_usb_device_properties megasky_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_megasky_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table),
.rc_map_table = rc_map_megasky_table,
.rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
.rc_query = m920x_rc_query,
},
@ -889,8 +889,8 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_tvwalkertwin_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table),
.rc_map_table = rc_map_tvwalkertwin_table,
.rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
.rc_query = m920x_rc_query,
},
@ -998,8 +998,8 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_pinnacle310e_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table),
.rc_map_table = rc_map_pinnacle310e_table,
.rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
.rc_query = m920x_rc_query,
},

View File

@ -21,7 +21,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define deb_ee(args...) dprintk(debug,0x02,args)
/* Hauppauge NOVA-T USB2 keys */
static struct ir_scancode ir_codes_haupp_table[] = {
static struct rc_map_table rc_map_haupp_table[] = {
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
{ 0x1e02, KEY_2 },
@ -91,14 +91,14 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
for (i = 0; i < ARRAY_SIZE(ir_codes_haupp_table); i++) {
if (rc5_data(&ir_codes_haupp_table[i]) == data &&
rc5_custom(&ir_codes_haupp_table[i]) == custom) {
for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
if (rc5_data(&rc_map_haupp_table[i]) == data &&
rc5_custom(&rc_map_haupp_table[i]) == custom) {
deb_rc("c: %x, d: %x\n", rc5_data(&ir_codes_haupp_table[i]),
rc5_custom(&ir_codes_haupp_table[i]));
deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
rc5_custom(&rc_map_haupp_table[i]));
*event = ir_codes_haupp_table[i].keycode;
*event = rc_map_haupp_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
if (st->old_toggle == toggle) {
if (st->last_repeat_count++ < 2)
@ -197,8 +197,8 @@ static struct dvb_usb_device_properties nova_t_properties = {
.rc.legacy = {
.rc_interval = 100,
.rc_key_map = ir_codes_haupp_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table),
.rc_map_table = rc_map_haupp_table,
.rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
.rc_query = nova_t_rc_query,
},

View File

@ -35,7 +35,7 @@
struct opera1_state {
u32 last_key_pressed;
};
struct ir_codes_opera_table {
struct rc_map_opera_table {
u32 keycode;
u32 event;
};
@ -331,7 +331,7 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
return 0;
}
static struct ir_scancode ir_codes_opera1_table[] = {
static struct rc_map_table rc_map_opera1_table[] = {
{0x5fa0, KEY_1},
{0x51af, KEY_2},
{0x5da2, KEY_3},
@ -404,12 +404,12 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
send_key = (send_key & 0xffff) | 0x0100;
for (i = 0; i < ARRAY_SIZE(ir_codes_opera1_table); i++) {
if (rc5_scan(&ir_codes_opera1_table[i]) == (send_key & 0xffff)) {
for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
*state = REMOTE_KEY_PRESSED;
*event = ir_codes_opera1_table[i].keycode;
*event = rc_map_opera1_table[i].keycode;
opst->last_key_pressed =
ir_codes_opera1_table[i].keycode;
rc_map_opera1_table[i].keycode;
break;
}
opst->last_key_pressed = 0;
@ -497,8 +497,8 @@ static struct dvb_usb_device_properties opera1_properties = {
.i2c_algo = &opera1_i2c_algo,
.rc.legacy = {
.rc_key_map = ir_codes_opera1_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table),
.rc_map_table = rc_map_opera1_table,
.rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
.rc_interval = 200,
.rc_query = opera1_rc_query,
},

View File

@ -43,6 +43,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct ttusb2_state {
u8 id;
u16 last_rc_key;
};
static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
@ -128,6 +129,33 @@ static struct i2c_algorithm ttusb2_i2c_algo = {
.functionality = ttusb2_i2c_func,
};
/* command to poll IR receiver (copied from pctv452e.c) */
#define CMD_GET_IR_CODE 0x1b
/* IR */
static int tt3650_rc_query(struct dvb_usb_device *d)
{
int ret;
u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
struct ttusb2_state *st = d->priv;
ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
if (ret != 0)
return ret;
if (rx[8] & 0x01) {
/* got a "press" event */
st->last_rc_key = (rx[3] << 8) | rx[2];
deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
rc_keydown(d->rc_dev, st->last_rc_key, 0);
} else if (st->last_rc_key) {
rc_keyup(d->rc_dev);
st->last_rc_key = 0;
}
return 0;
}
/* Callbacks for DVB USB */
static int ttusb2_identify_state (struct usb_device *udev, struct
dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
@ -345,6 +373,13 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
.size_of_priv = sizeof(struct ttusb2_state),
.rc.core = {
.rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */
.rc_codes = RC_MAP_TT_1500,
.rc_query = tt3650_rc_query,
.allowed_protos = RC_TYPE_UNKNOWN,
},
.num_adapters = 1,
.adapter = {
{

View File

@ -174,7 +174,7 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
}
/* keys for the enclosed remote control */
static struct ir_scancode ir_codes_vp702x_table[] = {
static struct rc_map_table rc_map_vp702x_table[] = {
{ 0x0001, KEY_1 },
{ 0x0002, KEY_2 },
};
@ -197,10 +197,10 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++)
if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) {
for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
*state = REMOTE_KEY_PRESSED;
*event = ir_codes_vp702x_table[i].keycode;
*event = rc_map_vp702x_table[i].keycode;
break;
}
return 0;
@ -284,8 +284,8 @@ static struct dvb_usb_device_properties vp702x_properties = {
.read_mac_address = vp702x_read_mac_addr,
.rc.legacy = {
.rc_key_map = ir_codes_vp702x_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table),
.rc_map_table = rc_map_vp702x_table,
.rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
.rc_interval = 400,
.rc_query = vp702x_rc_query,
},

View File

@ -99,7 +99,7 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded. */
static struct ir_scancode ir_codes_vp7045_table[] = {
static struct rc_map_table rc_map_vp7045_table[] = {
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
{ 0x0003, KEY_1 },
@ -165,10 +165,10 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
for (i = 0; i < ARRAY_SIZE(ir_codes_vp7045_table); i++)
if (rc5_data(&ir_codes_vp7045_table[i]) == key) {
for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
if (rc5_data(&rc_map_vp7045_table[i]) == key) {
*state = REMOTE_KEY_PRESSED;
*event = ir_codes_vp7045_table[i].keycode;
*event = rc_map_vp7045_table[i].keycode;
break;
}
return 0;
@ -261,8 +261,8 @@ static struct dvb_usb_device_properties vp7045_properties = {
.rc.legacy = {
.rc_interval = 400,
.rc_key_map = ir_codes_vp7045_table,
.rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table),
.rc_map_table = rc_map_vp7045_table,
.rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
.rc_query = vp7045_rc_query,
},

View File

@ -497,7 +497,7 @@ comment "ISDB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_S921
tristate "Sharp S921 tuner"
tristate "Sharp S921 frontend"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@ -512,6 +512,14 @@ config DVB_DIB8000
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
config DVB_MB86A20S
tristate "Fujitsu mb86a20s"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE

View File

@ -5,7 +5,6 @@
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
EXTRA_CFLAGS += -Idrivers/media/common/tuners/
s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
stv0900-objs = stv0900_core.o stv0900_sw.o
au8522-objs = au8522_dig.o au8522_decoder.o
@ -82,4 +81,5 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o
obj-$(CONFIG_DVB_EC100) += ec100.o
obj-$(CONFIG_DVB_DS3000) += ds3000.o
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o

View File

@ -964,7 +964,7 @@ static int af9013_update_snr(struct dvb_frontend *fe)
static int af9013_update_signal_strength(struct dvb_frontend *fe)
{
struct af9013_state *state = fe->demodulator_priv;
int ret;
int ret = 0;
u8 rf_gain, if_gain;
int signal_strength;

View File

@ -50,8 +50,7 @@ static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
msg2.addr = dev_addr;
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
__func__, reg, data);
dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1)
@ -77,8 +76,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1) {
dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
__func__, reg, ret);
dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
@ -88,7 +86,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
*p_data = buf2[0];
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
dprintk("%s: reg=0x%04X, data=0x%02X\n",
__func__, reg, buf2[0]);
return 0;

View File

@ -278,10 +278,18 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
} else {
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
}
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
@ -347,9 +355,11 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
/* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
@ -366,14 +376,14 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
/* It's not clear why they turn off the PGA before enabling the clamp
control, but the Windows trace does it so we will too... */
/* It's not clear why we have to have the PGA in automatic mode while
enabling clamp control, but it's what Windows does */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
/* Turn on the PGA */
/* Disable automatic PGA (since the CVBS is coming from the tuner) */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
@ -396,7 +406,10 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
/* Disable clamping control (required for S-video) */
/* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
setup_decoder_defaults(state,
@ -410,29 +423,15 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
static void disable_audio_input(struct au8522_state *state)
{
/* This can probably be optimized */
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
msleep(5);
au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
}
/* 0=disable, 1=SIF */
@ -622,7 +621,7 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return v4l2_ctrl_query_fill(qc, 0, 255, 1,
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_HUE:

View File

@ -397,7 +397,9 @@ void au8522_release_state(struct au8522_state *state);
#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO 0x2a
#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO 0x15
#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80

View File

@ -805,7 +805,7 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte
value = 0;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
case /* 4K MODE */ 255: value |= (2 << 7); break;
case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
default:
case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
}
@ -866,7 +866,7 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_fronte
/* P_dvsy_sync_wait */
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_8K: value = 256; break;
case /* 4K MODE */ 255: value = 128; break;
case TRANSMISSION_MODE_4K: value = 128; break;
case TRANSMISSION_MODE_2K:
default: value = 64; break;
}
@ -1020,7 +1020,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (6 << 8) | 0x80;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
case /* 4K MODE */ 255: value |= (8 << 12); break;
case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
default:
case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
}
@ -1030,7 +1030,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= 0x6; break;
case /* 4K MODE */ 255: value |= 0x7; break;
case TRANSMISSION_MODE_4K: value |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: value |= 0x8; break;
}
@ -1040,7 +1040,7 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
value = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= 0x6; break;
case /* 4K MODE */ 255: value |= 0x7; break;
case TRANSMISSION_MODE_4K: value |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: value |= 0x8; break;
}

View File

@ -717,7 +717,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
value = 0;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
case /* 4K MODE */ 255: value |= (2 << 7); break;
case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
default:
case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
}
@ -770,7 +770,7 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
/* P_dvsy_sync_wait */
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_8K: value = 256; break;
case /* 4K MODE */ 255: value = 128; break;
case TRANSMISSION_MODE_4K: value = 128; break;
case TRANSMISSION_MODE_2K:
default: value = 64; break;
}
@ -994,7 +994,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (6 << 8) | 0x80;
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
case /* 4K MODE */ 255: tmp |= (8 << 12); break;
case TRANSMISSION_MODE_4K: tmp |= (8 << 12); break;
default:
case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
}
@ -1004,7 +1004,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
case /* 4K MODE */ 255: tmp |= 0x7; break;
case TRANSMISSION_MODE_4K: tmp |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
}
@ -1014,7 +1014,7 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
tmp = (0 << 4);
switch (ch->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
case /* 4K MODE */ 255: tmp |= 0x7; break;
case TRANSMISSION_MODE_4K: tmp |= 0x7; break;
default:
case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
}

View File

@ -72,7 +72,7 @@ static int ix2505v_read_status_reg(struct ix2505v_state *state)
ret = i2c_transfer(state->i2c, msg, 1);
deb_i2c("Read %s ", __func__);
return (ret = 1) ? (int) b2[0] : -1;
return (ret == 1) ? (int) b2[0] : -1;
}
static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)

View File

@ -60,13 +60,12 @@ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
msg.addr += 0x02;
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, data);
dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
@ -91,15 +90,13 @@ static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
__func__, reg, ret);
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -1;
}
*p_data = b1[0];
if (debug >= 2)
printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, b1[0]);
dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
return 0;
}

View File

@ -0,0 +1,615 @@
/*
* Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
*
* Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
*
* FIXME: Need to port to DVB v5.2 API
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/kernel.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
#include "mb86a20s.h"
static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
#define rc(args...) do { \
printk(KERN_ERR "mb86a20s: " args); \
} while (0)
#define dprintk(args...) \
do { \
if (debug) { \
printk(KERN_DEBUG "mb86a20s: %s: ", __func__); \
printk(args); \
} \
} while (0)
struct mb86a20s_state {
struct i2c_adapter *i2c;
const struct mb86a20s_config *config;
struct dvb_frontend frontend;
};
struct regdata {
u8 reg;
u8 data;
};
/*
* Initialization sequence: Use whatevere default values that PV SBTVD
* does on its initialisation, obtained via USB snoop
*/
static struct regdata mb86a20s_init[] = {
{ 0x70, 0x0f },
{ 0x70, 0xff },
{ 0x08, 0x01 },
{ 0x09, 0x3e },
{ 0x50, 0xd1 },
{ 0x51, 0x22 },
{ 0x39, 0x01 },
{ 0x71, 0x00 },
{ 0x28, 0x2a },
{ 0x29, 0x00 },
{ 0x2a, 0xff },
{ 0x2b, 0x80 },
{ 0x28, 0x20 },
{ 0x29, 0x33 },
{ 0x2a, 0xdf },
{ 0x2b, 0xa9 },
{ 0x3b, 0x21 },
{ 0x3c, 0x3a },
{ 0x01, 0x0d },
{ 0x04, 0x08 },
{ 0x05, 0x05 },
{ 0x04, 0x0e },
{ 0x05, 0x00 },
{ 0x04, 0x0f },
{ 0x05, 0x14 },
{ 0x04, 0x0b },
{ 0x05, 0x8c },
{ 0x04, 0x00 },
{ 0x05, 0x00 },
{ 0x04, 0x01 },
{ 0x05, 0x07 },
{ 0x04, 0x02 },
{ 0x05, 0x0f },
{ 0x04, 0x03 },
{ 0x05, 0xa0 },
{ 0x04, 0x09 },
{ 0x05, 0x00 },
{ 0x04, 0x0a },
{ 0x05, 0xff },
{ 0x04, 0x27 },
{ 0x05, 0x64 },
{ 0x04, 0x28 },
{ 0x05, 0x00 },
{ 0x04, 0x1e },
{ 0x05, 0xff },
{ 0x04, 0x29 },
{ 0x05, 0x0a },
{ 0x04, 0x32 },
{ 0x05, 0x0a },
{ 0x04, 0x14 },
{ 0x05, 0x02 },
{ 0x04, 0x04 },
{ 0x05, 0x00 },
{ 0x04, 0x05 },
{ 0x05, 0x22 },
{ 0x04, 0x06 },
{ 0x05, 0x0e },
{ 0x04, 0x07 },
{ 0x05, 0xd8 },
{ 0x04, 0x12 },
{ 0x05, 0x00 },
{ 0x04, 0x13 },
{ 0x05, 0xff },
{ 0x52, 0x01 },
{ 0x50, 0xa7 },
{ 0x51, 0x00 },
{ 0x50, 0xa8 },
{ 0x51, 0xff },
{ 0x50, 0xa9 },
{ 0x51, 0xff },
{ 0x50, 0xaa },
{ 0x51, 0x00 },
{ 0x50, 0xab },
{ 0x51, 0xff },
{ 0x50, 0xac },
{ 0x51, 0xff },
{ 0x50, 0xad },
{ 0x51, 0x00 },
{ 0x50, 0xae },
{ 0x51, 0xff },
{ 0x50, 0xaf },
{ 0x51, 0xff },
{ 0x5e, 0x07 },
{ 0x50, 0xdc },
{ 0x51, 0x01 },
{ 0x50, 0xdd },
{ 0x51, 0xf4 },
{ 0x50, 0xde },
{ 0x51, 0x01 },
{ 0x50, 0xdf },
{ 0x51, 0xf4 },
{ 0x50, 0xe0 },
{ 0x51, 0x01 },
{ 0x50, 0xe1 },
{ 0x51, 0xf4 },
{ 0x50, 0xb0 },
{ 0x51, 0x07 },
{ 0x50, 0xb2 },
{ 0x51, 0xff },
{ 0x50, 0xb3 },
{ 0x51, 0xff },
{ 0x50, 0xb4 },
{ 0x51, 0xff },
{ 0x50, 0xb5 },
{ 0x51, 0xff },
{ 0x50, 0xb6 },
{ 0x51, 0xff },
{ 0x50, 0xb7 },
{ 0x51, 0xff },
{ 0x50, 0x50 },
{ 0x51, 0x02 },
{ 0x50, 0x51 },
{ 0x51, 0x04 },
{ 0x45, 0x04 },
{ 0x48, 0x04 },
{ 0x50, 0xd5 },
{ 0x51, 0x01 }, /* Serial */
{ 0x50, 0xd6 },
{ 0x51, 0x1f },
{ 0x50, 0xd2 },
{ 0x51, 0x03 },
{ 0x50, 0xd7 },
{ 0x51, 0x3f },
{ 0x1c, 0x01 },
{ 0x28, 0x06 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x03 },
{ 0x28, 0x07 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x0d },
{ 0x28, 0x08 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x02 },
{ 0x28, 0x09 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x01 },
{ 0x28, 0x0a },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x21 },
{ 0x28, 0x0b },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x29 },
{ 0x28, 0x0c },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x16 },
{ 0x28, 0x0d },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x31 },
{ 0x28, 0x0e },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x0e },
{ 0x28, 0x0f },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x4e },
{ 0x28, 0x10 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x46 },
{ 0x28, 0x11 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x0f },
{ 0x28, 0x12 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x56 },
{ 0x28, 0x13 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x35 },
{ 0x28, 0x14 },
{ 0x29, 0x00 },
{ 0x2a, 0x01 },
{ 0x2b, 0xbe },
{ 0x28, 0x15 },
{ 0x29, 0x00 },
{ 0x2a, 0x01 },
{ 0x2b, 0x84 },
{ 0x28, 0x16 },
{ 0x29, 0x00 },
{ 0x2a, 0x03 },
{ 0x2b, 0xee },
{ 0x28, 0x17 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x98 },
{ 0x28, 0x18 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x9f },
{ 0x28, 0x19 },
{ 0x29, 0x00 },
{ 0x2a, 0x07 },
{ 0x2b, 0xb2 },
{ 0x28, 0x1a },
{ 0x29, 0x00 },
{ 0x2a, 0x06 },
{ 0x2b, 0xc2 },
{ 0x28, 0x1b },
{ 0x29, 0x00 },
{ 0x2a, 0x07 },
{ 0x2b, 0x4a },
{ 0x28, 0x1c },
{ 0x29, 0x00 },
{ 0x2a, 0x01 },
{ 0x2b, 0xbc },
{ 0x28, 0x1d },
{ 0x29, 0x00 },
{ 0x2a, 0x04 },
{ 0x2b, 0xba },
{ 0x28, 0x1e },
{ 0x29, 0x00 },
{ 0x2a, 0x06 },
{ 0x2b, 0x14 },
{ 0x50, 0x1e },
{ 0x51, 0x5d },
{ 0x50, 0x22 },
{ 0x51, 0x00 },
{ 0x50, 0x23 },
{ 0x51, 0xc8 },
{ 0x50, 0x24 },
{ 0x51, 0x00 },
{ 0x50, 0x25 },
{ 0x51, 0xf0 },
{ 0x50, 0x26 },
{ 0x51, 0x00 },
{ 0x50, 0x27 },
{ 0x51, 0xc3 },
{ 0x50, 0x39 },
{ 0x51, 0x02 },
{ 0x50, 0xd5 },
{ 0x51, 0x01 },
{ 0xd0, 0x00 },
};
static struct regdata mb86a20s_reset_reception[] = {
{ 0x70, 0xf0 },
{ 0x70, 0xff },
{ 0x08, 0x01 },
{ 0x08, 0x00 },
};
static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
u8 i2c_addr, int reg, int data)
{
u8 buf[] = { reg, data };
struct i2c_msg msg = {
.addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
};
int rc;
rc = i2c_transfer(state->i2c, &msg, 1);
if (rc != 1) {
printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __func__, rc, reg, data);
return rc;
}
return 0;
}
static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
u8 i2c_addr, struct regdata *rd, int size)
{
int i, rc;
for (i = 0; i < size; i++) {
rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
rd[i].data);
if (rc < 0)
return rc;
}
return 0;
}
static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
u8 i2c_addr, u8 reg)
{
u8 val;
int rc;
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
{ .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
};
rc = i2c_transfer(state->i2c, msg, 2);
if (rc != 2) {
rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
return rc;
}
return val;
}
#define mb86a20s_readreg(state, reg) \
mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
#define mb86a20s_writereg(state, reg, val) \
mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
#define mb86a20s_writeregdata(state, regdata) \
mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
regdata, ARRAY_SIZE(regdata))
static int mb86a20s_initfe(struct dvb_frontend *fe)
{
struct mb86a20s_state *state = fe->demodulator_priv;
int rc;
u8 regD5 = 1;
dprintk("\n");
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
/* Initialize the frontend */
rc = mb86a20s_writeregdata(state, mb86a20s_init);
if (rc < 0)
return rc;
if (!state->config->is_serial) {
regD5 &= ~1;
rc = mb86a20s_writereg(state, 0x50, 0xd5);
if (rc < 0)
return rc;
rc = mb86a20s_writereg(state, 0x51, regD5);
if (rc < 0)
return rc;
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
return 0;
}
static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
struct mb86a20s_state *state = fe->demodulator_priv;
unsigned rf_max, rf_min, rf;
u8 val;
dprintk("\n");
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
/* Does a binary search to get RF strength */
rf_max = 0xfff;
rf_min = 0;
do {
rf = (rf_max + rf_min) / 2;
mb86a20s_writereg(state, 0x04, 0x1f);
mb86a20s_writereg(state, 0x05, rf >> 8);
mb86a20s_writereg(state, 0x04, 0x20);
mb86a20s_writereg(state, 0x04, rf);
val = mb86a20s_readreg(state, 0x02);
if (val & 0x08)
rf_min = (rf_max + rf_min) / 2;
else
rf_max = (rf_max + rf_min) / 2;
if (rf_max - rf_min < 4) {
*strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
break;
}
} while (1);
dprintk("signal strength = %d\n", *strength);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
return 0;
}
static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct mb86a20s_state *state = fe->demodulator_priv;
u8 val;
dprintk("\n");
*status = 0;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
val = mb86a20s_readreg(state, 0x0a) & 0xf;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (val >= 2)
*status |= FE_HAS_SIGNAL;
if (val >= 4)
*status |= FE_HAS_CARRIER;
if (val >= 5)
*status |= FE_HAS_VITERBI;
if (val >= 7)
*status |= FE_HAS_SYNC;
if (val >= 8) /* Maybe 9? */
*status |= FE_HAS_LOCK;
dprintk("val = %d, status = 0x%02x\n", val, *status);
return 0;
}
static int mb86a20s_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct mb86a20s_state *state = fe->demodulator_priv;
int rc;
dprintk("\n");
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.set_params(fe, p);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
return rc;
}
static int mb86a20s_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
/* FIXME: For now, it does nothing */
fe->dtv_property_cache.bandwidth_hz = 6000000;
fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
fe->dtv_property_cache.isdbt_partial_reception = 0;
return 0;
}
static int mb86a20s_tune(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params,
unsigned int mode_flags,
unsigned int *delay,
fe_status_t *status)
{
int rc = 0;
dprintk("\n");
if (params != NULL)
rc = mb86a20s_set_frontend(fe, params);
if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
mb86a20s_read_status(fe, status);
return rc;
}
static void mb86a20s_release(struct dvb_frontend *fe)
{
struct mb86a20s_state *state = fe->demodulator_priv;
dprintk("\n");
kfree(state);
}
static struct dvb_frontend_ops mb86a20s_ops;
struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
struct i2c_adapter *i2c)
{
u8 rev;
/* allocate memory for the internal state */
struct mb86a20s_state *state =
kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
dprintk("\n");
if (state == NULL) {
rc("Unable to kzalloc\n");
goto error;
}
/* setup the state */
state->config = config;
state->i2c = i2c;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &mb86a20s_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
/* Check if it is a mb86a20s frontend */
rev = mb86a20s_readreg(state, 0);
if (rev == 0x13) {
printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
} else {
printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
rev);
goto error;
}
return &state->frontend;
error:
kfree(state);
return NULL;
}
EXPORT_SYMBOL(mb86a20s_attach);
static struct dvb_frontend_ops mb86a20s_ops = {
/* Use dib8000 values per default */
.info = {
.name = "Fujitsu mb86A20s",
.type = FE_OFDM,
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
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_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
/* Actually, those values depend on the used tuner */
.frequency_min = 45000000,
.frequency_max = 864000000,
.frequency_stepsize = 62500,
},
.release = mb86a20s_release,
.init = mb86a20s_initfe,
.set_frontend = mb86a20s_set_frontend,
.get_frontend = mb86a20s_get_frontend,
.read_status = mb86a20s_read_status,
.read_signal_strength = mb86a20s_read_signal_strength,
.tune = mb86a20s_tune,
};
MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,52 @@
/*
* Fujitsu mb86a20s driver
*
* Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* 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.
*/
#ifndef MB86A20S_H
#define MB86A20S_H
#include <linux/dvb/frontend.h>
/**
* struct mb86a20s_config - Define the per-device attributes of the frontend
*
* @demod_address: the demodulator's i2c address
*/
struct mb86a20s_config {
u8 demod_address;
bool is_serial;
};
#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
&& defined(MODULE))
extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
struct i2c_adapter *i2c);
extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
#else
static inline struct dvb_frontend *mb86a20s_attach(
const struct mb86a20s_config *config, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static struct i2c_adapter *
mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* MB86A20S */

View File

@ -0,0 +1,548 @@
/*
* Sharp VA3A5JZ921 One Seg Broadcast Module driver
* This device is labeled as just S. 921 at the top of the frontend can
*
* Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
*
* Developed for Leadership SBTVD 1seg device sold in Brazil
*
* Frontend module based on cx24123 driver, getting some info from
* the old s921 driver.
*
* FIXME: Need to port to DVB v5.2 API
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/kernel.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
#include "s921.h"
static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
#define rc(args...) do { \
printk(KERN_ERR "s921: " args); \
} while (0)
#define dprintk(args...) \
do { \
if (debug) { \
printk(KERN_DEBUG "s921: %s: ", __func__); \
printk(args); \
} \
} while (0)
struct s921_state {
struct i2c_adapter *i2c;
const struct s921_config *config;
struct dvb_frontend frontend;
/* The Demod can't easily provide these, we cache them */
u32 currentfreq;
};
/*
* Various tuner defaults need to be established for a given frequency kHz.
* fixme: The bounds on the bands do not match the doc in real life.
* fixme: Some of them have been moved, other might need adjustment.
*/
static struct s921_bandselect_val {
u32 freq_low;
u8 band_reg;
} s921_bandselect[] = {
{ 0, 0x7b },
{ 485140000, 0x5b },
{ 515140000, 0x3b },
{ 545140000, 0x1b },
{ 599140000, 0xfb },
{ 623140000, 0xdb },
{ 659140000, 0xbb },
{ 713140000, 0x9b },
};
struct regdata {
u8 reg;
u8 data;
};
static struct regdata s921_init[] = {
{ 0x01, 0x80 }, /* Probably, a reset sequence */
{ 0x01, 0x40 },
{ 0x01, 0x80 },
{ 0x01, 0x40 },
{ 0x02, 0x00 },
{ 0x03, 0x40 },
{ 0x04, 0x01 },
{ 0x05, 0x00 },
{ 0x06, 0x00 },
{ 0x07, 0x00 },
{ 0x08, 0x00 },
{ 0x09, 0x00 },
{ 0x0a, 0x00 },
{ 0x0b, 0x5a },
{ 0x0c, 0x00 },
{ 0x0d, 0x00 },
{ 0x0f, 0x00 },
{ 0x13, 0x1b },
{ 0x14, 0x80 },
{ 0x15, 0x40 },
{ 0x17, 0x70 },
{ 0x18, 0x01 },
{ 0x19, 0x12 },
{ 0x1a, 0x01 },
{ 0x1b, 0x12 },
{ 0x1c, 0xa0 },
{ 0x1d, 0x00 },
{ 0x1e, 0x0a },
{ 0x1f, 0x08 },
{ 0x20, 0x40 },
{ 0x21, 0xff },
{ 0x22, 0x4c },
{ 0x23, 0x4e },
{ 0x24, 0x4c },
{ 0x25, 0x00 },
{ 0x26, 0x00 },
{ 0x27, 0xf4 },
{ 0x28, 0x60 },
{ 0x29, 0x88 },
{ 0x2a, 0x40 },
{ 0x2b, 0x40 },
{ 0x2c, 0xff },
{ 0x2d, 0x00 },
{ 0x2e, 0xff },
{ 0x2f, 0x00 },
{ 0x30, 0x20 },
{ 0x31, 0x06 },
{ 0x32, 0x0c },
{ 0x34, 0x0f },
{ 0x37, 0xfe },
{ 0x38, 0x00 },
{ 0x39, 0x63 },
{ 0x3a, 0x10 },
{ 0x3b, 0x10 },
{ 0x47, 0x00 },
{ 0x49, 0xe5 },
{ 0x4b, 0x00 },
{ 0x50, 0xc0 },
{ 0x52, 0x20 },
{ 0x54, 0x5a },
{ 0x55, 0x5b },
{ 0x56, 0x40 },
{ 0x57, 0x70 },
{ 0x5c, 0x50 },
{ 0x5d, 0x00 },
{ 0x62, 0x17 },
{ 0x63, 0x2f },
{ 0x64, 0x6f },
{ 0x68, 0x00 },
{ 0x69, 0x89 },
{ 0x6a, 0x00 },
{ 0x6b, 0x00 },
{ 0x6c, 0x00 },
{ 0x6d, 0x00 },
{ 0x6e, 0x00 },
{ 0x70, 0x10 },
{ 0x71, 0x00 },
{ 0x75, 0x00 },
{ 0x76, 0x30 },
{ 0x77, 0x01 },
{ 0xaf, 0x00 },
{ 0xb0, 0xa0 },
{ 0xb2, 0x3d },
{ 0xb3, 0x25 },
{ 0xb4, 0x8b },
{ 0xb5, 0x4b },
{ 0xb6, 0x3f },
{ 0xb7, 0xff },
{ 0xb8, 0xff },
{ 0xb9, 0xfc },
{ 0xba, 0x00 },
{ 0xbb, 0x00 },
{ 0xbc, 0x00 },
{ 0xd0, 0x30 },
{ 0xe4, 0x84 },
{ 0xf0, 0x48 },
{ 0xf1, 0x19 },
{ 0xf2, 0x5a },
{ 0xf3, 0x8e },
{ 0xf4, 0x2d },
{ 0xf5, 0x07 },
{ 0xf6, 0x5a },
{ 0xf7, 0xba },
{ 0xf8, 0xd7 },
};
static struct regdata s921_prefreq[] = {
{ 0x47, 0x60 },
{ 0x68, 0x00 },
{ 0x69, 0x89 },
{ 0xf0, 0x48 },
{ 0xf1, 0x19 },
};
static struct regdata s921_postfreq[] = {
{ 0xf5, 0xae },
{ 0xf6, 0xb7 },
{ 0xf7, 0xba },
{ 0xf8, 0xd7 },
{ 0x68, 0x0a },
{ 0x69, 0x09 },
};
static int s921_i2c_writereg(struct s921_state *state,
u8 i2c_addr, int reg, int data)
{
u8 buf[] = { reg, data };
struct i2c_msg msg = {
.addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
};
int rc;
rc = i2c_transfer(state->i2c, &msg, 1);
if (rc != 1) {
printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __func__, rc, reg, data);
return rc;
}
return 0;
}
static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
struct regdata *rd, int size)
{
int i, rc;
for (i = 0; i < size; i++) {
rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
if (rc < 0)
return rc;
}
return 0;
}
static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
{
u8 val;
int rc;
struct i2c_msg msg[] = {
{ .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
{ .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
};
rc = i2c_transfer(state->i2c, msg, 2);
if (rc != 2) {
rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
return rc;
}
return val;
}
#define s921_readreg(state, reg) \
s921_i2c_readreg(state, state->config->demod_address, reg)
#define s921_writereg(state, reg, val) \
s921_i2c_writereg(state, state->config->demod_address, reg, val)
#define s921_writeregdata(state, regdata) \
s921_i2c_writeregdata(state, state->config->demod_address, \
regdata, ARRAY_SIZE(regdata))
static int s921_pll_tune(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct s921_state *state = fe->demodulator_priv;
int band, rc, i;
unsigned long f_offset;
u8 f_switch;
u64 offset;
dprintk("frequency=%i\n", p->frequency);
for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
if (p->frequency < s921_bandselect[band].freq_low)
break;
band--;
if (band < 0) {
rc("%s: frequency out of range\n", __func__);
return -EINVAL;
}
f_switch = s921_bandselect[band].band_reg;
offset = ((u64)p->frequency) * 258;
do_div(offset, 6000000);
f_offset = ((unsigned long)offset) + 2321;
rc = s921_writeregdata(state, s921_prefreq);
if (rc < 0)
return rc;
rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
if (rc < 0)
return rc;
rc = s921_writereg(state, 0xf3, f_offset & 0xff);
if (rc < 0)
return rc;
rc = s921_writereg(state, 0xf4, f_switch);
if (rc < 0)
return rc;
rc = s921_writeregdata(state, s921_postfreq);
if (rc < 0)
return rc;
for (i = 0 ; i < 6; i++) {
rc = s921_readreg(state, 0x80);
dprintk("status 0x80: %02x\n", rc);
}
rc = s921_writereg(state, 0x01, 0x40);
if (rc < 0)
return rc;
rc = s921_readreg(state, 0x01);
dprintk("status 0x01: %02x\n", rc);
rc = s921_readreg(state, 0x80);
dprintk("status 0x80: %02x\n", rc);
rc = s921_readreg(state, 0x80);
dprintk("status 0x80: %02x\n", rc);
rc = s921_readreg(state, 0x32);
dprintk("status 0x32: %02x\n", rc);
dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
return 0;
}
static int s921_initfe(struct dvb_frontend *fe)
{
struct s921_state *state = fe->demodulator_priv;
int rc;
dprintk("\n");
rc = s921_writeregdata(state, s921_init);
if (rc < 0)
return rc;
return 0;
}
static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct s921_state *state = fe->demodulator_priv;
int regstatus, rc;
*status = 0;
rc = s921_readreg(state, 0x81);
if (rc < 0)
return rc;
regstatus = rc << 8;
rc = s921_readreg(state, 0x82);
if (rc < 0)
return rc;
regstatus |= rc;
dprintk("status = %04x\n", regstatus);
/* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
if ((regstatus & 0xff) == 0x40) {
*status = FE_HAS_SIGNAL |
FE_HAS_CARRIER |
FE_HAS_VITERBI |
FE_HAS_SYNC |
FE_HAS_LOCK;
} else if (regstatus & 0x40) {
/* This is close to Full Sync, but not enough to get useful info */
*status = FE_HAS_SIGNAL |
FE_HAS_CARRIER |
FE_HAS_VITERBI |
FE_HAS_SYNC;
}
return 0;
}
static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
fe_status_t status;
struct s921_state *state = fe->demodulator_priv;
int rc;
/* FIXME: Use the proper register for it... 0x80? */
rc = s921_read_status(fe, &status);
if (rc < 0)
return rc;
*strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
dprintk("strength = 0x%04x\n", *strength);
rc = s921_readreg(state, 0x01);
dprintk("status 0x01: %02x\n", rc);
rc = s921_readreg(state, 0x80);
dprintk("status 0x80: %02x\n", rc);
rc = s921_readreg(state, 0x32);
dprintk("status 0x32: %02x\n", rc);
return 0;
}
static int s921_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct s921_state *state = fe->demodulator_priv;
int rc;
dprintk("\n");
/* FIXME: We don't know how to use non-auto mode */
rc = s921_pll_tune(fe, p);
if (rc < 0)
return rc;
state->currentfreq = p->frequency;
return 0;
}
static int s921_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct s921_state *state = fe->demodulator_priv;
/* FIXME: Probably it is possible to get it from regs f1 and f2 */
p->frequency = state->currentfreq;
return 0;
}
static int s921_tune(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params,
unsigned int mode_flags,
unsigned int *delay,
fe_status_t *status)
{
int rc = 0;
dprintk("\n");
if (params != NULL)
rc = s921_set_frontend(fe, params);
if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
s921_read_status(fe, status);
return rc;
}
static int s921_get_algo(struct dvb_frontend *fe)
{
return 1; /* FE_ALGO_HW */
}
static void s921_release(struct dvb_frontend *fe)
{
struct s921_state *state = fe->demodulator_priv;
dprintk("\n");
kfree(state);
}
static struct dvb_frontend_ops s921_ops;
struct dvb_frontend *s921_attach(const struct s921_config *config,
struct i2c_adapter *i2c)
{
/* allocate memory for the internal state */
struct s921_state *state =
kzalloc(sizeof(struct s921_state), GFP_KERNEL);
dprintk("\n");
if (state == NULL) {
rc("Unable to kzalloc\n");
goto rcor;
}
/* setup the state */
state->config = config;
state->i2c = i2c;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &s921_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
rcor:
kfree(state);
return NULL;
}
EXPORT_SYMBOL(s921_attach);
static struct dvb_frontend_ops s921_ops = {
/* Use dib8000 values per default */
.info = {
.name = "Sharp S921",
.type = FE_OFDM,
.frequency_min = 470000000,
/*
* Max should be 770MHz instead, according with Sharp docs,
* but Leadership doc says it works up to 806 MHz. This is
* required to get channel 69, used in Brazil
*/
.frequency_max = 806000000,
.frequency_tolerance = 0,
.caps = FE_CAN_INVERSION_AUTO |
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_RECOVER |
FE_CAN_HIERARCHY_AUTO,
},
.release = s921_release,
.init = s921_initfe,
.set_frontend = s921_set_frontend,
.get_frontend = s921_get_frontend,
.read_status = s921_read_status,
.read_signal_strength = s921_read_signal_strength,
.tune = s921_tune,
.get_frontend_algo = s921_get_algo,
};
MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,47 @@
/*
* Sharp s921 driver
*
* Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* 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.
*/
#ifndef S921_H
#define S921_H
#include <linux/dvb/frontend.h>
struct s921_config {
/* the demodulator's i2c address */
u8 demod_address;
};
#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
&& defined(MODULE))
extern struct dvb_frontend *s921_attach(const struct s921_config *config,
struct i2c_adapter *i2c);
extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
#else
static inline struct dvb_frontend *s921_attach(
const struct s921_config *config, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static struct i2c_adapter *
s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* S921_H */

View File

@ -1,216 +0,0 @@
/*
* Driver for Sharp s921 driver
*
* Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include "s921_core.h"
static int s921_isdb_init(struct s921_isdb_t *dev);
static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
0xf8, 0xd7 };
static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
switch(cmd) {
case ISDB_T_CMD_INIT:
s921_isdb_init(dev);
break;
case ISDB_T_CMD_SET_PARAM:
s921_isdb_set_parameters(dev, data);
break;
case ISDB_T_CMD_TUNE:
s921_isdb_tune(dev, data);
break;
case ISDB_T_CMD_GET_STATUS:
s921_isdb_get_status(dev, data);
break;
default:
printk("unhandled command\n");
return -EINVAL;
}
return 0;
}
static int s921_isdb_init(struct s921_isdb_t *dev) {
unsigned int i;
unsigned int ret;
printk("isdb_init\n");
for (i = 0; i < sizeof(init_table); i+=2) {
ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
if (ret != 0) {
printk("i2c write failed\n");
return ret;
}
}
return 0;
}
static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
int ret;
/* auto is sufficient for now, lateron this should be reflected in an extra interface */
ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
if (ret < 0)
return -EINVAL;
return E_OK;
}
static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
int ret;
int index;
index = (params->frequency - 473143000)/6000000;
if (index > 48) {
return -EINVAL;
}
dev->i2c_write(dev->priv_dev, 0x47, 0x60);
ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
if (ret < 0)
return -EINVAL;
ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
if (ret < 0)
return -EINVAL;
dev->i2c_write(dev->priv_dev, 0x01, 0x40);
return 0;
}
static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
unsigned int *ret = (unsigned int*)data;
u8 ifagc_dt;
u8 rfagc_dt;
mdelay(10);
ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
if (rfagc_dt == 0x40) {
*ret = 1;
}
return 0;
}

View File

@ -1,114 +0,0 @@
#ifndef _S921_CORE_H
#define _S921_CORE_H
//#define u8 unsigned int
//#define u32 unsigned int
//#define EINVAL -1
#define E_OK 0
struct s921_isdb_t {
void *priv_dev;
int (*i2c_write)(void *dev, u8 reg, u8 val);
int (*i2c_read)(void *dev, u8 reg);
};
#define ISDB_T_CMD_INIT 0
#define ISDB_T_CMD_SET_PARAM 1
#define ISDB_T_CMD_TUNE 2
#define ISDB_T_CMD_GET_STATUS 3
struct s921_isdb_t_tune_params {
u32 frequency;
};
struct s921_isdb_t_status {
};
struct s921_isdb_t_transmission_mode_params {
u8 mode;
u8 layer_a_mode;
#define ISDB_T_LA_MODE_1 0
#define ISDB_T_LA_MODE_2 1
#define ISDB_T_LA_MODE_3 2
u8 layer_a_carrier_modulation;
#define ISDB_T_LA_CM_DQPSK 0
#define ISDB_T_LA_CM_QPSK 1
#define ISDB_T_LA_CM_16QAM 2
#define ISDB_T_LA_CM_64QAM 3
#define ISDB_T_LA_CM_NOLAYER 4
u8 layer_a_code_rate;
#define ISDB_T_LA_CR_1_2 0
#define ISDB_T_LA_CR_2_3 1
#define ISDB_T_LA_CR_3_4 2
#define ISDB_T_LA_CR_5_6 4
#define ISDB_T_LA_CR_7_8 8
#define ISDB_T_LA_CR_NOLAYER 16
u8 layer_a_time_interleave;
#define ISDB_T_LA_TI_0 0
#define ISDB_T_LA_TI_1 1
#define ISDB_T_LA_TI_2 2
#define ISDB_T_LA_TI_4 4
#define ISDB_T_LA_TI_8 8
#define ISDB_T_LA_TI_16 16
#define ISDB_T_LA_TI_32 32
u8 layer_a_nseg;
u8 layer_b_mode;
#define ISDB_T_LB_MODE_1 0
#define ISDB_T_LB_MODE_2 1
#define ISDB_T_LB_MODE_3 2
u8 layer_b_carrier_modulation;
#define ISDB_T_LB_CM_DQPSK 0
#define ISDB_T_LB_CM_QPSK 1
#define ISDB_T_LB_CM_16QAM 2
#define ISDB_T_LB_CM_64QAM 3
#define ISDB_T_LB_CM_NOLAYER 4
u8 layer_b_code_rate;
#define ISDB_T_LB_CR_1_2 0
#define ISDB_T_LB_CR_2_3 1
#define ISDB_T_LB_CR_3_4 2
#define ISDB_T_LB_CR_5_6 4
#define ISDB_T_LB_CR_7_8 8
#define ISDB_T_LB_CR_NOLAYER 16
u8 layer_b_time_interleave;
#define ISDB_T_LB_TI_0 0
#define ISDB_T_LB_TI_1 1
#define ISDB_T_LB_TI_2 2
#define ISDB_T_LB_TI_4 4
#define ISDB_T_LB_TI_8 8
#define ISDB_T_LB_TI_16 16
#define ISDB_T_LB_TI_32 32
u8 layer_b_nseg;
u8 layer_c_mode;
#define ISDB_T_LC_MODE_1 0
#define ISDB_T_LC_MODE_2 1
#define ISDB_T_LC_MODE_3 2
u8 layer_c_carrier_modulation;
#define ISDB_T_LC_CM_DQPSK 0
#define ISDB_T_LC_CM_QPSK 1
#define ISDB_T_LC_CM_16QAM 2
#define ISDB_T_LC_CM_64QAM 3
#define ISDB_T_LC_CM_NOLAYER 4
u8 layer_c_code_rate;
#define ISDB_T_LC_CR_1_2 0
#define ISDB_T_LC_CR_2_3 1
#define ISDB_T_LC_CR_3_4 2
#define ISDB_T_LC_CR_5_6 4
#define ISDB_T_LC_CR_7_8 8
#define ISDB_T_LC_CR_NOLAYER 16
u8 layer_c_time_interleave;
#define ISDB_T_LC_TI_0 0
#define ISDB_T_LC_TI_1 1
#define ISDB_T_LC_TI_2 2
#define ISDB_T_LC_TI_4 4
#define ISDB_T_LC_TI_8 8
#define ISDB_T_LC_TI_16 16
#define ISDB_T_LC_TI_32 32
u8 layer_c_nseg;
};
int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
#endif

View File

@ -1,192 +0,0 @@
/*
* Driver for Sharp s921 driver
*
* Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
*
* All rights reserved.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "s921_module.h"
#include "s921_core.h"
static unsigned int debug = 0;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"s921 debugging (default off)");
#define dprintk(fmt, args...) if (debug) do {\
printk("s921 debug: " fmt, ##args); } while (0)
struct s921_state
{
struct dvb_frontend frontend;
fe_modulation_t current_modulation;
__u32 snr;
__u32 current_frequency;
__u8 addr;
struct s921_isdb_t dev;
struct i2c_adapter *i2c;
};
static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
struct s921_isdb_t_transmission_mode_params params;
struct s921_isdb_t_tune_params tune_params;
tune_params.frequency = param->frequency;
s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
mdelay(100);
return 0;
}
static int s921_init(struct dvb_frontend *fe) {
printk("s921 init\n");
return 0;
}
static int s921_sleep(struct dvb_frontend *fe) {
printk("s921 sleep\n");
return 0;
}
static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
unsigned int ret;
mdelay(5);
s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
*status = 0;
printk("status: %02x\n", ret);
if (ret == 1) {
*status |= FE_HAS_CARRIER;
*status |= FE_HAS_VITERBI;
*status |= FE_HAS_LOCK;
*status |= FE_HAS_SYNC;
*status |= FE_HAS_SIGNAL;
}
return 0;
}
static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
{
dprintk("read ber\n");
return 0;
}
static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
{
dprintk("read snr\n");
return 0;
}
static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
{
dprintk("read ucblocks\n");
return 0;
}
static void s921_release(struct dvb_frontend *fe)
{
struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
kfree(state);
}
static struct dvb_frontend_ops demod_s921={
.info = {
.name = "SHARP S921",
.type = FE_OFDM,
.frequency_min = 473143000,
.frequency_max = 767143000,
.frequency_stepsize = 6000000,
.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
},
.init = s921_init,
.sleep = s921_sleep,
.set_frontend = s921_set_parameters,
.read_snr = s921_read_snr,
.read_ber = s921_read_ber,
.read_status = s921_read_status,
.read_ucblocks = s921_read_ucblocks,
.release = s921_release,
};
static int s921_write(void *dev, u8 reg, u8 val) {
struct s921_state *state = dev;
char buf[2]={reg,val};
int err;
struct i2c_msg i2cmsgs = {
.addr = state->addr,
.flags = 0,
.len = 2,
.buf = buf
};
if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
printk("%s i2c_transfer error %d\n", __func__, err);
if (err < 0)
return err;
else
return -EREMOTEIO;
}
return 0;
}
static int s921_read(void *dev, u8 reg) {
struct s921_state *state = dev;
u8 b1;
int ret;
struct i2c_msg msg[2] = { { .addr = state->addr,
.flags = 0,
.buf = &reg, .len = 1 },
{ .addr = state->addr,
.flags = I2C_M_RD,
.buf = &b1, .len = 1 } };
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
return ret;
return b1;
}
struct dvb_frontend* s921_attach(const struct s921_config *config,
struct i2c_adapter *i2c)
{
struct s921_state *state;
state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
if (state == NULL)
return NULL;
state->addr = config->i2c_address;
state->i2c = i2c;
state->dev.i2c_write = &s921_write;
state->dev.i2c_read = &s921_read;
state->dev.priv_dev = state;
s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
}
EXPORT_SYMBOL_GPL(s921_attach);
MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
MODULE_LICENSE("GPL");

View File

@ -1,49 +0,0 @@
/*
* Driver for DVB-T s921 demodulator
*
* Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
*
* 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 S921_MODULE_H
#define S921_MODULE_H
#include <linux/dvb/frontend.h>
#include "s921_core.h"
int s921_isdb_init(struct s921_isdb_t *dev);
int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
struct s921_config
{
/* demodulator's I2C address */
u8 i2c_address;
};
#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
extern struct dvb_frontend* s921_attach(const struct s921_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_S921 */
#endif /* S921_H */

View File

@ -714,7 +714,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
msleep(100);
return 0;
}

View File

@ -51,7 +51,7 @@ module_param(verbose, int, 0644);
if (x > y) \
printk(format, ##arg); \
} \
} while(0)
} while (0)
struct stb6100_lkup {
u32 val_low;
@ -117,7 +117,10 @@ static const struct stb6100_regmask stb6100_template[] = {
[STB6100_TEST3] = { 0x00, 0xde },
};
static void stb6100_normalise_regs(u8 regs[])
/*
* Currently unused. Some boards might need it in the future
*/
static inline void stb6100_normalise_regs(u8 regs[])
{
int i;
@ -157,13 +160,25 @@ static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
u8 regs[STB6100_NUMREGS];
int rc;
struct i2c_msg msg = {
.addr = state->config->tuner_address + reg,
.flags = I2C_M_RD,
.buf = regs,
.len = 1
};
rc = i2c_transfer(state->i2c, &msg, 1);
if (unlikely(reg >= STB6100_NUMREGS)) {
dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
return -EINVAL;
}
if ((rc = stb6100_read_regs(state, regs)) < 0)
return rc;
return (unsigned int)regs[reg];
if (unlikely(verbose > FE_DEBUG)) {
dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[reg], regs[0]);
}
return (unsigned int)regs[0];
}
static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
@ -211,20 +226,17 @@ static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
return stb6100_write_reg_range(state, &data, reg, 1);
}
static int stb6100_write_regs(struct stb6100_state *state, u8 regs[])
{
stb6100_normalise_regs(regs);
return stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 1);
}
static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
{
int rc;
struct stb6100_state *state = fe->tuner_priv;
if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0)
rc = stb6100_read_reg(state, STB6100_LD);
if (rc < 0) {
dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
return rc;
}
return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
}
@ -234,7 +246,8 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
u8 f;
struct stb6100_state *state = fe->tuner_priv;
if ((rc = stb6100_read_reg(state, STB6100_F)) < 0)
rc = stb6100_read_reg(state, STB6100_F);
if (rc < 0)
return rc;
f = rc & STB6100_F_F;
@ -265,14 +278,21 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
/* Turn on LPF bandwidth setting clock control,
* set bandwidth, wait 10ms, turn off.
*/
if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0)
rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
if (rc < 0)
return rc;
if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0)
rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
if (rc < 0)
return rc;
msleep(1);
if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0)
msleep(5); /* This is dangerous as another (related) thread may start */
rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
if (rc < 0)
return rc;
msleep(10); /* This is dangerous as another (related) thread may start */
return 0;
}
@ -284,7 +304,8 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
struct stb6100_state *state = fe->tuner_priv;
u8 regs[STB6100_NUMREGS];
if ((rc = stb6100_read_regs(state, regs)) < 0)
rc = stb6100_read_regs(state, regs);
if (rc < 0)
return rc;
odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
@ -312,8 +333,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
u8 regs[STB6100_NUMREGS];
u8 g, psd2, odiv;
if ((rc = stb6100_read_regs(state, regs)) < 0)
return rc;
dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
if (fe->ops.get_frontend) {
dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
@ -321,96 +341,140 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
}
srate = p.u.qpsk.symbol_rate;
regs[STB6100_DLB] = 0xdc;
/* Disable LPEN */
regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */
/* Set up tuner cleanly, LPF calibration on */
rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
if (rc < 0)
return rc; /* allow LPF calibration */
if ((rc = stb6100_write_regs(state, regs)) < 0)
/* PLL Loop disabled, bias on, VCO on, synth on */
regs[STB6100_LPEN] = 0xeb;
rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
if (rc < 0)
return rc;
/* Baseband gain. */
if (srate >= 15000000)
g = 9; // +4 dB
else if (srate >= 5000000)
g = 11; // +8 dB
else
g = 14; // +14 dB
regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g;
regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
/* Program the registers with their data values */
/* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
if (frequency <= 1075000)
odiv = 1;
else
odiv = 0;
regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT);
if ((frequency > 1075000) && (frequency <= 1325000))
psd2 = 0;
else
psd2 = 1;
regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
/* VCO enabled, seach clock off as per LL3.7, 3.4.1 */
regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
/* OSM */
for (ptr = lkup;
(ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
ptr++);
if (ptr->val_high == 0) {
printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
return -EINVAL;
}
regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
if (rc < 0)
return rc;
if ((frequency > 1075000) && (frequency <= 1325000))
psd2 = 0;
else
psd2 = 1;
/* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
fvco = frequency << (1 + odiv);
/* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
nint = fvco / (state->reference << psd2);
/* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
<< (9 - psd2),
state->reference);
<< (9 - psd2), state->reference);
/* NI */
regs[STB6100_NI] = nint;
rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
if (rc < 0)
return rc;
/* NF */
regs[STB6100_NF_LSB] = nfrac;
rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
if (rc < 0)
return rc;
/* K */
regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
if (rc < 0)
return rc;
/* G Baseband gain. */
if (srate >= 15000000)
g = 9; /* +4 dB */
else if (srate >= 5000000)
g = 11; /* +8 dB */
else
g = 14; /* +14 dB */
regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
if (rc < 0)
return rc;
/* F we don't write as it is set up in BW set */
/* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
regs[STB6100_DLB] = 0xcc;
rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
if (rc < 0)
return rc;
dprintk(verbose, FE_DEBUG, 1,
"frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
frequency, srate, (unsigned int)g, (unsigned int)odiv,
(unsigned int)psd2, state->reference,
ptr->reg, fvco, nint, nfrac);
regs[STB6100_NI] = nint;
regs[STB6100_NF_LSB] = nfrac;
regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */
regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */
regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */
regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */
/* Power up. */
regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN;
msleep(2);
if ((rc = stb6100_write_regs(state, regs)) < 0)
/* Set up the test registers */
regs[STB6100_TEST1] = 0x8f;
rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
if (rc < 0)
return rc;
regs[STB6100_TEST3] = 0xde;
rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
if (rc < 0)
return rc;
/* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
if (rc < 0)
return rc;
msleep(2);
regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */
if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0)
return rc;
/* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
if (rc < 0)
return rc;
msleep(10); /* wait for LO to lock */
msleep(10); /* This is dangerous as another (related) thread may start */ /* wait for LO to lock */
regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
return rc;
regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */
stb6100_normalise_regs(regs);
if ((rc = stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 3)) < 0)
rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
if (rc < 0)
return rc;
msleep(100);
rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
if (rc < 0)
return rc; /* Stop LPF calibration */
msleep(10); /* This is dangerous as another (related) thread may start */
/* wait for stabilisation, (should not be necessary) */
return 0;
}
@ -433,8 +497,8 @@ static int stb6100_init(struct dvb_frontend *fe)
state->bandwidth = status->bandwidth * 1000; /* Hz */
state->reference = status->refclock / 1000; /* kHz */
/* Set default bandwidth. */
return stb6100_set_bandwidth(fe, state->bandwidth);
/* Set default bandwidth. Modified, PN 13-May-10 */
return 0;
}
static int stb6100_get_state(struct dvb_frontend *fe,

View File

@ -1483,8 +1483,8 @@ static int stv090x_start_search(struct stv090x_state *state)
if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
goto err;
if ((state->search_mode == STV090x_DVBS1) ||
(state->search_mode == STV090x_DSS) ||
if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
(state->search_mode == STV090x_SEARCH_DSS) ||
(state->search_mode == STV090x_SEARCH_AUTO)) {
if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
@ -2940,7 +2940,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
break;
case STV090x_UNKNOWN:
case STV090x_ERROR:
default:
reg = STV090x_READ_DEMOD(state, DMDCFGMD);
STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);

View File

@ -1,6 +1,6 @@
config MANTIS_CORE
tristate "Mantis/Hopper PCI bridge based devices"
depends on PCI && I2C && INPUT && IR_CORE
depends on PCI && I2C && INPUT && RC_CORE
help
Support for PCI cards based on the Mantis and Hopper PCi bridge.

View File

@ -251,6 +251,8 @@ static struct pci_device_id hopper_pci_table[] = {
{ }
};
MODULE_DEVICE_TABLE(pci, hopper_pci_table);
static struct pci_driver hopper_pci_driver = {
.name = DRIVER_NAME,
.id_table = hopper_pci_table,

View File

@ -47,17 +47,17 @@ static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
struct mantis_hwconfig *config = mantis->hwconfig;
int err = 0;
gpio_set_bits(mantis, config->reset, 0);
mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
err = mantis_frontend_power(mantis, POWER_ON);
msleep(100);
gpio_set_bits(mantis, config->reset, 1);
mantis_gpio_set_bits(mantis, config->reset, 1);
err = mantis_frontend_power(mantis, POWER_ON);
if (err == 0) {
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
fe = zl10353_attach(&hopper_vp3028_config, adapter);
fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter);
if (!fe)
return -1;

View File

@ -281,6 +281,8 @@ static struct pci_device_id mantis_pci_table[] = {
{ }
};
MODULE_DEVICE_TABLE(pci, mantis_pci_table);
static struct pci_driver mantis_pci_driver = {
.name = DRIVER_NAME,
.id_table = mantis_pci_table,

View File

@ -171,7 +171,9 @@ struct mantis_pci {
struct work_struct uart_work;
spinlock_t uart_lock;
struct input_dev *rc;
struct rc_dev *rc;
char input_name[80];
char input_phys[80];
};
#define MANTIS_HIF_STATUS (mantis->gpio_status)

View File

@ -47,15 +47,15 @@ int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
switch (power) {
case POWER_ON:
dprintk(MANTIS_DEBUG, 1, "Power ON");
gpio_set_bits(mantis, config->power, POWER_ON);
mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
gpio_set_bits(mantis, config->power, POWER_ON);
mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
break;
case POWER_OFF:
dprintk(MANTIS_DEBUG, 1, "Power OFF");
gpio_set_bits(mantis, config->power, POWER_OFF);
mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
msleep(100);
break;
@ -73,13 +73,13 @@ void mantis_frontend_soft_reset(struct mantis_pci *mantis)
struct mantis_hwconfig *config = mantis->hwconfig;
dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
gpio_set_bits(mantis, config->reset, 0);
mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
gpio_set_bits(mantis, config->reset, 0);
mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
gpio_set_bits(mantis, config->reset, 1);
mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
gpio_set_bits(mantis, config->reset, 1);
mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
return;
@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
if (mantis->feeds == 1) {
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
mantis_dma_start(mantis);
tasklet_enable(&mantis->tasklet);
}
return mantis->feeds;
@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
mantis->feeds--;
if (mantis->feeds == 0) {
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
tasklet_disable(&mantis->tasklet);
mantis_dma_stop(mantis);
}
@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
tasklet_disable(&mantis->tasklet);
if (mantis->hwconfig) {
result = config->frontend_init(mantis, mantis->fe);
if (result < 0) {

View File

@ -18,8 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/input.h>
#include <media/ir-core.h>
#include <media/rc-core.h>
#include <linux/pci.h>
#include "dmxdev.h"
@ -33,8 +32,9 @@
#include "mantis_uart.h"
#define MODULE_NAME "mantis_core"
#define RC_MAP_MANTIS "rc-mantis"
static struct ir_scancode mantis_ir_table[] = {
static struct rc_map_table mantis_ir_table[] = {
{ 0x29, KEY_POWER },
{ 0x28, KEY_FAVORITES },
{ 0x30, KEY_TEXT },
@ -95,53 +95,65 @@ static struct ir_scancode mantis_ir_table[] = {
{ 0x00, KEY_BLUE },
};
struct ir_scancode_table ir_mantis = {
.scan = mantis_ir_table,
.size = ARRAY_SIZE(mantis_ir_table),
static struct rc_map_list ir_mantis_map = {
.map = {
.scan = mantis_ir_table,
.size = ARRAY_SIZE(mantis_ir_table),
.rc_type = RC_TYPE_UNKNOWN,
.name = RC_MAP_MANTIS,
}
};
EXPORT_SYMBOL_GPL(ir_mantis);
int mantis_input_init(struct mantis_pci *mantis)
{
struct input_dev *rc;
char name[80], dev[80];
struct rc_dev *dev;
int err;
rc = input_allocate_device();
if (!rc) {
dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
return -ENOMEM;
err = rc_map_register(&ir_mantis_map);
if (err)
goto out;
dev = rc_allocate_device();
if (!dev) {
dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
err = -ENOMEM;
goto out_map;
}
sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
rc->name = name;
rc->phys = dev;
dev->input_name = mantis->input_name;
dev->input_phys = mantis->input_phys;
dev->input_id.bustype = BUS_PCI;
dev->input_id.vendor = mantis->vendor_id;
dev->input_id.product = mantis->device_id;
dev->input_id.version = 1;
dev->driver_name = MODULE_NAME;
dev->map_name = RC_MAP_MANTIS;
dev->dev.parent = &mantis->pdev->dev;
rc->id.bustype = BUS_PCI;
rc->id.vendor = mantis->vendor_id;
rc->id.product = mantis->device_id;
rc->id.version = 1;
rc->dev = mantis->pdev->dev;
err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
err = rc_register_device(dev);
if (err) {
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
input_free_device(rc);
return -ENODEV;
goto out_dev;
}
mantis->rc = rc;
mantis->rc = dev;
return 0;
out_dev:
rc_free_device(dev);
out_map:
rc_map_unregister(&ir_mantis_map);
out:
return err;
}
int mantis_exit(struct mantis_pci *mantis)
{
struct input_dev *rc = mantis->rc;
ir_input_unregister(rc);
rc_unregister_device(mantis->rc);
rc_map_unregister(&ir_mantis_map);
return 0;
}

View File

@ -75,7 +75,7 @@ int mantis_get_mac(struct mantis_pci *mantis)
EXPORT_SYMBOL_GPL(mantis_get_mac);
/* Turn the given bit on or off. */
void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
{
u32 cur;
@ -90,7 +90,7 @@ void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
mmwrite(0x00, MANTIS_GPIF_DOUT);
}
EXPORT_SYMBOL_GPL(gpio_set_bits);
EXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
{

View File

@ -44,7 +44,7 @@ enum mantis_stream_control {
};
extern int mantis_get_mac(struct mantis_pci *mantis);
extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);

View File

@ -173,7 +173,7 @@ static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
fe = stv0299_attach(&lgtdqcs001f_config, adapter);
fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
if (fe) {
fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;

View File

@ -50,13 +50,13 @@ int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
switch (voltage) {
case SEC_VOLTAGE_13:
dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
gpio_set_bits(mantis, 13, 1);
gpio_set_bits(mantis, 14, 0);
mantis_gpio_set_bits(mantis, 13, 1);
mantis_gpio_set_bits(mantis, 14, 0);
break;
case SEC_VOLTAGE_18:
dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
gpio_set_bits(mantis, 13, 1);
gpio_set_bits(mantis, 14, 1);
mantis_gpio_set_bits(mantis, 13, 1);
mantis_gpio_set_bits(mantis, 14, 1);
break;
case SEC_VOLTAGE_OFF:
dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
@ -82,7 +82,7 @@ static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
fe = mb86a16_attach(&vp1034_mb86a16_config, adapter);
fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter);
if (fe) {
dprintk(MANTIS_ERROR, 1,
"found MB86A16 DVB-S/DSS frontend @0x%02x",

View File

@ -316,14 +316,14 @@ static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
if (err == 0) {
mantis_frontend_soft_reset(mantis);
msleep(250);
mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter);
mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter);
if (mantis->fe) {
dprintk(MANTIS_ERROR, 1,
"found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
vp1041_stb0899_config.demod_address);
if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) {
if (!lnbp21_attach(mantis->fe, adapter, 0, 0))
if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) {
if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0))
dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
}
} else {

View File

@ -132,7 +132,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
fe = tda10021_attach(&vp2033_tda1002x_cu1216_config,
fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@ -141,7 +141,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2033_tda1002x_cu1216_config.demod_address);
} else {
fe = tda10023_attach(&vp2033_tda10023_cu1216_config,
fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
adapter,
read_pwm(mantis));

View File

@ -132,7 +132,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
fe = tda10021_attach(&vp2040_tda1002x_cu1216_config,
fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@ -141,7 +141,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2040_tda1002x_cu1216_config.demod_address);
} else {
fe = tda10023_attach(&vp2040_tda10023_cu1216_config,
fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config,
adapter,
read_pwm(mantis));

Some files were not shown because too many files have changed in this diff Show More