Commit 2b8c70b2 authored by Linus Torvalds's avatar Linus Torvalds

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: (362 commits)
  V4L-DVB: cx88-dvb: remove extra attribution for core
  V4L/DVB: v4l: soc_camera: fix bound checking of mbus_fmt[] index
  V4L/DVB: Add support for SMT7020 to cx88
  V4L/DVB: radio-si470x: Use UTF-8 encoding on a comment
  V4L/DVB: MAINTAINERS: Telegent tlg2300 section fix
  V4L/DVB: gspca_stv06xx: Add support for camera button
  V4L/DVB: gspca_ov519: add support for the button on ov511 based cams
  V4L/DVB: gspca_ov519: Add support for the button on ov518 based cams
  V4L/DVB: gspca_ov519: add support for the button on ov519 based cams
  V4L/DVB: gspca_main: Fix a compile error when CONFIG_INPUT is not set
  V4L/DVB: gspca_main: some input error handling fixes
  V4L/DVB: gspca_main: Allow use of input device creation code for non int. inputs
  V4L/DVB: gspca_pac7302: much improved exposure control
  V4L/DVB: gspca_sonixb: Make sonixb driver handle pas106 and pas202 cameras
  V4L/DVB: gspca_sonixb: pas106: fixup bright ctrl and add gain and exposure ctrls
  V4L/DVB: Documentation: gspca.txt: update known mr97310a cams
  V4L/DVB: gspca_mr97310a: add support for the Sakar 1638x CyberPix
  V4L/DVB: gscpa_sonixb: limit ov7630 max framerate at 640x480
  V4L/DVB: gspca_sonixb: pas202: fixup brightness ctrl and add gain and exposure ctrls
  V4L/DVB: gscpa_sonixb: Differentiate between sensors with a coarse and fine expo ctrl
  ...
