提交 e3172349 编写于 作者: L Linus Torvalds

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

Pull media updates from Mauro Carvalho Chehab:
 - V4L2 API additions to better support JPEG compression control
 - media API additions to properly support MPEG decoders
 - V4L2 API additions for image crop/scaling
 - a few other V4L2 API DocBook fixes/improvements
 - two new DVB frontend drivers: m88rs2000 and rtl2830
 - two new DVB drivers: az6007 and rtl28xxu
 - a framework for ISA drivers, that removed lots of common code found
   at the ISA radio drivers
 - a new FM transmitter driver (radio-keene)
 - a GPIO-based IR receiver driver
 - a new sensor driver: mt9m032
 - some new video drivers: adv7183, blackfin, mx2_emmaprp, sii9234_drv,
   vs6624
 - several new board additions, driver fixes, improvements and cleanups.

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (295 commits)
  [media] update CARDLIST.em28xx
  [media] partially reverts changeset fa5527cd
  [media] stb0899: fix the limits for signal strength values
  [media] em28xx: support for 2304:0242 PCTV QuatroStick (510e)
  [media] em28xx: support for 2013:0251 PCTV QuatroStick nano (520e)
  [media] -EINVAL -> -ENOTTY
  [media] gspca - sn9c20x: Cleanup source
  [media] gspca - sn9c20x: Simplify register write for capture start/stop
  [media] gspca - sn9c20x: Add automatic JPEG compression mechanism
  [media] gspca - sn9c20x: Greater delay in case of sensor no response
  [media] gspca - sn9c20x: Optimize the code of write sequences
  [media] gspca - sn9c20x: Add the JPEG compression quality control
  [media] gspca - sn9c20x: Add a delay after Omnivision sensor reset
  [media] gspca - sn9c20x: Propagate USB errors to higher level
  [media] gspca - sn9c20x: Use the new video control mechanism
  [media] gspca - sn9c20x: Fix loss of frame start
  [media] gspca - zc3xx: Lack of register 08 value for sensor cs2102k
  [media] gspca - ov534_9: Add brightness to OmniVision 5621 sensor
  [media] gspca - zc3xx: Add V4L2_CID_JPEG_COMPRESSION_QUALITY control support
  [media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5
  ...
......@@ -128,6 +128,26 @@ url="http://www.ijg.org">http://www.ijg.org</ulink>)</corpauthor>
<subtitle>Version 1.02</subtitle>
</biblioentry>
<biblioentry id="itu-t81">
<abbrev>ITU-T.81</abbrev>
<authorgroup>
<corpauthor>International Telecommunication Union
(<ulink url="http://www.itu.int">http://www.itu.int</ulink>)</corpauthor>
</authorgroup>
<title>ITU-T Recommendation T.81
"Information Technology &mdash; Digital Compression and Coding of Continous-Tone
Still Images &mdash; Requirements and Guidelines"</title>
</biblioentry>
<biblioentry id="w3c-jpeg-jfif">
<abbrev>W3C JPEG JFIF</abbrev>
<authorgroup>
<corpauthor>The World Wide Web Consortium (<ulink
url="http://www.w3.org/Graphics/JPEG">http://www.w3.org</ulink>)</corpauthor>
</authorgroup>
<title>JPEG JFIF</title>
</biblioentry>
<biblioentry id="smpte12m">
<abbrev>SMPTE&nbsp;12M</abbrev>
<authorgroup>
......
......@@ -2393,6 +2393,20 @@ details.</para>
to the <link linkend="control">User controls class</link>.
</para>
</listitem>
<listitem>
<para>Added the device_caps field to struct v4l2_capabilities and added the new
V4L2_CAP_DEVICE_CAPS capability.</para>
</listitem>
</orderedlist>
</section>
<section>
<title>V4L2 in Linux 3.4</title>
<orderedlist>
<listitem>
<para>Added <link linkend="jpeg-controls">JPEG compression control
class</link>.</para>
</listitem>
</orderedlist>
</section>
......
......@@ -1284,6 +1284,49 @@ values are:</entry>
capturing. This is not done by muting audio hardware, which can still
produce a slight hiss, but in the encoder itself, guaranteeing a fixed
and reproducible audio bitstream. 0 = unmuted, 1 = muted.</entry>
</row>
<row><entry></entry></row>
<row id="v4l2-mpeg-audio-dec-playback">
<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK</constant>&nbsp;</entry>
<entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry>
</row><row><entry spanname="descr">Determines how monolingual audio should be played back.
Possible values are:</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO</constant>&nbsp;</entry>
<entry>Automatically determines the best playback mode.</entry>
</row>
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO</constant>&nbsp;</entry>
<entry>Stereo playback.</entry>
</row>
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT</constant>&nbsp;</entry>
<entry>Left channel playback.</entry>
</row>
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT</constant>&nbsp;</entry>
<entry>Right channel playback.</entry>
</row>
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO</constant>&nbsp;</entry>
<entry>Mono playback.</entry>
</row>
<row>
<entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO</constant>&nbsp;</entry>
<entry>Stereo playback with swapped left and right channels.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
<row id="v4l2-mpeg-audio-dec-multilingual-playback">
<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK</constant>&nbsp;</entry>
<entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry>
</row><row><entry spanname="descr">Determines how multilingual audio should be played back.</entry>
</row>
<row><entry></entry></row>
<row id="v4l2-mpeg-video-encoding">
......@@ -1447,6 +1490,22 @@ of the video. The supplied 32-bit integer is interpreted as follows (bit
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
<row id="v4l2-mpeg-video-dec-pts">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_PTS</constant>&nbsp;</entry>
<entry>integer64</entry>
</row><row><entry spanname="descr">This read-only control returns the
33-bit video Presentation Time Stamp as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1 of
the currently displayed frame. This is the same PTS as is used in &VIDIOC-DECODER-CMD;.</entry>
</row>
<row><entry></entry></row>
<row id="v4l2-mpeg-video-dec-frame">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_FRAME</constant>&nbsp;</entry>
<entry>integer64</entry>
</row><row><entry spanname="descr">This read-only control returns the
frame counter of the frame that is currently displayed (decoded). This value is reset to 0 whenever
the decoder is started.</entry>
</row>
<row><entry></entry></row>
......@@ -3377,6 +3436,167 @@ interface and may change in the future.</para>
</tbody>
</tgroup>
</table>
</section>
<section id="jpeg-controls">
<title>JPEG Control Reference</title>
<para>The JPEG class includes controls for common features of JPEG
encoders and decoders. Currently it includes features for codecs
implementing progressive baseline DCT compression process with
Huffman entrophy coding.</para>
<table pgwide="1" frame="none" id="jpeg-control-id">
<title>JPEG Control IDs</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="6*" />
<colspec colname="c3" colwidth="2*" />
<colspec colname="c4" colwidth="6*" />
<spanspec namest="c1" nameend="c2" spanname="id" />
<spanspec namest="c2" nameend="c4" spanname="descr" />
<thead>
<row>
<entry spanname="id" align="left">ID</entry>
<entry align="left">Type</entry>
</row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
</row>
</thead>
<tbody valign="top">
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_JPEG_CLASS</constant>&nbsp;</entry>
<entry>class</entry>
</row><row><entry spanname="descr">The JPEG class descriptor. Calling
&VIDIOC-QUERYCTRL; for this control will return a description of this
control class.
</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry>
<entry>menu</entry>
</row>
<row id="jpeg-chroma-subsampling-control">
<entry spanname="descr">The chroma subsampling factors describe how
each component of an input image is sampled, in respect to maximum
sample rate in each spatial dimension. See <xref linkend="itu-t81"/>,
clause A.1.1. for more details. The <constant>
V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant> control determines how
Cb and Cr components are downsampled after coverting an input image
from RGB to Y'CbCr color space.
</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_444</constant>
</entry><entry>No chroma subsampling, each pixel has
Y, Cr and Cb values.</entry>
</row>
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_422</constant>
</entry><entry>Horizontally subsample Cr, Cb components
by a factor of 2.</entry>
</row>
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_420</constant>
</entry><entry>Subsample Cr, Cb components horizontally
and vertically by 2.</entry>
</row>
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_411</constant>
</entry><entry>Horizontally subsample Cr, Cb components
by a factor of 4.</entry>
</row>
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_410</constant>
</entry><entry>Subsample Cr, Cb components horizontally
by 4 and vertically by 2.</entry>
</row>
<row>
<entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY</constant>
</entry><entry>Use only luminance component.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_JPEG_RESTART_INTERVAL</constant>
</entry><entry>integer</entry>
</row>
<row><entry spanname="descr">
The restart interval determines an interval of inserting RSTm
markers (m = 0..7). The purpose of these markers is to additionally
reinitialize the encoder process, in order to process blocks of
an image independently.
For the lossy compression processes the restart interval unit is
MCU (Minimum Coded Unit) and its value is contained in DRI
(Define Restart Interval) marker. If <constant>
V4L2_CID_JPEG_RESTART_INTERVAL</constant> control is set to 0,
DRI and RSTm markers will not be inserted.
</entry>
</row>
<row id="jpeg-quality-control">
<entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant></entry>
<entry>integer</entry>
</row>
<row>
<entry spanname="descr">
<constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control
determines trade-off between image quality and size.
It provides simpler method for applications to control image quality,
without a need for direct reconfiguration of luminance and chrominance
quantization tables.
In cases where a driver uses quantization tables configured directly
by an application, using interfaces defined elsewhere, <constant>
V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control should be set
by driver to 0.
<para>The value range of this control is driver-specific. Only
positive, non-zero values are meaningful. The recommended range
is 1 - 100, where larger values correspond to better image quality.
</para>
</entry>
</row>
<row id="jpeg-active-marker-control">
<entry spanname="id"><constant>V4L2_CID_JPEG_ACTIVE_MARKER</constant></entry>
<entry>bitmask</entry>
</row>
<row>
<entry spanname="descr">Specify which JPEG markers are included
in compressed stream. This control is valid only for encoders.
</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_JPEG_ACTIVE_MARKER_APP0</constant></entry>
<entry>Application data segment APP<subscript>0</subscript>.</entry>
</row><row>
<entry><constant>V4L2_JPEG_ACTIVE_MARKER_APP1</constant></entry>
<entry>Application data segment APP<subscript>1</subscript>.</entry>
</row><row>
<entry><constant>V4L2_JPEG_ACTIVE_MARKER_COM</constant></entry>
<entry>Comment segment.</entry>
</row><row>
<entry><constant>V4L2_JPEG_ACTIVE_MARKER_DQT</constant></entry>
<entry>Quantization tables segment.</entry>
</row><row>
<entry><constant>V4L2_JPEG_ACTIVE_MARKER_DHT</constant></entry>
<entry>Huffman tables segment.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
</tbody>
</tgroup>
</table>
<para>For more details about JPEG specification, refer
to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>,
<xref linkend="w3c-jpeg-jfif"/>.</para>
</section>
</section>
......@@ -52,6 +52,10 @@ cropping and composing rectangles have the same size.</para>
</textobject>
</mediaobject>
</figure>
For complete list of the available selection targets see table <xref
linkend="v4l2-sel-target"/>
</section>
<section>
......@@ -186,7 +190,7 @@ V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> target.</para>
<section>
<title>Scaling control.</title>
<title>Scaling control</title>
<para>An application can detect if scaling is performed by comparing the width
and the height of rectangles obtained using <constant> V4L2_SEL_TGT_CROP_ACTIVE
......@@ -200,7 +204,7 @@ the scaling ratios using these values.</para>
<section>
<title>Comparison with old cropping API.</title>
<title>Comparison with old cropping API</title>
<para>The selection API was introduced to cope with deficiencies of previous
<link linkend="crop"> API </link>, that was designed to control simple capture
......
......@@ -127,6 +127,22 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.xml), along with the possible impact on existing drivers and
applications. -->
<revision>
<revnumber>3.4</revnumber>
<date>2012-01-25</date>
<authorinitials>sn</authorinitials>
<revremark>Added <link linkend="jpeg-controls">JPEG compression
control class.</link>
</revremark>
</revision>
<revision>
<revnumber>3.3</revnumber>
<date>2012-01-11</date>
<authorinitials>hv</authorinitials>
<revremark>Added device_caps field to struct v4l2_capabilities.</revremark>
</revision>
<revision>
<revnumber>3.2</revnumber>
<date>2011-08-26</date>
......@@ -417,7 +433,7 @@ and discussions on the V4L mailing list.</revremark>
</partinfo>
<title>Video for Linux Two API Specification</title>
<subtitle>Revision 3.2</subtitle>
<subtitle>Revision 3.3</subtitle>
<chapter id="common">
&sub-common;
......@@ -473,6 +489,7 @@ and discussions on the V4L mailing list.</revremark>
&sub-cropcap;
&sub-dbg-g-chip-ident;
&sub-dbg-g-register;
&sub-decoder-cmd;
&sub-dqevent;
&sub-encoder-cmd;
&sub-enumaudio;
......
<refentry id="vidioc-decoder-cmd">
<refmeta>
<refentrytitle>ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_DECODER_CMD</refname>
<refname>VIDIOC_TRY_DECODER_CMD</refname>
<refpurpose>Execute an decoder command</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_decoder_cmd *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<note>
<title>Experimental</title>
<para>This is an <link linkend="experimental">experimental</link>
interface and may change in the future.</para>
</note>
<para>These ioctls control an audio/video (usually MPEG-) decoder.
<constant>VIDIOC_DECODER_CMD</constant> sends a command to the
decoder, <constant>VIDIOC_TRY_DECODER_CMD</constant> can be used to
try a command without actually executing it. To send a command applications
must initialize all fields of a &v4l2-decoder-cmd; and call
<constant>VIDIOC_DECODER_CMD</constant> or <constant>VIDIOC_TRY_DECODER_CMD</constant>
with a pointer to this structure.</para>
<para>The <structfield>cmd</structfield> field must contain the
command code. Some commands use the <structfield>flags</structfield> field for
additional information.
</para>
<para>A <function>write</function>() or &VIDIOC-STREAMON; call sends an implicit
START command to the decoder if it has not been started yet.
</para>
<para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming
file descriptor sends an implicit immediate STOP command to the decoder, and all
buffered data is discarded.</para>
<para>These ioctls are optional, not all drivers may support
them. They were introduced in Linux 3.3.</para>
<table pgwide="1" frame="none" id="v4l2-decoder-cmd">
<title>struct <structname>v4l2_decoder_cmd</structname></title>
<tgroup cols="5">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>cmd</structfield></entry>
<entry></entry>
<entry></entry>
<entry>The decoder command, see <xref linkend="decoder-cmds" />.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry></entry>
<entry></entry>
<entry>Flags to go with the command. If no flags are defined for
this command, drivers and applications must set this field to zero.</entry>
</row>
<row>
<entry>union</entry>
<entry>(anonymous)</entry>
<entry></entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry></entry>
<entry>struct</entry>
<entry><structfield>start</structfield></entry>
<entry></entry>
<entry>Structure containing additional data for the
<constant>V4L2_DEC_CMD_START</constant> command.</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__s32</entry>
<entry><structfield>speed</structfield></entry>
<entry>Playback speed and direction. The playback speed is defined as
<structfield>speed</structfield>/1000 of the normal speed. So 1000 is normal playback.
Negative numbers denote reverse playback, so -1000 does reverse playback at normal
speed. Speeds -1, 0 and 1 have special meanings: speed 0 is shorthand for 1000
(normal playback). A speed of 1 steps just one frame forward, a speed of -1 steps
just one frame back.
</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>format</structfield></entry>
<entry>Format restrictions. This field is set by the driver, not the
application. Possible values are <constant>V4L2_DEC_START_FMT_NONE</constant> if
there are no format restrictions or <constant>V4L2_DEC_START_FMT_GOP</constant>
if the decoder operates on full GOPs (<wordasword>Group Of Pictures</wordasword>).
This is usually the case for reverse playback: the decoder needs full GOPs, which
it can then play in reverse order. So to implement reverse playback the application
must feed the decoder the last GOP in the video file, then the GOP before that, etc. etc.
</entry>
</row>
<row>
<entry></entry>
<entry>struct</entry>
<entry><structfield>stop</structfield></entry>
<entry></entry>
<entry>Structure containing additional data for the
<constant>V4L2_DEC_CMD_STOP</constant> command.</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u64</entry>
<entry><structfield>pts</structfield></entry>
<entry>Stop playback at this <structfield>pts</structfield> or immediately
if the playback is already past that timestamp. Leave to 0 if you want to stop after the
last frame was decoded.
</entry>
</row>
<row>
<entry></entry>
<entry>struct</entry>
<entry><structfield>raw</structfield></entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>data</structfield>[16]</entry>
<entry>Reserved for future extensions. Drivers and
applications must set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="decoder-cmds">
<title>Decoder Commands</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_DEC_CMD_START</constant></entry>
<entry>0</entry>
<entry>Start the decoder. When the decoder is already
running or paused, this command will just change the playback speed.
That means that calling <constant>V4L2_DEC_CMD_START</constant> when
the decoder was paused will <emphasis>not</emphasis> resume the decoder.
You have to explicitly call <constant>V4L2_DEC_CMD_RESUME</constant> for that.
This command has one flag:
<constant>V4L2_DEC_CMD_START_MUTE_AUDIO</constant>. If set, then audio will
be muted when playing back at a non-standard speed.
</entry>
</row>
<row>
<entry><constant>V4L2_DEC_CMD_STOP</constant></entry>
<entry>1</entry>
<entry>Stop the decoder. When the decoder is already stopped,
this command does nothing. This command has two flags:
if <constant>V4L2_DEC_CMD_STOP_TO_BLACK</constant> is set, then the decoder will
set the picture to black after it stopped decoding. Otherwise the last image will
repeat. If <constant>V4L2_DEC_CMD_STOP_IMMEDIATELY</constant> is set, then the decoder
stops immediately (ignoring the <structfield>pts</structfield> value), otherwise it
will keep decoding until timestamp >= pts or until the last of the pending data from
its internal buffers was decoded.
</entry>
</row>
<row>
<entry><constant>V4L2_DEC_CMD_PAUSE</constant></entry>
<entry>2</entry>
<entry>Pause the decoder. When the decoder has not been
started yet, the driver will return an &EPERM;. When the decoder is
already paused, this command does nothing. This command has one flag:
if <constant>V4L2_DEC_CMD_PAUSE_TO_BLACK</constant> is set, then set the
decoder output to black when paused.
</entry>
</row>
<row>
<entry><constant>V4L2_DEC_CMD_RESUME</constant></entry>
<entry>3</entry>
<entry>Resume decoding after a PAUSE command. When the
decoder has not been started yet, the driver will return an &EPERM;.
When the decoder is already running, this command does nothing. No
flags are defined for this command.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The <structfield>cmd</structfield> field is invalid.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EPERM</errorcode></term>
<listitem>
<para>The application sent a PAUSE or RESUME command when
the decoder was not running.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
......@@ -74,15 +74,16 @@ only used by the STOP command and contains one bit: If the
encoding will continue until the end of the current <wordasword>Group
Of Pictures</wordasword>, otherwise it will stop immediately.</para>
<para>A <function>read</function>() call sends a START command to
the encoder if it has not been started yet. After a STOP command,
<para>A <function>read</function>() or &VIDIOC-STREAMON; call sends an implicit
START command to the encoder if it has not been started yet. After a STOP command,
<function>read</function>() calls will read the remaining data
buffered by the driver. When the buffer is empty,
<function>read</function>() will return zero and the next
<function>read</function>() call will restart the encoder.</para>
<para>A <function>close</function>() call sends an immediate STOP
to the encoder, and all buffered data is discarded.</para>
<para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming
file descriptor sends an implicit immediate STOP to the encoder, and all buffered
data is discarded.</para>
<para>These ioctls are optional, not all drivers may support
them. They were introduced in Linux 2.6.21.</para>
......
......@@ -57,6 +57,11 @@
<refsect1>
<title>Description</title>
<para>These ioctls are <emphasis role="bold">deprecated</emphasis>.
New drivers and applications should use <link linkend="jpeg-controls">
JPEG class controls</link> for image quality and JPEG markers control.
</para>
<para>[to do]</para>
<para>Ronald Bultje elaborates:</para>
......@@ -86,7 +91,10 @@ to add them.</para>
<row>
<entry>int</entry>
<entry><structfield>quality</structfield></entry>
<entry></entry>
<entry>Deprecated. If <link linkend="jpeg-quality-control"><constant>
V4L2_CID_JPEG_IMAGE_QUALITY</constant></link> control is exposed by
a driver applications should use it instead and ignore this field.
</entry>
</row>
<row>
<entry>int</entry>
......@@ -116,7 +124,11 @@ to add them.</para>
<row>
<entry>__u32</entry>
<entry><structfield>jpeg_markers</structfield></entry>
<entry>See <xref linkend="jpeg-markers" />.</entry>
<entry>See <xref linkend="jpeg-markers"/>. Deprecated.
If <link linkend="jpeg-active-marker-control"><constant>
V4L2_CID_JPEG_ACTIVE_MARKER</constant></link> control
is exposed by a driver applications should use it instead
and ignore this field.</entry>
</row>
</tbody>
</tgroup>
......
......@@ -58,43 +58,43 @@
<para>The ioctls are used to query and configure selection rectangles.</para>
<para> To query the cropping (composing) rectangle set <structfield>
&v4l2-selection;::type </structfield> to the respective buffer type. Do not
use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE
<para> To query the cropping (composing) rectangle set &v4l2-selection;
<structfield> type </structfield> field to the respective buffer type.
Do not use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is
setting <structfield> &v4l2-selection;::target </structfield> to value
<constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant>
setting the value of &v4l2-selection; <structfield>target</structfield> field
to <constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant>
V4L2_SEL_TGT_COMPOSE_ACTIVE </constant>). Please refer to table <xref
linkend="v4l2-sel-target" /> or <xref linkend="selection-api" /> for additional
targets. Fields <structfield> &v4l2-selection;::flags </structfield> and
<structfield> &v4l2-selection;::reserved </structfield> are ignored and they
must be filled with zeros. The driver fills the rest of the structure or
targets. The <structfield>flags</structfield> and <structfield>reserved
</structfield> fields of &v4l2-selection; are ignored and they must be filled
with zeros. The driver fills the rest of the structure or
returns &EINVAL; if incorrect buffer type or target was used. If cropping
(composing) is not supported then the active rectangle is not mutable and it is
always equal to the bounds rectangle. Finally, structure <structfield>
&v4l2-selection;::r </structfield> is filled with the current cropping
always equal to the bounds rectangle. Finally, the &v4l2-rect;
<structfield>r</structfield> rectangle is filled with the current cropping
(composing) coordinates. The coordinates are expressed in driver-dependent
units. The only exception are rectangles for images in raw formats, whose
coordinates are always expressed in pixels. </para>
<para> To change the cropping (composing) rectangle set <structfield>
&v4l2-selection;::type </structfield> to the respective buffer type. Do not
<para> To change the cropping (composing) rectangle set the &v4l2-selection;
<structfield>type</structfield> field to the respective buffer type. Do not
use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is
setting <structfield> &v4l2-selection;::target </structfield> to value
<constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant>
setting the value of &v4l2-selection; <structfield>target</structfield> to
<constant>V4L2_SEL_TGT_CROP_ACTIVE</constant> (<constant>
V4L2_SEL_TGT_COMPOSE_ACTIVE </constant>). Please refer to table <xref
linkend="v4l2-sel-target" /> or <xref linkend="selection-api" /> for additional
targets. Set desired active area into the field <structfield>
&v4l2-selection;::r </structfield>. Field <structfield>
&v4l2-selection;::reserved </structfield> is ignored and must be filled with
zeros. The driver may adjust the rectangle coordinates. An application may
introduce constraints to control rounding behaviour. Set the field
<structfield> &v4l2-selection;::flags </structfield> to one of values:
targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be
set to the desired active area. Field &v4l2-selection; <structfield> reserved
</structfield> is ignored and must be filled with zeros. The driver may adjust
coordinates of the requested rectangle. An application may
introduce constraints to control rounding behaviour. The &v4l2-selection;
<structfield>flags</structfield> field must be set to one of the following:
<itemizedlist>
<listitem>
......@@ -129,7 +129,7 @@ and vertical offset and sizes are chosen according to following priority:
<orderedlist>
<listitem>
<para>Satisfy constraints from <structfield>&v4l2-selection;::flags</structfield>.</para>
<para>Satisfy constraints from &v4l2-selection; <structfield>flags</structfield>.</para>
</listitem>
<listitem>
<para>Adjust width, height, left, and top to hardware limits and alignments.</para>
......@@ -145,7 +145,7 @@ and vertical offset and sizes are chosen according to following priority:
</listitem>
</orderedlist>
On success the field <structfield> &v4l2-selection;::r </structfield> contains
On success the &v4l2-rect; <structfield>r</structfield> field contains
the adjusted rectangle. When the parameters are unsuitable the application may
modify the cropping (composing) or image parameters and repeat the cycle until
satisfactory parameters have been negotiated. If constraints flags have to be
......@@ -162,38 +162,38 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
<tbody valign="top">
<row>
<entry><constant>V4L2_SEL_TGT_CROP_ACTIVE</constant></entry>
<entry>0</entry>
<entry>area that is currently cropped by hardware</entry>
<entry>0x0000</entry>
<entry>The area that is currently cropped by hardware.</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_CROP_DEFAULT</constant></entry>
<entry>1</entry>
<entry>suggested cropping rectangle that covers the "whole picture"</entry>
<entry>0x0001</entry>
<entry>Suggested cropping rectangle that covers the "whole picture".</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_CROP_BOUNDS</constant></entry>
<entry>2</entry>
<entry>limits for the cropping rectangle</entry>
<entry>0x0002</entry>
<entry>Limits for the cropping rectangle.</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_COMPOSE_ACTIVE</constant></entry>
<entry>256</entry>
<entry>area to which data are composed by hardware</entry>
<entry>0x0100</entry>
<entry>The area to which data is composed by hardware.</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant></entry>
<entry>257</entry>
<entry>suggested composing rectangle that covers the "whole picture"</entry>
<entry>0x0101</entry>
<entry>Suggested composing rectangle that covers the "whole picture".</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_COMPOSE_BOUNDS</constant></entry>
<entry>258</entry>
<entry>limits for the composing rectangle</entry>
<entry>0x0102</entry>
<entry>Limits for the composing rectangle.</entry>
</row>
<row>
<entry><constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant></entry>
<entry>259</entry>
<entry>the active area and all padding pixels that are inserted or modified by the hardware</entry>
<entry>0x0103</entry>
<entry>The active area and all padding pixels that are inserted or modified by hardware.</entry>
</row>
</tbody>
</tgroup>
......@@ -209,12 +209,14 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
<row>
<entry><constant>V4L2_SEL_FLAG_GE</constant></entry>
<entry>0x00000001</entry>
<entry>indicate that adjusted rectangle must contain a rectangle from <structfield>&v4l2-selection;::r</structfield></entry>
<entry>Indicates that the adjusted rectangle must contain the original
&v4l2-selection; <structfield>r</structfield> rectangle.</entry>
</row>
<row>
<entry><constant>V4L2_SEL_FLAG_LE</constant></entry>
<entry>0x00000002</entry>
<entry>indicate that adjusted rectangle must be inside a rectangle from <structfield>&v4l2-selection;::r</structfield></entry>
<entry>Indicates that the adjusted rectangle must be inside the original
&v4l2-rect; <structfield>r</structfield> rectangle.</entry>
</row>
</tbody>
</tgroup>
......@@ -245,27 +247,29 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
<row>
<entry>__u32</entry>
<entry><structfield>type</structfield></entry>
<entry>Type of the buffer (from &v4l2-buf-type;)</entry>
<entry>Type of the buffer (from &v4l2-buf-type;).</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>target</structfield></entry>
<entry>used to select between <link linkend="v4l2-sel-target"> cropping and composing rectangles </link></entry>
<entry>Used to select between <link linkend="v4l2-sel-target"> cropping
and composing rectangles</link>.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>control over coordinates adjustments, refer to <link linkend="v4l2-sel-flags">selection flags</link></entry>
<entry>Flags controlling the selection rectangle adjustments, refer to
<link linkend="v4l2-sel-flags">selection flags</link>.</entry>
</row>
<row>
<entry>&v4l2-rect;</entry>
<entry><structfield>r</structfield></entry>
<entry>selection rectangle</entry>
<entry>The selection rectangle.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved[9]</structfield></entry>
<entry>Reserved fields for future use</entry>
<entry>Reserved fields for future use.</entry>
</row>
</tbody>
</tgroup>
......@@ -278,24 +282,24 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The buffer <structfield> &v4l2-selection;::type </structfield>
or <structfield> &v4l2-selection;::target </structfield> is not supported, or
the <structfield> &v4l2-selection;::flags </structfield> are invalid.</para>
<para>Given buffer type <structfield>type</structfield> or
the selection target <structfield>target</structfield> is not supported,
or the <structfield>flags</structfield> argument is not valid.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>ERANGE</errorcode></term>
<listitem>
<para>it is not possible to adjust a rectangle <structfield>
&v4l2-selection;::r </structfield> that satisfies all contraints from
<structfield> &v4l2-selection;::flags </structfield>.</para>
<para>It is not possible to adjust &v4l2-rect; <structfield>
r</structfield> rectangle to satisfy all contraints given in the
<structfield>flags</structfield> argument.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>it is not possible to apply change of selection rectangle at the moment.
Usually because streaming is in progress.</para>
<para>It is not possible to apply change of the selection rectangle
at the moment. Usually because streaming is in progress.</para>
</listitem>
</varlistentry>
</variablelist>
......
......@@ -124,12 +124,35 @@ printf ("Version: %u.%u.%u\n",
<row>
<entry>__u32</entry>
<entry><structfield>capabilities</structfield></entry>
<entry>Device capabilities, see <xref
linkend="device-capabilities" />.</entry>
<entry>Available capabilities of the physical device as a whole, see <xref
linkend="device-capabilities" />. The same physical device can export
multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and /dev/radioZ).
The <structfield>capabilities</structfield> field should contain a union
of all capabilities available around the several V4L2 devices exported
to userspace.
For all those devices the <structfield>capabilities</structfield> field
returns the same set of capabilities. This allows applications to open
just one of the devices (typically the video device) and discover whether
video, vbi and/or radio are also supported.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[4]</entry>
<entry><structfield>device_caps</structfield></entry>
<entry>Device capabilities of the opened device, see <xref
linkend="device-capabilities" />. Should contain the available capabilities
of that specific device node. So, for example, <structfield>device_caps</structfield>
of a radio device will only contain radio related capabilities and
no video or vbi capabilities. This field is only set if the <structfield>capabilities</structfield>
field contains the <constant>V4L2_CAP_DEVICE_CAPS</constant> capability.
Only the <structfield>capabilities</structfield> field can have the
<constant>V4L2_CAP_DEVICE_CAPS</constant> capability, <structfield>device_caps</structfield>
will never set <constant>V4L2_CAP_DEVICE_CAPS</constant>.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[3]</entry>
<entry>Reserved for future extensions. Drivers must set
this array to zero.</entry>
</row>
......@@ -276,6 +299,13 @@ linkend="async">asynchronous</link> I/O methods.</entry>
<entry>The device supports the <link
linkend="mmap">streaming</link> I/O method.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_DEVICE_CAPS</constant></entry>
<entry>0x80000000</entry>
<entry>The driver fills the <structfield>device_caps</structfield>
field. This capability can only appear in the <structfield>capabilities</structfield>
field and never in the <structfield>device_caps</structfield> field.</entry>
</row>
</tbody>
</tgroup>
</table>
......
......@@ -96,8 +96,8 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[7]</entry>
<entry>Reserved for future extensions. Drivers and
applications must set the array to zero.</entry>
<entry>Reserved for future extensions. Applications
must set the array to zero.</entry>
</row>
</tbody>
</tgroup>
......@@ -112,7 +112,7 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The <structfield>tuner</structfield> index is out of
bounds or the value in the <structfield>type</structfield> field is
bounds, the wrap_around value is not supported or the value in the <structfield>type</structfield> field is
wrong.</para>
</listitem>
</varlistentry>
......
......@@ -119,4 +119,5 @@ o Cards based on the Phillips saa7134 PCI bridge:
- Compro Videomate DVB-T300
- Compro Videomate DVB-T200
- AVerMedia AVerTVHD MCE A180
- KWorld PC150-U ATSC Hybrid
......@@ -66,5 +66,16 @@ dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
For LME2510C
dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
---------------------------------------------------------------------
The m88rs2000 tuner driver can be found in windows/system32/drivers
US2B0D.sys (dated 29 Jun 2010)
dd if=US2B0D.sys ibs=1 skip=34432 count=3871 of=dvb-usb-lme2510c-rs2000.fw
We need to modify id of rs2000 firmware or it will warm boot id 3344:1120.
echo -ne \\xF0\\x22 | dd conv=notrunc bs=1 count=2 seek=266 of=dvb-usb-lme2510c-rs2000.fw
Copy the firmware file(s) to /lib/firmware
......@@ -32,3 +32,4 @@
31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39]
32 -> MPX-885
33 -> Mygica X8507 [14f1:8502]
34 -> TerraTec Cinergy T PCIe Dual [153b:117e]
......@@ -59,7 +59,7 @@
58 -> Pinnacle PCTV HD 800i [11bd:0051]
59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530]
60 -> Pinnacle Hybrid PCTV [12ab:1788]
61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618]
61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618,107d:6619]
62 -> PowerColor RA330 [14f1:ea3d]
63 -> Geniatech X8000-MT DVBT [14f1:8852]
64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30]
......@@ -87,3 +87,5 @@
86 -> TeVii S464 DVB-S/S2 [d464:9022]
87 -> Leadtek WinFast DTV2000 H PLUS [107d:6f42]
88 -> Leadtek WinFast DTV1800 H (XC4000) [107d:6f38]
89 -> Leadtek TV2000 XP Global (SC4100) [107d:6f36]
90 -> Leadtek TV2000 XP Global (XC4100) [107d:6f43]
......@@ -7,7 +7,7 @@
6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
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]
9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a,093b:a003]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
11 -> Terratec Hybrid XS (em2880)
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
......@@ -61,7 +61,7 @@
61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
62 -> Gadmei TVR200 (em2820/em2840)
63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303]
64 -> Easy Cap Capture DC-60 (em2860)
64 -> Easy Cap Capture DC-60 (em2860) [1b80:e309]
65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515]
66 -> Empire dual TV (em2880)
67 -> Terratec Grabby (em2860) [0ccd:0096,0ccd:10AF]
......@@ -76,7 +76,11 @@
76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340]
77 -> EM2874 Leadership ISDBT (em2874)
78 -> PCTV nanoStick T2 290e (em28174)
79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad]
79 -> Terratec Cinergy H5 (em2884) [0ccd:008e,0ccd:00ac,0ccd:10a2,0ccd:10ad]
80 -> PCTV DVB-S2 Stick (460e) (em28174)
81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605]
82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2]
83 -> Honestech Vidbox NW03 (em2860) [eb1a:5006]
84 -> MaxMedia UB425-TC (em2874) [1b80:e425]
85 -> PCTV QuatroStick (510e) (em2884) [2304:0242]
86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251]
......@@ -187,3 +187,4 @@
186 -> Beholder BeholdTV 501 [5ace:5010]
187 -> Beholder BeholdTV 503 FM [5ace:5030]
188 -> Sensoray 811/911 [6000:0811,6000:0911]
189 -> Kworld PC150-U [17de:a134]
......@@ -78,10 +78,11 @@ tuner=77 - TCL tuner MF02GIP-5N-E
tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
tuner=81 - Xceive 4000 tuner
tuner=81 - Partsnic (Daewoo) PTI-5NF05
tuner=82 - Philips CU1216L
tuner=83 - NXP TDA18271
tuner=84 - Sony BTF-Pxn01Z
tuner=85 - Philips FQ1236 MK5
tuner=86 - Tena TNF5337 MFD
tuner=87 - Xceive 4000 tuner
tuner=88 - Xceive 5000C tuner
Samsung S5P/EXYNOS4 FIMC driver
Copyright (C) 2012 Samsung Electronics Co., Ltd.
---------------------------------------------------------------------------
The FIMC (Fully Interactive Mobile Camera) device available in Samsung
SoC Application Processors is an integrated camera host interface, color
space converter, image resizer and rotator. It's also capable of capturing
data from LCD controller (FIMD) through the SoC internal writeback data
path. There are multiple FIMC instances in the SoCs (up to 4), having
slightly different capabilities, like pixel alignment constraints, rotator
availability, LCD writeback support, etc. The driver is located at
drivers/media/video/s5p-fimc directory.
1. Supported SoCs
=================
S5PC100 (mem-to-mem only), S5PV210, EXYNOS4210
2. Supported features
=====================
- camera parallel interface capture (ITU-R.BT601/565);
- camera serial interface capture (MIPI-CSI2);
- memory-to-memory processing (color space conversion, scaling, mirror
and rotation);
- dynamic pipeline re-configuration at runtime (re-attachment of any FIMC
instance to any parallel video input or any MIPI-CSI front-end);
- runtime PM and system wide suspend/resume
Not currently supported:
- LCD writeback input
- per frame clock gating (mem-to-mem)
3. Files partitioning
=====================
- media device driver
drivers/media/video/s5p-fimc/fimc-mdevice.[ch]
- camera capture video device driver
drivers/media/video/s5p-fimc/fimc-capture.c
- MIPI-CSI2 receiver subdev
drivers/media/video/s5p-fimc/mipi-csis.[ch]
- video post-processor (mem-to-mem)
drivers/media/video/s5p-fimc/fimc-core.c
- common files
drivers/media/video/s5p-fimc/fimc-core.h
drivers/media/video/s5p-fimc/fimc-reg.h
drivers/media/video/s5p-fimc/regs-fimc.h
4. User space interfaces
========================
4.1. Media device interface
The driver supports Media Controller API as defined at
http://http://linuxtv.org/downloads/v4l-dvb-apis/media_common.html
The media device driver name is "SAMSUNG S5P FIMC".
The purpose of this interface is to allow changing assignment of FIMC instances
to the SoC peripheral camera input at runtime and optionally to control internal
connections of the MIPI-CSIS device(s) to the FIMC entities.
The media device interface allows to configure the SoC for capturing image
data from the sensor through more than one FIMC instance (e.g. for simultaneous
viewfinder and still capture setup).
Reconfiguration is done by enabling/disabling media links created by the driver
during initialization. The internal device topology can be easily discovered
through media entity and links enumeration.
4.2. Memory-to-memory video node
V4L2 memory-to-memory interface at /dev/video? device node. This is standalone
video device, it has no media pads. However please note the mem-to-mem and
capture video node operation on same FIMC instance is not allowed. The driver
detects such cases but the applications should prevent them to avoid an
undefined behaviour.
4.3. Capture video node
The driver supports V4L2 Video Capture Interface as defined at:
http://linuxtv.org/downloads/v4l-dvb-apis/devices.html
At the capture and mem-to-mem video nodes only the multi-planar API is
supported. For more details see:
http://linuxtv.org/downloads/v4l-dvb-apis/planar-apis.html
4.4. Camera capture subdevs
Each FIMC instance exports a sub-device node (/dev/v4l-subdev?), a sub-device
node is also created per each available and enabled at the platform level
MIPI-CSI receiver device (currently up to two).
4.5. sysfs
In order to enable more precise camera pipeline control through the sub-device
API the driver creates a sysfs entry associated with "s5p-fimc-md" platform
device. The entry path is: /sys/platform/devices/s5p-fimc-md/subdev_conf_mode.
In typical use case there could be a following capture pipeline configuration:
sensor subdev -> mipi-csi subdev -> fimc subdev -> video node
When we configure these devices through sub-device API at user space, the
configuration flow must be from left to right, and the video node is
configured as last one.
When we don't use sub-device user space API the whole configuration of all
devices belonging to the pipeline is done at the video node driver.
The sysfs entry allows to instruct the capture node driver not to configure
the sub-devices (format, crop), to avoid resetting the subdevs' configuration
when the last configuration steps at the video node is performed.
For full sub-device control support (subdevs configured at user space before
starting streaming):
# echo "sub-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
For V4L2 video node control only (subdevs configured internally by the host
driver):
# echo "vid-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
This is a default option.
5. Device mapping to video and subdev device nodes
==================================================
There are associated two video device nodes with each device instance in
hardware - video capture and mem-to-mem and additionally a subdev node for
more precise FIMC capture subsystem control. In addition a separate v4l2
sub-device node is created per each MIPI-CSIS device.
How to find out which /dev/video? or /dev/v4l-subdev? is assigned to which
device?
You can either grep through the kernel log to find relevant information, i.e.
# dmesg | grep -i fimc
(note that udev, if present, might still have rearranged the video nodes),
or retrieve the information from /dev/media? with help of the media-ctl tool:
# media-ctl -p
6. Platform support
===================
The machine code (plat-s5p and arch/arm/mach-*) must select following options
CONFIG_S5P_DEV_FIMC0 mandatory
CONFIG_S5P_DEV_FIMC1 \
CONFIG_S5P_DEV_FIMC2 | optional
CONFIG_S5P_DEV_FIMC3 |
CONFIG_S5P_SETUP_FIMC /
CONFIG_S5P_SETUP_MIPIPHY \
CONFIG_S5P_DEV_CSIS0 | optional for MIPI-CSI interface
CONFIG_S5P_DEV_CSIS1 /
Except that, relevant s5p_device_fimc? should be registered in the machine code
in addition to a "s5p-fimc-md" platform device to which the media device driver
is bound. The "s5p-fimc-md" device instance is required even if only mem-to-mem
operation is used.
The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be
passed as the "s5p-fimc-md" device platform_data. The platform data structure
is defined in file include/media/s5p_fimc.h.
7. Build
========
This driver depends on following config options:
PLAT_S5P,
PM_RUNTIME,
I2C,
REGULATOR,
VIDEO_V4L2_SUBDEV_API,
If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
optional s5p-csis.ko (MIPI-CSI receiver subdev).
......@@ -217,6 +217,7 @@ 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
pac7302 06f8:301b Hercules Link
nw80x 0728:d001 AVerMedia Camguard
spca508 0733:0110 ViewQuest VQ110
spca501 0733:0401 Intel Create and Share
......
......@@ -661,7 +661,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "dma", dma_clk)
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
_REGISTER_CLOCK(NULL, "brom", brom_clk)
_REGISTER_CLOCK(NULL, "emma", emma_clk)
_REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk)
_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
_REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
_REGISTER_CLOCK(NULL, "emi", emi_clk)
......
......@@ -50,6 +50,8 @@ extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[];
extern const struct imx_mx2_camera_data imx27_mx2_camera_data;
#define imx27_add_mx2_camera(pdata) \
imx_add_mx2_camera(&imx27_mx2_camera_data, pdata)
#define imx27_add_mx2_emmaprp(pdata) \
imx_add_mx2_emmaprp(&imx27_mx2_camera_data)
extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data;
#define imx27_add_mxc_ehci_otg(pdata) \
......
......@@ -62,3 +62,21 @@ struct platform_device *__init imx_add_mx2_camera(
res, data->iobaseemmaprp ? 4 : 2,
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
}
struct platform_device *__init imx_add_mx2_emmaprp(
const struct imx_mx2_camera_data *data)
{
struct resource res[] = {
{
.start = data->iobaseemmaprp,
.end = data->iobaseemmaprp + data->iosizeemmaprp - 1,
.flags = IORESOURCE_MEM,
}, {
.start = data->irqemmaprp,
.end = data->irqemmaprp,
.flags = IORESOURCE_IRQ,
},
};
return imx_add_platform_device_dmamask("m2m-emmaprp", 0,
res, 2, NULL, 0, DMA_BIT_MASK(32));
}
......@@ -223,6 +223,8 @@ struct imx_mx2_camera_data {
struct platform_device *__init imx_add_mx2_camera(
const struct imx_mx2_camera_data *data,
const struct mx2_camera_platform_data *pdata);
struct platform_device *__init imx_add_mx2_emmaprp(
const struct imx_mx2_camera_data *data);
#include <mach/mxc_ehci.h>
struct imx_mxc_ehci_data {
......
......@@ -2026,6 +2026,16 @@ static bool hid_ignore(struct hid_device *hdev)
if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST &&
hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
return true;
/*
* The Keene FM transmitter USB device has the same USB ID as
* the Logitech AudioHub Speaker, but it should ignore the hid.
* Check if the name is that of the Keene device.
* For reference: the name of the AudioHub is
* "HOLTEK AudioHub Speaker".
*/
if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB &&
!strcmp(hdev->name, "HOLTEK B-LINK USB Audio "))
return true;
break;
case USB_VENDOR_ID_SOUNDGRAPH:
if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
......
......@@ -471,6 +471,7 @@
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
......
......@@ -29,5 +29,5 @@ obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
ccflags-y += -Idrivers/media/dvb/dvb-core
ccflags-y += -Idrivers/media/dvb/frontends
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
......@@ -168,7 +168,7 @@ int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
int i;
if (0 == divisor)
return -1;
return -EINVAL;
q = dividend / divisor;
remainder = dividend - q * divisor;
......@@ -194,10 +194,13 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
u8 tf_ntch;
u32 t;
u32 quotient, fraction;
int ret;
/* Set PLL divider according to RF frequency */
fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
&quotient, &fraction);
ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
&quotient, &fraction);
if (ret != 0)
return ret;
/* 20-bit fraction */
fraction >>= 12;
......
......@@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe)
/*
* ToDo: Add code here to implement a OS blocking
*/
msleep(10);
msleep(100);
return 0;
}
......@@ -2226,7 +2226,7 @@ static struct dvb_tuner_ops mt2063_ops = {
.info = {
.name = "MT2063 Silicon Tuner",
.frequency_min = 45000000,
.frequency_max = 850000000,
.frequency_max = 865000000,
.frequency_step = 0,
},
......
......@@ -23,10 +23,6 @@ static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
return NULL;
}
int mt2063_setTune(struct dvb_frontend *fe, u32 f_in,
u32 bw_in,
enum MTTune_atv_standard tv_type);
/* FIXME: Should use the standard DVB attachment interfaces */
unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
......
......@@ -1868,6 +1868,10 @@ struct tunertype tuners[] = {
.params = tuner_tena_tnf_5337_params,
.count = ARRAY_SIZE(tuner_tena_tnf_5337_params),
},
[TUNER_XC5000C] = { /* Xceive 5000C */
.name = "Xceive 5000C tuner",
/* see xc5000.c for details */
},
};
EXPORT_SYMBOL(tuners);
......
......@@ -49,9 +49,6 @@ static LIST_HEAD(hybrid_tuner_instance_list);
#define dprintk(level, fmt, arg...) if (debug >= level) \
printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
struct xc5000_priv {
struct tuner_i2c_props i2c_props;
struct list_head hybrid_tuner_instance_list;
......@@ -62,6 +59,8 @@ struct xc5000_priv {
u8 video_standard;
u8 rf_mode;
u8 radio_input;
int chip_id;
};
/* Misc Defines */
......@@ -204,6 +203,33 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
};
struct xc5000_fw_cfg {
char *name;
u16 size;
};
static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
.name = "dvb-fe-xc5000-1.6.114.fw",
.size = 12401,
};
static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
.name = "dvb-fe-xc5000c-41.024.5-31875.fw",
.size = 16503,
};
static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
{
switch (chip_id) {
default:
case XC5000A:
return &xc5000a_1_6_114;
case XC5000C:
return &xc5000c_41_024_5_31875;
}
}
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
......@@ -552,12 +578,14 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
struct xc5000_priv *priv = fe->tuner_priv;
const struct firmware *fw;
int ret;
const struct xc5000_fw_cfg *desired_fw =
xc5000_assign_firmware(priv->chip_id);
/* request the firmware, this will block and timeout */
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
XC5000_DEFAULT_FIRMWARE);
desired_fw->name);
ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
ret = request_firmware(&fw, desired_fw->name,
priv->i2c_props.adap->dev.parent);
if (ret) {
printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
......@@ -569,7 +597,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
ret = XC_RESULT_SUCCESS;
}
if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
if (fw->size != desired_fw->size) {
printk(KERN_ERR "xc5000: firmware incorrect size\n");
ret = XC_RESULT_RESET_FAILURE;
} else {
......@@ -1139,6 +1167,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
if (priv->radio_input == 0)
priv->radio_input = cfg->radio_input;
/* don't override chip id if it's already been set
unless explicitly specified */
if ((priv->chip_id == 0) || (cfg->chip_id))
/* use default chip id if none specified, set to 0 so
it can be overridden if this is a hybrid driver */
priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
*/
......
......@@ -27,10 +27,15 @@
struct dvb_frontend;
struct i2c_adapter;
#define XC5000A 1
#define XC5000C 2
struct xc5000_config {
u8 i2c_address;
u32 if_khz;
u8 radio_input;
int chip_id;
};
/* xc5000 callback command */
......
......@@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
struct drxk_config config;
memset(&config, 0, sizeof(config));
config.microcode_name = "drxk_a3.mc";
config.adr = 0x29 + (input->nr & 1);
fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
......
......@@ -32,8 +32,6 @@
#include <asm/dma.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/ca.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <linux/socket.h>
#include "dmxdev.h"
......
......@@ -655,6 +655,8 @@ static int dvb_frontend_thread(void *data)
dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
re_tune = true;
fepriv->state = FESTATE_TUNED;
} else {
re_tune = false;
}
if (fe->ops.tune)
......
......@@ -361,6 +361,14 @@ config DVB_USB_EC168
help
Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
config DVB_USB_AZ6007
tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
depends on DVB_USB
select DVB_DRXK if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
help
Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers.
config DVB_USB_AZ6027
tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
depends on DVB_USB
......@@ -378,6 +386,7 @@ config DVB_USB_LME2510
select DVB_IX2505V if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
help
Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
......@@ -403,3 +412,13 @@ config DVB_USB_MXL111SF
select VIDEO_TVEEPROM
help
Say Y here to support the MxL111SF USB2.0 DTV receiver.
config DVB_USB_RTL28XXU
tristate "Realtek RTL28xxU DVB USB support"
depends on DVB_USB && EXPERIMENTAL
select DVB_RTL2830
select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Realtek RTL28xxU DVB USB receiver.
......@@ -54,7 +54,6 @@ obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
dvb-usb-opera-objs = opera1.o
obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
dvb-usb-af9005-objs = af9005.o af9005-fe.o
obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
......@@ -88,6 +87,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-az6007-objs = az6007.o
obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
dvb-usb-az6027-objs = az6027.o
obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
......@@ -105,8 +107,12 @@ obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
dvb-usb-rtl28xxu-objs = rtl28xxu.o
obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
# due to tuner-xc3028
ccflags-y += -Idrivers/media/common/tuners
EXTRA_CFLAGS += -Idrivers/media/dvb/ttpci
ccflags-y += -I$(srctree)/drivers/media/common/tuners
ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
......@@ -1164,6 +1164,41 @@ static int af9015_af9013_sleep(struct dvb_frontend *fe)
return ret;
}
/* override tuner callbacks for resource locking */
static int af9015_tuner_init(struct dvb_frontend *fe)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;
if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;
ret = priv->tuner_init[adap->id](fe);
mutex_unlock(&adap->dev->usb_mutex);
return ret;
}
/* override tuner callbacks for resource locking */
static int af9015_tuner_sleep(struct dvb_frontend *fe)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;
if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;
ret = priv->tuner_sleep[adap->id](fe);
mutex_unlock(&adap->dev->usb_mutex);
return ret;
}
static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
{
int ret;
......@@ -1283,6 +1318,7 @@ static struct mxl5007t_config af9015_mxl5007t_config = {
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
int ret;
struct af9015_state *state = adap->dev->priv;
deb_info("%s:\n", __func__);
switch (af9015_af9013_config[adap->id].tuner) {
......@@ -1340,6 +1376,19 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
err("Unknown tuner id:%d",
af9015_af9013_config[adap->id].tuner);
}
if (adap->fe_adap[0].fe->ops.tuner_ops.init) {
state->tuner_init[adap->id] =
adap->fe_adap[0].fe->ops.tuner_ops.init;
adap->fe_adap[0].fe->ops.tuner_ops.init = af9015_tuner_init;
}
if (adap->fe_adap[0].fe->ops.tuner_ops.sleep) {
state->tuner_sleep[adap->id] =
adap->fe_adap[0].fe->ops.tuner_ops.sleep;
adap->fe_adap[0].fe->ops.tuner_ops.sleep = af9015_tuner_sleep;
}
return ret;
}
......
......@@ -108,6 +108,8 @@ struct af9015_state {
int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
int (*init[2]) (struct dvb_frontend *fe);
int (*sleep[2]) (struct dvb_frontend *fe);
int (*tuner_init[2]) (struct dvb_frontend *fe);
int (*tuner_sleep[2]) (struct dvb_frontend *fe);
};
struct af9015_config {
......
......@@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
u8 *rbuf, u8 rlen)
{
struct anysee_state *state = d->priv;
int act_len, ret;
int act_len, ret, i;
u8 buf[64];
memcpy(&buf[0], sbuf, slen);
......@@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
/* We need receive one message more after dvb_usb_generic_rw due
to weird transaction flow, which is 1 x send + 2 x receive. */
ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
if (!ret) {
if (ret)
goto error_unlock;
/* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
* (EPIPE, Broken pipe). Function supports currently msleep() as a
* parameter but I would not like to use it, since according to
* Documentation/timers/timers-howto.txt it should not be used such
* short, under < 20ms, sleeps. Repeating failed message would be
* better choice as not to add unwanted delays...
* Fixing that correctly is one of those or both;
* 1) use repeat if possible
* 2) add suitable delay
*/
/* get answer, retry few times if error returned */
for (i = 0; i < 3; i++) {
/* receive 2nd answer */
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
&act_len, 2000);
if (ret)
err("%s: recv bulk message failed: %d", __func__, ret);
else {
if (ret) {
deb_info("%s: recv bulk message failed: %d",
__func__, ret);
} else {
deb_xfer("<<< ");
debug_dump(buf, rlen, deb_xfer);
if (buf[63] != 0x4f)
deb_info("%s: cmd failed\n", __func__);
break;
}
}
if (ret) {
/* all retries failed, it is fatal */
err("%s: recv bulk message failed: %d", __func__, ret);
goto error_unlock;
}
/* read request, copy returned data to return buf */
if (!ret && rbuf && rlen)
if (rbuf && rlen)
memcpy(rbuf, buf, rlen);
error_unlock:
mutex_unlock(&anysee_usb_mutex);
return ret;
......
此差异已折叠。
......@@ -677,11 +677,9 @@ static void dib0700_rc_urb_completion(struct urb *purb)
u8 toggle;
deb_info("%s()\n", __func__);
if (d == NULL)
return;
if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
kfree(purb->transfer_buffer);
usb_free_urb(purb);
return;
}
......@@ -690,6 +688,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if (purb->status < 0) {
deb_info("discontinuing polling\n");
kfree(purb->transfer_buffer);
usb_free_urb(purb);
return;
}
......@@ -784,8 +783,11 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
dib0700_rc_urb_completion, d);
ret = usb_submit_urb(purb, GFP_ATOMIC);
if (ret)
if (ret) {
err("rc submit urb failed\n");
kfree(purb->transfer_buffer);
usb_free_urb(purb);
}
return ret;
}
......
......@@ -51,6 +51,7 @@
#define USB_VID_PINNACLE 0x2304
#define USB_VID_PCTV 0x2013
#define USB_VID_PIXELVIEW 0x1554
#define USB_VID_REALTEK 0x0bda
#define USB_VID_TECHNOTREND 0x0b48
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
......@@ -80,6 +81,7 @@
#define USB_PID_ANSONIC_DVBT_USB 0x6000
#define USB_PID_ANYSEE 0x861f
#define USB_PID_AZUREWAVE_AD_TU700 0x3237
#define USB_PID_AZUREWAVE_6007 0x0ccd
#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
......@@ -125,6 +127,8 @@
#define USB_PID_E3C_EC168_3 0xfffb
#define USB_PID_E3C_EC168_4 0x1001
#define USB_PID_E3C_EC168_5 0x1002
#define USB_PID_FREECOM_DVBT 0x0160
#define USB_PID_FREECOM_DVBT_2 0x0161
#define USB_PID_UNIWILL_STK7700P 0x6003
#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
......@@ -226,6 +230,8 @@
#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
#define USB_PID_TERRATEC_H7 0x10b4
#define USB_PID_TERRATEC_H7_2 0x10a3
#define USB_PID_TERRATEC_T3 0x10a0
#define USB_PID_TERRATEC_T5 0x10a1
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
......@@ -249,6 +255,8 @@
#define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222
#define USB_PID_PCTV_452E 0x021f
#define USB_PID_REALTEK_RTL2831U 0x2831
#define USB_PID_REALTEK_RTL2832U 0x2832
#define USB_PID_TECHNOTREND_CONNECT_S2_3600 0x3007
#define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI 0x300a
#define USB_PID_NEBULA_DIGITV 0x0201
......
......@@ -64,6 +64,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct it913x_state {
u8 id;
struct ite_config it913x_config;
u8 pid_filter_onoff;
};
struct ite_config it913x_config;
......@@ -259,15 +260,16 @@ static u32 it913x_query(struct usb_device *udev, u8 pro)
static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct it913x_state *st = adap->dev->priv;
struct usb_device *udev = adap->dev->udev;
int ret;
u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&adap->dev->i2c_mutex);
deb_info(1, "PID_C (%02x)", onoff);
ret = it913x_wr_reg(udev, pro, PID_EN, onoff);
ret = it913x_wr_reg(udev, pro, PID_EN, st->pid_filter_onoff);
mutex_unlock(&adap->dev->i2c_mutex);
return ret;
......@@ -276,12 +278,13 @@ static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int it913x_pid_filter(struct dvb_usb_adapter *adap,
int index, u16 pid, int onoff)
{
struct it913x_state *st = adap->dev->priv;
struct usb_device *udev = adap->dev->udev;
int ret;
u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&adap->dev->i2c_mutex);
deb_info(1, "PID_F (%02x)", onoff);
ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff));
......@@ -292,6 +295,13 @@ static int it913x_pid_filter(struct dvb_usb_adapter *adap,
ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f));
if (udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
ret |= it913x_wr_reg(udev, pro, PID_EN, !onoff);
st->pid_filter_onoff = !onoff;
} else
st->pid_filter_onoff =
adap->fe_adap[adap->active_fe].pid_filtering;
mutex_unlock(&adap->dev->i2c_mutex);
return 0;
}
......@@ -316,8 +326,8 @@ static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int ret;
u32 reg;
u8 pro;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&d->i2c_mutex);
debug_data_snipet(1, "Message out", msg[0].buf);
deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
......@@ -358,8 +368,7 @@ static int it913x_rc_query(struct dvb_usb_device *d)
int ret;
u32 key;
/* Avoid conflict with frontends*/
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&d->i2c_mutex);
ret = it913x_io(d->udev, READ_LONG, PRO_LINK, CMD_IR_GET,
0, 0, &ibuf[0], sizeof(ibuf));
......@@ -388,19 +397,12 @@ static int ite_firmware_select(struct usb_device *udev,
{
int sw;
/* auto switch */
if (le16_to_cpu(udev->descriptor.idProduct) ==
USB_PID_ITETECH_IT9135)
sw = IT9135_V1_FW;
else if (le16_to_cpu(udev->descriptor.idProduct) ==
USB_PID_ITETECH_IT9135_9005)
if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2)
sw = IT9137_FW;
else if (it913x_config.chip_ver == 1)
sw = IT9135_V1_FW;
else if (le16_to_cpu(udev->descriptor.idProduct) ==
USB_PID_ITETECH_IT9135_9006) {
else
sw = IT9135_V2_FW;
if (it913x_config.tuner_id_0 == 0)
it913x_config.tuner_id_0 = IT9135_60;
} else
sw = IT9137_FW;
/* force switch */
if (dvb_usb_it913x_firmware != IT9135_AUTO)
......@@ -410,41 +412,103 @@ static int ite_firmware_select(struct usb_device *udev,
case IT9135_V1_FW:
it913x_config.firmware_ver = 1;
it913x_config.adc_x2 = 1;
it913x_config.read_slevel = false;
props->firmware = fw_it9135_v1;
break;
case IT9135_V2_FW:
it913x_config.firmware_ver = 1;
it913x_config.adc_x2 = 1;
it913x_config.read_slevel = false;
props->firmware = fw_it9135_v2;
switch (it913x_config.tuner_id_0) {
case IT9135_61:
case IT9135_62:
break;
default:
info("Unknown tuner ID applying default 0x60");
case IT9135_60:
it913x_config.tuner_id_0 = IT9135_60;
}
break;
case IT9137_FW:
default:
it913x_config.firmware_ver = 0;
it913x_config.adc_x2 = 0;
it913x_config.read_slevel = true;
props->firmware = fw_it9137;
}
return 0;
}
static void it913x_select_remote(struct usb_device *udev,
struct dvb_usb_device_properties *props)
{
switch (le16_to_cpu(udev->descriptor.idProduct)) {
case USB_PID_ITETECH_IT9135_9005:
props->rc.core.rc_codes = RC_MAP_IT913X_V2;
return;
default:
props->rc.core.rc_codes = RC_MAP_IT913X_V1;
}
return;
}
#define TS_MPEG_PKT_SIZE 188
#define EP_LOW 21
#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE)
#define EP_HIGH 348
#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE)
static int it913x_identify_state(struct usb_device *udev,
struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc,
int *cold)
static int it913x_select_config(struct usb_device *udev,
struct dvb_usb_device_properties *props)
{
int ret = 0, firm_no;
u8 reg, remote;
int ret = 0, reg;
bool proprietary_ir = false;
firm_no = it913x_return_status(udev);
if (it913x_config.chip_ver == 0x02
&& it913x_config.chip_type == 0x9135)
reg = it913x_read_reg(udev, 0x461d);
else
reg = it913x_read_reg(udev, 0x461b);
/* checnk for dual mode */
it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5);
if (reg < 0)
return reg;
if (reg == 0) {
it913x_config.dual_mode = 0;
it913x_config.tuner_id_0 = IT9135_38;
proprietary_ir = true;
} else {
/* TS mode */
reg = it913x_read_reg(udev, 0x49c5);
if (reg < 0)
return reg;
it913x_config.dual_mode = reg;
/* IR mode type */
reg = it913x_read_reg(udev, 0x49ac);
if (reg < 0)
return reg;
if (reg == 5) {
info("Remote propriety (raw) mode");
proprietary_ir = true;
} else if (reg == 1) {
info("Remote HID mode NOT SUPPORTED");
proprietary_ir = false;
props->rc.core.rc_codes = NULL;
} else
props->rc.core.rc_codes = NULL;
/* Tuner_id */
reg = it913x_read_reg(udev, 0x49d0);
if (reg < 0)
return reg;
it913x_config.tuner_id_0 = reg;
}
if (proprietary_ir)
it913x_select_remote(udev, props);
if (udev->speed != USB_SPEED_HIGH) {
props->adapter[0].fe[0].pid_filter_count = 5;
......@@ -459,17 +523,6 @@ static int it913x_identify_state(struct usb_device *udev,
if(props->adapter[0].fe[0].pid_filter_count == 5)
props->adapter[0].fe[0].pid_filter_count = 31;
/* TODO different remotes */
remote = it913x_read_reg(udev, 0x49ac); /* Remote */
if (remote == 0)
props->rc.core.rc_codes = NULL;
/* TODO at the moment tuner_id is always assigned to 0x38 */
it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
, remote, it913x_config.tuner_id_0);
/* Select Stream Buffer Size and pid filter option*/
if (pid_filter) {
props->adapter[0].fe[0].stream.u.bulk.buffersize =
......@@ -490,8 +543,29 @@ static int it913x_identify_state(struct usb_device *udev,
} else
props->num_adapters = 1;
info("Dual mode=%x Tuner Type=%x", it913x_config.dual_mode,
it913x_config.tuner_id_0);
ret = ite_firmware_select(udev, props);
return ret;
}
static int it913x_identify_state(struct usb_device *udev,
struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc,
int *cold)
{
int ret = 0, firm_no;
u8 reg;
firm_no = it913x_return_status(udev);
/* Read and select config */
ret = it913x_select_config(udev, props);
if (ret < 0)
return ret;
if (firm_no > 0) {
*cold = 0;
return 0;
......@@ -538,18 +612,22 @@ static int it913x_identify_state(struct usb_device *udev,
static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct it913x_state *st = adap->dev->priv;
int ret = 0;
u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
deb_info(1, "STM (%02x)", onoff);
if (!onoff)
if (!onoff) {
mutex_lock(&adap->dev->i2c_mutex);
ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1);
mutex_unlock(&adap->dev->i2c_mutex);
st->pid_filter_onoff =
adap->fe_adap[adap->active_fe].pid_filtering;
mutex_unlock(&adap->dev->i2c_mutex);
}
return ret;
}
......@@ -789,7 +867,7 @@ static struct dvb_usb_device_properties it913x_properties = {
.rc_query = it913x_rc_query,
.rc_interval = IT913X_POLL,
.allowed_protos = RC_TYPE_NEC,
.rc_codes = RC_MAP_MSI_DIGIVOX_III,
.rc_codes = RC_MAP_IT913X_V1,
},
.i2c_algo = &it913x_i2c_algo,
.num_device_descs = 5,
......@@ -823,5 +901,5 @@ module_usb_driver(it913x_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("it913x USB 2 Driver");
MODULE_VERSION("1.22");
MODULE_VERSION("1.27");
MODULE_LICENSE("GPL");
......@@ -77,6 +77,7 @@
#include "stv0299.h"
#include "dvb-pll.h"
#include "z0194a.h"
#include "m88rs2000.h"
......@@ -104,7 +105,7 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
static int pid_filter;
module_param_named(pid, pid_filter, int, 0644);
MODULE_PARM_DESC(pid, "set default 0=on 1=off");
MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
......@@ -113,6 +114,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define TUNER_LG 0x1
#define TUNER_S7395 0x2
#define TUNER_S0194 0x3
#define TUNER_RS2000 0x4
struct lme2510_state {
u8 id;
......@@ -121,6 +123,8 @@ struct lme2510_state {
u8 signal_level;
u8 signal_sn;
u8 time_key;
u8 last_key;
u8 key_timeout;
u8 i2c_talk_onoff;
u8 i2c_gate;
u8 i2c_tuner_gate_w;
......@@ -128,6 +132,7 @@ struct lme2510_state {
u8 i2c_tuner_addr;
u8 stream_on;
u8 pid_size;
u8 pid_off;
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
......@@ -178,14 +183,8 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
/* the read/write capped at 64 */
memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
msleep(10);
ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
rlen : 64 , 0x01);
......@@ -199,9 +198,14 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
static int lme2510_stream_restart(struct dvb_usb_device *d)
{
static u8 stream_on[] = LME_ST_ON_W;
struct lme2510_state *st = d->priv;
u8 all_pids[] = LME_ALL_PIDS;
u8 stream_on[] = LME_ST_ON_W;
int ret;
u8 rbuff[10];
u8 rbuff[1];
if (st->pid_off)
ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
rbuff, sizeof(rbuff));
/*Restart Stream Command*/
ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
rbuff, sizeof(rbuff));
......@@ -308,6 +312,14 @@ static void lme2510_int_response(struct urb *lme_urb)
((ibuf[2] & 0x01) << 0x03);
}
break;
case TUNER_RS2000:
if (ibuf[2] > 0)
st->signal_lock = 0xff;
else
st->signal_lock = 0xf0;
st->signal_level = ibuf[4];
st->signal_sn = ibuf[5];
st->time_key = ibuf[7];
default:
break;
}
......@@ -359,19 +371,20 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap)
static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct lme2510_state *st = adap->dev->priv;
static u8 clear_pid_reg[] = LME_CLEAR_PID;
static u8 clear_pid_reg[] = LME_ALL_PIDS;
static u8 rbuf[1];
int ret;
deb_info(1, "PID Clearing Filter");
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
if (ret < 0)
return -EAGAIN;
mutex_lock(&adap->dev->i2c_mutex);
if (!onoff)
if (!onoff) {
ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
st->pid_off = true;
} else
st->pid_off = false;
st->pid_size = 0;
......@@ -389,11 +402,9 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
pid, index, onoff);
if (onoff) {
ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
if (ret < 0)
return -EAGAIN;
ret |= lme2510_enable_pid(adap->dev, index, pid);
mutex_unlock(&adap->dev->i2c_mutex);
mutex_lock(&adap->dev->i2c_mutex);
ret |= lme2510_enable_pid(adap->dev, index, pid);
mutex_unlock(&adap->dev->i2c_mutex);
}
......@@ -425,9 +436,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
int ret = 0;
struct lme2510_state *st = d->priv;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (st->i2c_talk_onoff == 1) {
ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
......@@ -456,8 +464,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->i2c_talk_onoff = 0;
}
}
if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
msleep(5);
}
break;
case TUNER_S0194:
......@@ -472,10 +478,12 @@ static int lme2510_msg(struct dvb_usb_device *d,
}
}
break;
case TUNER_RS2000:
default:
break;
}
} else {
/* TODO rewrite this section */
switch (st->tuner_config) {
case TUNER_LG:
switch (wbuf[3]) {
......@@ -559,6 +567,24 @@ static int lme2510_msg(struct dvb_usb_device *d,
break;
}
break;
case TUNER_RS2000:
switch (wbuf[3]) {
case 0x8c:
rbuf[0] = 0x55;
rbuf[1] = 0xff;
if (st->last_key == st->time_key) {
st->key_timeout++;
if (st->key_timeout > 5)
rbuf[1] = 0;
} else
st->key_timeout = 0;
st->last_key = st->time_key;
break;
default:
lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
st->i2c_talk_onoff = 1;
break;
}
default:
break;
}
......@@ -568,8 +594,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
}
mutex_unlock(&d->i2c_mutex);
return ret;
}
......@@ -584,6 +608,8 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
u16 len;
u8 gate = st->i2c_gate;
mutex_lock(&d->i2c_mutex);
if (gate == 0)
gate = 5;
......@@ -622,6 +648,7 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
deb_info(1, "i2c transfer failed.");
mutex_unlock(&d->i2c_mutex);
return -EAGAIN;
}
......@@ -634,6 +661,8 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
}
}
}
mutex_unlock(&d->i2c_mutex);
return i;
}
......@@ -653,7 +682,7 @@ static int lme2510_identify_state(struct usb_device *udev,
struct dvb_usb_device_description **desc,
int *cold)
{
if (pid_filter > 0)
if (pid_filter != 2)
props->adapter[0].fe[0].caps &=
~DVB_USB_ADAP_NEED_PID_FILTERING;
*cold = 0;
......@@ -663,7 +692,7 @@ 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 clear_reg_3[] = LME_CLEAR_PID;
static u8 clear_reg_3[] = LME_ALL_PIDS;
static u8 rbuf[1];
int ret = 0, rlen = sizeof(rbuf);
......@@ -675,8 +704,7 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
else {
deb_info(1, "STM Steam Off");
/* mutex is here only to avoid collision with I2C */
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&adap->dev->i2c_mutex);
ret = lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
......@@ -781,16 +809,18 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
const char fw_c_rs2000[] = "dvb-usb-lme2510c-rs2000.fw";
const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
const char *fw_lme;
int ret, cold_fw;
int ret = 0, cold_fw;
cold = (cold > 0) ? (cold & 1) : 0;
cold_fw = !cold;
if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) {
switch (le16_to_cpu(udev->descriptor.idProduct)) {
case 0x1122:
switch (dvb_usb_lme2510_firmware) {
default:
dvb_usb_lme2510_firmware = TUNER_S0194;
......@@ -813,7 +843,8 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
cold_fw = 0;
break;
}
} else {
break;
case 0x1120:
switch (dvb_usb_lme2510_firmware) {
default:
dvb_usb_lme2510_firmware = TUNER_S7395;
......@@ -842,8 +873,17 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
cold_fw = 0;
break;
}
break;
case 0x22f0:
fw_lme = fw_c_rs2000;
ret = request_firmware(&fw, fw_lme, &udev->dev);
dvb_usb_lme2510_firmware = TUNER_RS2000;
break;
default:
fw_lme = fw_c_s7395;
}
if (cold_fw) {
info("FRM Loading %s file", fw_lme);
ret = lme2510_download_firmware(udev, fw);
......@@ -906,6 +946,29 @@ static struct stv0299_config sharp_z0194_config = {
.set_symbol_rate = sharp_z0194a_set_symbol_rate,
};
static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
int caller)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct dvb_usb_device *d = adap->dev;
struct lme2510_state *st = d->priv;
mutex_lock(&d->i2c_mutex);
if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
st->i2c_talk_onoff = 0;
lme2510_stream_restart(d);
}
mutex_unlock(&d->i2c_mutex);
return 0;
}
static struct m88rs2000_config m88rs2000_config = {
.demod_addr = 0xd0,
.tuner_addr = 0xc0,
.set_ts_params = dm04_rs2000_set_ts_param,
};
static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
......@@ -915,8 +978,7 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
static u8 rbuf[1];
int ret = 0, len = 3, rlen = 1;
if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&adap->dev->i2c_mutex);
switch (voltage) {
case SEC_VOLTAGE_18:
......@@ -937,12 +999,31 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
return (ret < 0) ? -ENODEV : 0;
}
static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct lme2510_state *st = adap->dev->priv;
*strength = (u16)((u32)st->signal_level * 0xffff / 0x7f);
return 0;
}
static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct lme2510_state *st = adap->dev->priv;
*snr = (u16)((u32)st->signal_sn * 0xffff / 0xff);
return 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",
" SHARP:BS2F7HZ0194"};
" SHARP:BS2F7HZ0194", " RS2000"};
char *name = adap->fe_adap[0].fe->ops.info.name;
strlcpy(name, desc, 128);
......@@ -958,60 +1039,82 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
int ret = 0;
st->i2c_talk_onoff = 1;
switch (le16_to_cpu(adap->dev->udev->descriptor.idProduct)) {
case 0x1122:
case 0x1120:
st->i2c_gate = 4;
adap->fe_adap[0].fe = dvb_attach(tda10086_attach,
&tda10086_config, &adap->dev->i2c_adap);
if (adap->fe_adap[0].fe) {
info("TUN Found Frontend TDA10086");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 4;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_LG;
if (dvb_usb_lme2510_firmware != TUNER_LG) {
dvb_usb_lme2510_firmware = TUNER_LG;
ret = lme_firmware_switch(adap->dev->udev, 1);
}
break;
}
st->i2c_gate = 4;
adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config,
&adap->dev->i2c_adap);
if (adap->fe_adap[0].fe) {
info("TUN Found Frontend TDA10086");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 4;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_LG;
if (dvb_usb_lme2510_firmware != TUNER_LG) {
dvb_usb_lme2510_firmware = TUNER_LG;
ret = lme_firmware_switch(adap->dev->udev, 1);
st->i2c_gate = 4;
adap->fe_adap[0].fe = dvb_attach(stv0299_attach,
&sharp_z0194_config, &adap->dev->i2c_adap);
if (adap->fe_adap[0].fe) {
info("FE Found Stv0299");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S0194;
if (dvb_usb_lme2510_firmware != TUNER_S0194) {
dvb_usb_lme2510_firmware = TUNER_S0194;
ret = lme_firmware_switch(adap->dev->udev, 1);
}
break;
}
goto end;
}
st->i2c_gate = 4;
adap->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194_config,
st->i2c_gate = 5;
adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config,
&adap->dev->i2c_adap);
if (adap->fe_adap[0].fe) {
info("FE Found Stv0299");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S0194;
if (dvb_usb_lme2510_firmware != TUNER_S0194) {
dvb_usb_lme2510_firmware = TUNER_S0194;
ret = lme_firmware_switch(adap->dev->udev, 1);
if (adap->fe_adap[0].fe) {
info("FE Found Stv0288");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S7395;
if (dvb_usb_lme2510_firmware != TUNER_S7395) {
dvb_usb_lme2510_firmware = TUNER_S7395;
ret = lme_firmware_switch(adap->dev->udev, 1);
}
break;
}
goto end;
}
case 0x22f0:
st->i2c_gate = 5;
adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
&m88rs2000_config, &adap->dev->i2c_adap);
st->i2c_gate = 5;
adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config,
&adap->dev->i2c_adap);
if (adap->fe_adap[0].fe) {
info("FE Found Stv0288");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S7395;
if (dvb_usb_lme2510_firmware != TUNER_S7395) {
dvb_usb_lme2510_firmware = TUNER_S7395;
ret = lme_firmware_switch(adap->dev->udev, 1);
if (adap->fe_adap[0].fe) {
info("FE Found M88RS2000");
st->i2c_tuner_gate_w = 5;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_RS2000;
adap->fe_adap[0].fe->ops.read_signal_strength =
dm04_rs2000_read_signal_strength;
adap->fe_adap[0].fe->ops.read_snr =
dm04_rs2000_read_snr;
}
} else {
info("DM04 Not Supported");
return -ENODEV;
break;
}
if (adap->fe_adap[0].fe == NULL) {
info("DM04/QQBOX Not Powered up or not Supported");
return -ENODEV;
}
end: if (ret) {
if (ret) {
if (adap->fe_adap[0].fe) {
dvb_frontend_detach(adap->fe_adap[0].fe);
adap->fe_adap[0].fe = NULL;
......@@ -1028,7 +1131,7 @@ end: if (ret) {
static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
{
struct lme2510_state *st = adap->dev->priv;
char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"};
char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
int ret = 0;
switch (st->tuner_config) {
......@@ -1047,6 +1150,9 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
&adap->dev->i2c_adap, DVB_PLL_OPERA1))
ret = st->tuner_config;
break;
case TUNER_RS2000:
ret = st->tuner_config;
break;
default:
break;
}
......@@ -1075,10 +1181,9 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
static u8 lnb_on[] = LNB_ON;
static u8 lnb_off[] = LNB_OFF;
static u8 rbuf[1];
int ret, len = 3, rlen = 1;
int ret = 0, len = 3, rlen = 1;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
mutex_lock(&d->i2c_mutex);
if (onoff)
ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
......@@ -1136,6 +1241,7 @@ static int lme2510_probe(struct usb_interface *intf,
static struct usb_device_id lme2510_table[] = {
{ USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
{ USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
{ USB_DEVICE(0x3344, 0x22f0) }, /* LME2510C RS2000 */
{} /* Terminating entry */
};
......@@ -1153,7 +1259,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
DVB_USB_ADAP_NEED_PID_FILTERING|
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.streaming_ctrl = lme2510_streaming_ctrl,
.pid_filter_count = 15,
.pid_filter_count = 32,
.pid_filter = lme2510_pid_filter,
.pid_filter_ctrl = lme2510_pid_filter_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
......@@ -1204,7 +1310,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
DVB_USB_ADAP_NEED_PID_FILTERING|
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.streaming_ctrl = lme2510_streaming_ctrl,
.pid_filter_count = 15,
.pid_filter_count = 32,
.pid_filter = lme2510_pid_filter,
.pid_filter_ctrl = lme2510_pid_filter_ctrl,
.frontend_attach = dm04_lme2510_frontend_attach,
......@@ -1234,11 +1340,14 @@ static struct dvb_usb_device_properties lme2510c_properties = {
.identify_state = lme2510_identify_state,
.i2c_algo = &lme2510_i2c_algo,
.generic_bulk_ctrl_endpoint = 0,
.num_device_descs = 1,
.num_device_descs = 2,
.devices = {
{ "DM04_LME2510C_DVB-S",
{ &lme2510_table[1], NULL },
},
{ "DM04_LME2510C_DVB-S RS2000",
{ &lme2510_table[2], NULL },
},
}
};
......@@ -1295,5 +1404,5 @@ module_usb_driver(lme2510_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
MODULE_VERSION("1.91");
MODULE_VERSION("1.99");
MODULE_LICENSE("GPL");
......@@ -41,6 +41,7 @@
#define LME_ST_ON_W {0x06, 0x00}
#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
#define LME_ALL_PIDS {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
/* LNB Voltage
* 07 XX XX
......
......@@ -351,15 +351,13 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
adap_state->ep6_clockphase,
0, 0);
mxl_fail(ret);
#if 0
} else {
ret = mxl111sf_disable_656_port(state);
mxl_fail(ret);
#endif
}
mxl111sf_read_reg(state, 0x12, &tmp);
tmp &= ~0x04;
mxl111sf_write_reg(state, 0x12, tmp);
return ret;
}
......
此差异已折叠。
/*
* Realtek RTL28xxU DVB USB driver
*
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
* Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef RTL28XXU_H
#define RTL28XXU_H
#define DVB_USB_LOG_PREFIX "rtl28xxu"
#include "dvb-usb.h"
#define deb_info(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x01, args)
#define deb_rc(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x02, args)
#define deb_xfer(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x04, args)
#define deb_reg(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x08, args)
#define deb_i2c(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x10, args)
#define deb_fw(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x20, args)
#define deb_dump(r, t, v, i, b, l, func) { \
int loop_; \
func("%02x %02x %02x %02x %02x %02x %02x %02x", \
t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
func(" >>> "); \
else \
func(" <<< "); \
for (loop_ = 0; loop_ < l; loop_++) \
func("%02x ", b[loop_]); \
func("\n");\
}
/*
* USB commands
* (usb_control_msg() index parameter)
*/
#define DEMOD 0x0000
#define USB 0x0100
#define SYS 0x0200
#define I2C 0x0300
#define I2C_DA 0x0600
#define CMD_WR_FLAG 0x0010
#define CMD_DEMOD_RD 0x0000
#define CMD_DEMOD_WR 0x0010
#define CMD_USB_RD 0x0100
#define CMD_USB_WR 0x0110
#define CMD_SYS_RD 0x0200
#define CMD_IR_RD 0x0201
#define CMD_IR_WR 0x0211
#define CMD_SYS_WR 0x0210
#define CMD_I2C_RD 0x0300
#define CMD_I2C_WR 0x0310
#define CMD_I2C_DA_RD 0x0600
#define CMD_I2C_DA_WR 0x0610
struct rtl28xxu_priv {
u8 chip_id;
u8 tuner;
u8 page; /* integrated demod active register page */
bool rc_active;
};
enum rtl28xxu_chip_id {
CHIP_ID_NONE,
CHIP_ID_RTL2831U,
CHIP_ID_RTL2832U,
};
enum rtl28xxu_tuner {
TUNER_NONE,
TUNER_RTL2830_QT1010,
TUNER_RTL2830_MT2060,
TUNER_RTL2830_MXL5005S,
TUNER_RTL2832_MT2266,
TUNER_RTL2832_FC2580,
TUNER_RTL2832_MT2063,
TUNER_RTL2832_MAX3543,
TUNER_RTL2832_TUA9001,
TUNER_RTL2832_MXL5007T,
TUNER_RTL2832_FC0012,
TUNER_RTL2832_E4000,
TUNER_RTL2832_TDA18272,
TUNER_RTL2832_FC0013,
};
struct rtl28xxu_req {
u16 value;
u16 index;
u16 size;
u8 *data;
};
struct rtl28xxu_reg_val {
u16 reg;
u8 val;
};
/*
* memory map
*
* 0x0000 DEMOD : demodulator
* 0x2000 USB : SIE, USB endpoint, debug, DMA
* 0x3000 SYS : system
* 0xfc00 RC : remote controller (not RTL2831U)
*/
/*
* USB registers
*/
/* SIE Control Registers */
#define USB_SYSCTL 0x2000 /* USB system control */
#define USB_SYSCTL_0 0x2000 /* USB system control */
#define USB_SYSCTL_1 0x2001 /* USB system control */
#define USB_SYSCTL_2 0x2002 /* USB system control */
#define USB_SYSCTL_3 0x2003 /* USB system control */
#define USB_IRQSTAT 0x2008 /* SIE interrupt status */
#define USB_IRQEN 0x200C /* SIE interrupt enable */
#define USB_CTRL 0x2010 /* USB control */
#define USB_STAT 0x2014 /* USB status */
#define USB_DEVADDR 0x2018 /* USB device address */
#define USB_TEST 0x201C /* USB test mode */
#define USB_FRAME_NUMBER 0x2020 /* frame number */
#define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */
#define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */
#define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */
/* Endpoint Registers */
#define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */
#define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */
#define USB_EP0_CFG 0x2104 /* EP 0 configure */
#define USB_EP0_CTL 0x2108 /* EP 0 control */
#define USB_EP0_STAT 0x210C /* EP 0 status */
#define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */
#define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */
#define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */
#define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */
#define USB_EPA_CFG 0x2144 /* EP A configure */
#define USB_EPA_CFG_0 0x2144 /* EP A configure */
#define USB_EPA_CFG_1 0x2145 /* EP A configure */
#define USB_EPA_CFG_2 0x2146 /* EP A configure */
#define USB_EPA_CFG_3 0x2147 /* EP A configure */
#define USB_EPA_CTL 0x2148 /* EP A control */
#define USB_EPA_CTL_0 0x2148 /* EP A control */
#define USB_EPA_CTL_1 0x2149 /* EP A control */
#define USB_EPA_CTL_2 0x214A /* EP A control */
#define USB_EPA_CTL_3 0x214B /* EP A control */
#define USB_EPA_STAT 0x214C /* EP A status */
#define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */
#define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */
#define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */
#define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */
#define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */
#define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */
#define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */
#define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */
#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */
#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */
#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */
#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */
/* Debug Registers */
#define USB_PHYTSTDIS 0x2F04 /* PHY test disable */
#define USB_TOUT_VAL 0x2F08 /* USB time-out time */
#define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */
#define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */
#define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */
#define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */
#define USB_UTMI_TST 0x2F80 /* UTMI test */
#define USB_UTMI_STATUS 0x2F84 /* UTMI status */
#define USB_TSTCTL 0x2F88 /* test control */
#define USB_TSTCTL2 0x2F8C /* test control 2 */
#define USB_PID_FORCE 0x2F90 /* force PID */
#define USB_PKTERR_CNT 0x2F94 /* packet error counter */
#define USB_RXERR_CNT 0x2F98 /* RX error counter */
#define USB_MEM_BIST 0x2F9C /* MEM BIST test */
#define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */
#define USB_CNTTEST 0x2FA4 /* counter test */
#define USB_PHYTST 0x2FC0 /* USB PHY test */
#define USB_DBGIDX 0x2FF0 /* select individual block debug signal */
#define USB_DBGMUX 0x2FF4 /* debug signal module mux */
/*
* SYS registers
*/
/* demod control registers */
#define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */
#define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */
/* GPIO registers */
#define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */
#define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */
#define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */
#define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */
#define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */
#define SYS_SYSINTE 0x3005 /* system interrupt enable */
#define SYS_SYSINTS 0x3006 /* system interrupt status */
#define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */
#define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */
#define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */
#define SYS_DEMOD_CTL1 0x300B
/* IrDA registers */
#define SYS_IRRC_PSR 0x3020 /* IR protocol selection */
#define SYS_IRRC_PER 0x3024 /* IR protocol extension */
#define SYS_IRRC_SF 0x3028 /* IR sampling frequency */
#define SYS_IRRC_DPIR 0x302C /* IR data package interval */
#define SYS_IRRC_CR 0x3030 /* IR control */
#define SYS_IRRC_RP 0x3034 /* IR read port */
#define SYS_IRRC_SR 0x3038 /* IR status */
/* I2C master registers */
#define SYS_I2CCR 0x3040 /* I2C clock */
#define SYS_I2CMCR 0x3044 /* I2C master control */
#define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */
#define SYS_I2CMSR 0x304C /* I2C master status */
#define SYS_I2CMFR 0x3050 /* I2C master FIFO */
/*
* IR registers
*/
#define IR_RX_BUF 0xFC00
#define IR_RX_IE 0xFD00
#define IR_RX_IF 0xFD01
#define IR_RX_CTRL 0xFD02
#define IR_RX_CFG 0xFD03
#define IR_MAX_DURATION0 0xFD04
#define IR_MAX_DURATION1 0xFD05
#define IR_IDLE_LEN0 0xFD06
#define IR_IDLE_LEN1 0xFD07
#define IR_GLITCH_LEN 0xFD08
#define IR_RX_BUF_CTRL 0xFD09
#define IR_RX_BUF_DATA 0xFD0A
#define IR_RX_BC 0xFD0B
#define IR_RX_CLK 0xFD0C
#define IR_RX_C_COUNT_L 0xFD0D
#define IR_RX_C_COUNT_H 0xFD0E
#define IR_SUSPEND_CTRL 0xFD10
#define IR_ERR_TOL_CTRL 0xFD11
#define IR_UNIT_LEN 0xFD12
#define IR_ERR_TOL_LEN 0xFD13
#define IR_MAX_H_TOL_LEN 0xFD14
#define IR_MAX_L_TOL_LEN 0xFD15
#define IR_MASK_CTRL 0xFD16
#define IR_MASK_DATA 0xFD17
#define IR_RES_MASK_ADDR 0xFD18
#define IR_RES_MASK_T_LEN 0xFD19
#endif
......@@ -425,6 +425,13 @@ config DVB_CXD2820R
help
Say Y when you want to support this frontend.
config DVB_RTL2830
tristate "Realtek RTL2830 DVB-T"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
Say Y when you want to support this frontend.
comment "DVB-C (cable) frontends"
depends on DVB_CORE
......@@ -698,6 +705,14 @@ config DVB_IT913X_FE
A DVB-T tuner module.
Say Y when you want to support this frontend.
config DVB_M88RS2000
tristate "M88RS2000 DVB-S demodulator and tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module.
Say Y when you want to support this frontend.
comment "Tools to develop new frontends"
config DVB_DUMMY_FE
......
......@@ -2,8 +2,8 @@
# Makefile for the kernel DVB frontend device drivers.
#
ccflags-y += -Idrivers/media/dvb/dvb-core/
ccflags-y += -Idrivers/media/common/tuners/
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/common/tuners/
stb0899-objs = stb0899_drv.o stb0899_algo.o
stv0900-objs = stv0900_core.o stv0900_sw.o
......@@ -96,4 +96,6 @@ obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
......@@ -839,15 +839,4 @@ static struct i2c_driver au8522_driver = {
.id_table = au8522_id,
};
static __init int init_au8522(void)
{
return i2c_add_driver(&au8522_driver);
}
static __exit void exit_au8522(void)
{
i2c_del_driver(&au8522_driver);
}
module_init(init_au8522);
module_exit(exit_au8522);
module_i2c_driver(au8522_driver);
......@@ -588,11 +588,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
(state->current_modulation == c->modulation))
return 0;
au8522_enable_modulation(fe, c->modulation);
/* Allow the demod to settle */
msleep(100);
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
......@@ -604,6 +599,11 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
if (ret < 0)
return ret;
/* Allow the tuner to settle */
msleep(100);
au8522_enable_modulation(fe, c->modulation);
state->current_frequency = c->frequency;
return 0;
......
......@@ -502,10 +502,26 @@ static int cx22702_read_signal_strength(struct dvb_frontend *fe,
u16 *signal_strength)
{
struct cx22702_state *state = fe->demodulator_priv;
u8 reg23;
u16 rs_ber;
rs_ber = cx22702_readreg(state, 0x23);
*signal_strength = (rs_ber << 8) | rs_ber;
/*
* Experience suggests that the strength signal register works as
* follows:
* - In the absence of signal, value is 0xff.
* - In the presence of a weak signal, bit 7 is set, not sure what
* the lower 7 bits mean.
* - In the presence of a strong signal, the register holds a 7-bit
* value (bit 7 is cleared), with greater values standing for
* weaker signals.
*/
reg23 = cx22702_readreg(state, 0x23);
if (reg23 & 0x80) {
*signal_strength = 0;
} else {
reg23 = ~reg23 & 0x7f;
/* Scale to 16 bit */
*signal_strength = (reg23 << 9) | (reg23 << 2) | (reg23 >> 5);
}
return 0;
}
......
......@@ -519,7 +519,7 @@ static int dib0090_fw_identify(struct dvb_frontend *fe)
return 0;
identification_error:
return -EIO;;
return -EIO;
}
static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
......
......@@ -101,9 +101,9 @@ struct SCfgAgc {
struct SNoiseCal {
int cpOpt;
u16 cpNexpOfs;
u16 tdCal2k;
u16 tdCal8k;
short cpNexpOfs;
short tdCal2k;
short tdCal8k;
};
enum app_env {
......
......@@ -7,15 +7,19 @@
/**
* struct drxk_config - Configure the initial parameters for DRX-K
*
* adr: I2C Address of the DRX-K
* parallel_ts: true means that the device uses parallel TS,
* @adr: I2C Address of the DRX-K
* @parallel_ts: True means that the device uses parallel TS,
* Serial otherwise.
* single_master: Device is on the single master mode
* no_i2c_bridge: Don't switch the I2C bridge to talk with tuner
* antenna_gpio: GPIO bit used to control the antenna
* antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1
* @dynamic_clk: True means that the clock will be dynamically
* adjusted. Static clock otherwise.
* @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
* @single_master: Device is on the single master mode
* @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner
* @antenna_gpio: GPIO bit used to control the antenna
* @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1
* means that 1=DVBC, 0 = DVBT. Zero means the opposite.
* microcode_name: Name of the firmware file with the microcode
* @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
* @microcode_name: Name of the firmware file with the microcode
*
* On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
* UIO-3.
......@@ -25,11 +29,14 @@ struct drxk_config {
bool single_master;
bool no_i2c_bridge;
bool parallel_ts;
bool dynamic_clk;
bool enable_merr_cfg;
bool antenna_dvbt;
u16 antenna_gpio;
int chunk_size;
u8 mpeg_out_clk_strength;
int chunk_size;
const char *microcode_name;
};
......
......@@ -332,6 +332,7 @@ struct drxk_state {
u16 UIO_mask; /* Bits used by UIO */
bool enable_merr_cfg;
bool single_master;
bool no_i2c_bridge;
bool antenna_dvbt;
......
......@@ -201,6 +201,11 @@ fe_modulation_t fe_con[] = {
QAM_64,
};
enum {
PRIORITY_HIGH = 0, /* High-priority stream */
PRIORITY_LOW, /* Low-priority stream */
};
/* Standard demodulator functions */
static struct it913xset set_solo_fe[] = {
{PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -216,6 +216,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
struct drxk_config config;
memset(&config, 0, sizeof(config));
config.microcode_name = "drxk_a3.mc";
config.adr = 0x29 + (chan->number ^ 2);
chan->fe = dvb_attach(drxk_attach, &config, i2c);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册