parents 29e1fa35 3621263a
......@@ -589,7 +589,8 @@ number of a video input as in &v4l2-input; field
<entry></entry>
<entry>A place holder for future extensions and custom
(driver defined) buffer types
<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher. Applications
should set this to 0.</entry>
</row>
</tbody>
</tgroup>
......
......@@ -54,12 +54,10 @@ to enqueue an empty (capturing) or filled (output) buffer in the
driver's incoming queue. The semantics depend on the selected I/O
method.</para>
<para>To enqueue a <link linkend="mmap">memory mapped</link>
buffer applications set the <structfield>type</structfield> field of a
&v4l2-buffer; to the same buffer type as previously &v4l2-format;
<structfield>type</structfield> and &v4l2-requestbuffers;
<structfield>type</structfield>, the <structfield>memory</structfield>
field to <constant>V4L2_MEMORY_MMAP</constant> and the
<para>To enqueue a buffer applications set the <structfield>type</structfield>
field of a &v4l2-buffer; to the same buffer type as was previously used
with &v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
<structfield>type</structfield>. Applications must also set the
<structfield>index</structfield> field. Valid index numbers range from
zero to the number of buffers allocated with &VIDIOC-REQBUFS;
(&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The
......@@ -70,8 +68,19 @@ intended for output (<structfield>type</structfield> is
<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
initialize the <structfield>bytesused</structfield>,
<structfield>field</structfield> and
<structfield>timestamp</structfield> fields. See <xref
linkend="buffer" /> for details. When
<structfield>timestamp</structfield> fields, see <xref
linkend="buffer" /> for details.
Applications must also set <structfield>flags</structfield> to 0. If a driver
supports capturing from specific video inputs and you want to specify a video
input, then <structfield>flags</structfield> should be set to
<constant>V4L2_BUF_FLAG_INPUT</constant> and the field
<structfield>input</structfield> must be initialized to the desired input.
The <structfield>reserved</structfield> field must be set to 0.
</para>
<para>To enqueue a <link linkend="mmap">memory mapped</link>
buffer applications set the <structfield>memory</structfield>
field to <constant>V4L2_MEMORY_MMAP</constant>. When
<constant>VIDIOC_QBUF</constant> is called with a pointer to this
structure the driver sets the
<constant>V4L2_BUF_FLAG_MAPPED</constant> and
......@@ -81,14 +90,10 @@ structure the driver sets the
&EINVAL;.</para>
<para>To enqueue a <link linkend="userp">user pointer</link>
buffer applications set the <structfield>type</structfield> field of a
&v4l2-buffer; to the same buffer type as previously &v4l2-format;
<structfield>type</structfield> and &v4l2-requestbuffers;
<structfield>type</structfield>, the <structfield>memory</structfield>
field to <constant>V4L2_MEMORY_USERPTR</constant> and the
buffer applications set the <structfield>memory</structfield>
field to <constant>V4L2_MEMORY_USERPTR</constant>, the
<structfield>m.userptr</structfield> field to the address of the
buffer and <structfield>length</structfield> to its size. When the
buffer is intended for output additional fields must be set as above.
buffer and <structfield>length</structfield> to its size.
When <constant>VIDIOC_QBUF</constant> is called with a pointer to this
structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant>
flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
......@@ -96,13 +101,14 @@ flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
<structfield>flags</structfield> field, or it returns an error code.
This ioctl locks the memory pages of the buffer in physical memory,
they cannot be swapped out to disk. Buffers remain locked until
dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are
dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is
called, or until the device is closed.</para>
<para>Applications call the <constant>VIDIOC_DQBUF</constant>
ioctl to dequeue a filled (capturing) or displayed (output) buffer
from the driver's outgoing queue. They just set the
<structfield>type</structfield> and <structfield>memory</structfield>
<structfield>type</structfield>, <structfield>memory</structfield>
and <structfield>reserved</structfield>
fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
is called with a pointer to this structure the driver fills the
remaining fields or returns an error code.</para>
......
......@@ -54,12 +54,13 @@ buffer at any time after buffers have been allocated with the
&VIDIOC-REQBUFS; ioctl.</para>
<para>Applications set the <structfield>type</structfield> field
of a &v4l2-buffer; to the same buffer type as previously
of a &v4l2-buffer; to the same buffer type as was previously used with
&v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
<structfield>type</structfield>, and the <structfield>index</structfield>
field. Valid index numbers range from zero
to the number of buffers allocated with &VIDIOC-REQBUFS;
(&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
The <structfield>reserved</structfield> field should to set to 0.
After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
this structure drivers return an error code or fill the rest of
the structure.</para>
......@@ -68,8 +69,8 @@ the structure.</para>
<constant>V4L2_BUF_FLAG_MAPPED</constant>,
<constant>V4L2_BUF_FLAG_QUEUED</constant> and
<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
<structfield>memory</structfield> field will be set to
<constant>V4L2_MEMORY_MMAP</constant>, the <structfield>m.offset</structfield>
<structfield>memory</structfield> field will be set to the current
I/O method, the <structfield>m.offset</structfield>
contains the offset of the buffer from the start of the device memory,
the <structfield>length</structfield> field its size. The driver may
or may not set the remaining fields and flags, they are meaningless in
......
......@@ -54,23 +54,23 @@ I/O. Memory mapped buffers are located in device memory and must be
allocated with this ioctl before they can be mapped into the
application's address space. User buffers are allocated by
applications themselves, and this ioctl is merely used to switch the
driver into user pointer I/O mode.</para>
driver into user pointer I/O mode and to setup some internal structures.</para>
<para>To allocate device buffers applications initialize three
fields of a <structname>v4l2_requestbuffers</structname> structure.
<para>To allocate device buffers applications initialize all
fields of the <structname>v4l2_requestbuffers</structname> structure.
They set the <structfield>type</structfield> field to the respective
stream or buffer type, the <structfield>count</structfield> field to
the desired number of buffers, and <structfield>memory</structfield>
must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl
is called with a pointer to this structure the driver attempts to
allocate the requested number of buffers and stores the actual number
the desired number of buffers, <structfield>memory</structfield>
must be set to the requested I/O method and the reserved array
must be zeroed. When the ioctl
is called with a pointer to this structure the driver will attempt to allocate
the requested number of buffers and it stores the actual number
allocated in the <structfield>count</structfield> field. It can be
smaller than the number requested, even zero, when the driver runs out
of free memory. A larger number is possible when the driver requires
more buffers to function correctly.<footnote>
<para>For example video output requires at least two buffers,
of free memory. A larger number is also possible when the driver requires
more buffers to function correctly. For example video output requires at least two buffers,
one displayed and one filled by the application.</para>
</footnote> When memory mapping I/O is not supported the ioctl
<para>When the I/O method is not supported the ioctl
returns an &EINVAL;.</para>
<para>Applications can call <constant>VIDIOC_REQBUFS</constant>
......@@ -81,14 +81,6 @@ in progress, an implicit &VIDIOC-STREAMOFF;. <!-- mhs: I see no
reason why munmap()ping one or even all buffers must imply
streamoff.--></para>
<para>To negotiate user pointer I/O, applications initialize only
the <structfield>type</structfield> field and set
<structfield>memory</structfield> to
<constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called
with a pointer to this structure the driver prepares for user pointer
I/O, when this I/O method is not supported the ioctl returns an
&EINVAL;.</para>
<table pgwide="1" frame="none" id="v4l2-requestbuffers">
<title>struct <structname>v4l2_requestbuffers</structname></title>
<tgroup cols="3">
......@@ -97,9 +89,7 @@ I/O, when this I/O method is not supported the ioctl returns an
<row>
<entry>__u32</entry>
<entry><structfield>count</structfield></entry>
<entry>The number of buffers requested or granted. This
field is only used when <structfield>memory</structfield> is set to
<constant>V4L2_MEMORY_MMAP</constant>.</entry>
<entry>The number of buffers requested or granted.</entry>
</row>
<row>
<entry>&v4l2-buf-type;</entry>
......@@ -120,7 +110,7 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref
<entry><structfield>reserved</structfield>[2]</entry>
<entry>A place holder for future extensions and custom
(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
higher.</entry>
higher. This array should be zeroed by applications.</entry>
</row>
</tbody>
</tgroup>
......
......@@ -26,7 +26,7 @@ use IO::Handle;
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
"af9015");
"af9015", "ngene");
# Check args
syntax() if (scalar(@ARGV) != 1);
......@@ -39,7 +39,7 @@ for ($i=0; $i < scalar(@components); $i++) {
die $@ if $@;
print STDERR <<EOF;
Firmware(s) $outfile extracted successfully.
Now copy it(they) to either /usr/lib/hotplug/firmware or /lib/firmware
Now copy it(them) to either /usr/lib/hotplug/firmware or /lib/firmware
(depending on configuration of firmware hotplug).
EOF
exit(0);
......@@ -549,6 +549,24 @@ sub af9015 {
close INFILE;
}
sub ngene {
my $url = "http://www.digitaldevices.de/download/";
my $file1 = "ngene_15.fw";
my $hash1 = "d798d5a757121174f0dbc5f2833c0c85";
my $file2 = "ngene_17.fw";
my $hash2 = "26b687136e127b8ac24b81e0eeafc20b";
checkstandard();
wgetfile($file1, $url . $file1);
verify($file1, $hash1);
wgetfile($file2, $url . $file2);
verify($file2, $hash2);
"$file1, $file2";
}
# ---------------------------------------------------------------
# Utilities
......@@ -667,6 +685,7 @@ sub delzero{
sub syntax() {
print STDERR "syntax: get_dvb_firmware <component>\n";
print STDERR "Supported components:\n";
@components = sort @components;
for($i=0; $i < scalar(@components); $i++) {
print STDERR "\t" . $components[$i] . "\n";
}
......
......@@ -26,3 +26,4 @@
25 -> Compro VideoMate E800 [1858:e800]
26 -> Hauppauge WinTV-HVR1290 [0070:8551]
27 -> Mygica X8558 PRO DMB-TH [14f1:8578]
28 -> LEADTEK WinFast PxTV1200 [107d:6f22]
......@@ -174,3 +174,4 @@
173 -> Zolid Hybrid TV Tuner PCI [1131:2004]
174 -> Asus Europa Hybrid OEM [1043:4847]
175 -> Leadtek Winfast DTV1000S [107d:6655]
176 -> Beholder BeholdTV 505 RDS [0000:5051]
......@@ -81,3 +81,4 @@ tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
tuner=81 - Partsnic (Daewoo) PTI-5NF05
tuner=82 - Philips CU1216L
tuner=83 - NXP TDA18271
tuner=84 - Sony BTF-Pxn01Z
tlg2300 release notes
====================
This is a v4l2/dvb device driver for the tlg2300 chip.
current status
==============
video
- support mmap and read().(no overlay)
audio
- The driver will register a ALSA card for the audio input.
vbi
- Works for almost TV norms.
dvb-t
- works for DVB-T
FM
- Works for radio.
---------------------------------------------------------------------------
TESTED APPLICATIONS:
-VLC1.0.4 test the video and dvb. The GUI is friendly to use.
-Mplayer test the video.
-Mplayer test the FM. The mplayer should be compiled with --enable-radio and
--enable-radio-capture.
The command runs as this(The alsa audio registers to card 1):
#mplayer radio://103.7/capture/ -radio adevice=hw=1,0:arate=48000 \
-rawaudio rate=48000:channels=2
---------------------------------------------------------------------------
KNOWN PROBLEMS:
about preemphasis:
You can set the preemphasis for radio by the following command:
#v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1
"pre_emphasis_settings=1" means that you select the 50us. If you want
to select the 75us, please use "pre_emphasis_settings=2"
......@@ -42,6 +42,7 @@ ov519 041e:4064 Creative Live! VISTA VF0420
ov519 041e:4067 Creative Live! Cam Video IM (VF0350)
ov519 041e:4068 Creative Live! VISTA VF0470
spca561 0458:7004 Genius VideoCAM Express V2
sn9c2028 0458:7005 Genius Smart 300, version 2
sunplus 0458:7006 Genius Dsc 1.3 Smart
zc3xx 0458:7007 Genius VideoCam V2
zc3xx 0458:700c Genius VideoCam V3
......@@ -109,6 +110,7 @@ sunplus 04a5:3003 Benq DC 1300
sunplus 04a5:3008 Benq DC 1500
sunplus 04a5:300a Benq DC 3410
spca500 04a5:300c Benq DC 1016
benq 04a5:3035 Benq DC E300
finepix 04cb:0104 Fujifilm FinePix 4800
finepix 04cb:0109 Fujifilm FinePix A202
finepix 04cb:010b Fujifilm FinePix A203
......@@ -142,6 +144,7 @@ sunplus 04fc:5360 Sunplus Generic
spca500 04fc:7333 PalmPixDC85
sunplus 04fc:ffff Pure DigitalDakota
spca501 0506:00df 3Com HomeConnect Lite
sunplus 052b:1507 Megapixel 5 Pretec DC-1007
sunplus 052b:1513 Megapix V4
sunplus 052b:1803 MegaImage VI
tv8532 0545:808b Veo Stingray
......@@ -151,6 +154,7 @@ sunplus 0546:3191 Polaroid Ion 80
sunplus 0546:3273 Polaroid PDC2030
ov519 054c:0154 Sonny toy4
ov519 054c:0155 Sonny toy5
cpia1 0553:0002 CPIA CPiA (version1) based cameras
zc3xx 055f:c005 Mustek Wcam300A
spca500 055f:c200 Mustek Gsmart 300
sunplus 055f:c211 Kowa Bs888e Microcamera
......@@ -188,8 +192,7 @@ spca500 06bd:0404 Agfa CL20
spca500 06be:0800 Optimedia
sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
spca506 06e1:a190 ADS Instant VCD
ov534 06f8:3002 Hercules Blog Webcam
ov534 06f8:3003 Hercules Dualpix HD Weblog
ov534_9 06f8:3003 Hercules Dualpix HD Weblog
sonixj 06f8:3004 Hercules Classic Silver
sonixj 06f8:3008 Hercules Deluxe Optical Glass
pac7302 06f8:3009 Hercules Classic Link
......@@ -204,6 +207,7 @@ sunplus 0733:2221 Mercury Digital Pro 3.1p
sunplus 0733:3261 Concord 3045 spca536a
sunplus 0733:3281 Cyberpix S550V
spca506 0734:043b 3DeMon USB Capture aka
cpia1 0813:0001 QX3 camera
ov519 0813:0002 Dual Mode USB Camera Plus
spca500 084d:0003 D-Link DSC-350
spca500 08ca:0103 Aiptek PocketDV
......@@ -225,7 +229,8 @@ sunplus 08ca:2050 Medion MD 41437
sunplus 08ca:2060 Aiptek PocketDV5300
tv8532 0923:010f ICM532 cams
mars 093a:050f Mars-Semi Pc-Camera
mr97310a 093a:010f Sakar Digital no. 77379
mr97310a 093a:010e All known CIF cams with this ID
mr97310a 093a:010f All known VGA cams with this ID
pac207 093a:2460 Qtec Webcam 100
pac207 093a:2461 HP Webcam
pac207 093a:2463 Philips SPC 220 NC
......@@ -302,6 +307,7 @@ sonixj 0c45:613b Surfer SN-206
sonixj 0c45:613c Sonix Pccam168
sonixj 0c45:6143 Sonix Pccam168
sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
sonixj 0c45:614a Frontech E-Ccam (JIL-2225)
sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001)
sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111)
sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655)
......@@ -324,6 +330,10 @@ sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112)
sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655)
sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660)
sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R)
sn9c2028 0c45:8001 Wild Planet Digital Spy Camera
sn9c2028 0c45:8003 Sakar #11199, #6637x, #67480 keychain cams
sn9c2028 0c45:8008 Mini-Shotz ms-350
sn9c2028 0c45:800a Vivitar Vivicam 3350B
sunplus 0d64:0303 Sunplus FashionCam DXG
ov519 0e96:c001 TRUST 380 USB2 SPACEC@M
etoms 102c:6151 Qcam Sangha CIF
......@@ -341,10 +351,11 @@ spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
pac207 2001:f115 D-Link DSB-C120
sq905c 2770:9050 sq905c
sq905c 2770:905c DualCamera
sq905 2770:9120 Argus Digital Camera DC1512
sq905c 2770:913d sq905c
sq905c 2770:9050 Disney pix micro (CIF)
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
sq905c 2770:913d All 4 known cameras with this ID
spca500 2899:012c Toptro Industrial
ov519 8020:ef04 ov519
spca508 8086:0110 Intel Easy PC Camera
......
......@@ -599,99 +599,13 @@ video_device::minor fields.
video buffer helper functions
-----------------------------
The v4l2 core API provides a standard method for dealing with video
buffers. Those methods allow a driver to implement read(), mmap() and
overlay() on a consistent way.
There are currently methods for using video buffers on devices that
supports DMA with scatter/gather method (videobuf-dma-sg), DMA with
linear access (videobuf-dma-contig), and vmalloced buffers, mostly
used on USB drivers (videobuf-vmalloc).
Any driver using videobuf should provide operations (callbacks) for
four handlers:
ops->buf_setup - calculates the size of the video buffers and avoid they
to waste more than some maximum limit of RAM;
ops->buf_prepare - fills the video buffer structs and calls
videobuf_iolock() to alloc and prepare mmaped memory;
ops->buf_queue - advices the driver that another buffer were
requested (by read() or by QBUF);
ops->buf_release - frees any buffer that were allocated.
In order to use it, the driver need to have a code (generally called at
interrupt context) that will properly handle the buffer request lists,
announcing that a new buffer were filled.
The irq handling code should handle the videobuf task lists, in order
to advice videobuf that a new frame were filled, in order to honor to a
request. The code is generally like this one:
if (list_empty(&dma_q->active))
return;
buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue);
if (!waitqueue_active(&buf->vb.done))
return;
/* Some logic to handle the buf may be needed here */
list_del(&buf->vb.queue);
do_gettimeofday(&buf->vb.ts);
wake_up(&buf->vb.done);
Those are the videobuffer functions used on drivers, implemented on
videobuf-core:
- Videobuf init functions
videobuf_queue_sg_init()
Initializes the videobuf infrastructure. This function should be
called before any other videobuf function on drivers that uses DMA
Scatter/Gather buffers.
videobuf_queue_dma_contig_init
Initializes the videobuf infrastructure. This function should be
called before any other videobuf function on drivers that need DMA
contiguous buffers.
videobuf_queue_vmalloc_init()
Initializes the videobuf infrastructure. This function should be
called before any other videobuf function on USB (and other drivers)
that need a vmalloced type of videobuf.
- videobuf_iolock()
Prepares the videobuf memory for the proper method (read, mmap, overlay).
- videobuf_queue_is_busy()
Checks if a videobuf is streaming.
- videobuf_queue_cancel()
Stops video handling.
- videobuf_mmap_free()
frees mmap buffers.
- videobuf_stop()
Stops video handling, ends mmap and frees mmap and other buffers.
- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls:
videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(),
videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff().
- V4L1 api function (corresponds to VIDIOCMBUF ioctl):
videobuf_cgmbuf()
This function is used to provide backward compatibility with V4L1
API.
- Some help functions for read()/poll() operations:
videobuf_read_stream()
For continuous stream read()
videobuf_read_one()
For snapshot read()
videobuf_poll_stream()
polling help function
The better way to understand it is to take a look at vivi driver. One
of the main reasons for vivi is to be a videobuf usage example. the
vivi_thread_tick() does the task that the IRQ callback would do on PCI
drivers (or the irq callback on USB).
The v4l2 core API provides a set of standard methods (called "videobuf")
for dealing with video buffers. Those methods allow a driver to implement
read(), mmap() and overlay() in a consistent way. There are currently
methods for using video buffers on devices that supports DMA with
scatter/gather method (videobuf-dma-sg), DMA with linear access
(videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers
(videobuf-vmalloc).
Please see Documentation/video4linux/videobuf for more information on how
to use the videobuf layer.
This diff is collapsed.
......@@ -4693,6 +4693,13 @@ F: drivers/media/common/saa7146*
F: drivers/media/video/*7146*
F: include/media/*7146*
TLG2300 VIDEO4LINUX-2 DRIVER
M: Huang Shijie <shijie8@gmail.com>
M: Kang Yong <kangyong@telegent.com>
M: Zhang Xiaobing <xbzhang@telegent.com>
S: Supported
F: drivers/media/video/tlg2300
SC1200 WDT DRIVER
M: Zwane Mwaikambo <zwane@arm.linux.org.uk>
S: Maintained
......
......@@ -37,6 +37,8 @@
#include <mach/nand.h>
#include <mach/keyscan.h>
#include <media/tvp514x.h>
static inline int have_imager(void)
{
/* REVISIT when it's supported, trigger via Kconfig */
......@@ -306,6 +308,73 @@ static void dm365evm_mmc_configure(void)
davinci_cfg_reg(DM365_SD1_DATA0);
}
static struct tvp514x_platform_data tvp5146_pdata = {
.clk_polarity = 0,
.hs_polarity = 1,
.vs_polarity = 1
};
#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/* Inputs available at the TVP5146 */
static struct v4l2_input tvp5146_inputs[] = {
{
.index = 0,
.name = "Composite",
.type = V4L2_INPUT_TYPE_CAMERA,
.std = TVP514X_STD_ALL,
},
{
.index = 1,
.name = "S-Video",
.type = V4L2_INPUT_TYPE_CAMERA,
.std = TVP514X_STD_ALL,
},
};
/*
* this is the route info for connecting each input to decoder
* ouput that goes to vpfe. There is a one to one correspondence
* with tvp5146_inputs
*/
static struct vpfe_route tvp5146_routes[] = {
{
.input = INPUT_CVBS_VI2B,
.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
{
.input = INPUT_SVIDEO_VI2C_VI1C,
.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
};
static struct vpfe_subdev_info vpfe_sub_devs[] = {
{
.name = "tvp5146",
.grp_id = 0,
.num_inputs = ARRAY_SIZE(tvp5146_inputs),
.inputs = tvp5146_inputs,
.routes = tvp5146_routes,
.can_route = 1,
.ccdc_if_params = {
.if_type = VPFE_BT656,
.hdpol = VPFE_PINPOL_POSITIVE,
.vdpol = VPFE_PINPOL_POSITIVE,
},
.board_info = {
I2C_BOARD_INFO("tvp5146", 0x5d),
.platform_data = &tvp5146_pdata,
},
},
};
static struct vpfe_config vpfe_cfg = {
.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
.sub_devs = vpfe_sub_devs,
.i2c_adapter_id = 1,
.card_name = "DM365 EVM",
.ccdc = "ISIF",
};
static void __init evm_init_i2c(void)
{
davinci_init_i2c(&i2c_pdata);
......@@ -497,6 +566,8 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init dm365_evm_map_io(void)
{
/* setup input configuration for VPFE input devices */
dm365_set_vpfe_config(&vpfe_cfg);
dm365_init();
}
......
......@@ -125,7 +125,6 @@ static struct clk vpss_slave_clk = {
.lpsc = DAVINCI_LPSC_VPSSSLV,
};
static struct clk clkout1_clk = {
.name = "clkout1",
.parent = &pll1_aux_clk,
......@@ -665,6 +664,17 @@ static struct platform_device dm355_asp1_device = {
.resource = dm355_asp1_resources,
};
static void dm355_ccdc_setup_pinmux(void)
{
davinci_cfg_reg(DM355_VIN_PCLK);
davinci_cfg_reg(DM355_VIN_CAM_WEN);
davinci_cfg_reg(DM355_VIN_CAM_VD);
davinci_cfg_reg(DM355_VIN_CAM_HD);
davinci_cfg_reg(DM355_VIN_YIN_EN);
davinci_cfg_reg(DM355_VIN_CINL_EN);
davinci_cfg_reg(DM355_VIN_CINH_EN);
}
static struct resource dm355_vpss_resources[] = {
{
/* VPSS BL Base address */
......@@ -701,6 +711,10 @@ static struct resource vpfe_resources[] = {
.end = IRQ_VDINT1,
.flags = IORESOURCE_IRQ,
},
};
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
static struct resource dm355_ccdc_resource[] = {
/* CCDC Base address */
{
.flags = IORESOURCE_MEM,
......@@ -708,8 +722,18 @@ static struct resource vpfe_resources[] = {
.end = 0x01c70600 + 0x1ff,
},
};
static struct platform_device dm355_ccdc_dev = {
.name = "dm355_ccdc",
.id = -1,
.num_resources = ARRAY_SIZE(dm355_ccdc_resource),
.resource = dm355_ccdc_resource,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = dm355_ccdc_setup_pinmux,
},
};
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
static struct platform_device vpfe_capture_dev = {
.name = CAPTURE_DRV_NAME,
.id = -1,
......@@ -857,20 +881,13 @@ static int __init dm355_init_devices(void)
if (!cpu_is_davinci_dm355())
return 0;
/* Add ccdc clock aliases */
clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
davinci_cfg_reg(DM355_INT_EDMA_CC);
platform_device_register(&dm355_edma_device);
platform_device_register(&dm355_vpss_device);
/*
* setup Mux configuration for vpfe input and register
* vpfe capture platform device
*/
davinci_cfg_reg(DM355_VIN_PCLK);
davinci_cfg_reg(DM355_VIN_CAM_WEN);
davinci_cfg_reg(DM355_VIN_CAM_VD);
davinci_cfg_reg(DM355_VIN_CAM_HD);
davinci_cfg_reg(DM355_VIN_YIN_EN);
davinci_cfg_reg(DM355_VIN_CINL_EN);
davinci_cfg_reg(DM355_VIN_CINH_EN);
platform_device_register(&dm355_ccdc_dev);
platform_device_register(&vpfe_capture_dev);
return 0;
......
......@@ -1008,6 +1008,97 @@ void __init dm365_init(void)
davinci_common_init(&davinci_soc_info_dm365);
}
static struct resource dm365_vpss_resources[] = {
{
/* VPSS ISP5 Base address */
.name = "isp5",
.start = 0x01c70000,
.end = 0x01c70000 + 0xff,
.flags = IORESOURCE_MEM,
},
{
/* VPSS CLK Base address */
.name = "vpss",
.start = 0x01c70200,
.end = 0x01c70200 + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dm365_vpss_device = {
.name = "vpss",
.id = -1,
.dev.platform_data = "dm365_vpss",
.num_resources = ARRAY_SIZE(dm365_vpss_resources),
.resource = dm365_vpss_resources,
};
static struct resource vpfe_resources[] = {
{
.start = IRQ_VDINT0,
.end = IRQ_VDINT0,
.flags = IORESOURCE_IRQ,
},
{
.start = IRQ_VDINT1,
.end = IRQ_VDINT1,
.flags = IORESOURCE_IRQ,
},
};
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
static struct platform_device vpfe_capture_dev = {
.name = CAPTURE_DRV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(vpfe_resources),
.resource = vpfe_resources,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static void dm365_isif_setup_pinmux(void)
{
davinci_cfg_reg(DM365_VIN_CAM_WEN);
davinci_cfg_reg(DM365_VIN_CAM_VD);
davinci_cfg_reg(DM365_VIN_CAM_HD);
davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
}
static struct resource isif_resource[] = {
/* ISIF Base address */
{
.start = 0x01c71000,
.end = 0x01c71000 + 0x1ff,
.flags = IORESOURCE_MEM,
},
/* ISIF Linearization table 0 */
{
.start = 0x1C7C000,
.end = 0x1C7C000 + 0x2ff,
.flags = IORESOURCE_MEM,
},
/* ISIF Linearization table 1 */
{
.start = 0x1C7C400,
.end = 0x1C7C400 + 0x2ff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dm365_isif_dev = {
.name = "isif",
.id = -1,
.num_resources = ARRAY_SIZE(isif_resource),
.resource = isif_resource,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = dm365_isif_setup_pinmux,
},
};
static int __init dm365_init_devices(void)
{
if (!cpu_is_davinci_dm365())
......@@ -1016,7 +1107,16 @@ static int __init dm365_init_devices(void)
davinci_cfg_reg(DM365_INT_EDMA_CC);
platform_device_register(&dm365_edma_device);
platform_device_register(&dm365_emac_device);
/* Add isif clock alias */
clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
platform_device_register(&dm365_vpss_device);
platform_device_register(&dm365_isif_dev);
platform_device_register(&vpfe_capture_dev);
return 0;
}
postcore_initcall(dm365_init_devices);
void dm365_set_vpfe_config(struct vpfe_config *cfg)
{
vpfe_capture_dev.dev.platform_data = cfg;
}
......@@ -612,6 +612,11 @@ static struct resource vpfe_resources[] = {
.end = IRQ_VDINT1,
.flags = IORESOURCE_IRQ,
},
};
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
static struct resource dm644x_ccdc_resource[] = {
/* CCDC Base address */
{
.start = 0x01c70400,
.end = 0x01c70400 + 0xff,
......@@ -619,7 +624,17 @@ static struct resource vpfe_resources[] = {
},
};
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
static struct platform_device dm644x_ccdc_dev = {
.name = "dm644x_ccdc",
.id = -1,
.num_resources = ARRAY_SIZE(dm644x_ccdc_resource),
.resource = dm644x_ccdc_resource,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct platform_device vpfe_capture_dev = {
.name = CAPTURE_DRV_NAME,
.id = -1,
......@@ -769,9 +784,13 @@ static int __init dm644x_init_devices(void)
if (!cpu_is_davinci_dm644x())
return 0;
/* Add ccdc clock aliases */
clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
platform_device_register(&dm644x_edma_device);
platform_device_register(&dm644x_emac_device);
platform_device_register(&dm644x_vpss_device);
platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&vpfe_capture_dev);
return 0;
......
......@@ -18,6 +18,7 @@
#include <mach/emac.h>
#include <mach/asp.h>
#include <mach/keyscan.h>
#include <media/davinci/vpfe_capture.h>
#define DM365_EMAC_BASE (0x01D07000)
#define DM365_EMAC_CNTRL_OFFSET (0x0000)
......@@ -36,4 +37,5 @@ void __init dm365_init_asp(struct snd_platform_data *pdata);
void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
void __init dm365_init_rtc(void);
void dm365_set_vpfe_config(struct vpfe_config *cfg);
#endif /* __ASM_ARCH_DM365_H */
......@@ -35,8 +35,6 @@
#define PXA_CAMERA_VSP 0x400
struct pxacamera_platform_data {
int (*init)(struct device *);
unsigned long flags;
unsigned long mclk_10khz;
};
......
......@@ -471,8 +471,8 @@ static struct i2c_board_info ap325rxa_i2c_camera[] = {
};
static struct ov772x_camera_info ov7725_info = {
.buswidth = SOCAM_DATAWIDTH_8,
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \
OV772X_FLAG_8BIT,
.edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
};
......
......@@ -431,7 +431,7 @@ static struct i2c_board_info migor_i2c_camera[] = {
};
static struct ov772x_camera_info ov7725_info = {
.buswidth = SOCAM_DATAWIDTH_8,
.flags = OV772X_FLAG_8BIT,
};
static struct soc_camera_link ov7725_link = {
......
ir-common-objs := ir-functions.o ir-keymaps.o
ir-core-objs := ir-keytable.o
ir-core-objs := ir-keytable.o ir-sysfs.o
obj-$(CONFIG_IR_CORE) += ir-core.o
obj-$(CONFIG_VIDEO_IR) += ir-common.o
......@@ -52,7 +52,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
/* -------------------------------------------------------------------------- */
int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
int ir_type)
const u64 ir_type)
{
ir->ir_type = ir_type;
......
......@@ -3393,3 +3393,102 @@ struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
};
EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
/* Leadtek Winfast TV USB II Deluxe remote
Magnus Alm <magnus.alm@gmail.com>
*/
static struct ir_scancode ir_codes_winfast_usbii_deluxe[] = {
{ 0x62, KEY_0},
{ 0x75, KEY_1},
{ 0x76, KEY_2},
{ 0x77, KEY_3},
{ 0x79, KEY_4},
{ 0x7a, KEY_5},
{ 0x7b, KEY_6},
{ 0x7d, KEY_7},
{ 0x7e, KEY_8},
{ 0x7f, KEY_9},
{ 0x38, KEY_CAMERA}, /* SNAPSHOT */
{ 0x37, KEY_RECORD}, /* RECORD */
{ 0x35, KEY_TIME}, /* TIMESHIFT */
{ 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
{ 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
{ 0x64, KEY_MUTE}, /* MUTE */
{ 0x21, KEY_CHANNEL}, /* SURF */
{ 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
{ 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
{ 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
{ 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
{ 0x70, KEY_POWER2}, /* TV ON/OFF */
{ 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
{ 0x3a, KEY_NEW}, /* PIP */
{ 0x73, KEY_ZOOM}, /* FULLSECREEN */
{ 0x66, KEY_INFO}, /* OSD (DISPLAY) */
{ 0x31, KEY_DOT}, /* '.' */
{ 0x63, KEY_ENTER}, /* ENTER */
};
struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table = {
.scan = ir_codes_winfast_usbii_deluxe,
.size = ARRAY_SIZE(ir_codes_winfast_usbii_deluxe),
};
EXPORT_SYMBOL_GPL(ir_codes_winfast_usbii_deluxe_table);
/* Kworld 315U
*/
static struct ir_scancode ir_codes_kworld_315u[] = {
{ 0x6143, KEY_POWER },
{ 0x6101, KEY_TUNER }, /* source */
{ 0x610b, KEY_ZOOM },
{ 0x6103, KEY_POWER2 }, /* shutdown */
{ 0x6104, KEY_1 },
{ 0x6108, KEY_2 },
{ 0x6102, KEY_3 },
{ 0x6109, KEY_CHANNELUP },
{ 0x610f, KEY_4 },
{ 0x6105, KEY_5 },
{ 0x6106, KEY_6 },
{ 0x6107, KEY_CHANNELDOWN },
{ 0x610c, KEY_7 },
{ 0x610d, KEY_8 },
{ 0x610a, KEY_9 },
{ 0x610e, KEY_VOLUMEUP },
{ 0x6110, KEY_LAST },
{ 0x6111, KEY_0 },
{ 0x6112, KEY_ENTER },
{ 0x6113, KEY_VOLUMEDOWN },
{ 0x6114, KEY_RECORD },
{ 0x6115, KEY_STOP },
{ 0x6116, KEY_PLAY },
{ 0x6117, KEY_MUTE },
{ 0x6118, KEY_UP },
{ 0x6119, KEY_DOWN },
{ 0x611a, KEY_LEFT },
{ 0x611b, KEY_RIGHT },
{ 0x611c, KEY_RED },
{ 0x611d, KEY_GREEN },
{ 0x611e, KEY_YELLOW },
{ 0x611f, KEY_BLUE },
};
struct ir_scancode_table ir_codes_kworld_315u_table = {
.scan = ir_codes_kworld_315u,
.size = ARRAY_SIZE(ir_codes_kworld_315u),
.ir_type = IR_TYPE_NEC,
};
EXPORT_SYMBOL_GPL(ir_codes_kworld_315u_table);
......@@ -65,7 +65,7 @@ static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
* In order to reduce the quantity of table resizes, it has a minimum
* table size of IR_TAB_MIN_SIZE.
*/
int ir_roundup_tablesize(int n_elems)
static int ir_roundup_tablesize(int n_elems)
{
size_t size;
......@@ -81,7 +81,6 @@ int ir_roundup_tablesize(int n_elems)
return n_elems;
}
EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
/**
* ir_copy_table() - copies a keytable, discarding the unused entries
......@@ -89,9 +88,11 @@ EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
* @origin: origin table
*
* Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
* Also copies table size and table protocol.
* NOTE: It shouldn't copy the lock field
*/
int ir_copy_table(struct ir_scancode_table *destin,
static int ir_copy_table(struct ir_scancode_table *destin,
const struct ir_scancode_table *origin)
{
int i, j = 0;
......@@ -105,12 +106,12 @@ int ir_copy_table(struct ir_scancode_table *destin,
j++;
}
destin->size = j;
destin->ir_type = origin->ir_type;
IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
return 0;
}
EXPORT_SYMBOL_GPL(ir_copy_table);
/**
* ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
......@@ -184,18 +185,14 @@ static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
int newsize = rc_tab->size - 1;
int resize = ir_is_resize_needed(rc_tab, newsize);
struct ir_scancode *oldkeymap = rc_tab->scan;
struct ir_scancode *newkeymap;
struct ir_scancode *newkeymap = NULL;
if (resize) {
if (resize)
newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
sizeof(*newkeymap), GFP_ATOMIC);
/* There's no memory for resize. Keep the old table */
if (!newkeymap)
resize = 0;
}
if (!resize) {
if (!resize || !newkeymap) {
newkeymap = oldkeymap;
/* We'll modify the live table. Lock it */
......@@ -399,12 +396,14 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
* @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 should be called before registering the IR device.
* 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,
struct ir_scancode_table *rc_tab)
const struct ir_scancode_table *rc_tab,
const struct ir_dev_props *props)
{
struct ir_input_dev *ir_dev;
struct ir_scancode *keymap = rc_tab->scan;
......@@ -417,19 +416,22 @@ int ir_input_register(struct input_dev *input_dev,
if (!ir_dev)
return -ENOMEM;
spin_lock_init(&rc_tab->lock);
spin_lock_init(&ir_dev->rc_tab.lock);
ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
sizeof(struct ir_scancode), GFP_KERNEL);
if (!ir_dev->rc_tab.scan)
if (!ir_dev->rc_tab.scan) {
kfree(ir_dev);
return -ENOMEM;
}
IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
ir_dev->rc_tab.size,
ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
ir_copy_table(&ir_dev->rc_tab, rc_tab);
ir_dev->props = props;
/* set the bits for the keys */
IR_dprintk(1, "key map size: %d\n", rc_tab->size);
......@@ -447,16 +449,31 @@ int ir_input_register(struct input_dev *input_dev,
input_set_drvdata(input_dev, ir_dev);
rc = input_register_device(input_dev);
if (rc < 0)
goto err;
rc = ir_register_class(input_dev);
if (rc < 0) {
input_unregister_device(input_dev);
goto err;
}
return 0;
err:
kfree(rc_tab->scan);
kfree(ir_dev);
input_set_drvdata(input_dev, NULL);
}
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 *dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
......@@ -472,6 +489,8 @@ void ir_input_unregister(struct input_dev *dev)
kfree(rc_tab->scan);
rc_tab->scan = NULL;
ir_unregister_class(dev);
kfree(ir_dev);
input_unregister_device(dev);
}
......
/* ir-register.c - handle IR scancode->keycode tables
*
* Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/input.h>
#include <linux/device.h>
#include <media/ir-core.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/irrcv */
static struct class *ir_input_class;
/**
* show_protocol() - shows the current IR protocol
* @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.
* it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol.
* It returns the protocol name, as understood by the driver.
*/
static ssize_t show_protocol(struct device *d,
struct device_attribute *mattr, char *buf)
{
char *s;
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
u64 ir_type = ir_dev->rc_tab.ir_type;
IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
/* FIXME: doesn't support multiple protocols at the same time */
if (ir_type == IR_TYPE_UNKNOWN)
s = "Unknown";
else if (ir_type == IR_TYPE_RC5)
s = "RC-5";
else if (ir_type == IR_TYPE_PD)
s = "Pulse/distance";
else if (ir_type == IR_TYPE_NEC)
s = "NEC";
else
s = "Other";
return sprintf(buf, "%s\n", s);
}
/**
* store_protocol() - shows the current IR protocol
* @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 reading /sys/class/irrcv/irrcv?/current_protocol.
* It changes the IR the protocol name, if the IR type is recognized
* by the driver.
* If an unknown protocol name is used, returns -EINVAL.
*/
static ssize_t store_protocol(struct device *d,
struct device_attribute *mattr,
const char *data,
size_t len)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
u64 ir_type = IR_TYPE_UNKNOWN;
int rc = -EINVAL;
unsigned long flags;
char *buf;
buf = strsep((char **) &data, "\n");
if (!strcasecmp(buf, "rc-5"))
ir_type = IR_TYPE_RC5;
else if (!strcasecmp(buf, "pd"))
ir_type = IR_TYPE_PD;
else if (!strcasecmp(buf, "nec"))
ir_type = IR_TYPE_NEC;
if (ir_type == IR_TYPE_UNKNOWN) {
IR_dprintk(1, "Error setting protocol to %lld\n",
(long long)ir_type);
return -EINVAL;
}
if (ir_dev->props && ir_dev->props->change_protocol)
rc = ir_dev->props->change_protocol(ir_dev->props->priv,
ir_type);
if (rc < 0) {
IR_dprintk(1, "Error setting protocol to %lld\n",
(long long)ir_type);
return -EINVAL;
}
spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
ir_dev->rc_tab.ir_type = ir_type;
spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
IR_dprintk(1, "Current protocol is %lld\n",
(long long)ir_type);
return len;
}
/*
* Static device attribute struct with the sysfs attributes for IR's
*/
static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR,
show_protocol, store_protocol);
static struct attribute *ir_dev_attrs[] = {
&dev_attr_current_protocol.attr,
NULL,
};
/**
* ir_register_class() - creates the sysfs for /sys/class/irrcv/irrcv?
* @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)
{
int rc;
struct kobject *kobj;
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->attr.attrs = ir_dev_attrs;
ir_dev->class_dev = device_create(ir_input_class, NULL,
input_dev->dev.devt, ir_dev,
"irrcv%d", devno);
kobj = &ir_dev->class_dev->kobj;
printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj));
rc = sysfs_create_group(kobj, &ir_dev->attr);
if (unlikely(rc < 0)) {
device_destroy(ir_input_class, input_dev->dev.devt);
return -ENOMEM;
}
ir_dev->devno = devno;
set_bit(devno, &ir_core_dev_number);
return 0;
};
/**
* ir_unregister_class() - removes the sysfs for sysfs for
* /sys/class/irrcv/irrcv?
* @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);
struct kobject *kobj;
clear_bit(ir_dev->devno, &ir_core_dev_number);
kobj = &ir_dev->class_dev->kobj;
sysfs_remove_group(kobj, &ir_dev->attr);
device_destroy(ir_input_class, input_dev->dev.devt);
kfree(ir_dev->attr.name);
}
/*
* Init/exit code for the module. Basically, creates/removes /sys/class/irrcv
*/
static int __init ir_core_init(void)
{
ir_input_class = class_create(THIS_MODULE, "irrcv");
if (IS_ERR(ir_input_class)) {
printk(KERN_ERR "ir_core: unable to register irrcv class\n");
return PTR_ERR(ir_input_class);
}
return 0;
}
static void __exit ir_core_exit(void)
{
class_destroy(ir_input_class);
}
module_init(ir_core_init);
module_exit(ir_core_exit);
......@@ -423,14 +423,15 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
}
}
int saa7146_vv_devinit(struct saa7146_dev *dev)
{
return v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
}
EXPORT_SYMBOL_GPL(saa7146_vv_devinit);
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
struct saa7146_vv *vv;
int err;
err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
if (err)
return err;
vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
if (vv == NULL) {
......
......@@ -1337,6 +1337,22 @@ static struct tuner_params tuner_philips_cu1216l_params[] = {
},
};
/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
{ 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
{ 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
{ 16 * 999.99 , 0x8e, 0x04, },
};
static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
{
.type = TUNER_PARAM_TYPE_NTSC,
.ranges = tuner_sony_btf_pxn01z_ranges,
.count = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
},
};
/* --------------------------------------------------------------------- */
struct tunertype tuners[] = {
......@@ -1805,6 +1821,11 @@ struct tunertype tuners[] = {
.name = "NXP TDA18271",
/* see tda18271-fe.c for details */
},
[TUNER_SONY_BTF_PXN01Z] = {
.name = "Sony BTF-Pxn01Z",
.params = tuner_sony_btf_pxn01z_params,
.count = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
},
};
EXPORT_SYMBOL(tuners);
......
......@@ -917,30 +917,68 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
* that xc2028 will be in a safe state.
* Maybe this might also be needed for DTV.
*/
if (new_mode == T_ANALOG_TV)
if (new_mode == T_ANALOG_TV) {
rc = send_seq(priv, {0x00, 0x00});
/* Analog modes require offset = 0 */
} else {
/*
* Digital modes require an offset to adjust to the
* proper frequency.
* Analog modes require offset = 0
* proper frequency. The offset depends on what
* firmware version is used.
*/
/*
* Adjust to the center frequency. This is calculated by the
* formula: offset = 1.25MHz - BW/2
* For DTV 7/8, the firmware uses BW = 8000, so it needs a
* further adjustment to get the frequency center on VHF
*/
if (new_mode == T_DIGITAL_TV) {
/* Sets the offset according with firmware */
if (priv->cur_fw.type & DTV6)
offset = 1750000;
else if (priv->cur_fw.type & DTV7)
offset = 2250000;
else /* DTV8 or DTV78 */
offset = 2750000;
if ((priv->cur_fw.type & DTV78) && freq < 470000000)
offset -= 500000;
/*
* We must adjust the offset by 500kHz when
* tuning a 7MHz VHF channel with DTV78 firmware
* (used in Australia, Italy and Germany)
* xc3028 additional "magic"
* Depending on the firmware version, it needs some adjustments
* to properly centralize the frequency. This seems to be
* needed to compensate the SCODE table adjustments made by
* newer firmwares
*/
if ((priv->cur_fw.type & DTV78) && freq < 470000000)
offset -= 500000;
#if 1
/*
* The proper adjustment would be to do it at s-code table.
* However, this didn't work, as reported by
* Robert Lowery <rglowery@exemail.com.au>
*/
if (priv->cur_fw.type & DTV7)
offset += 500000;
#else
/*
* Still need tests for XC3028L (firmware 3.2 or upper)
* So, for now, let's just comment the per-firmware
* version of this change. Reports with xc3028l working
* with and without the lines bellow are welcome
*/
if (priv->firm_version < 0x0302) {
if (priv->cur_fw.type & DTV7)
offset += 500000;
} else {
if (priv->cur_fw.type & DTV7)
offset -= 300000;
else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
offset += 200000;
}
#endif
}
div = (freq - offset + DIV / 2) / DIV;
......@@ -1097,17 +1135,24 @@ static int xc2028_set_params(struct dvb_frontend *fe,
/* All S-code tables need a 200kHz shift */
if (priv->ctrl.demod) {
demod = priv->ctrl.demod + 200;
demod = priv->ctrl.demod;
/*
* Newer firmwares require a 200 kHz offset only for ATSC
*/
if (type == ATSC || priv->firm_version < 0x0302)
demod += 200;
/*
* The DTV7 S-code table needs a 700 kHz shift.
* Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
*
* DTV7 is only used in Australia. Germany or Italy may also
* use this firmware after initialization, but a tune to a UHF
* channel should then cause DTV78 to be used.
*
* Unfortunately, on real-field tests, the s-code offset
* didn't work as expected, as reported by
* Robert Lowery <rglowery@exemail.com.au>
*/
if (type & DTV7)
demod += 500;
}
return generic_set_freq(fe, p->frequency,
......
......@@ -76,6 +76,10 @@ comment "Supported Mantis Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/mantis/Kconfig"
comment "Supported nGene Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/ngene/Kconfig"
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
......
......@@ -14,6 +14,7 @@ obj-y := dvb-core/ \
siano/ \
dm1105/ \
pt1/ \
mantis/
mantis/ \
ngene/
obj-$(CONFIG_DVB_FIREDTV) += firewire/
......@@ -576,43 +576,30 @@ static struct pci_driver bt878_pci_driver = {
.remove = __devexit_p(bt878_remove),
};
static int bt878_pci_driver_registered;
/*******************************/
/* Module management functions */
/*******************************/
static int bt878_init_module(void)
static int __init bt878_init_module(void)
{
bt878_num = 0;
bt878_pci_driver_registered = 0;
printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
(BT878_VERSION_CODE >> 16) & 0xff,
(BT878_VERSION_CODE >> 8) & 0xff,
BT878_VERSION_CODE & 0xff);
/*
bt878_check_chipset();
*/
/* later we register inside of bt878_find_audio_dma()
* because we may want to ignore certain cards */
bt878_pci_driver_registered = 1;
return pci_register_driver(&bt878_pci_driver);
}
static void bt878_cleanup_module(void)
static void __exit bt878_cleanup_module(void)
{
if (bt878_pci_driver_registered) {
bt878_pci_driver_registered = 0;
pci_unregister_driver(&bt878_pci_driver);
}
return;
}
module_init(bt878_init_module);
module_exit(bt878_cleanup_module);
//MODULE_AUTHOR("XXX");
MODULE_LICENSE("GPL");
/*
......
......@@ -1352,7 +1352,6 @@ static int dst_get_tuna(struct dst_state *state)
return retval;
}
if ((state->type_flags & DST_TYPE_HAS_VLF) &&
!(state->dst_type == DST_TYPE_IS_CABLE) &&
!(state->dst_type == DST_TYPE_IS_ATSC)) {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
......@@ -1820,8 +1819,13 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
.frequency_max = 858000000,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
/* . symbol_rate_tolerance = ???,*/
.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
.caps = FE_CAN_FEC_AUTO |
FE_CAN_QAM_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256
},
.release = dst_release,
......
......@@ -8,6 +8,7 @@ config DVB_DM1105
select DVB_STB6000 if !DVB_FE_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_DS3000 if !DVB_FE_CUSTOMISE
select VIDEO_IR
help
Support for cards based on the SDMC DM1105 PCI chip like
......
This diff is collapsed.
......@@ -1199,8 +1199,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
{
int r = 0;
dtv_property_dump(tvp);
/* Allow the frontend to validate incoming properties */
if (fe->ops.get_property)
r = fe->ops.get_property(fe, tvp);
......@@ -1323,6 +1321,8 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
r = -1;
}
dtv_property_dump(tvp);
return r;
}
......@@ -1488,7 +1488,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int err = -EOPNOTSUPP;
dprintk ("%s\n", __func__);
dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
if (fepriv->exit)
return -ENODEV;
......@@ -1536,8 +1536,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
tvp = (struct dtv_property *) kmalloc(tvps->num *
sizeof(struct dtv_property), GFP_KERNEL);
tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
if (!tvp) {
err = -ENOMEM;
goto out;
......@@ -1569,8 +1568,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
tvp = (struct dtv_property *) kmalloc(tvps->num *
sizeof(struct dtv_property), GFP_KERNEL);
tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
if (!tvp) {
err = -ENOMEM;
goto out;
......
......@@ -89,6 +89,7 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
rbuf->pread = rbuf->pwrite;
rbuf->error = 0;
}
EXPORT_SYMBOL(dvb_ringbuffer_flush);
void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
{
......
......@@ -336,3 +336,11 @@ config DVB_USB_EC168
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
config DVB_USB_AZ6027
tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
depends on DVB_USB
select DVB_STB0899 if !DVB_FE_CUSTOMISE
select DVB_STB6100 if !DVB_FE_CUSTOMISE
help
Say Y here to support the AZ6027 device
......@@ -85,6 +85,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
dvb-usb-ec168-objs = ec168.o
obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
dvb-usb-az6027-objs = az6027.o
obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
......
This diff is collapsed.
......@@ -107,6 +107,7 @@ struct af9015_config {
u16 mt2060_if1[2];
u16 firmware_size;
u16 firmware_checksum;
u32 eeprom_sum;
u8 *ir_table;
u16 ir_table_size;
};
......
This diff is collapsed.
#ifndef _DVB_USB_VP6027_H_
#define _DVB_USB_VP6027_H_
#define DVB_USB_LOG_PREFIX "az6027"
#include "dvb-usb.h"
extern int dvb_usb_az6027_debug;
#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
#define deb_rc(args...) dprintk(dvb_usb_az6027_debug, 0x04, args)
#define deb_fe(args...) dprintk(dvb_usb_az6027_debug, 0x08, args)
#endif
......@@ -1184,6 +1184,9 @@ static struct atbm8830_config mygica_d689_atbm8830_cfg = {
.osc_clk_freq = 30400, /* in kHz */
.if_freq = 0, /* zero IF */
.zif_swap_iq = 1,
.agc_min = 0x2E,
.agc_max = 0x90,
.agc_hold_loop = 0,
};
static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
......
......@@ -42,7 +42,6 @@ struct dib0700_state {
u16 mt2060_if1[2];
u8 rc_toggle;
u8 rc_counter;
u8 rc_func_version;
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
......
......@@ -471,14 +471,209 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4);
}
/* Number of keypresses to ignore before start repeating */
#define RC_REPEAT_DELAY_V1_20 10
/* This is the structure of the RC response packet starting in firmware 1.20 */
struct dib0700_rc_response {
u8 report_id;
u8 data_state;
u16 system;
u8 data;
u8 not_data;
};
#define RC_MSG_SIZE_V1_20 6
static void dib0700_rc_urb_completion(struct urb *purb)
{
struct dvb_usb_device *d = purb->context;
struct dvb_usb_rc_key *keymap;
struct dib0700_state *st;
struct dib0700_rc_response poll_reply;
u8 *buf;
int found = 0;
u32 event;
int state;
int i;
deb_info("%s()\n", __func__);
if (d == NULL)
return;
if (d->rc_input_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
usb_free_urb(purb);
return;
}
keymap = d->props.rc_key_map;
st = d->priv;
buf = (u8 *)purb->transfer_buffer;
if (purb->status < 0) {
deb_info("discontinuing polling\n");
usb_free_urb(purb);
return;
}
if (purb->actual_length != RC_MSG_SIZE_V1_20) {
deb_info("malformed rc msg size=%d\n", purb->actual_length);
goto resubmit;
}
/* Set initial results in case we exit the function early */
event = 0;
state = REMOTE_NO_KEY_PRESSED;
deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0],
buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length);
switch (dvb_usb_dib0700_ir_proto) {
case 0:
/* NEC Protocol */
poll_reply.report_id = 0;
poll_reply.data_state = 1;
poll_reply.system = buf[2];
poll_reply.data = buf[4];
poll_reply.not_data = buf[5];
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
&& (poll_reply.not_data == 0xff)) {
poll_reply.data_state = 2;
break;
}
break;
default:
/* RC5 Protocol */
poll_reply.report_id = buf[0];
poll_reply.data_state = buf[1];
poll_reply.system = (buf[2] << 8) | buf[3];
poll_reply.data = buf[4];
poll_reply.not_data = buf[5];
break;
}
if ((poll_reply.data + poll_reply.not_data) != 0xff) {
/* Key failed integrity check */
err("key failed integrity check: %04x %02x %02x",
poll_reply.system,
poll_reply.data, poll_reply.not_data);
goto resubmit;
}
deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n",
poll_reply.report_id, poll_reply.data_state,
poll_reply.system, poll_reply.data, poll_reply.not_data);
/* Find the key in the map */
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
rc5_data(&keymap[i]) == poll_reply.data) {
event = keymap[i].event;
found = 1;
break;
}
}
if (found == 0) {
err("Unknown remote controller key: %04x %02x %02x",
poll_reply.system, poll_reply.data, poll_reply.not_data);
d->last_event = 0;
goto resubmit;
}
if (poll_reply.data_state == 1) {
/* New key hit */
st->rc_counter = 0;
event = keymap[i].event;
state = REMOTE_KEY_PRESSED;
d->last_event = keymap[i].event;
} else if (poll_reply.data_state == 2) {
/* Key repeated */
st->rc_counter++;
/* prevents unwanted double hits */
if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
event = d->last_event;
state = REMOTE_KEY_PRESSED;
st->rc_counter = RC_REPEAT_DELAY_V1_20;
}
} else {
err("Unknown data state [%d]", poll_reply.data_state);
}
switch (state) {
case REMOTE_NO_KEY_PRESSED:
break;
case REMOTE_KEY_PRESSED:
deb_info("key pressed\n");
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_info("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);
break;
default:
break;
}
resubmit:
/* Clean the buffer before we requeue */
memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
/* Requeue URB */
usb_submit_urb(purb, GFP_ATOMIC);
}
int dib0700_rc_setup(struct dvb_usb_device *d)
{
struct dib0700_state *st = d->priv;
u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
int i = dib0700_ctrl_wr(d, rc_setup, 3);
struct urb *purb;
int ret;
int i;
if (d->props.rc_key_map == NULL)
return 0;
/* Set the IR mode */
i = dib0700_ctrl_wr(d, rc_setup, 3);
if (i<0) {
err("ir protocol setup failed");
return -1;
}
if (st->fw_version < 0x10200)
return 0;
/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
purb = usb_alloc_urb(0, GFP_KERNEL);
if (purb == NULL) {
err("rc usb alloc urb failed\n");
return -1;
}
purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
if (purb->transfer_buffer == NULL) {
err("rc kzalloc failed\n");
usb_free_urb(purb);
return -1;
}
purb->status = -EINPROGRESS;
usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
purb->transfer_buffer, RC_MSG_SIZE_V1_20,
dib0700_rc_urb_completion, d);
ret = usb_submit_urb(purb, GFP_ATOMIC);
if (ret != 0) {
err("rc submit urb failed\n");
return -1;
}
return 0;
}
......
......@@ -472,20 +472,25 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
/* Number of keypresses to ignore before start repeating */
#define RC_REPEAT_DELAY 6
#define RC_REPEAT_DELAY_V1_20 10
/* Used by firmware versions < 1.20 (deprecated) */
static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
int *state)
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
u8 key[4];
int i;
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
struct dib0700_state *st = d->priv;
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
if (st->fw_version >= 0x10200) {
/* For 1.20 firmware , We need to keep the RC polling
callback so we can reuse the input device setup in
dvb-usb-remote.c. However, the actual work is being done
in the bulk URB completion handler. */
return 0;
}
i=dib0700_ctrl_rd(d,rc_request,2,key,4);
if (i<=0) {
err("RC Query Failed");
......@@ -557,149 +562,6 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
return 0;
}
/* This is the structure of the RC response packet starting in firmware 1.20 */
struct dib0700_rc_response {
u8 report_id;
u8 data_state;
u16 system;
u8 data;
u8 not_data;
};
/* This supports the new IR response format for firmware v1.20 */
static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
int *state)
{
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
struct dib0700_state *st = d->priv;
struct dib0700_rc_response poll_reply;
u8 buf[6];
int i;
int status;
int actlen;
int found = 0;
/* Set initial results in case we exit the function early */
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
/* Firmware v1.20 provides RC data via bulk endpoint 1 */
status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
sizeof(buf), &actlen, 50);
if (status < 0) {
/* No data available (meaning no key press) */
return 0;
}
switch (dvb_usb_dib0700_ir_proto) {
case 0:
poll_reply.report_id = 0;
poll_reply.data_state = 1;
poll_reply.system = buf[2];
poll_reply.data = buf[4];
poll_reply.not_data = buf[5];
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
&& (poll_reply.not_data == 0xff)) {
poll_reply.data_state = 2;
break;
}
break;
default:
if (actlen != sizeof(buf)) {
/* We didn't get back the 6 byte message we expected */
err("Unexpected RC response size [%d]", actlen);
return -1;
}
poll_reply.report_id = buf[0];
poll_reply.data_state = buf[1];
poll_reply.system = (buf[2] << 8) | buf[3];
poll_reply.data = buf[4];
poll_reply.not_data = buf[5];
break;
}
if ((poll_reply.data + poll_reply.not_data) != 0xff) {
/* Key failed integrity check */
err("key failed integrity check: %04x %02x %02x",
poll_reply.system,
poll_reply.data, poll_reply.not_data);
return -1;
}
/* Find the key in the map */
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
rc5_data(&keymap[i]) == poll_reply.data) {
*event = keymap[i].event;
found = 1;
break;
}
}
if (found == 0) {
err("Unknown remote controller key: %04x %02x %02x",
poll_reply.system,
poll_reply.data, poll_reply.not_data);
d->last_event = 0;
return 0;
}
if (poll_reply.data_state == 1) {
/* New key hit */
st->rc_counter = 0;
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
d->last_event = keymap[i].event;
} else if (poll_reply.data_state == 2) {
/* Key repeated */
st->rc_counter++;
/* prevents unwanted double hits */
if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
*event = d->last_event;
*state = REMOTE_KEY_PRESSED;
st->rc_counter = RC_REPEAT_DELAY_V1_20;
}
} else {
err("Unknown data state [%d]", poll_reply.data_state);
}
return 0;
}
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct dib0700_state *st = d->priv;
/* Because some people may have improperly named firmware files,
let's figure out whether to use the new firmware call or the legacy
call based on the firmware version embedded in the file */
if (st->rc_func_version == 0) {
u32 hwver, romver, ramver, fwtype;
int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
&fwtype);
if (ret < 0) {
err("Could not determine version info");
return -1;
}
if (ramver < 0x10200)
st->rc_func_version = 1;
else
st->rc_func_version = 2;
}
if (st->rc_func_version == 2)
return dib0700_rc_query_v1_20(d, event, state);
else
return dib0700_rc_query_legacy(d, event, state);
}
static struct dvb_usb_rc_key dib0700_rc_keys[] = {
/* Key codes for the tiny Pinnacle remote*/
{ 0x0700, KEY_MUTE },
......
......@@ -64,6 +64,8 @@
#define USB_VID_HUMAX_COEX 0x10b9
#define USB_VID_774 0x7a69
#define USB_VID_EVOLUTEPC 0x1e59
#define USB_VID_AZUREWAVE 0x13d3
#define USB_VID_TECHNISAT 0x14f7
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
......@@ -138,6 +140,7 @@
#define USB_PID_TWINHAN_VP7021_COLD 0x3207
#define USB_PID_TWINHAN_VP7021_WARM 0x3208
#define USB_PID_TINYTWIN 0x3226
#define USB_PID_TINYTWIN_2 0xe402
#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
......@@ -209,6 +212,7 @@
#define USB_PID_PINNACLE_PCTV71E 0x022b
#define USB_PID_PINNACLE_PCTV72E 0x0236
#define USB_PID_PINNACLE_PCTV73E 0x0237
#define USB_PID_PINNACLE_PCTV310E 0x3211
#define USB_PID_PINNACLE_PCTV801E 0x023a
#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
#define USB_PID_PINNACLE_PCTV73A 0x0243
......@@ -248,6 +252,7 @@
#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361
#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
#define USB_PID_WINFAST_DTV2000DS 0x6a04
#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
......@@ -290,5 +295,7 @@
#define USB_PID_FRIIO_WHITE 0x0001
#define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d
#define USB_PID_AZUREWAVE_AZ6027 0x3275
#define USB_PID_TERRATEC_DVBS2CI 0x3275
#define USB_PID_TECHNISAT_USB2_HDCI 0x0002
#endif
......@@ -243,7 +243,7 @@ int dvb_usb_device_init(struct usb_interface *intf,
d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
if (d == NULL) {
err("no memory for 'struct dvb_usb_device'");
return ret;
return -ENOMEM;
}
d->udev = udev;
......
......@@ -107,6 +107,7 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
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);
break;
......
This diff is collapsed.
......@@ -366,7 +366,7 @@ static u8 init_code[][2] = {
{0x76, 0x0C},
};
const static int init_code_len = sizeof(init_code) / sizeof(u8[2]);
static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
static int jdvbt90502_init(struct dvb_frontend *fe)
{
......
This diff is collapsed.
......@@ -18,7 +18,7 @@
#define M9206_FW 0x30
#define M9206_MAX_FILTERS 8
#define M9206_MAX_ADAPTERS 2
#define M9206_MAX_ADAPTERS 4
/*
sequences found in logs:
......
......@@ -138,7 +138,7 @@ static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
(msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
msg[i].buf,
msg[i].len
)!= msg[i].len)) {
)) != msg[i].len) {
break;
}
if (dvb_usb_opera1_debug & 0x10)
......
......@@ -90,13 +90,14 @@ static inline struct node_entry *node_of(struct firedtv *fdtv)
return container_of(fdtv->device, struct unit_directory, device)->ne;
}
static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
{
quadlet_t *d = data;
int ret;
ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
(__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
data[0] = data[1];
ret = hpsb_node_lock(node_of(fdtv), addr,
EXTCODE_COMPARE_SWAP, &d[1], d[0]);
d[0] = d[1];
return ret;
}
......@@ -192,9 +193,13 @@ static int node_probe(struct device *dev)
int kv_len, err;
void *kv_str;
kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
if (ud->model_name_kv) {
kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
} else {
kv_len = 0;
kv_str = NULL;
}
fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
if (!fdtv)
return -ENOMEM;
......
This diff is collapsed.
......@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device *dev,
mutex_init(&fdtv->avc_mutex);
init_waitqueue_head(&fdtv->avc_wait);
fdtv->avc_reply_received = true;
mutex_init(&fdtv->demux_mutex);
INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
......
......@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
return rcode != RCODE_COMPLETE ? -EIO : 0;
}
static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
{
return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
}
......
......@@ -73,7 +73,7 @@ struct input_dev;
struct firedtv;
struct firedtv_backend {
int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
int (*read)(struct firedtv *fdtv, u64 addr, void *data);
int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
int (*start_iso)(struct firedtv *fdtv);
......@@ -114,8 +114,8 @@ struct firedtv {
unsigned long channel_active;
u16 channel_pid[16];
size_t response_length;
u8 response[512];
int avc_data_length;
u8 avc_data[512];
};
/* firedtv-1394.c */
......
......@@ -44,6 +44,7 @@ enum af9013_tuner {
AF9013_TUNER_MT2060_2 = 147, /* Microtune */
AF9013_TUNER_TDA18271 = 156, /* NXP */
AF9013_TUNER_QT1010A = 162, /* Quantek */
AF9013_TUNER_TDA18218 = 179, /* NXP */
};
/* AF9013/5 GPIOs (mostly guessed)
......
......@@ -170,6 +170,19 @@ static int is_locked(struct atbm_state *priv, u8 *locked)
return 0;
}
static int set_agc_config(struct atbm_state *priv,
u8 min, u8 max, u8 hold_loop)
{
/* no effect if both min and max are zero */
if (!min && !max)
return 0;
atbm8830_write_reg(priv, REG_AGC_MIN, min);
atbm8830_write_reg(priv, REG_AGC_MAX, max);
atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
return 0;
}
static int set_static_channel_mode(struct atbm_state *priv)
{
......@@ -227,6 +240,9 @@ static int atbm8830_init(struct dvb_frontend *fe)
/*Set IF frequency*/
set_if_freq(priv, cfg->if_freq);
/*Set AGC Config*/
set_agc_config(priv, cfg->agc_min, cfg->agc_max,
cfg->agc_hold_loop);
/*Set static channel mode*/
set_static_channel_mode(priv);
......
......@@ -283,7 +283,7 @@ static int dib0090_sleep(struct dvb_frontend *fe)
return 0;
}
extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
{
struct dib0090_state *state = fe->tuner_priv;
if (fast)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment