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

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (505 commits)
  [media] af9015: Fix max I2C message size when used with tda18271
  [media] IR: initialize ir_raw_event in few more drivers
  [media] Guard a divide in v4l1 compat layer
  [media] imon: fix nomouse modprobe option
  [media] imon: remove redundant change_protocol call
  [media] imon: fix my egregious brown paper bag w/rdev/idev split
  [media] cafe_ccic: Configure ov7670 correctly
  [media] ov7670: allow configuration of image size, clock speed, and I/O method
  [media] af9015: support for DigitalNow TinyTwin v3 [1f4d:9016]
  [media] af9015: map DigitalNow TinyTwin v2 remote
  [media] DigitalNow TinyTwin remote controller
  [media] af9015: RC fixes and improvements
  videodev2.h.xml: Update to reflect the latest changes at videodev2.h
  [media] v4l: document new Bayer and monochrome pixel formats
  [media] DocBook/v4l: Add missing formats used on gspca cpia1 and sn9c2028
  [media] firedtv: add parameter to fake ca_system_ids in CA_INFO
  [media] tm6000: fix a macro coding style issue
  tm6000: Remove some ugly debug code
  [media] Nova-S-Plus audio line input
  [media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers
  ...
This commit is contained in:
Linus Torvalds 2010-10-28 09:35:11 -07:00
commit 0851668fdd
531 changed files with 41168 additions and 13122 deletions

View File

@ -250,6 +250,9 @@
<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
<!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
<!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
<!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
@ -347,6 +350,9 @@
<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
<!ENTITY srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
<!ENTITY srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY y10 SYSTEM "v4l/pixfmt-y10.xml">
<!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
<!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">

View File

@ -21,11 +21,15 @@ API.</para>
<title>Opening and Closing Devices</title>
<para>For compatibility reasons the character device file names
recommended for V4L2 video capture, overlay, radio, teletext and raw
recommended for V4L2 video capture, overlay, radio and raw
vbi capture devices did not change from those used by V4L. They are
listed in <xref linkend="devices" /> and below in <xref
linkend="v4l-dev" />.</para>
<para>The teletext devices (minor range 192-223) have been removed in
V4L2 and no longer exist. There is no hardware available anymore for handling
pure teletext. Instead raw or sliced VBI is used.</para>
<para>The V4L <filename>videodev</filename> module automatically
assigns minor numbers to drivers in load order, depending on the
registered device type. We recommend that V4L2 drivers by default
@ -65,13 +69,6 @@ not compatible with V4L or V4L2.</para> </footnote>,
<filename>/dev/radio63</filename></para></entry>
<entry>64-127</entry>
</row>
<row>
<entry>Teletext decoder</entry>
<entry><para><filename>/dev/vtx</filename>,
<filename>/dev/vtx0</filename> to
<filename>/dev/vtx31</filename></para></entry>
<entry>192-223</entry>
</row>
<row>
<entry>Raw VBI capture</entry>
<entry><para><filename>/dev/vbi</filename>,
@ -2345,6 +2342,17 @@ more information.</para>
</listitem>
</orderedlist>
</section>
<section>
<title>V4L2 in Linux 2.6.37</title>
<orderedlist>
<listitem>
<para>Remove the vtx (videotext/teletext) API. This API was no longer
used and no hardware exists to verify the API. Nor were any userspace applications found
that used it. It was originally scheduled for removal in 2.6.35.
</para>
</listitem>
</orderedlist>
</section>
<section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title>

View File

@ -311,11 +311,18 @@ minimum value disables backlight compensation.</entry>
bits 8-15 Green color information, bits 16-23 Blue color
information and bits 24-31 must be zero.</entry>
</row>
<row>
<entry><constant>V4L2_CID_ILLUMINATORS_1</constant>
<constant>V4L2_CID_ILLUMINATORS_2</constant></entry>
<entry>boolean</entry>
<entry>Switch on or off the illuminator 1 or 2 of the device
(usually a microscope).</entry>
</row>
<row>
<entry><constant>V4L2_CID_LASTP1</constant></entry>
<entry></entry>
<entry>End of the predefined control IDs (currently
<constant>V4L2_CID_BG_COLOR</constant> + 1).</entry>
<constant>V4L2_CID_ILLUMINATORS_2</constant> + 1).</entry>
</row>
<row>
<entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
@ -357,9 +364,6 @@ enumerate_menu (void)
querymenu.index++) {
if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
printf (" %s\n", querymenu.name);
} else {
perror ("VIDIOC_QUERYMENU");
exit (EXIT_FAILURE);
}
}
}

View File

@ -3,15 +3,16 @@
<para>The Radio Data System transmits supplementary
information in binary format, for example the station name or travel
information, on an inaudible audio subcarrier of a radio program. This
interface is aimed at devices capable of receiving and decoding RDS
interface is aimed at devices capable of receiving and/or transmitting RDS
information.</para>
<para>For more information see the core RDS standard <xref linkend="en50067" />
and the RBDS standard <xref linkend="nrsc4" />.</para>
<para>Note that the RBDS standard as is used in the USA is almost identical
to the RDS standard. Any RDS decoder can also handle RBDS. Only some of the fields
have slightly different meanings. See the RBDS standard for more information.</para>
to the RDS standard. Any RDS decoder/encoder can also handle RBDS. Only some of the
fields have slightly different meanings. See the RBDS standard for more
information.</para>
<para>The RBDS standard also specifies support for MMBS (Modified Mobile Search).
This is a proprietary format which seems to be discontinued. The RDS interface does not
@ -21,16 +22,25 @@ be needed, then please contact the linux-media mailing list: &v4l-ml;.</para>
<section>
<title>Querying Capabilities</title>
<para>Devices supporting the RDS capturing API
set the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in
<para>Devices supporting the RDS capturing API set
the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in
the <structfield>capabilities</structfield> field of &v4l2-capability;
returned by the &VIDIOC-QUERYCAP; ioctl.
Any tuner that supports RDS will set the
<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
field of &v4l2-tuner;.
Whether an RDS signal is present can be detected by looking at
the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: the
<constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data was detected.</para>
returned by the &VIDIOC-QUERYCAP; ioctl. Any tuner that supports RDS
will set the <constant>V4L2_TUNER_CAP_RDS</constant> flag in
the <structfield>capability</structfield> field of &v4l2-tuner;. If
the driver only passes RDS blocks without interpreting the data
the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be
set, see <link linkend="reading-rds-data">Reading RDS data</link>.
For future use the
flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> has also been
defined. However, a driver for a radio tuner with this capability does
not yet exist, so if you are planning to write such a driver you
should discuss this on the linux-media mailing list: &v4l-ml;.</para>
<para> Whether an RDS signal is present can be detected by looking
at the <structfield>rxsubchans</structfield> field of &v4l2-tuner;:
the <constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data
was detected.</para>
<para>Devices supporting the RDS output API
set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in
@ -40,16 +50,31 @@ Any modulator that supports RDS will set the
<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
field of &v4l2-modulator;.
In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant>
bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.</para>
bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.
If the driver only passes RDS blocks without interpreting the data
the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be set. If the
tuner is capable of handling RDS entities like program identification codes and radio
text, the flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> should be set,
see <link linkend="writing-rds-data">Writing RDS data</link> and
<link linkend="fm-tx-controls">FM Transmitter Control Reference</link>.</para>
</section>
<section>
<section id="reading-rds-data">
<title>Reading RDS data</title>
<para>RDS data can be read from the radio device
with the &func-read; function. The data is packed in groups of three bytes,
with the &func-read; function. The data is packed in groups of three bytes.</para>
</section>
<section id="writing-rds-data">
<title>Writing RDS data</title>
<para>RDS data can be written to the radio device
with the &func-write; function. The data is packed in groups of three bytes,
as follows:</para>
</section>
<section>
<table frame="none" pgwide="1" id="v4l2-rds-data">
<title>struct
<structname>v4l2_rds_data</structname></title>
@ -111,48 +136,57 @@ as follows:</para>
<tbody valign="top">
<row>
<entry>V4L2_RDS_BLOCK_MSK</entry>
<entry> </entry>
<entry>7</entry>
<entry>Mask for bits 0-2 to get the block ID.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_A</entry>
<entry> </entry>
<entry>0</entry>
<entry>Block A.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_B</entry>
<entry> </entry>
<entry>1</entry>
<entry>Block B.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_C</entry>
<entry> </entry>
<entry>2</entry>
<entry>Block C.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_D</entry>
<entry> </entry>
<entry>3</entry>
<entry>Block D.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_C_ALT</entry>
<entry> </entry>
<entry>4</entry>
<entry>Block C'.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_INVALID</entry>
<entry>read-only</entry>
<entry>7</entry>
<entry>An invalid block.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_CORRECTED</entry>
<entry>read-only</entry>
<entry>0x40</entry>
<entry>A bit error was detected but corrected.</entry>
</row>
<row>
<entry>V4L2_RDS_BLOCK_ERROR</entry>
<entry>read-only</entry>
<entry>0x80</entry>
<entry>An incorrectable error occurred.</entry>
<entry>An uncorrectable error occurred.</entry>
</row>
</tbody>
</tgroup>

View File

@ -1,35 +1,32 @@
<title>Teletext Interface</title>
<para>This interface aims at devices receiving and demodulating
<para>This interface was aimed at devices receiving and demodulating
Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the
Teletext packages and storing formatted pages in cache memory. Such
devices are usually implemented as microcontrollers with serial
interface (I<superscript>2</superscript>C) and can be found on older
interface (I<superscript>2</superscript>C) and could be found on old
TV cards, dedicated Teletext decoding cards and home-brew devices
connected to the PC parallel port.</para>
<para>The Teletext API was designed by Martin Buck. It is defined in
<para>The Teletext API was designed by Martin Buck. It was defined in
the kernel header file <filename>linux/videotext.h</filename>, the
specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/">
ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of
the German public television Teletext service.) Conventional character
device file names are <filename>/dev/vtx</filename> and
<filename>/dev/vttuner</filename>, with device number 83, 0 and 83, 16
respectively. A similar interface exists for the Philips SAA5249
Teletext decoder [specification?] with character device file names
<filename>/dev/tlkN</filename>, device number 102, N.</para>
the German public television Teletext service.)</para>
<para>Eventually the Teletext API was integrated into the V4L API
with character device file names <filename>/dev/vtx0</filename> to
<filename>/dev/vtx31</filename>, device major number 81, minor numbers
192 to 223. For reference the V4L Teletext API specification is
reproduced here in full: "Teletext interfaces talk the existing VTX
API." Teletext devices with major number 83 and 102 will be removed in
Linux 2.6.</para>
192 to 223.</para>
<para>There are no plans to replace the Teletext API or to integrate
it into V4L2. Please write to the linux-media mailing list: &v4l-ml;
when the need arises.</para>
<para>However, teletext decoders were quickly replaced by more
generic VBI demodulators and those dedicated teletext decoders no longer exist.
For many years the vtx devices were still around, even though nobody used
them. So the decision was made to finally remove support for the Teletext API in
kernel 2.6.37.</para>
<para>Modern devices all use the <link linkend="raw-vbi">raw</link> or
<link linkend="sliced">sliced</link> VBI API.</para>
<!--
Local Variables:

View File

@ -739,7 +739,7 @@ defined in error. Drivers may interpret them as in <xref
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-BGR666">
<row><!-- id="V4L2-PIX-FMT-BGR666" -->
<entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
<entry>'BGRH'</entry>
<entry></entry>

View File

@ -0,0 +1,90 @@
<refentry>
<refmeta>
<refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'),
V4L2_PIX_FMT_SGRBG10 ('BA10'),
V4L2_PIX_FMT_SGBRG10 ('GB10'),
V4L2_PIX_FMT_SBGGR10 ('BG10'),
</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname id="V4L2-PIX-FMT-SRGGB10"><constant>V4L2_PIX_FMT_SRGGB10</constant></refname>
<refname id="V4L2-PIX-FMT-SGRBG10"><constant>V4L2_PIX_FMT_SGRBG10</constant></refname>
<refname id="V4L2-PIX-FMT-SGBRG10"><constant>V4L2_PIX_FMT_SGBRG10</constant></refname>
<refname id="V4L2-PIX-FMT-SBGGR10"><constant>V4L2_PIX_FMT_SBGGR10</constant></refname>
<refpurpose>10-bit Bayer formats expanded to 16 bits</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>The following four pixel formats are raw sRGB / Bayer formats with
10 bits per colour. Each colour component is stored in a 16-bit word, with 6
unused high bits filled with zeros. Each n-pixel row contains n/2 green samples
and n/2 blue or red samples, with alternating red and blue rows. Bytes are
stored in memory in little endian order. They are conventionally described
as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these
formats</para>
<example>
<title><constant>V4L2_PIX_FMT_SBGGR10</constant> 4 &times; 4
pixel image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte, high 6 bits in high bytes are 0.
<informaltable frame="none">
<tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>B<subscript>00low</subscript></entry>
<entry>B<subscript>00high</subscript></entry>
<entry>G<subscript>01low</subscript></entry>
<entry>G<subscript>01high</subscript></entry>
<entry>B<subscript>02low</subscript></entry>
<entry>B<subscript>02high</subscript></entry>
<entry>G<subscript>03low</subscript></entry>
<entry>G<subscript>03high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;8:</entry>
<entry>G<subscript>10low</subscript></entry>
<entry>G<subscript>10high</subscript></entry>
<entry>R<subscript>11low</subscript></entry>
<entry>R<subscript>11high</subscript></entry>
<entry>G<subscript>12low</subscript></entry>
<entry>G<subscript>12high</subscript></entry>
<entry>R<subscript>13low</subscript></entry>
<entry>R<subscript>13high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;16:</entry>
<entry>B<subscript>20low</subscript></entry>
<entry>B<subscript>20high</subscript></entry>
<entry>G<subscript>21low</subscript></entry>
<entry>G<subscript>21high</subscript></entry>
<entry>B<subscript>22low</subscript></entry>
<entry>B<subscript>22high</subscript></entry>
<entry>G<subscript>23low</subscript></entry>
<entry>G<subscript>23high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;24:</entry>
<entry>G<subscript>30low</subscript></entry>
<entry>G<subscript>30high</subscript></entry>
<entry>R<subscript>31low</subscript></entry>
<entry>R<subscript>31high</subscript></entry>
<entry>G<subscript>32low</subscript></entry>
<entry>G<subscript>32high</subscript></entry>
<entry>R<subscript>33low</subscript></entry>
<entry>R<subscript>33high</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View File

@ -0,0 +1,67 @@
<refentry id="V4L2-PIX-FMT-SRGGB8">
<refmeta>
<refentrytitle>V4L2_PIX_FMT_SRGGB8 ('RGGB')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname><constant>V4L2_PIX_FMT_SRGGB8</constant></refname>
<refpurpose>Bayer RGB format</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>This is commonly the native format of digital cameras,
reflecting the arrangement of sensors on the CCD device. Only one red,
green or blue value is given for each pixel. Missing components must
be interpolated from neighbouring pixels. From left to right the first
row consists of a red and green value, the second row of a green and
blue value. This scheme repeats to the right and down for every two
columns and rows.</para>
<example>
<title><constant>V4L2_PIX_FMT_SRGGB8</constant> 4 &times; 4
pixel image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>R<subscript>00</subscript></entry>
<entry>G<subscript>01</subscript></entry>
<entry>R<subscript>02</subscript></entry>
<entry>G<subscript>03</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;4:</entry>
<entry>G<subscript>10</subscript></entry>
<entry>B<subscript>11</subscript></entry>
<entry>G<subscript>12</subscript></entry>
<entry>B<subscript>13</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;8:</entry>
<entry>R<subscript>20</subscript></entry>
<entry>G<subscript>21</subscript></entry>
<entry>R<subscript>22</subscript></entry>
<entry>G<subscript>23</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;12:</entry>
<entry>G<subscript>30</subscript></entry>
<entry>B<subscript>31</subscript></entry>
<entry>G<subscript>32</subscript></entry>
<entry>B<subscript>33</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View File

@ -0,0 +1,79 @@
<refentry id="V4L2-PIX-FMT-Y10">
<refmeta>
<refentrytitle>V4L2_PIX_FMT_Y10 ('Y10 ')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname><constant>V4L2_PIX_FMT_Y10</constant></refname>
<refpurpose>Grey-scale image</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>This is a grey-scale image with a depth of 10 bits per pixel. Pixels
are stored in 16-bit words with unused high bits padded with 0. The least
significant byte is stored at lower memory addresses (little-endian).</para>
<example>
<title><constant>V4L2_PIX_FMT_Y10</constant> 4 &times; 4
pixel image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="9" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>Y'<subscript>00low</subscript></entry>
<entry>Y'<subscript>00high</subscript></entry>
<entry>Y'<subscript>01low</subscript></entry>
<entry>Y'<subscript>01high</subscript></entry>
<entry>Y'<subscript>02low</subscript></entry>
<entry>Y'<subscript>02high</subscript></entry>
<entry>Y'<subscript>03low</subscript></entry>
<entry>Y'<subscript>03high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;8:</entry>
<entry>Y'<subscript>10low</subscript></entry>
<entry>Y'<subscript>10high</subscript></entry>
<entry>Y'<subscript>11low</subscript></entry>
<entry>Y'<subscript>11high</subscript></entry>
<entry>Y'<subscript>12low</subscript></entry>
<entry>Y'<subscript>12high</subscript></entry>
<entry>Y'<subscript>13low</subscript></entry>
<entry>Y'<subscript>13high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;16:</entry>
<entry>Y'<subscript>20low</subscript></entry>
<entry>Y'<subscript>20high</subscript></entry>
<entry>Y'<subscript>21low</subscript></entry>
<entry>Y'<subscript>21high</subscript></entry>
<entry>Y'<subscript>22low</subscript></entry>
<entry>Y'<subscript>22high</subscript></entry>
<entry>Y'<subscript>23low</subscript></entry>
<entry>Y'<subscript>23high</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;24:</entry>
<entry>Y'<subscript>30low</subscript></entry>
<entry>Y'<subscript>30high</subscript></entry>
<entry>Y'<subscript>31low</subscript></entry>
<entry>Y'<subscript>31high</subscript></entry>
<entry>Y'<subscript>32low</subscript></entry>
<entry>Y'<subscript>32high</subscript></entry>
<entry>Y'<subscript>33low</subscript></entry>
<entry>Y'<subscript>33high</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View File

@ -566,7 +566,9 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.<
&sub-sbggr8;
&sub-sgbrg8;
&sub-sgrbg8;
&sub-srggb8;
&sub-sbggr16;
&sub-srggb10;
</section>
<section id="yuv-formats">
@ -589,6 +591,7 @@ information.</para>
&sub-packed-yuv;
&sub-grey;
&sub-y10;
&sub-y16;
&sub-yuyv;
&sub-uyvy;
@ -685,6 +688,11 @@ http://www.ivtvdriver.org/</ulink></para><para>The format is documented in the
kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename>
</para></entry>
</row>
<row id="V4L2-PIX-FMT-CPIA1">
<entry><constant>V4L2_PIX_FMT_CPIA1</constant></entry>
<entry>'CPIA'</entry>
<entry>YUV format used by the gspca cpia1 driver.</entry>
</row>
<row id="V4L2-PIX-FMT-SPCA501">
<entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry>
<entry>'S501'</entry>
@ -705,11 +713,6 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm
<entry>'S561'</entry>
<entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
</row>
<row id="V4L2-PIX-FMT-SGRBG10">
<entry><constant>V4L2_PIX_FMT_SGRBG10</constant></entry>
<entry>'DA10'</entry>
<entry>10 bit raw Bayer, expanded to 16 bits.</entry>
</row>
<row id="V4L2-PIX-FMT-SGRBG10DPCM8">
<entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
<entry>'DB10'</entry>
@ -770,6 +773,11 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm
<entry>'S920'</entry>
<entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
</row>
<row id="V4L2-PIX-FMT-SN9C2028">
<entry><constant>V4L2_PIX_FMT_SN9C2028</constant></entry>
<entry>'SONX'</entry>
<entry>Compressed GBRG bayer format of the gspca sn9c2028 driver.</entry>
</row>
<row id="V4L2-PIX-FMT-STV0680">
<entry><constant>V4L2_PIX_FMT_STV0680</constant></entry>
<entry>'S680'</entry>
@ -787,6 +795,20 @@ http://www.thedirks.org/winnov/</ulink></para></entry>
<entry>'TM60'</entry>
<entry><para>Used by Trident tm6000</para></entry>
</row>
<row id="V4L2-PIX-FMT-CIT-YYVYUY">
<entry><constant>V4L2_PIX_FMT_CIT_YYVYUY</constant></entry>
<entry>'CITV'</entry>
<entry><para>Used by xirlink CIT, found at IBM webcams.</para>
<para>Uses one line of Y then 1 line of VYUY</para>
</entry>
</row>
<row id="V4L2-PIX-FMT-KONICA420">
<entry><constant>V4L2_PIX_FMT_KONICA420</constant></entry>
<entry>'KONI'</entry>
<entry><para>Used by Konica webcams.</para>
<para>YUV420 planar in blocks of 256 pixels.</para>
</entry>
</row>
<row id="V4L2-PIX-FMT-YYUV">
<entry><constant>V4L2_PIX_FMT_YYUV</constant></entry>
<entry>'YYUV'</entry>

View File

@ -99,6 +99,7 @@ Remote Controller chapter.</contrib>
<year>2007</year>
<year>2008</year>
<year>2009</year>
<year>2010</year>
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
</copyright>
@ -110,9 +111,16 @@ Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
<!-- Put document revisions here, newest first. -->
<!-- API revisions (changes and additions of defines, enums,
structs, ioctls) must be noted in more detail in the history chapter
(compat.sgml), along with the possible impact on existing drivers and
(compat.xml), along with the possible impact on existing drivers and
applications. -->
<revision>
<revnumber>2.6.37</revnumber>
<date>2010-08-06</date>
<authorinitials>hv</authorinitials>
<revremark>Removed obsolete vtx (videotext) API.</revremark>
</revision>
<revision>
<revnumber>2.6.33</revnumber>
<date>2009-12-03</date>

View File

@ -154,23 +154,13 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
V4L2_BUF_TYPE_VBI_OUTPUT = 5,
V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
#if 1 /*KEEP*/
#if 1
/* Experimental */
V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
#endif
V4L2_BUF_TYPE_PRIVATE = 0x80,
};
enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> {
V4L2_CTRL_TYPE_INTEGER = 1,
V4L2_CTRL_TYPE_BOOLEAN = 2,
V4L2_CTRL_TYPE_MENU = 3,
V4L2_CTRL_TYPE_BUTTON = 4,
V4L2_CTRL_TYPE_INTEGER64 = 5,
V4L2_CTRL_TYPE_CTRL_CLASS = 6,
V4L2_CTRL_TYPE_STRING = 7,
};
enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
V4L2_TUNER_RADIO = 1,
V4L2_TUNER_ANALOG_TV = 2,
@ -288,6 +278,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-RGB565">V4L2_PIX_FMT_RGB565</link> v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
#define <link linkend="V4L2-PIX-FMT-RGB555X">V4L2_PIX_FMT_RGB555X</link> v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */
#define <link linkend="V4L2-PIX-FMT-RGB565X">V4L2_PIX_FMT_RGB565X</link> v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */
#define <link linkend="V4L2-PIX-FMT-BGR666">V4L2_PIX_FMT_BGR666</link> v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */
#define <link linkend="V4L2-PIX-FMT-BGR24">V4L2_PIX_FMT_BGR24</link> v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */
#define <link linkend="V4L2-PIX-FMT-RGB24">V4L2_PIX_FMT_RGB24</link> v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */
#define <link linkend="V4L2-PIX-FMT-BGR32">V4L2_PIX_FMT_BGR32</link> v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */
@ -295,6 +286,9 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
/* Grey formats */
#define <link linkend="V4L2-PIX-FMT-GREY">V4L2_PIX_FMT_GREY</link> v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
#define <link linkend="V4L2-PIX-FMT-Y4">V4L2_PIX_FMT_Y4</link> v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
#define <link linkend="V4L2-PIX-FMT-Y6">V4L2_PIX_FMT_Y6</link> v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
#define <link linkend="V4L2-PIX-FMT-Y10">V4L2_PIX_FMT_Y10</link> v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
#define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link> v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
/* Palette formats */
@ -330,7 +324,11 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
#define <link linkend="V4L2-PIX-FMT-SGRBG8">V4L2_PIX_FMT_SGRBG8</link> v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
#define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */
#define <link linkend="V4L2-PIX-FMT-SRGGB8">V4L2_PIX_FMT_SRGGB8</link> v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */
#define <link linkend="V4L2-PIX-FMT-SBGGR10">V4L2_PIX_FMT_SBGGR10</link> v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */
#define <link linkend="V4L2-PIX-FMT-SGBRG10">V4L2_PIX_FMT_SGBRG10</link> v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */
#define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */
#define <link linkend="V4L2-PIX-FMT-SRGGB10">V4L2_PIX_FMT_SRGGB10</link> v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */
/* 10bit raw bayer DPCM compressed to 8 bits */
#define <link linkend="V4L2-PIX-FMT-SGRBG10DPCM8">V4L2_PIX_FMT_SGRBG10DPCM8</link> v4l2_fourcc('B', 'D', '1', '0')
/*
@ -346,6 +344,7 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-MPEG">V4L2_PIX_FMT_MPEG</link> v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */
/* Vendor-specific formats */
#define <link linkend="V4L2-PIX-FMT-CPIA1">V4L2_PIX_FMT_CPIA1</link> v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
#define <link linkend="V4L2-PIX-FMT-WNVA">V4L2_PIX_FMT_WNVA</link> v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
#define <link linkend="V4L2-PIX-FMT-SN9C10X">V4L2_PIX_FMT_SN9C10X</link> v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
#define <link linkend="V4L2-PIX-FMT-SN9C20X-I420">V4L2_PIX_FMT_SN9C20X_I420</link> v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
@ -358,12 +357,15 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
#define <link linkend="V4L2-PIX-FMT-SPCA561">V4L2_PIX_FMT_SPCA561</link> v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
#define <link linkend="V4L2-PIX-FMT-PAC207">V4L2_PIX_FMT_PAC207</link> v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
#define <link linkend="V4L2-PIX-FMT-MR97310A">V4L2_PIX_FMT_MR97310A</link> v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
#define <link linkend="V4L2-PIX-FMT-SN9C2028">V4L2_PIX_FMT_SN9C2028</link> v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */
#define <link linkend="V4L2-PIX-FMT-SQ905C">V4L2_PIX_FMT_SQ905C</link> v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
#define <link linkend="V4L2-PIX-FMT-PJPG">V4L2_PIX_FMT_PJPG</link> v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
#define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
#define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
#define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link> v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
#define <link linkend="V4L2-PIX-FMT-CIT-YYVYUY">V4L2_PIX_FMT_CIT_YYVYUY</link> v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
#define <link linkend="V4L2-PIX-FMT-KONICA420">V4L2_PIX_FMT_KONICA420</link> v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
/*
* F O R M A T E N U M E R A T I O N
@ -380,7 +382,7 @@ struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link> {
#define V4L2_FMT_FLAG_COMPRESSED 0x0001
#define V4L2_FMT_FLAG_EMULATED 0x0002
#if 1 /*KEEP*/
#if 1
/* Experimental Frame Size and frame rate enumeration */
/*
* F R A M E S I Z E E N U M E R A T I O N
@ -544,6 +546,8 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
/* Buffer is ready, but the data contained within is corrupted. */
#define V4L2_BUF_FLAG_ERROR 0x0040
#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
@ -934,6 +938,16 @@ struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link> {
#define V4L2_CTRL_ID2CLASS(id) ((id) &amp; 0x0fff0000UL)
#define V4L2_CTRL_DRIVER_PRIV(id) (((id) &amp; 0xffff) &gt;= 0x1000)
enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> {
V4L2_CTRL_TYPE_INTEGER = 1,
V4L2_CTRL_TYPE_BOOLEAN = 2,
V4L2_CTRL_TYPE_MENU = 3,
V4L2_CTRL_TYPE_BUTTON = 4,
V4L2_CTRL_TYPE_INTEGER64 = 5,
V4L2_CTRL_TYPE_CTRL_CLASS = 6,
V4L2_CTRL_TYPE_STRING = 7,
};
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link> {
__u32 id;
@ -1018,21 +1032,27 @@ enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
V4L2_COLORFX_NONE = 0,
V4L2_COLORFX_BW = 1,
V4L2_COLORFX_SEPIA = 2,
V4L2_COLORFX_NEGATIVE = 3,
V4L2_COLORFX_EMBOSS = 4,
V4L2_COLORFX_SKETCH = 5,
V4L2_COLORFX_SKY_BLUE = 6,
V4L2_COLORFX_NEGATIVE = 3,
V4L2_COLORFX_EMBOSS = 4,
V4L2_COLORFX_SKETCH = 5,
V4L2_COLORFX_SKY_BLUE = 6,
V4L2_COLORFX_GRASS_GREEN = 7,
V4L2_COLORFX_SKIN_WHITEN = 8,
V4L2_COLORFX_VIVID = 9.
V4L2_COLORFX_VIVID = 9,
};
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36)
#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37)
#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38)
/* last CID + 1 */
#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36)
#define V4L2_CID_LASTP1 (V4L2_CID_BASE+39)
/* MPEG-class control IDs defined by V4L2 */
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
@ -1349,6 +1369,8 @@ struct <link linkend="v4l2-modulator">v4l2_modulator</link> {
#define V4L2_TUNER_CAP_SAP 0x0020
#define V4L2_TUNER_CAP_LANG1 0x0040
#define V4L2_TUNER_CAP_RDS 0x0080
#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100
#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200
/* Flags for the 'rxsubchans' field */
#define V4L2_TUNER_SUB_MONO 0x0001
@ -1378,7 +1400,8 @@ struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link> {
enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type;
__u32 seek_upward;
__u32 wrap_around;
__u32 reserved[8];
__u32 spacing;
__u32 reserved[7];
};
/*
@ -1433,7 +1456,7 @@ struct <link linkend="v4l2-audioout">v4l2_audioout</link> {
*
* NOTE: EXPERIMENTAL API
*/
#if 1 /*KEEP*/
#if 1
#define V4L2_ENC_IDX_FRAME_I (0)
#define V4L2_ENC_IDX_FRAME_P (1)
#define V4L2_ENC_IDX_FRAME_B (2)
@ -1625,6 +1648,38 @@ struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
} parm;
};
/*
* E V E N T S
*/
#define V4L2_EVENT_ALL 0
#define V4L2_EVENT_VSYNC 1
#define V4L2_EVENT_EOS 2
#define V4L2_EVENT_PRIVATE_START 0x08000000
/* Payload for V4L2_EVENT_VSYNC */
struct <link linkend="v4l2-event-vsync">v4l2_event_vsync</link> {
/* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */
__u8 field;
} __attribute__ ((packed));
struct <link linkend="v4l2-event">v4l2_event</link> {
__u32 type;
union {
struct <link linkend="v4l2-event-vsync">v4l2_event_vsync</link> vsync;
__u8 data[64];
} u;
__u32 pending;
__u32 sequence;
struct timespec timestamp;
__u32 reserved[9];
};
struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link> {
__u32 type;
__u32 reserved[7];
};
/*
* A D V A N C E D D E B U G G I N G
*
@ -1720,7 +1775,7 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
#if 1 /*KEEP*/
#if 1
#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link>)
#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link>)
#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link>)
@ -1728,7 +1783,7 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>)
#endif
#if 1 /*KEEP*/
#if 1
/* Experimental, meant for debugging, testing and internal use.
Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
You must be root to use these ioctls. Never use these in applications! */
@ -1747,6 +1802,9 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
#define VIDIOC_DQEVENT _IOR('V', 89, struct <link linkend="v4l2-event">v4l2_event</link>)
#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link>)
#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct <link linkend="v4l2-event-subscription">v4l2_event_subscription</link>)
/* Reminder: when adding new ioctls please add support for them to
drivers/media/video/v4l2-compat-ioctl32.c as well! */

View File

@ -16,8 +16,7 @@
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>&v4l2-dv-preset;
*<parameter>argp</parameter></paramdef>
<paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>

View File

@ -16,8 +16,7 @@
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>&v4l2-dv-timings;
*<parameter>argp</parameter></paramdef>
<paramdef>struct v4l2_dv_timings *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>

View File

@ -16,7 +16,7 @@ input</refpurpose>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>&v4l2-dv-preset; *<parameter>argp</parameter></paramdef>
<paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>

View File

@ -184,7 +184,7 @@ data.</entry>
<row>
<entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry>
<entry>0x00000100</entry>
<entry>The device supports the <link linkend="rds">RDS</link> interface.</entry>
<entry>The device supports the <link linkend="rds">RDS</link> capture interface.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry>
@ -205,6 +205,11 @@ driver capabilities.</para></footnote></entry>
<entry>The device supports the &VIDIOC-S-HW-FREQ-SEEK; ioctl for
hardware frequency seeking.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_RDS_OUTPUT</constant></entry>
<entry>0x00000800</entry>
<entry>The device supports the <link linkend="rds">RDS</link> output interface.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_TUNER</constant></entry>
<entry>0x00010000</entry>

View File

@ -103,8 +103,12 @@ structure. The driver fills the rest of the structure or returns an
<structfield>index</structfield> is invalid. Menu items are enumerated
by calling <constant>VIDIOC_QUERYMENU</constant> with successive
<structfield>index</structfield> values from &v4l2-queryctrl;
<structfield>minimum</structfield> (0) to
<structfield>maximum</structfield>, inclusive.</para>
<structfield>minimum</structfield> to
<structfield>maximum</structfield>, inclusive. Note that it is possible
for <constant>VIDIOC_QUERYMENU</constant> to return an &EINVAL; for some
indices between <structfield>minimum</structfield> and <structfield>maximum</structfield>.
In that case that particular menu item is not supported by this driver. Also note that
the <structfield>minimum</structfield> value is not necessarily 0.</para>
<para>See also the examples in <xref linkend="control" />.</para>
@ -139,7 +143,7 @@ string. This information is intended for the user.</entry>
<entry><structfield>minimum</structfield></entry>
<entry>Minimum value, inclusive. This field gives a lower
bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
lowest valid index (always 0) for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
lowest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value
gives the minimum length of the string. This length <emphasis>does not include the terminating
zero</emphasis>. It may not be valid for any other type of control, including
@ -279,7 +283,7 @@ values which are actually different on the hardware.</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry>
<entry>0</entry>
<entry>&ge; 0</entry>
<entry>1</entry>
<entry>N-1</entry>
<entry>The control has a menu of N choices. The names of
@ -405,8 +409,10 @@ writing a value will cause the device to carry out a given action
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-queryctrl; <structfield>id</structfield>
is invalid. The &v4l2-querymenu; <structfield>id</structfield> or
<structfield>index</structfield> is invalid.</para>
is invalid. The &v4l2-querymenu; <structfield>id</structfield> is
invalid or <structfield>index</structfield> is out of range (less than
<structfield>minimum</structfield> or greater than <structfield>maximum</structfield>)
or this particular menu item is not supported by the driver.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -51,7 +51,8 @@
<para>Start a hardware frequency seek from the current frequency.
To do this applications initialize the <structfield>tuner</structfield>,
<structfield>type</structfield>, <structfield>seek_upward</structfield> and
<structfield>type</structfield>, <structfield>seek_upward</structfield>,
<structfield>spacing</structfield> and
<structfield>wrap_around</structfield> fields, and zero out the
<structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and
call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer
@ -89,7 +90,12 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry><structfield>spacing</structfield></entry>
<entry>If non-zero, defines the hardware seek resolution in Hz. The driver selects the nearest value that is supported by the device. If spacing is zero a reasonable default value is used.</entry>
</row>
<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>
</row>

View File

@ -1496,9 +1496,6 @@ Your cooperation is appreciated.
64 = /dev/radio0 Radio device
...
127 = /dev/radio63 Radio device
192 = /dev/vtx0 Teletext device
...
223 = /dev/vtx31 Teletext device
224 = /dev/vbi0 Vertical blank interrupt
...
255 = /dev/vbi31 Vertical blank interrupt

View File

@ -26,7 +26,8 @@ use IO::Handle;
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
"af9015", "ngene", "az6027");
"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
"lme2510c_s7395_old");
# Check args
syntax() if (scalar(@ARGV) != 1);
@ -584,6 +585,49 @@ sub az6027{
$firmware;
}
sub lme2510_lg {
my $sourcefile = "LMEBDA_DVBS.sys";
my $hash = "fc6017ad01e79890a97ec53bea157ed2";
my $outfile = "dvb-usb-lme2510-lg.fw";
my $hasho = "caa065d5fdbd2c09ad57b399bbf55cad";
checkstandard();
verify($sourcefile, $hash);
extract($sourcefile, 4168, 3841, $outfile);
verify($outfile, $hasho);
$outfile;
}
sub lme2510c_s7395 {
my $sourcefile = "US2A0D.sys";
my $hash = "b0155a8083fb822a3bd47bc360e74601";
my $outfile = "dvb-usb-lme2510c-s7395.fw";
my $hasho = "3a3cf1aeebd17b6ddc04cebe131e94cf";
checkstandard();
verify($sourcefile, $hash);
extract($sourcefile, 37248, 3720, $outfile);
verify($outfile, $hasho);
$outfile;
}
sub lme2510c_s7395_old {
my $sourcefile = "LMEBDA_DVBS7395C.sys";
my $hash = "7572ae0eb9cdf91baabd7c0ba9e09b31";
my $outfile = "dvb-usb-lme2510c-s7395.fw";
my $hasho = "90430c5b435eb5c6f88fd44a9d950674";
checkstandard();
verify($sourcefile, $hash);
extract($sourcefile, 4208, 3881, $outfile);
verify($outfile, $hasho);
$outfile;
}
# ---------------------------------------------------------------
# Utilities

View File

@ -0,0 +1,58 @@
To extract firmware for the DM04/QQBOX you need to copy the
following file(s) to this directory.
for DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
-------------------------------------------
The Sharp 7395 driver can be found in windows/system32/driver
US2A0D.sys (dated 17 Mar 2009)
and run
./get_dvb_firmware lme2510c_s7395
will produce
dvb-usb-lme2510c-s7395.fw
An alternative but older firmware can be found on the driver
disk DVB-S_EN_3.5A in BDADriver/driver
LMEBDA_DVBS7395C.sys (dated 18 Jan 2008)
and run
./get_dvb_firmware lme2510c_s7395_old
will produce
dvb-usb-lme2510c-s7395.fw
--------------------------------------------------------------------
The LG firmware can be found on the driver
disk DM04+_5.1A[LG] in BDADriver/driver
for DM04 LME2510 (LG Tuner)
---------------------------
LMEBDA_DVBS.sys (dated 13 Nov 2007)
and run
./get_dvb_firmware lme2510_lg
will produce
dvb-usb-lme2510-lg.fw
Other LG firmware can be extracted manually from US280D.sys
only found in windows/system32/driver.
dd if=US280D.sys ibs=1 skip=42616 count=3668 of=dvb-usb-lme2510-lg.fw
for DM04 LME2510C (LG Tuner)
---------------------------
dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
---------------------------------------------------------------------
Copy the firmware file(s) to /lib/firmware

View File

@ -98,7 +98,7 @@ Who: Pavel Machek <pavel@ucw.cz>
---------------------------
What: Video4Linux API 1 ioctls and from Video devices.
When: July 2009
When: kernel 2.6.38
Files: include/linux/videodev.h
Check: include/linux/videodev.h
Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
@ -116,6 +116,21 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: Video4Linux obsolete drivers using V4L1 API
When: kernel 2.6.38
Files: drivers/staging/cpia/* drivers/staging/stradis/*
Check: drivers/staging/cpia/cpia.c drivers/staging/stradis/stradis.c
Why: There are some drivers still using V4L1 API, despite all efforts we've done
to migrate. Those drivers are for obsolete hardware that the old maintainer
didn't care (or not have the hardware anymore), and that no other developer
could find any hardware to buy. They probably have no practical usage today,
and people with such old hardware could probably keep using an older version
of the kernel. Those drivers will be moved to staging on 2.6.37 and, if nobody
care enough to port and test them with V4L2 API, they'll be removed on 2.6.38.
Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: sys_sysctl
When: September 2010
Option: CONFIG_SYSCTL_SYSCALL
@ -470,29 +485,6 @@ When: April 2011
Why: Superseded by xt_CT
Who: Netfilter developer team <netfilter-devel@vger.kernel.org>
---------------------------
What: video4linux /dev/vtx teletext API support
When: 2.6.35
Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
include/linux/videotext.h
Why: The vtx device nodes have been superseded by vbi device nodes
for many years. No applications exist that use the vtx support.
Of the two i2c drivers that actually support this API the saa5249
has been impossible to use for a year now and no known hardware
that supports this device exists. The saa5246a is theoretically
supported by the old mxb boards, but it never actually worked.
In summary: there is no hardware that can use this API and there
are no applications actually implementing this API.
The vtx support still reserves minors 192-223 and we would really
like to reuse those for upcoming new functionality. In the unlikely
event that new hardware appears that wants to use the functionality
provided by the vtx API, then that functionality should be build
around the sliced VBI API instead.
Who: Hans Verkuil <hverkuil@xs4all.nl>
----------------------------
What: IRQF_DISABLED

View File

@ -278,7 +278,6 @@ Code Seq#(hex) Include File Comments
<mailto:oe@port.de>
'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
0x80 00-1F linux/fb.h
0x81 00-1F linux/videotext.h
0x88 00-3F media/ovcamchip.h
0x89 00-06 arch/x86/include/asm/sockios.h
0x89 0B-DF linux/sockios.h

View File

@ -83,3 +83,4 @@
82 -> WinFast DTV2000 H rev. J [107d:6f2b]
83 -> Prof 7301 DVB-S/S2 [b034:3034]
84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd]
85 -> Twinhan VP-1027 DVB-S [1822:0023]

View File

@ -31,6 +31,7 @@
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
31 -> Usbgear VD204v9 (em2821)
32 -> Supercomp USB 2.0 TV (em2821)
33 -> Elgato Video Capture (em2860) [0fd9:0033]
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
35 -> Typhoon DVD Maker (em2860)
36 -> NetGMBH Cam (em2860)
@ -45,7 +46,7 @@
45 -> Pinnacle PCTV DVB-T (em2870)
46 -> Compro, VideoMate U3 (em2870) [185b:2870]
47 -> KWorld DVB-T 305U (em2880) [eb1a:e305]
48 -> KWorld DVB-T 310U (em2880) [eb1a:e310]
48 -> KWorld DVB-T 310U (em2880)
49 -> MSI DigiVox A/D (em2880) [eb1a:e310]
50 -> MSI DigiVox A/D II (em2880) [eb1a:e320]
51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c]

View File

@ -126,7 +126,7 @@
125 -> Beholder BeholdTV 409 [0000:4090]
126 -> Beholder BeholdTV 505 FM [5ace:5050]
127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090]
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
128 -> Beholder BeholdTV Columbus TV/FM [0000:5201]
129 -> Beholder BeholdTV 607 FM [5ace:6070]
130 -> Beholder BeholdTV M6 [5ace:6190]
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]

View File

@ -19,7 +19,6 @@ function makedev () {
echo "*** new device names ***"
makedev video 0
makedev radio 64
makedev vtx 192
makedev vbi 224
#echo "*** old device names (for compatibility only) ***"

View File

@ -302,12 +302,14 @@ sonixj 0c45:60fb Surfer NoName
sonixj 0c45:60fc LG-LIC300
sonixj 0c45:60fe Microdia Audio
sonixj 0c45:6100 PC Camera (SN9C128)
sonixj 0c45:6102 PC Camera (SN9C128)
sonixj 0c45:610a PC Camera (SN9C128)
sonixj 0c45:610b PC Camera (SN9C128)
sonixj 0c45:610c PC Camera (SN9C128)
sonixj 0c45:610e PC Camera (SN9C128)
sonixj 0c45:6128 Microdia/Sonix SNP325
sonixj 0c45:612a Avant Camera
sonixj 0c45:612b Speed-Link REFLECT2
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
sonixj 0c45:6130 Sonix Pccam
sonixj 0c45:6138 Sn9c120 Mo4000

View File

@ -44,8 +44,8 @@ All drivers have the following structure:
2) A way of initializing and commanding sub-devices (if any).
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
/dev/vtxX) and keeping track of device-node specific data.
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX and /dev/radioX)
and keeping track of device-node specific data.
4) Filehandle-specific structs containing per-filehandle data;
@ -192,6 +192,11 @@ You also need a way to go from the low-level struct to v4l2_subdev. For the
common i2c_client struct the i2c_set_clientdata() call is used to store a
v4l2_subdev pointer, for other busses you may have to use other methods.
Bridges might also need to store per-subdev private data, such as a pointer to
bridge-specific per-subdev private data. The v4l2_subdev structure provides
host private data for that purpose that can be accessed with
v4l2_get_subdev_hostdata() and v4l2_set_subdev_hostdata().
From the bridge driver perspective you load the sub-device module and somehow
obtain the v4l2_subdev pointer. For i2c devices this is easy: you call
i2c_get_clientdata(). For other busses something similar needs to be done.
@ -448,6 +453,10 @@ You should also set these fields:
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
(highly recommended to use this and it might become compulsory in the
future!), then set this to your v4l2_ioctl_ops struct.
- lock: leave to NULL if you want to do all the locking in the driver.
Otherwise you give it a pointer to a struct mutex_lock and before any
of the v4l2_file_operations is called this lock will be taken by the
core and released afterwards.
- parent: you only set this if v4l2_device was registered with NULL as
the parent device struct. This only happens in cases where one hardware
device has multiple PCI devices that all share the same v4l2_device core.
@ -464,6 +473,22 @@ If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
The v4l2_file_operations struct is a subset of file_operations. The main
difference is that the inode argument is omitted since it is never used.
v4l2_file_operations and locking
--------------------------------
You can set a pointer to a mutex_lock in struct video_device. Usually this
will be either a top-level mutex or a mutex per device node. If you want
finer-grained locking then you have to set it to NULL and do you own locking.
If a lock is specified then all file operations will be serialized on that
lock. If you use videobuf then you must pass the same lock to the videobuf
queue initialize function: if videobuf has to wait for a frame to arrive, then
it will temporarily unlock the lock and relock it afterwards. If your driver
also waits in the code, then you should do the same to allow other processes
to access the device node while the first process is waiting for something.
The implementation of a hotplug disconnect should also take the lock before
calling v4l2_device_disconnect.
video_device registration
-------------------------
@ -483,7 +508,6 @@ types exist:
VFL_TYPE_GRABBER: videoX for video input/output devices
VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext)
VFL_TYPE_RADIO: radioX for radio tuners
VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
The last argument gives you a certain amount of control over the device
device node number used (i.e. the X in videoX). Normally you will pass -1
@ -547,9 +571,8 @@ from /dev).
After video_unregister_device() returns no new opens can be done. However,
in the case of USB devices some application might still have one of these
device nodes open. So after the unregister all file operations will return
an error as well, except for the ioctl and unlocked_ioctl file operations:
those will still be passed on since some buffer ioctls may still be needed.
device nodes open. So after the unregister all file operations (except
release, of course) will return an error as well.
When the last user of the video device node exits, then the vdev->release()
callback is called and you can do the final cleanup there.

View File

@ -311,7 +311,6 @@ static struct soc_camera_link iclink_mt9v022 = {
.bus_id = 0, /* Must match with the camera ID */
.board_info = &pcm037_i2c_camera[1],
.i2c_adapter_id = 2,
.module_name = "mt9v022",
};
static struct soc_camera_link iclink_mt9t031 = {
@ -319,7 +318,6 @@ static struct soc_camera_link iclink_mt9t031 = {
.power = pcm037_camera_power,
.board_info = &pcm037_i2c_camera[0],
.i2c_adapter_id = 2,
.module_name = "mt9t031",
};
static struct i2c_board_info pcm037_i2c_devices[] = {

View File

@ -179,7 +179,6 @@ static struct soc_camera_link base_iclink = {
.reset = marxbot_basecam_reset,
.board_info = &marxbot_i2c_devices[0],
.i2c_adapter_id = 0,
.module_name = "mt9t031",
};
static struct platform_device marxbot_camera[] = {

View File

@ -88,7 +88,6 @@ static struct soc_camera_link base_iclink = {
.reset = smartbot_cam_reset,
.board_info = &smartbot_i2c_devices[0],
.i2c_adapter_id = 0,
.module_name = "mt9t031",
};
static struct platform_device smartbot_camera[] = {

View File

@ -1015,7 +1015,6 @@ static struct soc_camera_link iclink = {
.power = em_x270_sensor_power,
.board_info = &em_x270_i2c_cam_info[0],
.i2c_adapter_id = 0,
.module_name = "mt9m111",
};
static struct platform_device em_x270_camera = {

View File

@ -755,7 +755,6 @@ static struct soc_camera_link a780_iclink = {
.flags = SOCAM_SENSOR_INVERT_PCLK,
.i2c_adapter_id = 0,
.board_info = &a780_camera_i2c_board_info,
.module_name = "mt9m111",
.power = a780_camera_power,
.reset = a780_camera_reset,
};
@ -1024,7 +1023,6 @@ static struct soc_camera_link a910_iclink = {
.bus_id = 0,
.i2c_adapter_id = 0,
.board_info = &a910_camera_i2c_board_info,
.module_name = "mt9m111",
.power = a910_camera_power,
.reset = a910_camera_reset,
};

View File

@ -711,7 +711,6 @@ static struct soc_camera_link iclink = {
.bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
.board_info = &mioa701_i2c_devices[0],
.i2c_adapter_id = 0,
.module_name = "mt9m111",
};
struct i2c_pxa_platform_data i2c_pdata = {

View File

@ -453,7 +453,6 @@ static struct soc_camera_link iclink[] = {
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
.free_bus = pcm990_camera_free_bus,
.module_name = "mt9v022",
}, {
.bus_id = 0, /* Must match with the camera ID */
.board_info = &pcm990_camera_i2c[1],
@ -461,7 +460,6 @@ static struct soc_camera_link iclink[] = {
.query_bus_param = pcm990_camera_query_bus_param,
.set_bus_param = pcm990_camera_set_bus_param,
.free_bus = pcm990_camera_free_bus,
.module_name = "mt9m001",
},
};

View File

@ -481,7 +481,6 @@ static struct soc_camera_link ov7725_link = {
.power = ov7725_power,
.board_info = &ap325rxa_i2c_camera[0],
.i2c_adapter_id = 0,
.module_name = "ov772x",
.priv = &ov7725_info,
};

View File

@ -620,7 +620,6 @@ static struct soc_camera_link tw9910_link = {
.bus_id = 1,
.power = tw9910_power,
.board_info = &i2c_camera[0],
.module_name = "tw9910",
.priv = &tw9910_info,
};
@ -644,7 +643,6 @@ static struct soc_camera_link mt9t112_link1 = {
.power = mt9t112_power1,
.bus_id = 0,
.board_info = &i2c_camera[1],
.module_name = "mt9t112",
.priv = &mt9t112_info1,
};
@ -667,7 +665,6 @@ static struct soc_camera_link mt9t112_link2 = {
.power = mt9t112_power2,
.bus_id = 1,
.board_info = &i2c_camera[2],
.module_name = "mt9t112",
.priv = &mt9t112_info2,
};
@ -793,7 +790,6 @@ static struct sh_vou_pdata sh_vou_pdata = {
.flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
.board_info = &ak8813,
.i2c_adap = 0,
.module_name = "ak881x",
};
static struct resource sh_vou_resources[] = {

View File

@ -333,7 +333,6 @@ static struct soc_camera_link rj54n1_link = {
.power = camera_power,
.board_info = &kfr2r09_i2c_camera,
.i2c_adapter_id = 1,
.module_name = "rj54n1cb0c",
.priv = &rj54n1_priv,
};

View File

@ -450,7 +450,6 @@ static struct soc_camera_link ov7725_link = {
.power = ov7725_power,
.board_info = &migor_i2c_camera[0],
.i2c_adapter_id = 0,
.module_name = "ov772x",
.priv = &ov7725_info,
};
@ -463,7 +462,6 @@ static struct soc_camera_link tw9910_link = {
.power = tw9910_power,
.board_info = &migor_i2c_camera[1],
.i2c_adapter_id = 0,
.module_name = "tw9910",
.priv = &tw9910_info,
};

View File

@ -550,7 +550,6 @@ static struct sh_vou_pdata sh_vou_pdata = {
.flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
.board_info = &ak8813,
.i2c_adap = 0,
.module_name = "ak881x",
};
static struct resource sh_vou_resources[] = {

View File

@ -79,6 +79,18 @@ config IR_SONY_DECODER
Enable this option if you have an infrared remote control which
uses the Sony protocol, and you need software decoding support.
config IR_RC5_SZ_DECODER
tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
depends on IR_CORE
select BITREVERSE
default y
---help---
Enable this option if you have IR with RC-5 (streamzap) protocol,
and if the IR is decoded in software. (The Streamzap PC Remote
uses an IR protocol that is almost standard RC-5, but not quite,
as it uses an additional bit).
config IR_LIRC_CODEC
tristate "Enable IR to LIRC bridge"
depends on IR_CORE
@ -89,6 +101,20 @@ config IR_LIRC_CODEC
Enable this option to pass raw IR to and from userspace via
the LIRC interface.
config IR_ENE
tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)"
depends on PNP
depends on IR_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transceiver made by ENE.
You can see if you have it by looking at lspnp output.
Output should include ENE0100 ENE0200 or something similar.
To compile this driver as a module, choose M here: the
module will be called ene_ir.
config IR_IMON
tristate "SoundGraph iMON Receiver and Display"
depends on USB_ARCH_HAS_HCD
@ -113,19 +139,18 @@ config IR_MCEUSB
To compile this driver as a module, choose M here: the
module will be called mceusb.
config IR_ENE
tristate "ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx)"
config IR_NUVOTON
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
depends on PNP
depends on IR_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transciever made by ENE.
You can see if you have it by looking at lspnp output.
Output should include ENE0100 ENE0200 or something similiar.
/transciever made by Nuvoton (formerly Winbond). This chip is
found in the ASRock ION 330HT, as well as assorted Intel
DP55-series motherboards (and of course, possibly others).
To compile this driver as a module, choose M here: the
module will be called ene_ir.
module will be called nuvoton-cir.
config IR_STREAMZAP
tristate "Streamzap PC Remote IR Receiver"

View File

@ -11,10 +11,12 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
# stand-alone IR receivers/transmitters
obj-$(CONFIG_IR_IMON) += imon.o
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_ENE) += ene_ir.o
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* driver for ENE KB3926 B/C/D CIR (also known as ENE0XXX)
* driver for ENE KB3926 B/C/D/E/F CIR (also known as ENE0XXX)
*
* Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com>
*
@ -26,43 +26,50 @@
#define ENE_ADDR_HI 1 /* hi byte of register address */
#define ENE_ADDR_LO 2 /* low byte of register address */
#define ENE_IO 3 /* read/write window */
#define ENE_MAX_IO 4
#define ENE_IO_SIZE 4
/* 8 bytes of samples, divided in 2 halfs*/
#define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */
#define ENE_SAMPLE_SPC_MASK 0x80 /* sample is space */
#define ENE_SAMPLE_VALUE_MASK 0x7F
#define ENE_SAMPLE_OVERFLOW 0x7F
#define ENE_SAMPLES_SIZE 4
/* 8 bytes of samples, divided in 2 packets*/
#define ENE_FW_SAMPLE_BUFFER 0xF8F0 /* sample buffer */
#define ENE_FW_SAMPLE_SPACE 0x80 /* sample is space */
#define ENE_FW_PACKET_SIZE 4
/* fan input sample buffer */
#define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */
/* each sample of normal buffer */
#define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */
/* if set, says that sample is pulse */
#define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */
/* first firmware register */
#define ENE_FW1 0xF8F8
/* first firmware flag register */
#define ENE_FW1 0xF8F8 /* flagr */
#define ENE_FW1_ENABLE 0x01 /* enable fw processing */
#define ENE_FW1_TXIRQ 0x02 /* TX interrupt pending */
#define ENE_FW1_HAS_EXTRA_BUF 0x04 /* fw uses extra buffer*/
#define ENE_FW1_EXTRA_BUF_HND 0x08 /* extra buffer handshake bit*/
#define ENE_FW1_LED_ON 0x10 /* turn on a led */
#define ENE_FW1_WPATTERN 0x20 /* enable wake pattern */
#define ENE_FW1_WAKE 0x40 /* enable wake from S3 */
#define ENE_FW1_IRQ 0x80 /* enable interrupt */
/* second firmware register */
#define ENE_FW2 0xF8F9
#define ENE_FW2_BUF_HIGH 0x01 /* which half of the buffer to read */
#define ENE_FW2_IRQ_CLR 0x04 /* clear this on IRQ */
#define ENE_FW2_GP40_AS_LEARN 0x08 /* normal input is used as */
/* learning input */
#define ENE_FW2_FAN_AS_NRML_IN 0x40 /* fan is used as normal input */
/* second firmware flag register */
#define ENE_FW2 0xF8F9 /* flagw */
#define ENE_FW2_BUF_WPTR 0x01 /* which half of the buffer to read */
#define ENE_FW2_RXIRQ 0x04 /* RX IRQ pending*/
#define ENE_FW2_GP0A 0x08 /* Use GPIO0A for demodulated input */
#define ENE_FW2_EMMITER1_CONN 0x10 /* TX emmiter 1 connected */
#define ENE_FW2_EMMITER2_CONN 0x20 /* TX emmiter 2 connected */
#define ENE_FW2_FAN_INPUT 0x40 /* fan input used for demodulated data*/
#define ENE_FW2_LEARNING 0x80 /* hardware supports learning and TX */
/* firmware RX pointer for new style buffer */
#define ENE_FW_RX_POINTER 0xF8FA
/* high parts of samples for fan input (8 samples)*/
#define ENE_FW_SMPL_BUF_FAN 0xF8FB
#define ENE_FW_SMPL_BUF_FAN_PLS 0x8000 /* combined sample is pulse */
#define ENE_FW_SMPL_BUF_FAN_MSK 0x0FFF /* combined sample maximum value */
#define ENE_FW_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
/* transmitter ports */
#define ENE_TX_PORT2 0xFC01 /* this enables one or both */
#define ENE_TX_PORT2_EN 0x20 /* TX ports */
#define ENE_TX_PORT1 0xFC08
#define ENE_TX_PORT1_EN 0x02
#define ENE_GPIOFS1 0xFC01
#define ENE_GPIOFS1_GPIO0D 0x20 /* enable tx output on GPIO0D */
#define ENE_GPIOFS8 0xFC08
#define ENE_GPIOFS8_GPIO41 0x02 /* enable tx output on GPIO40 */
/* IRQ registers block (for revision B) */
#define ENEB_IRQ 0xFD09 /* IRQ number */
@ -70,98 +77,100 @@
#define ENEB_IRQ_STATUS 0xFD80 /* irq status */
#define ENEB_IRQ_STATUS_IR 0x20 /* IR irq */
/* fan as input settings - only if learning capable */
/* fan as input settings */
#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */
#define ENE_FAN_AS_IN1_EN 0xCD
#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */
#define ENE_FAN_AS_IN2_EN 0x03
#define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
/* IRQ registers block (for revision C,D) */
#define ENEC_IRQ 0xFE9B /* new irq settings register */
#define ENEC_IRQ_MASK 0x0F /* irq number mask */
#define ENEC_IRQ_UNK_EN 0x10 /* always enabled */
#define ENEC_IRQ_STATUS 0x20 /* irq status and ACK */
#define ENE_IRQ 0xFE9B /* new irq settings register */
#define ENE_IRQ_MASK 0x0F /* irq number mask */
#define ENE_IRQ_UNK_EN 0x10 /* always enabled */
#define ENE_IRQ_STATUS 0x20 /* irq status and ACK */
/* CIR block settings */
#define ENE_CIR_CONF1 0xFEC0
#define ENE_CIR_CONF1_TX_CLEAR 0x01 /* clear that on revC */
/* while transmitting */
#define ENE_CIR_CONF1_RX_ON 0x07 /* normal receiver enabled */
#define ENE_CIR_CONF1_LEARN1 0x08 /* enabled on learning mode */
#define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */
#define ENE_CIR_CONF1_TX_CARR 0x80 /* send TX carrier or not */
/* CIR Config register #1 */
#define ENE_CIRCFG 0xFEC0
#define ENE_CIRCFG_RX_EN 0x01 /* RX enable */
#define ENE_CIRCFG_RX_IRQ 0x02 /* Enable hardware interrupt */
#define ENE_CIRCFG_REV_POL 0x04 /* Input polarity reversed */
#define ENE_CIRCFG_CARR_DEMOD 0x08 /* Enable carrier demodulator */
#define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */
#define ENE_CIR_CONF2_LEARN2 0x10 /* set on enable learning */
#define ENE_CIR_CONF2_GPIO40DIS 0x20 /* disable input via gpio40 */
#define ENE_CIRCFG_TX_EN 0x10 /* TX enable */
#define ENE_CIRCFG_TX_IRQ 0x20 /* Send interrupt on TX done */
#define ENE_CIRCFG_TX_POL_REV 0x40 /* TX polarity reversed */
#define ENE_CIRCFG_TX_CARR 0x80 /* send TX carrier or not */
#define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */
#define ENE_CIR_SAMPLE_OVERFLOW 0x80 /* interrupt on overflows if set */
/* CIR config register #2 */
#define ENE_CIRCFG2 0xFEC1
#define ENE_CIRCFG2_RLC 0x00
#define ENE_CIRCFG2_RC5 0x01
#define ENE_CIRCFG2_RC6 0x02
#define ENE_CIRCFG2_NEC 0x03
#define ENE_CIRCFG2_CARR_DETECT 0x10 /* Enable carrier detection */
#define ENE_CIRCFG2_GPIO0A 0x20 /* Use GPIO0A instead of GPIO40 for input */
#define ENE_CIRCFG2_FAST_SAMPL1 0x40 /* Fast leading pulse detection for RC6 */
#define ENE_CIRCFG2_FAST_SAMPL2 0x80 /* Fast data detection for RC6 */
/* Knobs for protocol decoding - will document when/if will use them */
#define ENE_CIRPF 0xFEC2
#define ENE_CIRHIGH 0xFEC3
#define ENE_CIRBIT 0xFEC4
#define ENE_CIRSTART 0xFEC5
#define ENE_CIRSTART2 0xFEC6
/* Actual register which contains RLC RX data - read by firmware */
#define ENE_CIRDAT_IN 0xFEC7
/* Two byte tx buffer */
#define ENE_TX_INPUT1 0xFEC9
#define ENE_TX_INPUT2 0xFECA
#define ENE_TX_PULSE_MASK 0x80 /* Transmitted sample is pulse */
#define ENE_TX_SMLP_MASK 0x7F
#define ENE_TX_SMPL_PERIOD 50 /* transmit sample period - fixed */
/* RLC configuration - sample period (1us resulution) + idle mode */
#define ENE_CIRRLC_CFG 0xFEC8
#define ENE_CIRRLC_CFG_OVERFLOW 0x80 /* interrupt on overflows if set */
#define ENE_DEFAULT_SAMPLE_PERIOD 50
/* Two byte RLC TX buffer */
#define ENE_CIRRLC_OUT0 0xFEC9
#define ENE_CIRRLC_OUT1 0xFECA
#define ENE_CIRRLC_OUT_PULSE 0x80 /* Transmitted sample is pulse */
#define ENE_CIRRLC_OUT_MASK 0x7F
/* Unknown TX setting - TX sample period ??? */
#define ENE_TX_UNK1 0xFECB /* set to 0x63 */
/* Carrier detect setting
* Low nibble - number of carrier pulses to average
* High nibble - number of initial carrier pulses to discard
*/
#define ENE_CIRCAR_PULS 0xFECB
/* Current received carrier period */
#define ENE_RX_CARRIER 0xFECC /* RX period (500 ns) */
#define ENE_RX_CARRIER_VALID 0x80 /* Register content valid */
/* detected RX carrier period (resolution: 500 ns) */
#define ENE_CIRCAR_PRD 0xFECC
#define ENE_CIRCAR_PRD_VALID 0x80 /* data valid content valid */
/* detected RX carrier pulse width (resolution: 500 ns) */
#define ENE_CIRCAR_HPRD 0xFECD
/* TX period (1/carrier) */
#define ENE_TX_PERIOD 0xFECE /* TX period (500 ns) */
#define ENE_TX_PERIOD_UNKBIT 0x80 /* This bit set on transmit*/
#define ENE_TX_PERIOD_PULSE 0xFECF /* TX pulse period (500 ns)*/
/* TX period (resolution: 500 ns, minimum 2)*/
#define ENE_CIRMOD_PRD 0xFECE
#define ENE_CIRMOD_PRD_POL 0x80 /* TX carrier polarity*/
#define ENE_CIRMOD_PRD_MAX 0x7F /* 15.87 kHz */
#define ENE_CIRMOD_PRD_MIN 0x02 /* 1 Mhz */
/* TX pulse width (resolution: 500 ns)*/
#define ENE_CIRMOD_HPRD 0xFECF
/* Hardware versions */
#define ENE_HW_VERSION 0xFF00 /* hardware revision */
#define ENE_ECHV 0xFF00 /* hardware revision */
#define ENE_PLLFRH 0xFF16
#define ENE_PLLFRL 0xFF17
#define ENE_DEFAULT_PLL_FREQ 1000
#define ENE_HW_UNK 0xFF1D
#define ENE_HW_UNK_CLR 0x04
#define ENE_HW_VER_MAJOR 0xFF1E /* chip version */
#define ENE_HW_VER_MINOR 0xFF1F
#define ENE_ECSTS 0xFF1D
#define ENE_ECSTS_RSRVD 0x04
#define ENE_ECVER_MAJOR 0xFF1E /* chip version */
#define ENE_ECVER_MINOR 0xFF1F
#define ENE_HW_VER_OLD 0xFD00
/* Normal/Learning carrier ranges - only valid if we have learning input*/
/* TODO: test */
#define ENE_NORMAL_RX_LOW 34
#define ENE_NORMAL_RX_HI 38
/* Tx carrier range */
/* Hardware might be able to do more, but this range is enough for
all purposes */
#define ENE_TX_PERIOD_MAX 32 /* corresponds to 29.4 kHz */
#define ENE_TX_PERIOD_MIN 16 /* corrsponds to 62.5 kHz */
/* Minimal and maximal gaps */
/* Normal case:
Minimal gap is 0x7F * sample period
Maximum gap depends on hardware.
For KB3926B, it is unlimited, for newer models its around
250000, after which HW stops sending samples, and that is
not possible to change */
/* Fan case:
Both minimal and maximal gaps are same, and equal to 0xFFF * 0x61
And there is nothing to change this setting
*/
#define ENE_MAXGAP 250000
#define ENE_MINGAP (127 * sample_period)
/******************************************************************************/
#define ENE_DRIVER_NAME "ene_ir"
@ -171,46 +180,60 @@
#define ENE_HW_B 1 /* 3926B */
#define ENE_HW_C 2 /* 3926C */
#define ENE_HW_D 3 /* 3926D */
#define ENE_HW_D 3 /* 3926D or later */
#define ene_printk(level, text, ...) \
printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
printk(level ENE_DRIVER_NAME ": " text "\n", ## __VA_ARGS__)
#define ene_dbg(text, ...) \
if (debug) \
printk(KERN_DEBUG \
ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
#define ene_notice(text, ...) ene_printk(KERN_NOTICE, text, ## __VA_ARGS__)
#define ene_warn(text, ...) ene_printk(KERN_WARNING, text, ## __VA_ARGS__)
#define ene_dbg_verbose(text, ...) \
if (debug > 1) \
printk(KERN_DEBUG \
ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
#define __dbg(level, format, ...) \
do { \
if (debug >= level) \
printk(KERN_DEBUG ENE_DRIVER_NAME \
": " format "\n", ## __VA_ARGS__); \
} while (0)
#define dbg(format, ...) __dbg(1, format, ## __VA_ARGS__)
#define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__)
#define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__)
#define MS_TO_NS(msec) ((msec) * 1000)
struct ene_device {
struct pnp_dev *pnp_dev;
struct input_dev *idev;
struct ir_dev_props *props;
int in_use;
/* hw IO settings */
unsigned long hw_io;
long hw_io;
int irq;
spinlock_t hw_lock;
/* HW features */
int hw_revision; /* hardware revision */
bool hw_learning_and_tx_capable; /* learning capable */
bool hw_gpio40_learning; /* gpio40 is learning */
bool hw_fan_as_normal_input; /* fan input is used as */
/* regular input */
bool hw_use_gpio_0a; /* gpio0a is demodulated input*/
bool hw_extra_buffer; /* hardware has 'extra buffer' */
bool hw_fan_input; /* fan input is IR data source */
bool hw_learning_and_tx_capable; /* learning & tx capable */
int pll_freq;
int buffer_len;
/* Extra RX buffer location */
int extra_buf1_address;
int extra_buf1_len;
int extra_buf2_address;
int extra_buf2_len;
/* HW state*/
int rx_pointer; /* hw pointer to rx buffer */
int r_pointer; /* pointer to next sample to read */
int w_pointer; /* pointer to next sample hw will write */
bool rx_fan_input_inuse; /* is fan input in use for rx*/
int tx_reg; /* current reg used for TX */
u8 saved_conf1; /* saved FEC0 reg */
/* TX sample handling */
unsigned int tx_sample; /* current sample for TX */
bool tx_sample_pulse; /* current sample is pulse */
@ -229,7 +252,11 @@ struct ene_device {
int transmitter_mask;
/* RX settings */
bool learning_enabled; /* learning input enabled */
bool learning_mode_enabled; /* learning input enabled */
bool carrier_detect_enabled; /* carrier detect enabled */
int rx_period_adjust;
bool rx_enabled;
};
static int ene_irq_status(struct ene_device *dev);
static void ene_rx_read_hw_pointer(struct ene_device *dev);

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#define _IR_RAW_EVENT
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <media/ir-core.h>
struct ir_raw_handler {
@ -33,6 +34,7 @@ struct ir_raw_handler {
struct ir_raw_event_ctrl {
struct list_head list; /* to keep track of raw clients */
struct task_struct *thread;
spinlock_t lock;
struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */
@ -76,10 +78,22 @@ struct ir_raw_event_ctrl {
bool first;
bool toggle;
} jvc;
struct rc5_sz_dec {
int state;
u32 bits;
unsigned count;
unsigned wanted_bits;
} rc5_sz;
struct lirc_codec {
struct ir_input_dev *ir_dev;
struct lirc_driver *drv;
int carrier_low;
ktime_t gap_start;
u64 gap_duration;
bool gap;
bool send_timeout_reports;
} lirc;
};
@ -107,13 +121,19 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
ev->duration -= duration;
}
/* Returns true if event is normal pulse/space event */
static inline bool is_timing_event(struct ir_raw_event ev)
{
return !ev.carrier_report && !ev.reset;
}
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
#define IS_RESET(ev) (ev.duration == 0)
/*
* Routines from ir-sysfs.c - Meant to be called only internally inside
* ir-core
*/
int ir_register_input(struct input_dev *input_dev);
int ir_register_class(struct input_dev *input_dev);
void ir_unregister_class(struct input_dev *input_dev);

View File

@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}

View File

@ -435,7 +435,7 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
* This routine is used to signal that a key has been released on the
* remote control. It reports a keyup input event via input_report_key().
*/
static void ir_keyup(struct ir_input_dev *ir)
void ir_keyup(struct ir_input_dev *ir)
{
if (!ir->keypressed)
return;
@ -445,6 +445,7 @@ static void ir_keyup(struct ir_input_dev *ir)
input_sync(ir->input_dev);
ir->keypressed = false;
}
EXPORT_SYMBOL_GPL(ir_keyup);
/**
* ir_timer_keyup() - generates a keyup event after a timeout
@ -640,6 +641,10 @@ int __ir_input_register(struct input_dev *input_dev,
goto out_event;
}
rc = ir_register_input(input_dev);
if (rc < 0)
goto out_event;
IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
driver_name, rc_tab->name,
(ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?

View File

@ -32,6 +32,7 @@
static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct lirc_codec *lirc = &ir_dev->raw->lirc;
int sample;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
return -EINVAL;
if (IS_RESET(ev))
/* Packet start */
if (ev.reset)
return 0;
IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
TO_US(ev.duration), TO_STR(ev.pulse));
/* Carrier reports */
if (ev.carrier_report) {
sample = LIRC_FREQUENCY(ev.carrier);
sample = ev.duration / 1000;
if (ev.pulse)
sample |= PULSE_BIT;
/* Packet end */
} else if (ev.timeout) {
if (lirc->gap)
return 0;
lirc->gap_start = ktime_get();
lirc->gap = true;
lirc->gap_duration = ev.duration;
if (!lirc->send_timeout_reports)
return 0;
sample = LIRC_TIMEOUT(ev.duration / 1000);
/* Normal sample */
} else {
if (lirc->gap) {
int gap_sample;
lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
lirc->gap_start));
/* Convert to ms and cap by LIRC_VALUE_MASK */
do_div(lirc->gap_duration, 1000);
lirc->gap_duration = min(lirc->gap_duration,
(u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration);
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
(unsigned char *) &gap_sample);
lirc->gap = false;
}
sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
LIRC_SPACE(ev.duration / 1000);
}
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
(unsigned char *) &sample);
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
return 0;
}
@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
struct ir_input_dev *ir_dev;
int ret = 0;
void *drv_data;
unsigned long val = 0;
__u32 val = 0, tmp;
lirc = lirc_get_pdata(filep);
if (!lirc)
@ -115,7 +152,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
drv_data = ir_dev->props->priv;
if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = get_user(val, (unsigned long *)arg);
ret = get_user(val, (__u32 *)arg);
if (ret)
return ret;
}
@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
case LIRC_SET_SEND_MODE:
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
return -EINVAL;
break;
return 0;
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
if (ir_dev->props->s_tx_mask)
ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
else
if (!ir_dev->props->s_tx_mask)
return -EINVAL;
break;
return ir_dev->props->s_tx_mask(drv_data, val);
case LIRC_SET_SEND_CARRIER:
if (ir_dev->props->s_tx_carrier)
ir_dev->props->s_tx_carrier(drv_data, (u32)val);
else
if (!ir_dev->props->s_tx_carrier)
return -EINVAL;
break;
return ir_dev->props->s_tx_carrier(drv_data, val);
case LIRC_SET_SEND_DUTY_CYCLE:
if (!ir_dev->props->s_tx_duty_cycle)
@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
if (val <= 0 || val >= 100)
return -EINVAL;
ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
break;
return ir_dev->props->s_tx_duty_cycle(drv_data, val);
/* RX settings */
case LIRC_SET_REC_CARRIER:
if (ir_dev->props->s_rx_carrier_range)
ret = ir_dev->props->s_rx_carrier_range(
ir_dev->props->priv,
ir_dev->raw->lirc.carrier_low, val);
else
if (!ir_dev->props->s_rx_carrier_range)
return -ENOSYS;
if (!ret)
ir_dev->raw->lirc.carrier_low = 0;
break;
if (val <= 0)
return -EINVAL;
return ir_dev->props->s_rx_carrier_range(drv_data,
ir_dev->raw->lirc.carrier_low, val);
case LIRC_SET_REC_CARRIER_RANGE:
if (val >= 0)
ir_dev->raw->lirc.carrier_low = val;
break;
if (val <= 0)
return -EINVAL;
ir_dev->raw->lirc.carrier_low = val;
return 0;
case LIRC_GET_REC_RESOLUTION:
val = ir_dev->props->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
if (ir_dev->props->s_learning_mode)
return ir_dev->props->s_learning_mode(
ir_dev->props->priv, !!val);
else
if (!ir_dev->props->s_learning_mode)
return -ENOSYS;
return ir_dev->props->s_learning_mode(drv_data, !!val);
case LIRC_SET_MEASURE_CARRIER_MODE:
if (!ir_dev->props->s_carrier_report)
return -ENOSYS;
return ir_dev->props->s_carrier_report(drv_data, !!val);
/* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT:
if (!ir_dev->props->max_timeout)
@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
break;
case LIRC_SET_REC_TIMEOUT:
if (val < ir_dev->props->min_timeout ||
val > ir_dev->props->max_timeout)
return -EINVAL;
ir_dev->props->timeout = val * 1000;
if (!ir_dev->props->max_timeout)
return -ENOSYS;
tmp = val * 1000;
if (tmp < ir_dev->props->min_timeout ||
tmp > ir_dev->props->max_timeout)
return -EINVAL;
ir_dev->props->timeout = tmp;
break;
case LIRC_SET_REC_TIMEOUT_REPORTS:
lirc->send_timeout_reports = !!val;
break;
default:
@ -212,7 +260,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
}
if (_IOC_DIR(cmd) & _IOC_READ)
ret = put_user(val, (unsigned long *)arg);
ret = put_user(val, (__u32 *)arg);
return ret;
}
@ -231,6 +279,9 @@ static struct file_operations lirc_fops = {
.owner = THIS_MODULE,
.write = ir_lirc_transmit_ir,
.unlocked_ioctl = ir_lirc_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ir_lirc_ioctl,
#endif
.read = lirc_dev_fop_read,
.poll = lirc_dev_fop_poll,
.open = lirc_dev_fop_open,
@ -278,6 +329,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
if (ir_dev->props->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
if (ir_dev->props->s_carrier_report)
features |= LIRC_CAN_MEASURE_CARRIER;
if (ir_dev->props->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;

View File

@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}

View File

@ -39,22 +39,34 @@ static int ir_raw_event_thread(void *data)
struct ir_raw_event ev;
struct ir_raw_handler *handler;
struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
int retval;
while (!kthread_should_stop()) {
try_to_freeze();
mutex_lock(&ir_raw_handler_lock);
spin_lock_irq(&raw->lock);
retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
list_for_each_entry(handler, &ir_raw_handler_list, list)
handler->decode(raw->input_dev, ev);
raw->prev_ev = ev;
if (!retval) {
set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop())
set_current_state(TASK_RUNNING);
spin_unlock_irq(&raw->lock);
schedule();
continue;
}
mutex_unlock(&ir_raw_handler_lock);
spin_unlock_irq(&raw->lock);
set_current_state(TASK_INTERRUPTIBLE);
schedule();
BUG_ON(retval != sizeof(ev));
mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list)
handler->decode(raw->input_dev, ev);
raw->prev_ev = ev;
mutex_unlock(&ir_raw_handler_lock);
}
return 0;
@ -77,7 +89,7 @@ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
if (!ir->raw)
return -EINVAL;
IR_dprintk(2, "sample: (05%dus %s)\n",
IR_dprintk(2, "sample: (%05dus %s)\n",
TO_US(ev->duration), TO_STR(ev->pulse));
if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
@ -162,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
if (ir->idle && !ev->pulse)
return 0;
else if (ir->idle)
ir_raw_event_set_idle(input_dev, 0);
ir_raw_event_set_idle(input_dev, false);
if (!raw->this_ev.duration) {
raw->this_ev = *ev;
@ -175,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
/* Enter idle mode if nessesary */
if (!ev->pulse && ir->props->timeout &&
raw->this_ev.duration >= ir->props->timeout)
ir_raw_event_set_idle(input_dev, 1);
raw->this_ev.duration >= ir->props->timeout) {
ir_raw_event_set_idle(input_dev, true);
}
return 0;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
/**
* ir_raw_event_set_idle() - hint the ir core if device is receiving
* IR data or not
* @input_dev: the struct input_dev device descriptor
* @idle: the hint value
*/
void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
{
struct ir_input_dev *ir = input_get_drvdata(input_dev);
struct ir_raw_event_ctrl *raw = ir->raw;
ktime_t now;
u64 delta;
if (!ir->props)
if (!ir->props || !ir->raw)
return;
if (!ir->raw)
goto out;
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) {
IR_dprintk(2, "enter idle mode\n");
raw->last_event = ktime_get();
} else {
IR_dprintk(2, "exit idle mode\n");
now = ktime_get();
delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
WARN_ON(raw->this_ev.pulse);
raw->this_ev.duration =
min(raw->this_ev.duration + delta,
(u64)IR_MAX_DURATION);
raw->this_ev.timeout = true;
ir_raw_event_store(input_dev, &raw->this_ev);
if (raw->this_ev.duration == IR_MAX_DURATION)
ir_raw_event_reset(input_dev);
raw->this_ev.duration = 0;
init_ir_raw_event(&raw->this_ev);
}
out:
if (ir->props->s_idle)
ir->props->s_idle(ir->props->priv, idle);
ir->idle = idle;
@ -232,11 +231,14 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
void ir_raw_event_handle(struct input_dev *input_dev)
{
struct ir_input_dev *ir = input_get_drvdata(input_dev);
unsigned long flags;
if (!ir->raw)
return;
spin_lock_irqsave(&ir->raw->lock, flags);
wake_up_process(ir->raw->thread);
spin_unlock_irqrestore(&ir->raw->lock, flags);
}
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
@ -275,6 +277,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
return rc;
}
spin_lock_init(&ir->raw->lock);
ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
"rc%u", (unsigned int)ir->devno);

View File

@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}

View File

@ -0,0 +1,154 @@
/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
*
* Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* This code handles the 15 bit RC5-ish protocol used by the Streamzap
* PC Remote.
* It considers a carrier of 36 kHz, with a total of 15 bits, where
* the first two bits are start bits, and a third one is a filing bit
*/
#include "ir-core-priv.h"
#define RC5_SZ_NBITS 15
#define RC5_UNIT 888888 /* ns */
#define RC5_BIT_START (1 * RC5_UNIT)
#define RC5_BIT_END (1 * RC5_UNIT)
enum rc5_sz_state {
STATE_INACTIVE,
STATE_BIT_START,
STATE_BIT_END,
STATE_FINISHED,
};
/**
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
* @input_dev: the struct input_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
u8 toggle, command, system;
u32 scancode;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
return 0;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
goto out;
again:
IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
return 0;
switch (data->state) {
case STATE_INACTIVE:
if (!ev.pulse)
break;
data->state = STATE_BIT_START;
data->count = 1;
data->wanted_bits = RC5_SZ_NBITS;
decrease_duration(&ev, RC5_BIT_START);
goto again;
case STATE_BIT_START:
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
break;
data->bits <<= 1;
if (!ev.pulse)
data->bits |= 1;
data->count++;
data->state = STATE_BIT_END;
return 0;
case STATE_BIT_END:
if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
data->state = STATE_FINISHED;
else
data->state = STATE_BIT_START;
decrease_duration(&ev, RC5_BIT_END);
goto again;
case STATE_FINISHED:
if (ev.pulse)
break;
/* RC5-sz */
command = (data->bits & 0x0003F) >> 0;
system = (data->bits & 0x02FC0) >> 6;
toggle = (data->bits & 0x01000) ? 1 : 0;
scancode = system << 6 | command;
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
scancode, toggle);
ir_keydown(input_dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
out:
IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
static struct ir_raw_handler rc5_sz_handler = {
.protocols = IR_TYPE_RC5_SZ,
.decode = ir_rc5_sz_decode,
};
static int __init ir_rc5_sz_decode_init(void)
{
ir_raw_handler_register(&rc5_sz_handler);
printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
return 0;
}
static void __exit ir_rc5_sz_decode_exit(void)
{
ir_raw_handler_unregister(&rc5_sz_handler);
}
module_init(ir_rc5_sz_decode_init);
module_exit(ir_rc5_sz_decode_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");

View File

@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}

View File

@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
if (!is_timing_event(ev)) {
if (ev.reset)
data->state = STATE_INACTIVE;
return 0;
}

View File

@ -43,6 +43,7 @@ static struct {
{ IR_TYPE_RC6, "rc-6" },
{ IR_TYPE_JVC, "jvc" },
{ IR_TYPE_SONY, "sony" },
{ IR_TYPE_RC5_SZ, "rc-5-sz" },
{ IR_TYPE_LIRC, "lirc" },
};
@ -67,6 +68,10 @@ static ssize_t show_protocols(struct device *d,
char *tmp = buf;
int i;
/* Device is being removed */
if (!ir_dev)
return -EINVAL;
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
enabled = ir_dev->rc_tab.ir_type;
allowed = ir_dev->props->allowed_protos;
@ -122,6 +127,10 @@ static ssize_t store_protocols(struct device *d,
int rc, i, count = 0;
unsigned long flags;
/* Device is being removed */
if (!ir_dev)
return -EINVAL;
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
type = ir_dev->rc_tab.ir_type;
else if (ir_dev->raw)
@ -256,8 +265,6 @@ static struct device_type rc_dev_type = {
*/
int ir_register_class(struct input_dev *input_dev)
{
int rc;
const char *path;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
int devno = find_first_zero_bit(&ir_core_dev_number,
IRRCV_NUM_DEVICES);
@ -266,17 +273,28 @@ int ir_register_class(struct input_dev *input_dev)
return devno;
ir_dev->dev.type = &rc_dev_type;
ir_dev->devno = devno;
ir_dev->dev.class = &ir_input_class;
ir_dev->dev.parent = input_dev->dev.parent;
input_dev->dev.parent = &ir_dev->dev;
dev_set_name(&ir_dev->dev, "rc%d", devno);
dev_set_drvdata(&ir_dev->dev, ir_dev);
rc = device_register(&ir_dev->dev);
if (rc)
return rc;
return device_register(&ir_dev->dev);
};
/**
* ir_register_input - registers ir input device with input subsystem
* @input_dev: the struct input_dev descriptor of the device
*/
int ir_register_input(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
int rc;
const char *path;
input_dev->dev.parent = &ir_dev->dev;
rc = input_register_device(input_dev);
if (rc < 0) {
device_del(&ir_dev->dev);
@ -292,11 +310,9 @@ int ir_register_class(struct input_dev *input_dev)
path ? path : "N/A");
kfree(path);
ir_dev->devno = devno;
set_bit(devno, &ir_core_dev_number);
set_bit(ir_dev->devno, &ir_core_dev_number);
return 0;
};
}
/**
* ir_unregister_class() - removes the sysfs for sysfs for
@ -309,6 +325,7 @@ void ir_unregister_class(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
input_set_drvdata(input_dev, NULL);
clear_bit(ir_dev->devno, &ir_core_dev_number);
input_unregister_device(input_dev);
device_del(&ir_dev->dev);

View File

@ -1,4 +1,6 @@
obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-alink-dtu-m.o \
rc-anysee.o \
rc-apac-viewcomp.o \
rc-asus-pc39.o \
rc-ati-tv-wonder-hd-600.o \
@ -8,7 +10,9 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-avermedia-dvbt.o \
rc-avermedia-m135a.o \
rc-avermedia-m733a-rm-k6.o \
rc-avermedia-rm-ks.o \
rc-avertv-303.o \
rc-azurewave-ad-tu700.o \
rc-behold.o \
rc-behold-columbus.o \
rc-budget-ci-old.o \
@ -16,6 +20,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-cinergy.o \
rc-dib0700-nec.o \
rc-dib0700-rc5.o \
rc-digitalnow-tinytwin.o \
rc-digittrade.o \
rc-dm1105-nec.o \
rc-dntv-live-dvb-t.o \
rc-dntv-live-dvbt-pro.o \
@ -38,8 +44,12 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-kaiomy.o \
rc-kworld-315u.o \
rc-kworld-plus-tv-analog.o \
rc-leadtek-y04g0051.o \
rc-lirc.o \
rc-lme2510.o \
rc-manli.o \
rc-msi-digivox-ii.o \
rc-msi-digivox-iii.o \
rc-msi-tvanywhere.o \
rc-msi-tvanywhere-plus.o \
rc-nebula.o \
@ -58,14 +68,18 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-purpletv.o \
rc-pv951.o \
rc-rc5-hauppauge-new.o \
rc-rc5-streamzap.o \
rc-rc5-tv.o \
rc-rc6-mce.o \
rc-real-audio-220-32-keys.o \
rc-streamzap.o \
rc-tbs-nec.o \
rc-terratec-cinergy-xs.o \
rc-terratec-slim.o \
rc-tevii-nec.o \
rc-total-media-in-hand.o \
rc-trekstor.o \
rc-tt-1500.o \
rc-twinhan1027.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
rc-winfast.o \

View File

@ -0,0 +1,68 @@
/*
* A-Link DTU(m) remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
static struct ir_scancode alink_dtu_m[] = {
{ 0x0800, KEY_VOLUMEUP },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_3 },
{ 0x0803, KEY_7 },
{ 0x0804, KEY_9 },
{ 0x0805, KEY_NEW }, /* symbol: PIP */
{ 0x0806, KEY_0 },
{ 0x0807, KEY_CHANNEL }, /* JUMP */
{ 0x080d, KEY_5 },
{ 0x080f, KEY_2 },
{ 0x0812, KEY_POWER2 },
{ 0x0814, KEY_CHANNELUP },
{ 0x0816, KEY_VOLUMEDOWN },
{ 0x0818, KEY_6 },
{ 0x081a, KEY_MUTE },
{ 0x081b, KEY_8 },
{ 0x081c, KEY_4 },
{ 0x081d, KEY_CHANNELDOWN },
};
static struct rc_keymap alink_dtu_m_map = {
.map = {
.scan = alink_dtu_m,
.size = ARRAY_SIZE(alink_dtu_m),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_ALINK_DTU_M,
}
};
static int __init init_rc_map_alink_dtu_m(void)
{
return ir_register_map(&alink_dtu_m_map);
}
static void __exit exit_rc_map_alink_dtu_m(void)
{
ir_unregister_map(&alink_dtu_m_map);
}
module_init(init_rc_map_alink_dtu_m)
module_exit(exit_rc_map_alink_dtu_m)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,93 @@
/*
* Anysee remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
static struct ir_scancode anysee[] = {
{ 0x0800, KEY_0 },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_2 },
{ 0x0803, KEY_3 },
{ 0x0804, KEY_4 },
{ 0x0805, KEY_5 },
{ 0x0806, KEY_6 },
{ 0x0807, KEY_7 },
{ 0x0808, KEY_8 },
{ 0x0809, KEY_9 },
{ 0x080a, KEY_POWER2 }, /* [red power button] */
{ 0x080b, KEY_VIDEO }, /* [*] MODE */
{ 0x080c, KEY_CHANNEL }, /* [symbol counterclockwise arrow] */
{ 0x080d, KEY_NEXT }, /* [>>|] */
{ 0x080e, KEY_MENU }, /* MENU */
{ 0x080f, KEY_EPG }, /* [EPG] */
{ 0x0810, KEY_CLEAR }, /* EXIT */
{ 0x0811, KEY_CHANNELUP },
{ 0x0812, KEY_VOLUMEDOWN },
{ 0x0813, KEY_VOLUMEUP },
{ 0x0814, KEY_CHANNELDOWN },
{ 0x0815, KEY_OK },
{ 0x0816, KEY_RADIO }, /* [symbol TV/radio] */
{ 0x0817, KEY_INFO }, /* [i] */
{ 0x0818, KEY_PREVIOUS }, /* [|<<] */
{ 0x0819, KEY_FAVORITES }, /* FAV. */
{ 0x081a, KEY_SUBTITLE }, /* Subtitle */
{ 0x081b, KEY_CAMERA }, /* [symbol camera] */
{ 0x081c, KEY_YELLOW },
{ 0x081d, KEY_RED },
{ 0x081e, KEY_LANGUAGE }, /* [symbol Second Audio Program] */
{ 0x081f, KEY_GREEN },
{ 0x0820, KEY_SLEEP }, /* Sleep */
{ 0x0821, KEY_SCREEN }, /* 16:9 / 4:3 */
{ 0x0822, KEY_ZOOM }, /* SIZE */
{ 0x0824, KEY_FN }, /* [F1] */
{ 0x0825, KEY_FN }, /* [F2] */
{ 0x0842, KEY_MUTE }, /* symbol mute */
{ 0x0844, KEY_BLUE },
{ 0x0847, KEY_TEXT }, /* TEXT */
{ 0x0848, KEY_STOP },
{ 0x0849, KEY_RECORD },
{ 0x0850, KEY_PLAY },
{ 0x0851, KEY_PAUSE },
};
static struct rc_keymap anysee_map = {
.map = {
.scan = anysee,
.size = ARRAY_SIZE(anysee),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_ANYSEE,
}
};
static int __init init_rc_map_anysee(void)
{
return ir_register_map(&anysee_map);
}
static void __exit exit_rc_map_anysee(void)
{
ir_unregister_map(&anysee_map);
}
module_init(init_rc_map_anysee)
module_exit(exit_rc_map_anysee)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -20,56 +20,56 @@
static struct ir_scancode asus_pc39[] = {
/* Keys 0 to 9 */
{ 0x15, KEY_0 },
{ 0x29, KEY_1 },
{ 0x2d, KEY_2 },
{ 0x2b, KEY_3 },
{ 0x09, KEY_4 },
{ 0x0d, KEY_5 },
{ 0x0b, KEY_6 },
{ 0x31, KEY_7 },
{ 0x35, KEY_8 },
{ 0x33, KEY_9 },
{ 0x082a, KEY_0 },
{ 0x0816, KEY_1 },
{ 0x0812, KEY_2 },
{ 0x0814, KEY_3 },
{ 0x0836, KEY_4 },
{ 0x0832, KEY_5 },
{ 0x0834, KEY_6 },
{ 0x080e, KEY_7 },
{ 0x080a, KEY_8 },
{ 0x080c, KEY_9 },
{ 0x3e, KEY_RADIO }, /* radio */
{ 0x03, KEY_MENU }, /* dvd/menu */
{ 0x2a, KEY_VOLUMEUP },
{ 0x19, KEY_VOLUMEDOWN },
{ 0x37, KEY_UP },
{ 0x3b, KEY_DOWN },
{ 0x27, KEY_LEFT },
{ 0x2f, KEY_RIGHT },
{ 0x25, KEY_VIDEO }, /* video */
{ 0x39, KEY_AUDIO }, /* music */
{ 0x0801, KEY_RADIO }, /* radio */
{ 0x083c, KEY_MENU }, /* dvd/menu */
{ 0x0815, KEY_VOLUMEUP },
{ 0x0826, KEY_VOLUMEDOWN },
{ 0x0808, KEY_UP },
{ 0x0804, KEY_DOWN },
{ 0x0818, KEY_LEFT },
{ 0x0810, KEY_RIGHT },
{ 0x081a, KEY_VIDEO }, /* video */
{ 0x0806, KEY_AUDIO }, /* music */
{ 0x21, KEY_TV }, /* tv */
{ 0x1d, KEY_EXIT }, /* back */
{ 0x0a, KEY_CHANNELUP }, /* channel / program + */
{ 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
{ 0x1a, KEY_ENTER }, /* enter */
{ 0x081e, KEY_TV }, /* tv */
{ 0x0822, KEY_EXIT }, /* back */
{ 0x0835, KEY_CHANNELUP }, /* channel / program + */
{ 0x0824, KEY_CHANNELDOWN }, /* channel / program - */
{ 0x0825, KEY_ENTER }, /* enter */
{ 0x06, KEY_PAUSE }, /* play/pause */
{ 0x1e, KEY_PREVIOUS }, /* rew */
{ 0x26, KEY_NEXT }, /* forward */
{ 0x0e, KEY_REWIND }, /* backward << */
{ 0x3a, KEY_FASTFORWARD }, /* forward >> */
{ 0x36, KEY_STOP },
{ 0x2e, KEY_RECORD }, /* recording */
{ 0x16, KEY_POWER }, /* the button that reads "close" */
{ 0x0839, KEY_PAUSE }, /* play/pause */
{ 0x0821, KEY_PREVIOUS }, /* rew */
{ 0x0819, KEY_NEXT }, /* forward */
{ 0x0831, KEY_REWIND }, /* backward << */
{ 0x0805, KEY_FASTFORWARD }, /* forward >> */
{ 0x0809, KEY_STOP },
{ 0x0811, KEY_RECORD }, /* recording */
{ 0x0829, KEY_POWER }, /* the button that reads "close" */
{ 0x11, KEY_ZOOM }, /* full screen */
{ 0x13, KEY_MACRO }, /* recall */
{ 0x23, KEY_HOME }, /* home */
{ 0x05, KEY_PVR }, /* picture */
{ 0x3d, KEY_MUTE }, /* mute */
{ 0x01, KEY_DVD }, /* dvd */
{ 0x082e, KEY_ZOOM }, /* full screen */
{ 0x082c, KEY_MACRO }, /* recall */
{ 0x081c, KEY_HOME }, /* home */
{ 0x083a, KEY_PVR }, /* picture */
{ 0x0802, KEY_MUTE }, /* mute */
{ 0x083e, KEY_DVD }, /* dvd */
};
static struct rc_keymap asus_pc39_map = {
.map = {
.scan = asus_pc39,
.size = ARRAY_SIZE(asus_pc39),
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
.ir_type = IR_TYPE_RC5,
.name = RC_MAP_ASUS_PC39,
}
};

View File

@ -0,0 +1,79 @@
/*
* AverMedia RM-KS remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net>
and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
/* FIXME: mappings are not 100% correct? */
static struct ir_scancode avermedia_rm_ks[] = {
{ 0x0501, KEY_POWER2 },
{ 0x0502, KEY_CHANNELUP },
{ 0x0503, KEY_CHANNELDOWN },
{ 0x0504, KEY_VOLUMEUP },
{ 0x0505, KEY_VOLUMEDOWN },
{ 0x0506, KEY_MUTE },
{ 0x0507, KEY_RIGHT },
{ 0x0508, KEY_PROG1 },
{ 0x0509, KEY_1 },
{ 0x050a, KEY_2 },
{ 0x050b, KEY_3 },
{ 0x050c, KEY_4 },
{ 0x050d, KEY_5 },
{ 0x050e, KEY_6 },
{ 0x050f, KEY_7 },
{ 0x0510, KEY_8 },
{ 0x0511, KEY_9 },
{ 0x0512, KEY_0 },
{ 0x0513, KEY_AUDIO },
{ 0x0515, KEY_EPG },
{ 0x0516, KEY_PLAY },
{ 0x0517, KEY_RECORD },
{ 0x0518, KEY_STOP },
{ 0x051c, KEY_BACK },
{ 0x051d, KEY_FORWARD },
{ 0x054d, KEY_LEFT },
{ 0x0556, KEY_ZOOM },
};
static struct rc_keymap avermedia_rm_ks_map = {
.map = {
.scan = avermedia_rm_ks,
.size = ARRAY_SIZE(avermedia_rm_ks),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_RM_KS,
}
};
static int __init init_rc_map_avermedia_rm_ks(void)
{
return ir_register_map(&avermedia_rm_ks_map);
}
static void __exit exit_rc_map_avermedia_rm_ks(void)
{
ir_unregister_map(&avermedia_rm_ks_map);
}
module_init(init_rc_map_avermedia_rm_ks)
module_exit(exit_rc_map_avermedia_rm_ks)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,102 @@
/*
* TwinHan AzureWave AD-TU700(704J) remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
static struct ir_scancode azurewave_ad_tu700[] = {
{ 0x0000, KEY_TAB }, /* Tab */
{ 0x0001, KEY_2 },
{ 0x0002, KEY_CHANNELDOWN },
{ 0x0003, KEY_1 },
{ 0x0004, KEY_MENU }, /* Record List */
{ 0x0005, KEY_CHANNELUP },
{ 0x0006, KEY_3 },
{ 0x0007, KEY_SLEEP }, /* Hibernate */
{ 0x0008, KEY_VIDEO }, /* A/V */
{ 0x0009, KEY_4 },
{ 0x000a, KEY_VOLUMEDOWN },
{ 0x000c, KEY_CANCEL }, /* Cancel */
{ 0x000d, KEY_7 },
{ 0x000e, KEY_AGAIN }, /* Recall */
{ 0x000f, KEY_TEXT }, /* Teletext */
{ 0x0010, KEY_MUTE },
{ 0x0011, KEY_RECORD },
{ 0x0012, KEY_FASTFORWARD }, /* FF >> */
{ 0x0013, KEY_BACK }, /* Back */
{ 0x0014, KEY_PLAY },
{ 0x0015, KEY_0 },
{ 0x0016, KEY_POWER2 }, /* [red power button] */
{ 0x0017, KEY_FAVORITES }, /* Favorite List */
{ 0x0018, KEY_RED },
{ 0x0019, KEY_8 },
{ 0x001a, KEY_STOP },
{ 0x001b, KEY_9 },
{ 0x001c, KEY_EPG }, /* Info/EPG */
{ 0x001d, KEY_5 },
{ 0x001e, KEY_VOLUMEUP },
{ 0x001f, KEY_6 },
{ 0x0040, KEY_REWIND }, /* FR << */
{ 0x0041, KEY_PREVIOUS }, /* Replay */
{ 0x0042, KEY_NEXT }, /* Skip */
{ 0x0043, KEY_SUBTITLE }, /* Subtitle / CC */
{ 0x0045, KEY_KPPLUS }, /* Zoom+ */
{ 0x0046, KEY_KPMINUS }, /* Zoom- */
{ 0x0047, KEY_NEW }, /* PIP */
{ 0x0048, KEY_INFO }, /* Preview */
{ 0x0049, KEY_MODE }, /* L/R */
{ 0x004a, KEY_CLEAR }, /* Clear */
{ 0x004b, KEY_UP }, /* up arrow */
{ 0x004c, KEY_PAUSE },
{ 0x004d, KEY_ZOOM }, /* Full Screen */
{ 0x004e, KEY_LEFT }, /* left arrow */
{ 0x004f, KEY_OK }, /* Enter / ok */
{ 0x0050, KEY_LANGUAGE }, /* SAP */
{ 0x0051, KEY_DOWN }, /* down arrow */
{ 0x0052, KEY_RIGHT }, /* right arrow */
{ 0x0053, KEY_GREEN },
{ 0x0054, KEY_CAMERA }, /* Capture */
{ 0x005e, KEY_YELLOW },
{ 0x005f, KEY_BLUE },
};
static struct rc_keymap azurewave_ad_tu700_map = {
.map = {
.scan = azurewave_ad_tu700,
.size = ARRAY_SIZE(azurewave_ad_tu700),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_AZUREWAVE_AD_TU700,
}
};
static int __init init_rc_map_azurewave_ad_tu700(void)
{
return ir_register_map(&azurewave_ad_tu700_map);
}
static void __exit exit_rc_map_azurewave_ad_tu700(void)
{
ir_unregister_map(&azurewave_ad_tu700_map);
}
module_init(init_rc_map_azurewave_ad_tu700)
module_exit(exit_rc_map_azurewave_ad_tu700)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,98 @@
/*
* DigitalNow TinyTwin remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
static struct ir_scancode digitalnow_tinytwin[] = {
{ 0x0000, KEY_MUTE }, /* [symbol speaker] */
{ 0x0001, KEY_VOLUMEUP },
{ 0x0002, KEY_POWER2 }, /* TV [power button] */
{ 0x0003, KEY_2 },
{ 0x0004, KEY_3 },
{ 0x0005, KEY_4 },
{ 0x0006, KEY_6 },
{ 0x0007, KEY_7 },
{ 0x0008, KEY_8 },
{ 0x0009, KEY_NUMERIC_STAR }, /* [*] */
{ 0x000a, KEY_0 },
{ 0x000b, KEY_NUMERIC_POUND }, /* [#] */
{ 0x000c, KEY_RIGHT }, /* [right arrow] */
{ 0x000d, KEY_HOMEPAGE }, /* [symbol home] Start */
{ 0x000e, KEY_RED }, /* [red] Videos */
{ 0x0010, KEY_POWER }, /* PC [power button] */
{ 0x0011, KEY_YELLOW }, /* [yellow] Pictures */
{ 0x0012, KEY_DOWN }, /* [down arrow] */
{ 0x0013, KEY_GREEN }, /* [green] Music */
{ 0x0014, KEY_CYCLEWINDOWS }, /* BACK */
{ 0x0015, KEY_FAVORITES }, /* MORE */
{ 0x0016, KEY_UP }, /* [up arrow] */
{ 0x0017, KEY_LEFT }, /* [left arrow] */
{ 0x0018, KEY_OK }, /* OK */
{ 0x0019, KEY_BLUE }, /* [blue] MyTV */
{ 0x001a, KEY_REWIND }, /* REW [<<] */
{ 0x001b, KEY_PLAY }, /* PLAY */
{ 0x001c, KEY_5 },
{ 0x001d, KEY_9 },
{ 0x001e, KEY_VOLUMEDOWN },
{ 0x001f, KEY_1 },
{ 0x0040, KEY_STOP }, /* STOP */
{ 0x0042, KEY_PAUSE }, /* PAUSE */
{ 0x0043, KEY_SCREEN }, /* Aspect */
{ 0x0044, KEY_FORWARD }, /* FWD [>>] */
{ 0x0045, KEY_NEXT }, /* SKIP */
{ 0x0048, KEY_RECORD }, /* RECORD */
{ 0x0049, KEY_VIDEO }, /* RTV */
{ 0x004a, KEY_EPG }, /* Guide */
{ 0x004b, KEY_CHANNELUP },
{ 0x004c, KEY_HELP }, /* Help */
{ 0x004d, KEY_RADIO }, /* Radio */
{ 0x004f, KEY_CHANNELDOWN },
{ 0x0050, KEY_DVD }, /* DVD */
{ 0x0051, KEY_AUDIO }, /* Audio */
{ 0x0052, KEY_TITLE }, /* Title */
{ 0x0053, KEY_NEW }, /* [symbol PIP?] */
{ 0x0057, KEY_MENU }, /* Mouse */
{ 0x005a, KEY_PREVIOUS }, /* REPLAY */
};
static struct rc_keymap digitalnow_tinytwin_map = {
.map = {
.scan = digitalnow_tinytwin,
.size = ARRAY_SIZE(digitalnow_tinytwin),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_DIGITALNOW_TINYTWIN,
}
};
static int __init init_rc_map_digitalnow_tinytwin(void)
{
return ir_register_map(&digitalnow_tinytwin_map);
}
static void __exit exit_rc_map_digitalnow_tinytwin(void)
{
ir_unregister_map(&digitalnow_tinytwin_map);
}
module_init(init_rc_map_digitalnow_tinytwin)
module_exit(exit_rc_map_digitalnow_tinytwin)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,82 @@
/*
* Digittrade DVB-T USB Stick remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* Digittrade DVB-T USB Stick remote controller. */
/* Imported from af9015.h.
Initial keytable was from Alain Kalker <miki@dds.nl> */
/* Digittrade DVB-T USB Stick */
static struct ir_scancode digittrade[] = {
{ 0x0000, KEY_9 },
{ 0x0001, KEY_EPG }, /* EPG */
{ 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */
{ 0x0003, KEY_TEXT }, /* TELETEXT */
{ 0x0004, KEY_8 },
{ 0x0005, KEY_MUTE }, /* MUTE */
{ 0x0006, KEY_POWER2 }, /* POWER */
{ 0x0009, KEY_ZOOM }, /* FULLSCREEN */
{ 0x000a, KEY_RECORD }, /* RECORD */
{ 0x000d, KEY_SUBTITLE }, /* SUBTITLE */
{ 0x000e, KEY_STOP }, /* STOP */
{ 0x0010, KEY_OK }, /* RETURN */
{ 0x0011, KEY_2 },
{ 0x0012, KEY_4 },
{ 0x0015, KEY_3 },
{ 0x0016, KEY_5 },
{ 0x0017, KEY_CHANNELDOWN }, /* Ch Dn */
{ 0x0019, KEY_CHANNELUP }, /* CH Up */
{ 0x001a, KEY_PAUSE }, /* PAUSE */
{ 0x001b, KEY_1 },
{ 0x001d, KEY_AUDIO }, /* DUAL SOUND */
{ 0x001e, KEY_PLAY }, /* PLAY */
{ 0x001f, KEY_CAMERA }, /* SNAPSHOT */
{ 0x0040, KEY_VOLUMEUP }, /* Vol Up */
{ 0x0048, KEY_7 },
{ 0x004c, KEY_6 },
{ 0x004d, KEY_PLAYPAUSE }, /* TIMESHIFT */
{ 0x0054, KEY_0 },
};
static struct rc_keymap digittrade_map = {
.map = {
.scan = digittrade,
.size = ARRAY_SIZE(digittrade),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_DIGITTRADE,
}
};
static int __init init_rc_map_digittrade(void)
{
return ir_register_map(&digittrade_map);
}
static void __exit exit_rc_map_digittrade(void)
{
ir_unregister_map(&digittrade_map);
}
module_init(init_rc_map_digittrade)
module_exit(exit_rc_map_digittrade)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,99 @@
/*
* LeadTek Y04G0051 remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
static struct ir_scancode leadtek_y04g0051[] = {
{ 0x0300, KEY_POWER2 },
{ 0x0303, KEY_SCREEN },
{ 0x0304, KEY_RIGHT },
{ 0x0305, KEY_1 },
{ 0x0306, KEY_2 },
{ 0x0307, KEY_3 },
{ 0x0308, KEY_LEFT },
{ 0x0309, KEY_4 },
{ 0x030a, KEY_5 },
{ 0x030b, KEY_6 },
{ 0x030c, KEY_UP },
{ 0x030d, KEY_7 },
{ 0x030e, KEY_8 },
{ 0x030f, KEY_9 },
{ 0x0310, KEY_DOWN },
{ 0x0311, KEY_AGAIN },
{ 0x0312, KEY_0 },
{ 0x0313, KEY_OK }, /* 1st ok */
{ 0x0314, KEY_MUTE },
{ 0x0316, KEY_OK }, /* 2nd ok */
{ 0x031e, KEY_VIDEO }, /* 2nd video */
{ 0x031b, KEY_AUDIO },
{ 0x031f, KEY_TEXT },
{ 0x0340, KEY_SLEEP },
{ 0x0341, KEY_DOT },
{ 0x0342, KEY_REWIND },
{ 0x0343, KEY_PLAY },
{ 0x0344, KEY_FASTFORWARD },
{ 0x0345, KEY_TIME },
{ 0x0346, KEY_STOP }, /* 2nd stop */
{ 0x0347, KEY_RECORD },
{ 0x0348, KEY_CAMERA },
{ 0x0349, KEY_ESC },
{ 0x034a, KEY_NEW },
{ 0x034b, KEY_RED },
{ 0x034c, KEY_GREEN },
{ 0x034d, KEY_YELLOW },
{ 0x034e, KEY_BLUE },
{ 0x034f, KEY_MENU },
{ 0x0350, KEY_STOP }, /* 1st stop */
{ 0x0351, KEY_CHANNEL },
{ 0x0352, KEY_VIDEO }, /* 1st video */
{ 0x0353, KEY_EPG },
{ 0x0354, KEY_PREVIOUS },
{ 0x0355, KEY_NEXT },
{ 0x0356, KEY_TV },
{ 0x035a, KEY_VOLUMEDOWN },
{ 0x035b, KEY_CHANNELUP },
{ 0x035e, KEY_VOLUMEUP },
{ 0x035f, KEY_CHANNELDOWN },
};
static struct rc_keymap leadtek_y04g0051_map = {
.map = {
.scan = leadtek_y04g0051,
.size = ARRAY_SIZE(leadtek_y04g0051),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_LEADTEK_Y04G0051,
}
};
static int __init init_rc_map_leadtek_y04g0051(void)
{
return ir_register_map(&leadtek_y04g0051_map);
}
static void __exit exit_rc_map_leadtek_y04g0051(void)
{
ir_unregister_map(&leadtek_y04g0051_map);
}
module_init(init_rc_map_leadtek_y04g0051)
module_exit(exit_rc_map_leadtek_y04g0051)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,68 @@
/* LME2510 remote control
*
*
* Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <media/rc-map.h>
static struct ir_scancode lme2510_rc[] = {
{ 0xba45, KEY_0 },
{ 0xa05f, KEY_1 },
{ 0xaf50, KEY_2 },
{ 0xa25d, KEY_3 },
{ 0xbe41, KEY_4 },
{ 0xf50a, KEY_5 },
{ 0xbd42, KEY_6 },
{ 0xb847, KEY_7 },
{ 0xb649, KEY_8 },
{ 0xfa05, KEY_9 },
{ 0xbc43, KEY_POWER },
{ 0xb946, KEY_SUBTITLE },
{ 0xf906, KEY_PAUSE },
{ 0xfc03, KEY_MEDIA_REPEAT},
{ 0xfd02, KEY_PAUSE },
{ 0xa15e, KEY_VOLUMEUP },
{ 0xa35c, KEY_VOLUMEDOWN },
{ 0xf609, KEY_CHANNELUP },
{ 0xe51a, KEY_CHANNELDOWN },
{ 0xe11e, KEY_PLAY },
{ 0xe41b, KEY_ZOOM },
{ 0xa659, KEY_MUTE },
{ 0xa55a, KEY_TV },
{ 0xe718, KEY_RECORD },
{ 0xf807, KEY_EPG },
{ 0xfe01, KEY_STOP },
};
static struct rc_keymap lme2510_map = {
.map = {
.scan = lme2510_rc,
.size = ARRAY_SIZE(lme2510_rc),
.ir_type = IR_TYPE_UNKNOWN,
.name = RC_MAP_LME2510,
}
};
static int __init init_rc_lme2510_map(void)
{
return ir_register_map(&lme2510_map);
}
static void __exit exit_rc_lme2510_map(void)
{
ir_unregister_map(&lme2510_map);
}
module_init(init_rc_lme2510_map)
module_exit(exit_rc_lme2510_map)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");

View File

@ -0,0 +1,67 @@
/*
* MSI DIGIVOX mini II remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
static struct ir_scancode msi_digivox_ii[] = {
{ 0x0002, KEY_2 },
{ 0x0003, KEY_UP }, /* up */
{ 0x0004, KEY_3 },
{ 0x0005, KEY_CHANNELDOWN },
{ 0x0008, KEY_5 },
{ 0x0009, KEY_0 },
{ 0x000b, KEY_8 },
{ 0x000d, KEY_DOWN }, /* down */
{ 0x0010, KEY_9 },
{ 0x0011, KEY_7 },
{ 0x0014, KEY_VOLUMEUP },
{ 0x0015, KEY_CHANNELUP },
{ 0x0016, KEY_OK },
{ 0x0017, KEY_POWER2 },
{ 0x001a, KEY_1 },
{ 0x001c, KEY_4 },
{ 0x001d, KEY_6 },
{ 0x001f, KEY_VOLUMEDOWN },
};
static struct rc_keymap msi_digivox_ii_map = {
.map = {
.scan = msi_digivox_ii,
.size = ARRAY_SIZE(msi_digivox_ii),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_II,
}
};
static int __init init_rc_map_msi_digivox_ii(void)
{
return ir_register_map(&msi_digivox_ii_map);
}
static void __exit exit_rc_map_msi_digivox_ii(void)
{
ir_unregister_map(&msi_digivox_ii_map);
}
module_init(init_rc_map_msi_digivox_ii)
module_exit(exit_rc_map_msi_digivox_ii)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,85 @@
/*
* MSI DIGIVOX mini III remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* MSI DIGIVOX mini III */
/* Uses NEC extended 0x61d6. */
/* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote
since rc-kworld-315u.c lacks NEC extended address byte. */
static struct ir_scancode msi_digivox_iii[] = {
{ 0x61d601, KEY_VIDEO }, /* Source */
{ 0x61d602, KEY_3 },
{ 0x61d603, KEY_POWER }, /* ShutDown */
{ 0x61d604, KEY_1 },
{ 0x61d605, KEY_5 },
{ 0x61d606, KEY_6 },
{ 0x61d607, KEY_CHANNELDOWN }, /* CH- */
{ 0x61d608, KEY_2 },
{ 0x61d609, KEY_CHANNELUP }, /* CH+ */
{ 0x61d60a, KEY_9 },
{ 0x61d60b, KEY_ZOOM }, /* Zoom */
{ 0x61d60c, KEY_7 },
{ 0x61d60d, KEY_8 },
{ 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */
{ 0x61d60f, KEY_4 },
{ 0x61d610, KEY_ESC }, /* [back up arrow] */
{ 0x61d611, KEY_0 },
{ 0x61d612, KEY_OK }, /* [enter arrow] */
{ 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */
{ 0x61d614, KEY_RECORD }, /* Rec */
{ 0x61d615, KEY_STOP }, /* Stop */
{ 0x61d616, KEY_PLAY }, /* Play */
{ 0x61d617, KEY_MUTE }, /* Mute */
{ 0x61d618, KEY_UP },
{ 0x61d619, KEY_DOWN },
{ 0x61d61a, KEY_LEFT },
{ 0x61d61b, KEY_RIGHT },
{ 0x61d61c, KEY_RED },
{ 0x61d61d, KEY_GREEN },
{ 0x61d61e, KEY_YELLOW },
{ 0x61d61f, KEY_BLUE },
{ 0x61d643, KEY_POWER2 }, /* [red power button] */
};
static struct rc_keymap msi_digivox_iii_map = {
.map = {
.scan = msi_digivox_iii,
.size = ARRAY_SIZE(msi_digivox_iii),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_III,
}
};
static int __init init_rc_map_msi_digivox_iii(void)
{
return ir_register_map(&msi_digivox_iii_map);
}
static void __exit exit_rc_map_msi_digivox_iii(void)
{
ir_unregister_map(&msi_digivox_iii_map);
}
module_init(init_rc_map_msi_digivox_iii)
module_exit(exit_rc_map_msi_digivox_iii)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -1,81 +0,0 @@
/* rc-rc5-streamzap.c - Keytable for Streamzap PC Remote, for use
* with the Streamzap PC Remote IR Receiver.
*
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <media/rc-map.h>
static struct ir_scancode rc5_streamzap[] = {
/*
* FIXME: The Streamzap remote isn't actually true RC-5, it has an extra
* bit in it, which presently throws the in-kernel RC-5 decoder for a loop.
* We either have to enhance the decoder to support it, add a new decoder,
* or just rely on lirc userspace decoding.
*/
{ 0x00, KEY_NUMERIC_0 },
{ 0x01, KEY_NUMERIC_1 },
{ 0x02, KEY_NUMERIC_2 },
{ 0x03, KEY_NUMERIC_3 },
{ 0x04, KEY_NUMERIC_4 },
{ 0x05, KEY_NUMERIC_5 },
{ 0x06, KEY_NUMERIC_6 },
{ 0x07, KEY_NUMERIC_7 },
{ 0x08, KEY_NUMERIC_8 },
{ 0x0a, KEY_POWER },
{ 0x0b, KEY_MUTE },
{ 0x0c, KEY_CHANNELUP },
{ 0x0d, KEY_VOLUMEUP },
{ 0x0e, KEY_CHANNELDOWN },
{ 0x0f, KEY_VOLUMEDOWN },
{ 0x10, KEY_UP },
{ 0x11, KEY_LEFT },
{ 0x12, KEY_OK },
{ 0x13, KEY_RIGHT },
{ 0x14, KEY_DOWN },
{ 0x15, KEY_MENU },
{ 0x16, KEY_EXIT },
{ 0x17, KEY_PLAY },
{ 0x18, KEY_PAUSE },
{ 0x19, KEY_STOP },
{ 0x1a, KEY_BACK },
{ 0x1b, KEY_FORWARD },
{ 0x1c, KEY_RECORD },
{ 0x1d, KEY_REWIND },
{ 0x1e, KEY_FASTFORWARD },
{ 0x20, KEY_RED },
{ 0x21, KEY_GREEN },
{ 0x22, KEY_YELLOW },
{ 0x23, KEY_BLUE },
};
static struct rc_keymap rc5_streamzap_map = {
.map = {
.scan = rc5_streamzap,
.size = ARRAY_SIZE(rc5_streamzap),
.ir_type = IR_TYPE_RC5,
.name = RC_MAP_RC5_STREAMZAP,
}
};
static int __init init_rc_map_rc5_streamzap(void)
{
return ir_register_map(&rc5_streamzap_map);
}
static void __exit exit_rc_map_rc5_streamzap(void)
{
ir_unregister_map(&rc5_streamzap_map);
}
module_init(init_rc_map_rc5_streamzap)
module_exit(exit_rc_map_rc5_streamzap)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");

View File

@ -12,35 +12,8 @@
#include <media/rc-map.h>
static struct ir_scancode rc6_mce[] = {
{ 0x800f0415, KEY_REWIND },
{ 0x800f0414, KEY_FASTFORWARD },
{ 0x800f041b, KEY_PREVIOUS },
{ 0x800f041a, KEY_NEXT },
{ 0x800f0416, KEY_PLAY },
{ 0x800f0418, KEY_PAUSE },
{ 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f0419, KEY_STOP },
{ 0x800f0417, KEY_RECORD },
{ 0x800f041e, KEY_UP },
{ 0x800f041f, KEY_DOWN },
{ 0x800f0420, KEY_LEFT },
{ 0x800f0421, KEY_RIGHT },
{ 0x800f040b, KEY_ENTER },
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
{ 0x800f040a, KEY_DELETE },
{ 0x800f040e, KEY_MUTE },
{ 0x800f0410, KEY_VOLUMEUP },
{ 0x800f0411, KEY_VOLUMEDOWN },
{ 0x800f0412, KEY_CHANNELUP },
{ 0x800f0413, KEY_CHANNELDOWN },
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0400, KEY_NUMERIC_0 },
{ 0x800f0401, KEY_NUMERIC_1 },
{ 0x800f0402, KEY_NUMERIC_2 },
{ 0x800f0403, KEY_NUMERIC_3 },
@ -50,38 +23,67 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0407, KEY_NUMERIC_7 },
{ 0x800f0408, KEY_NUMERIC_8 },
{ 0x800f0409, KEY_NUMERIC_9 },
{ 0x800f0400, KEY_NUMERIC_0 },
{ 0x800f041d, KEY_NUMERIC_STAR },
{ 0x800f040a, KEY_DELETE },
{ 0x800f040b, KEY_ENTER },
{ 0x800f040c, KEY_POWER },
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f040e, KEY_MUTE },
{ 0x800f040f, KEY_INFO },
{ 0x800f0410, KEY_VOLUMEUP },
{ 0x800f0411, KEY_VOLUMEDOWN },
{ 0x800f0412, KEY_CHANNELUP },
{ 0x800f0413, KEY_CHANNELDOWN },
{ 0x800f0414, KEY_FASTFORWARD },
{ 0x800f0415, KEY_REWIND },
{ 0x800f0416, KEY_PLAY },
{ 0x800f0417, KEY_RECORD },
{ 0x800f0418, KEY_PAUSE },
{ 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f0419, KEY_STOP },
{ 0x800f041a, KEY_NEXT },
{ 0x800f041b, KEY_PREVIOUS },
{ 0x800f041c, KEY_NUMERIC_POUND },
{ 0x800f041d, KEY_NUMERIC_STAR },
{ 0x800f041e, KEY_UP },
{ 0x800f041f, KEY_DOWN },
{ 0x800f0420, KEY_LEFT },
{ 0x800f0421, KEY_RIGHT },
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
{ 0x800f0424, KEY_DVD },
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
{ 0x800f0426, KEY_EPG }, /* Guide */
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV },
{ 0x800f0447, KEY_AUDIO }, /* My Music */
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0447, KEY_AUDIO }, /* My Music */
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO },
{ 0x800f0424, KEY_DVD },
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
{ 0x800f044c, KEY_LANGUAGE },
{ 0x800f044d, KEY_TITLE },
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f0450, KEY_RADIO },
{ 0x800f044c, KEY_LANGUAGE },
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE },
{ 0x800f040f, KEY_INFO },
{ 0x800f0426, KEY_EPG }, /* Guide */
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f044d, KEY_TITLE },
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f040c, KEY_POWER },
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0481, KEY_PLAYPAUSE },
};
static struct rc_keymap rc6_mce_map = {

View File

@ -0,0 +1,82 @@
/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
* with the Streamzap PC Remote IR Receiver.
*
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <media/rc-map.h>
static struct ir_scancode streamzap[] = {
/*
* The Streamzap remote is almost, but not quite, RC-5, as it has an extra
* bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
* an additional RC-5-sz decoder is being deployed to support it, but it
* may be possible to merge it back with the standard RC-5 decoder.
*/
{ 0x28c0, KEY_NUMERIC_0 },
{ 0x28c1, KEY_NUMERIC_1 },
{ 0x28c2, KEY_NUMERIC_2 },
{ 0x28c3, KEY_NUMERIC_3 },
{ 0x28c4, KEY_NUMERIC_4 },
{ 0x28c5, KEY_NUMERIC_5 },
{ 0x28c6, KEY_NUMERIC_6 },
{ 0x28c7, KEY_NUMERIC_7 },
{ 0x28c8, KEY_NUMERIC_8 },
{ 0x28c9, KEY_NUMERIC_9 },
{ 0x28ca, KEY_POWER },
{ 0x28cb, KEY_MUTE },
{ 0x28cc, KEY_CHANNELUP },
{ 0x28cd, KEY_VOLUMEUP },
{ 0x28ce, KEY_CHANNELDOWN },
{ 0x28cf, KEY_VOLUMEDOWN },
{ 0x28d0, KEY_UP },
{ 0x28d1, KEY_LEFT },
{ 0x28d2, KEY_OK },
{ 0x28d3, KEY_RIGHT },
{ 0x28d4, KEY_DOWN },
{ 0x28d5, KEY_MENU },
{ 0x28d6, KEY_EXIT },
{ 0x28d7, KEY_PLAY },
{ 0x28d8, KEY_PAUSE },
{ 0x28d9, KEY_STOP },
{ 0x28da, KEY_BACK },
{ 0x28db, KEY_FORWARD },
{ 0x28dc, KEY_RECORD },
{ 0x28dd, KEY_REWIND },
{ 0x28de, KEY_FASTFORWARD },
{ 0x28e0, KEY_RED },
{ 0x28e1, KEY_GREEN },
{ 0x28e2, KEY_YELLOW },
{ 0x28e3, KEY_BLUE },
};
static struct rc_keymap streamzap_map = {
.map = {
.scan = streamzap,
.size = ARRAY_SIZE(streamzap),
.ir_type = IR_TYPE_RC5_SZ,
.name = RC_MAP_STREAMZAP,
}
};
static int __init init_rc_map_streamzap(void)
{
return ir_register_map(&streamzap_map);
}
static void __exit exit_rc_map_streamzap(void)
{
ir_unregister_map(&streamzap_map);
}
module_init(init_rc_map_streamzap)
module_exit(exit_rc_map_streamzap)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");

View File

@ -0,0 +1,79 @@
/*
* TerraTec remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* TerraTec slim remote, 7 rows, 4 columns. */
/* Uses NEC extended 0x02bd. */
static struct ir_scancode terratec_slim[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
{ 0x02bd03, KEY_4 },
{ 0x02bd04, KEY_5 },
{ 0x02bd05, KEY_6 },
{ 0x02bd06, KEY_7 },
{ 0x02bd07, KEY_8 },
{ 0x02bd08, KEY_9 },
{ 0x02bd09, KEY_0 },
{ 0x02bd0a, KEY_MUTE },
{ 0x02bd0b, KEY_NEW }, /* symbol: PIP */
{ 0x02bd0e, KEY_VOLUMEDOWN },
{ 0x02bd0f, KEY_PLAYPAUSE },
{ 0x02bd10, KEY_RIGHT },
{ 0x02bd11, KEY_LEFT },
{ 0x02bd12, KEY_UP },
{ 0x02bd13, KEY_DOWN },
{ 0x02bd15, KEY_OK },
{ 0x02bd16, KEY_STOP },
{ 0x02bd17, KEY_CAMERA }, /* snapshot */
{ 0x02bd18, KEY_CHANNELUP },
{ 0x02bd19, KEY_RECORD },
{ 0x02bd1a, KEY_CHANNELDOWN },
{ 0x02bd1c, KEY_ESC },
{ 0x02bd1f, KEY_VOLUMEUP },
{ 0x02bd44, KEY_EPG },
{ 0x02bd45, KEY_POWER2 }, /* [red power button] */
};
static struct rc_keymap terratec_slim_map = {
.map = {
.scan = terratec_slim,
.size = ARRAY_SIZE(terratec_slim),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_TERRATEC_SLIM,
}
};
static int __init init_rc_map_terratec_slim(void)
{
return ir_register_map(&terratec_slim_map);
}
static void __exit exit_rc_map_terratec_slim(void)
{
ir_unregister_map(&terratec_slim_map);
}
module_init(init_rc_map_terratec_slim)
module_exit(exit_rc_map_terratec_slim)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,85 @@
/*
* Total Media In Hand remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* Uses NEC extended 0x02bd */
static struct ir_scancode total_media_in_hand[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
{ 0x02bd03, KEY_4 },
{ 0x02bd04, KEY_5 },
{ 0x02bd05, KEY_6 },
{ 0x02bd06, KEY_7 },
{ 0x02bd07, KEY_8 },
{ 0x02bd08, KEY_9 },
{ 0x02bd09, KEY_0 },
{ 0x02bd0a, KEY_MUTE },
{ 0x02bd0b, KEY_CYCLEWINDOWS }, /* yellow, [min / max] */
{ 0x02bd0c, KEY_VIDEO }, /* TV / AV */
{ 0x02bd0e, KEY_VOLUMEDOWN },
{ 0x02bd0f, KEY_TIME }, /* TimeShift */
{ 0x02bd10, KEY_RIGHT }, /* right arrow */
{ 0x02bd11, KEY_LEFT }, /* left arrow */
{ 0x02bd12, KEY_UP }, /* up arrow */
{ 0x02bd13, KEY_DOWN }, /* down arrow */
{ 0x02bd14, KEY_POWER2 }, /* [red] */
{ 0x02bd15, KEY_OK }, /* OK */
{ 0x02bd16, KEY_STOP },
{ 0x02bd17, KEY_CAMERA }, /* Snapshot */
{ 0x02bd18, KEY_CHANNELUP },
{ 0x02bd19, KEY_RECORD },
{ 0x02bd1a, KEY_CHANNELDOWN },
{ 0x02bd1c, KEY_ESC }, /* Esc */
{ 0x02bd1e, KEY_PLAY },
{ 0x02bd1f, KEY_VOLUMEUP },
{ 0x02bd40, KEY_PAUSE },
{ 0x02bd41, KEY_FASTFORWARD }, /* FF >> */
{ 0x02bd42, KEY_REWIND }, /* FR << */
{ 0x02bd43, KEY_ZOOM }, /* [window + mouse pointer] */
{ 0x02bd44, KEY_SHUFFLE }, /* Shuffle */
{ 0x02bd45, KEY_INFO }, /* [red (I)] */
};
static struct rc_keymap total_media_in_hand_map = {
.map = {
.scan = total_media_in_hand,
.size = ARRAY_SIZE(total_media_in_hand),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_TOTAL_MEDIA_IN_HAND,
}
};
static int __init init_rc_map_total_media_in_hand(void)
{
return ir_register_map(&total_media_in_hand_map);
}
static void __exit exit_rc_map_total_media_in_hand(void)
{
ir_unregister_map(&total_media_in_hand_map);
}
module_init(init_rc_map_total_media_in_hand)
module_exit(exit_rc_map_total_media_in_hand)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,80 @@
/*
* TrekStor remote controller keytable
*
* Copyright (C) 2010 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.
*/
#include <media/rc-map.h>
/* TrekStor DVB-T USB Stick remote controller. */
/* Imported from af9015.h.
Initial keytable was from Marc Schneider <macke@macke.org> */
static struct ir_scancode trekstor[] = {
{ 0x0084, KEY_0 },
{ 0x0085, KEY_MUTE }, /* Mute */
{ 0x0086, KEY_HOMEPAGE }, /* Home */
{ 0x0087, KEY_UP }, /* Up */
{ 0x0088, KEY_OK }, /* OK */
{ 0x0089, KEY_RIGHT }, /* Right */
{ 0x008a, KEY_FASTFORWARD }, /* Fast forward */
{ 0x008b, KEY_VOLUMEUP }, /* Volume + */
{ 0x008c, KEY_DOWN }, /* Down */
{ 0x008d, KEY_PLAY }, /* Play/Pause */
{ 0x008e, KEY_STOP }, /* Stop */
{ 0x008f, KEY_EPG }, /* Info/EPG */
{ 0x0090, KEY_7 },
{ 0x0091, KEY_4 },
{ 0x0092, KEY_1 },
{ 0x0093, KEY_CHANNELDOWN }, /* Channel - */
{ 0x0094, KEY_8 },
{ 0x0095, KEY_5 },
{ 0x0096, KEY_2 },
{ 0x0097, KEY_CHANNELUP }, /* Channel + */
{ 0x0098, KEY_9 },
{ 0x0099, KEY_6 },
{ 0x009a, KEY_3 },
{ 0x009b, KEY_VOLUMEDOWN }, /* Volume - */
{ 0x009c, KEY_TV }, /* TV */
{ 0x009d, KEY_RECORD }, /* Record */
{ 0x009e, KEY_REWIND }, /* Rewind */
{ 0x009f, KEY_LEFT }, /* Left */
};
static struct rc_keymap trekstor_map = {
.map = {
.scan = trekstor,
.size = ARRAY_SIZE(trekstor),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_TREKSTOR,
}
};
static int __init init_rc_map_trekstor(void)
{
return ir_register_map(&trekstor_map);
}
static void __exit exit_rc_map_trekstor(void)
{
ir_unregister_map(&trekstor_map);
}
module_init(init_rc_map_trekstor)
module_exit(exit_rc_map_trekstor)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

View File

@ -0,0 +1,87 @@
#include <media/rc-map.h>
static struct ir_scancode twinhan_vp1027[] = {
{ 0x16, KEY_POWER2 },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
{ 0x48, KEY_INFO},
{ 0x1c, KEY_EPG },
{ 0x04, KEY_LIST },
{ 0x03, KEY_1 },
{ 0x01, KEY_2 },
{ 0x06, KEY_3 },
{ 0x09, KEY_4 },
{ 0x1d, KEY_5 },
{ 0x1f, KEY_6 },
{ 0x0d, KEY_7 },
{ 0x19, KEY_8 },
{ 0x1b, KEY_9 },
{ 0x15, KEY_0 },
{ 0x0c, KEY_CANCEL },
{ 0x4a, KEY_CLEAR },
{ 0x13, KEY_BACKSPACE },
{ 0x00, KEY_TAB },
{ 0x4b, KEY_UP },
{ 0x51, KEY_DOWN },
{ 0x4e, KEY_LEFT },
{ 0x52, KEY_RIGHT },
{ 0x4f, KEY_ENTER },
{ 0x1e, KEY_VOLUMEUP },
{ 0x0a, KEY_VOLUMEDOWN },
{ 0x02, KEY_CHANNELDOWN },
{ 0x05, KEY_CHANNELUP },
{ 0x11, KEY_RECORD },
{ 0x14, KEY_PLAY },
{ 0x4c, KEY_PAUSE },
{ 0x1a, KEY_STOP },
{ 0x40, KEY_REWIND },
{ 0x12, KEY_FASTFORWARD },
{ 0x41, KEY_PREVIOUSSONG },
{ 0x42, KEY_NEXTSONG },
{ 0x54, KEY_SAVE },
{ 0x50, KEY_LANGUAGE },
{ 0x47, KEY_MEDIA },
{ 0x4d, KEY_SCREEN },
{ 0x43, KEY_SUBTITLE },
{ 0x10, KEY_MUTE },
{ 0x49, KEY_AUDIO },
{ 0x07, KEY_SLEEP },
{ 0x08, KEY_VIDEO },
{ 0x0e, KEY_AGAIN },
{ 0x45, KEY_EQUAL },
{ 0x46, KEY_MINUS },
{ 0x18, KEY_RED },
{ 0x53, KEY_GREEN },
{ 0x5e, KEY_YELLOW },
{ 0x5f, KEY_BLUE },
};
static struct rc_keymap twinhan_vp1027_map = {
.map = {
.scan = twinhan_vp1027,
.size = ARRAY_SIZE(twinhan_vp1027),
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TWINHAN_VP1027_DVBS,
}
};
static int __init init_rc_map_twinhan_vp1027(void)
{
return ir_register_map(&twinhan_vp1027_map);
}
static void __exit exit_rc_map_twinhan_vp1027(void)
{
ir_unregister_map(&twinhan_vp1027_map);
}
module_init(init_rc_map_twinhan_vp1027)
module_exit(exit_rc_map_twinhan_vp1027)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sergey Ivanov <123kash@gmail.com>");

View File

@ -57,13 +57,12 @@ struct irctl {
struct task_struct *task;
long jiffies_to_wait;
struct cdev cdev;
};
static DEFINE_MUTEX(lirc_dev_lock);
static struct irctl *irctls[MAX_IRCTL_DEVICES];
static struct cdev cdevs[MAX_IRCTL_DEVICES];
/* Only used for sysfs but defined to void otherwise */
static struct class *lirc_class;
@ -71,15 +70,13 @@ static struct class *lirc_class;
/* helper function
* initializes the irctl structure
*/
static void init_irctl(struct irctl *ir)
static void lirc_irctl_init(struct irctl *ir)
{
dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
ir->d.name, ir->d.minor);
mutex_init(&ir->irctl_lock);
ir->d.minor = NOPLUG;
}
static void cleanup(struct irctl *ir)
static void lirc_irctl_cleanup(struct irctl *ir)
{
dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
@ -96,7 +93,7 @@ static void cleanup(struct irctl *ir)
* reads key codes from driver and puts them into buffer
* returns 0 on success
*/
static int add_to_buf(struct irctl *ir)
static int lirc_add_to_buf(struct irctl *ir)
{
if (ir->d.add_to_buf) {
int res = -ENODATA;
@ -139,7 +136,7 @@ static int lirc_thread(void *irctl)
}
if (kthread_should_stop())
break;
if (!add_to_buf(ir))
if (!lirc_add_to_buf(ir))
wake_up_interruptible(&ir->buf->wait_poll);
} else {
set_current_state(TASK_INTERRUPTIBLE);
@ -154,12 +151,15 @@ static int lirc_thread(void *irctl)
}
static struct file_operations fops = {
static struct file_operations lirc_dev_fops = {
.owner = THIS_MODULE,
.read = lirc_dev_fop_read,
.write = lirc_dev_fop_write,
.poll = lirc_dev_fop_poll,
.unlocked_ioctl = lirc_dev_fop_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = lirc_dev_fop_ioctl,
#endif
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
.llseek = noop_llseek,
@ -169,19 +169,20 @@ static int lirc_cdev_add(struct irctl *ir)
{
int retval;
struct lirc_driver *d = &ir->d;
struct cdev *cdev = &cdevs[d->minor];
if (d->fops) {
cdev_init(&ir->cdev, d->fops);
ir->cdev.owner = d->owner;
cdev_init(cdev, d->fops);
cdev->owner = d->owner;
} else {
cdev_init(&ir->cdev, &fops);
ir->cdev.owner = THIS_MODULE;
cdev_init(cdev, &lirc_dev_fops);
cdev->owner = THIS_MODULE;
}
kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor);
kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
if (retval)
kobject_put(&ir->cdev.kobj);
kobject_put(&cdev->kobj);
return retval;
}
@ -202,6 +203,12 @@ int lirc_register_driver(struct lirc_driver *d)
goto out;
}
if (!d->dev) {
printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__);
err = -EINVAL;
goto out;
}
if (MAX_IRCTL_DEVICES <= d->minor) {
dev_err(d->dev, "lirc_dev: lirc_register_driver: "
"\"minor\" must be between 0 and %d (%d)!\n",
@ -277,7 +284,7 @@ int lirc_register_driver(struct lirc_driver *d)
err = -ENOMEM;
goto out_lock;
}
init_irctl(ir);
lirc_irctl_init(ir);
irctls[minor] = ir;
d->minor = minor;
@ -316,7 +323,6 @@ int lirc_register_driver(struct lirc_driver *d)
d->features = LIRC_CAN_REC_LIRCCODE;
ir->d = *d;
ir->d.minor = minor;
device_create(lirc_class, ir->d.dev,
MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
@ -357,21 +363,28 @@ EXPORT_SYMBOL(lirc_register_driver);
int lirc_unregister_driver(int minor)
{
struct irctl *ir;
struct cdev *cdev;
if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
"\"minor (%d)\" must be between 0 and %d!\n",
minor, MAX_IRCTL_DEVICES-1);
printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
"0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
return -EBADRQC;
}
ir = irctls[minor];
if (!ir) {
printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct "
"for minor %d!\n", __func__, minor);
return -ENOENT;
}
cdev = &cdevs[minor];
mutex_lock(&lirc_dev_lock);
if (ir->d.minor != minor) {
printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
"minor (%d) device not registered!", minor);
printk(KERN_ERR "lirc_dev: %s: minor (%d) device not "
"registered!\n", __func__, minor);
mutex_unlock(&lirc_dev_lock);
return -ENOENT;
}
@ -390,12 +403,11 @@ int lirc_unregister_driver(int minor)
wake_up_interruptible(&ir->buf->wait_poll);
mutex_lock(&ir->irctl_lock);
ir->d.set_use_dec(ir->d.data);
module_put(ir->d.owner);
module_put(cdev->owner);
mutex_unlock(&ir->irctl_lock);
cdev_del(&ir->cdev);
} else {
cleanup(ir);
cdev_del(&ir->cdev);
lirc_irctl_cleanup(ir);
cdev_del(cdev);
kfree(ir);
irctls[minor] = NULL;
}
@ -409,6 +421,7 @@ EXPORT_SYMBOL(lirc_unregister_driver);
int lirc_dev_fop_open(struct inode *inode, struct file *file)
{
struct irctl *ir;
struct cdev *cdev;
int retval = 0;
if (iminor(inode) >= MAX_IRCTL_DEVICES) {
@ -425,7 +438,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
retval = -ENODEV;
goto error;
}
file->private_data = ir;
dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
@ -439,13 +451,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
goto error;
}
if (try_module_get(ir->d.owner)) {
++ir->open;
cdev = &cdevs[iminor(inode)];
if (try_module_get(cdev->owner)) {
ir->open++;
retval = ir->d.set_use_inc(ir->d.data);
if (retval) {
module_put(ir->d.owner);
--ir->open;
module_put(cdev->owner);
ir->open--;
} else {
lirc_buffer_clear(ir->buf);
}
@ -469,17 +482,24 @@ EXPORT_SYMBOL(lirc_dev_fop_open);
int lirc_dev_fop_close(struct inode *inode, struct file *file)
{
struct irctl *ir = irctls[iminor(inode)];
struct cdev *cdev = &cdevs[iminor(inode)];
if (!ir) {
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
return -EINVAL;
}
dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
WARN_ON(mutex_lock_killable(&lirc_dev_lock));
--ir->open;
ir->open--;
if (ir->attached) {
ir->d.set_use_dec(ir->d.data);
module_put(ir->d.owner);
module_put(cdev->owner);
} else {
cleanup(ir);
lirc_irctl_cleanup(ir);
cdev_del(cdev);
irctls[ir->d.minor] = NULL;
kfree(ir);
}
@ -495,6 +515,11 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
unsigned int ret;
if (!ir) {
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
return POLLERR;
}
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
if (!ir->attached) {
@ -521,9 +546,14 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);
long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned long mode;
__u32 mode;
int result = 0;
struct irctl *ir = file->private_data;
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
if (!ir) {
printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__);
return -ENODEV;
}
dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
ir->d.name, ir->d.minor, cmd);
@ -538,7 +568,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
switch (cmd) {
case LIRC_GET_FEATURES:
result = put_user(ir->d.features, (unsigned long *)arg);
result = put_user(ir->d.features, (__u32 *)arg);
break;
case LIRC_GET_REC_MODE:
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@ -548,7 +578,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
result = put_user(LIRC_REC2MODE
(ir->d.features & LIRC_CAN_REC_MASK),
(unsigned long *)arg);
(__u32 *)arg);
break;
case LIRC_SET_REC_MODE:
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@ -556,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
result = get_user(mode, (unsigned long *)arg);
result = get_user(mode, (__u32 *)arg);
if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
result = -EINVAL;
/*
@ -565,7 +595,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
break;
case LIRC_GET_LENGTH:
result = put_user(ir->d.code_length, (unsigned long *)arg);
result = put_user(ir->d.code_length, (__u32 *)arg);
break;
case LIRC_GET_MIN_TIMEOUT:
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@ -574,7 +604,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
result = put_user(ir->d.min_timeout, (unsigned long *)arg);
result = put_user(ir->d.min_timeout, (__u32 *)arg);
break;
case LIRC_GET_MAX_TIMEOUT:
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@ -583,7 +613,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
result = put_user(ir->d.max_timeout, (unsigned long *)arg);
result = put_user(ir->d.max_timeout, (__u32 *)arg);
break;
default:
result = -EINVAL;
@ -604,12 +634,21 @@ ssize_t lirc_dev_fop_read(struct file *file,
loff_t *ppos)
{
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
unsigned char buf[ir->chunk_size];
unsigned char *buf;
int ret = 0, written = 0;
DECLARE_WAITQUEUE(wait, current);
if (!ir) {
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
return -ENODEV;
}
dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
buf = kzalloc(ir->chunk_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (mutex_lock_interruptible(&ir->irctl_lock))
return -ERESTARTSYS;
if (!ir->attached) {
@ -681,6 +720,7 @@ ssize_t lirc_dev_fop_read(struct file *file,
mutex_unlock(&ir->irctl_lock);
out_unlocked:
kfree(buf);
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
@ -709,6 +749,11 @@ ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
{
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
if (!ir) {
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
return -ENODEV;
}
dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
if (!ir->attached)

View File

@ -46,24 +46,58 @@
"device driver"
#define DRIVER_NAME "mceusb"
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
/* MCE constants */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
#define MCE_CONTROL_HEADER 0x9F /* MCE status header */
#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */
#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
#define MCE_PULSE_MASK 0x7F /* Pulse mask */
#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */
#define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
#define MCE_IRDATA_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
#define MCE_IRDATA_TRAILER 0x80 /* End of IR data */
#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
#define MCE_DEFAULT_TX_MASK 0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */
#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
#define MCE_PULSE_MASK 0x7f /* Pulse mask */
#define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */
#define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */
#define MCE_COMMAND_HEADER 0x9f /* MCE command header */
#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */
#define MCE_COMMAND_NULL 0x00 /* These show up various places... */
/* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER,
* then we're looking at a raw IR data sample */
#define MCE_COMMAND_IRDATA 0x80
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
#define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */
#define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */
#define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */
#define MCE_CMD_UNKNOWN3 0x09 /* Unknown */
#define MCE_CMD_UNKNOWN4 0x0a /* Unknown */
#define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */
#define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */
#define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */
#define MCE_CMD_UNKNOWN5 0x0e /* Unknown */
#define MCE_CMD_UNKNOWN6 0x0f /* Unknown */
#define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
#define MCE_CMD_UNKNOWN8 0x19 /* Unknown */
#define MCE_CMD_UNKNOWN9 0x1b /* Unknown */
#define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */
#define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */
/* module parameters */
@ -104,14 +138,64 @@ static int debug;
#define VENDOR_NORTHSTAR 0x04eb
#define VENDOR_REALTEK 0x0bda
#define VENDOR_TIVO 0x105a
#define VENDOR_CONEXANT 0x0572
enum mceusb_model_type {
MCE_GEN2 = 0, /* Most boards */
MCE_GEN1,
MCE_GEN3,
MCE_GEN2_TX_INV,
POLARIS_EVK,
};
struct mceusb_model {
u32 mce_gen1:1;
u32 mce_gen2:1;
u32 mce_gen3:1;
u32 tx_mask_inverted:1;
u32 is_polaris:1;
const char *rc_map; /* Allow specify a per-board map */
const char *name; /* per-board name */
};
static const struct mceusb_model mceusb_model[] = {
[MCE_GEN1] = {
.mce_gen1 = 1,
.tx_mask_inverted = 1,
},
[MCE_GEN2] = {
.mce_gen2 = 1,
},
[MCE_GEN2_TX_INV] = {
.mce_gen2 = 1,
.tx_mask_inverted = 1,
},
[MCE_GEN3] = {
.mce_gen3 = 1,
.tx_mask_inverted = 1,
},
[POLARIS_EVK] = {
.is_polaris = 1,
/*
* In fact, the EVK is shipped without
* remotes, but we should have something handy,
* to allow testing it
*/
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
.name = "cx231xx MCE IR",
},
};
static struct usb_device_id mceusb_dev_table[] = {
/* Original Microsoft MCE IR Transceiver (often HP-branded) */
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d),
.driver_info = MCE_GEN1 },
/* Philips Infrared Transceiver - Sahara branded */
{ USB_DEVICE(VENDOR_PHILIPS, 0x0608) },
/* Philips Infrared Transceiver - HP branded */
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c),
.driver_info = MCE_GEN2_TX_INV },
/* Philips SRM5100 */
{ USB_DEVICE(VENDOR_PHILIPS, 0x060d) },
/* Philips Infrared Transceiver - Omaura */
@ -127,11 +211,14 @@ static struct usb_device_id mceusb_dev_table[] = {
/* Realtek MCE IR Receiver */
{ USB_DEVICE(VENDOR_REALTEK, 0x0161) },
/* SMK/Toshiba G83C0004D410 */
{ USB_DEVICE(VENDOR_SMK, 0x031d) },
{ USB_DEVICE(VENDOR_SMK, 0x031d),
.driver_info = MCE_GEN2_TX_INV },
/* SMK eHome Infrared Transceiver (Sony VAIO) */
{ USB_DEVICE(VENDOR_SMK, 0x0322) },
{ USB_DEVICE(VENDOR_SMK, 0x0322),
.driver_info = MCE_GEN2_TX_INV },
/* bundled with Hauppauge PVR-150 */
{ USB_DEVICE(VENDOR_SMK, 0x0334) },
{ USB_DEVICE(VENDOR_SMK, 0x0334),
.driver_info = MCE_GEN2_TX_INV },
/* SMK eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_SMK, 0x0338) },
/* Tatung eHome Infrared Transceiver */
@ -145,17 +232,23 @@ static struct usb_device_id mceusb_dev_table[] = {
/* Mitsumi */
{ USB_DEVICE(VENDOR_MITSUMI, 0x2501) },
/* Topseed eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001),
.driver_info = MCE_GEN2_TX_INV },
/* Topseed HP eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006),
.driver_info = MCE_GEN2_TX_INV },
/* Topseed eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007),
.driver_info = MCE_GEN2_TX_INV },
/* Topseed eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008),
.driver_info = MCE_GEN3 },
/* Topseed eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a),
.driver_info = MCE_GEN2_TX_INV },
/* Topseed eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011),
.driver_info = MCE_GEN2_TX_INV },
/* Ricavision internal Infrared Transceiver */
{ USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
/* Itron ione Libra Q-11 */
@ -185,7 +278,8 @@ static struct usb_device_id mceusb_dev_table[] = {
/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
{ USB_DEVICE(VENDOR_FINTEK, 0x0702) },
/* Pinnacle Remote Kit */
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225),
.driver_info = MCE_GEN3 },
/* Elitegroup Computer Systems IR */
{ USB_DEVICE(VENDOR_ECS, 0x0f38) },
/* Wistron Corp. eHome Infrared Receiver */
@ -198,37 +292,13 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
/* TiVo PC IR Receiver */
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
/* Conexant SDK */
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
.driver_info = POLARIS_EVK },
/* Terminating entry */
{ }
};
static struct usb_device_id gen3_list[] = {
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
{}
};
static struct usb_device_id microsoft_gen1_list[] = {
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
{}
};
static struct usb_device_id std_tx_mask_list[] = {
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
{ USB_DEVICE(VENDOR_SMK, 0x031d) },
{ USB_DEVICE(VENDOR_SMK, 0x0322) },
{ USB_DEVICE(VENDOR_SMK, 0x0334) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
{}
};
/* data structure for each usb transceiver */
struct mceusb_dev {
/* ir-core bits */
@ -248,8 +318,15 @@ struct mceusb_dev {
/* buffers and dma */
unsigned char *buf_in;
unsigned int len_in;
u8 cmd; /* MCE command type */
u8 rem; /* Remaining IR data bytes in packet */
enum {
CMD_HEADER = 0,
SUBCMD,
CMD_DATA,
PARSE_IRDATA,
} parser_state;
u8 cmd, rem; /* Remaining IR data bytes in packet */
dma_addr_t dma_in;
dma_addr_t dma_out;
@ -257,7 +334,6 @@ struct mceusb_dev {
u32 connected:1;
u32 tx_mask_inverted:1;
u32 microsoft_gen1:1;
u32 reserved:29;
} flags;
/* transmit support */
@ -267,6 +343,7 @@ struct mceusb_dev {
char name[128];
char phys[64];
enum mceusb_model_type model;
};
/*
@ -291,43 +368,81 @@ struct mceusb_dev {
* - SET_RX_TIMEOUT sets the receiver timeout
* - SET_RX_SENSOR sets which receiver sensor to use
*/
static char DEVICE_RESET[] = {0x00, 0xff, 0xaa};
static char GET_REVISION[] = {0xff, 0x0b};
static char GET_UNKNOWN[] = {0xff, 0x18};
static char GET_UNKNOWN2[] = {0x9f, 0x05};
static char GET_CARRIER_FREQ[] = {0x9f, 0x07};
static char GET_RX_TIMEOUT[] = {0x9f, 0x0d};
static char GET_TX_BITMASK[] = {0x9f, 0x13};
static char GET_RX_SENSOR[] = {0x9f, 0x15};
static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER,
MCE_CMD_DEVICE_RESET};
static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION};
static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7};
static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER};
static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT};
static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK};
static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR};
/* sub in desired values in lower byte or bytes for full command */
/* FIXME: make use of these for transmit.
static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00};
static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00};
static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00};
static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00};
static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER,
MCE_CMD_S_CARRIER, 0x00, 0x00};
static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00};
static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER,
MCE_CMD_S_TIMEOUT, 0x00, 0x00};
static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER,
MCE_CMD_S_RXSENSOR, 0x00};
*/
static int mceusb_cmdsize(u8 cmd, u8 subcmd)
{
int datasize = 0;
switch (cmd) {
case MCE_COMMAND_NULL:
if (subcmd == MCE_HW_CMD_HEADER)
datasize = 1;
break;
case MCE_HW_CMD_HEADER:
switch (subcmd) {
case MCE_CMD_G_REVISION:
datasize = 2;
break;
}
case MCE_COMMAND_HEADER:
switch (subcmd) {
case MCE_CMD_UNKNOWN:
case MCE_CMD_S_CARRIER:
case MCE_CMD_S_TIMEOUT:
case MCE_CMD_G_RXSENSOR:
datasize = 2;
break;
case MCE_CMD_S_TXMASK:
case MCE_CMD_S_RXSENSOR:
datasize = 1;
break;
}
}
return datasize;
}
static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
int len, bool out)
int offset, int len, bool out)
{
char codes[USB_BUFLEN * 3 + 1];
char inout[9];
int i;
u8 cmd, subcmd, data1, data2;
struct device *dev = ir->dev;
int idx = 0;
int i, start, skip = 0;
if (!debug)
return;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
if (ir->flags.microsoft_gen1 && !out)
idx = 2;
skip = 2;
if (len <= idx)
if (len <= skip)
return;
for (i = 0; i < len && i < USB_BUFLEN; i++)
snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF);
snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff);
dev_info(dev, "%sx data: %s (length=%d)\n",
dev_info(dev, "%sx data: %s(length=%d)\n",
(out ? "t" : "r"), codes, len);
if (out)
@ -335,91 +450,93 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
else
strcpy(inout, "Got\0");
cmd = buf[idx] & 0xff;
subcmd = buf[idx + 1] & 0xff;
data1 = buf[idx + 2] & 0xff;
data2 = buf[idx + 3] & 0xff;
start = offset + skip;
cmd = buf[start] & 0xff;
subcmd = buf[start + 1] & 0xff;
data1 = buf[start + 2] & 0xff;
data2 = buf[start + 3] & 0xff;
switch (cmd) {
case 0x00:
if (subcmd == 0xff && data1 == 0xaa)
case MCE_COMMAND_NULL:
if ((subcmd == MCE_HW_CMD_HEADER) &&
(data1 == MCE_CMD_DEVICE_RESET))
dev_info(dev, "Device reset requested\n");
else
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
case 0xff:
case MCE_HW_CMD_HEADER:
switch (subcmd) {
case 0x0b:
case MCE_CMD_G_REVISION:
if (len == 2)
dev_info(dev, "Get hw/sw rev?\n");
else
dev_info(dev, "hw/sw rev 0x%02x 0x%02x "
"0x%02x 0x%02x\n", data1, data2,
buf[idx + 4], buf[idx + 5]);
buf[start + 4], buf[start + 5]);
break;
case 0xaa:
case MCE_CMD_DEVICE_RESET:
dev_info(dev, "Device reset requested\n");
break;
case 0xfe:
case MCE_RSP_CMD_INVALID:
dev_info(dev, "Previous command not supported\n");
break;
case 0x18:
case 0x1b:
case MCE_CMD_UNKNOWN7:
case MCE_CMD_UNKNOWN9:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
}
break;
case 0x9f:
case MCE_COMMAND_HEADER:
switch (subcmd) {
case 0x03:
case MCE_CMD_PING:
dev_info(dev, "Ping\n");
break;
case 0x04:
case MCE_CMD_UNKNOWN:
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
data1, data2);
break;
case 0x06:
case MCE_CMD_S_CARRIER:
dev_info(dev, "%s carrier mode and freq of "
"0x%02x 0x%02x\n", inout, data1, data2);
break;
case 0x07:
case MCE_CMD_G_CARRIER:
dev_info(dev, "Get carrier mode and freq\n");
break;
case 0x08:
case MCE_CMD_S_TXMASK:
dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
inout, data1);
break;
case 0x0c:
case MCE_CMD_S_TIMEOUT:
/* value is in units of 50us, so x*50/100 or x/2 ms */
dev_info(dev, "%s receive timeout of %d ms\n",
inout, ((data1 << 8) | data2) / 2);
break;
case 0x0d:
case MCE_CMD_G_TIMEOUT:
dev_info(dev, "Get receive timeout\n");
break;
case 0x13:
case MCE_CMD_G_TXMASK:
dev_info(dev, "Get transmit blaster mask\n");
break;
case 0x14:
case MCE_CMD_S_RXSENSOR:
dev_info(dev, "%s %s-range receive sensor in use\n",
inout, data1 == 0x02 ? "short" : "long");
break;
case 0x15:
case MCE_CMD_G_RXSENSOR:
if (len == 2)
dev_info(dev, "Get receive sensor\n");
else
dev_info(dev, "Received pulse count is %d\n",
((data1 << 8) | data2));
break;
case 0xfe:
case MCE_RSP_CMD_INVALID:
dev_info(dev, "Error! Hardware is likely wedged...\n");
break;
case 0x05:
case 0x09:
case 0x0f:
case MCE_CMD_UNKNOWN2:
case MCE_CMD_UNKNOWN3:
case MCE_CMD_UNKNOWN5:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
@ -429,6 +546,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
default:
break;
}
if (cmd == MCE_IRDATA_TRAILER)
dev_info(dev, "End of raw IR data\n");
else if ((cmd != MCE_COMMAND_HEADER) &&
((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA))
dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem);
}
static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
@ -446,9 +569,7 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
urb->status, len);
if (debug)
mceusb_dev_printdata(ir, urb->transfer_buffer,
len, true);
mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
}
}
@ -536,8 +657,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
return -ENOMEM;
/* MCE tx init header */
cmdbuf[cmdcount++] = MCE_CONTROL_HEADER;
cmdbuf[cmdcount++] = 0x08;
cmdbuf[cmdcount++] = MCE_COMMAND_HEADER;
cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK;
cmdbuf[cmdcount++] = ir->tx_mask;
/* Generate mce packet data */
@ -551,7 +672,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
if ((cmdcount < MCE_CMDBUF_SIZE) &&
(cmdcount - MCE_TX_HEADER_LENGTH) %
MCE_CODE_LENGTH == 0)
cmdbuf[cmdcount++] = MCE_PACKET_HEADER;
cmdbuf[cmdcount++] = MCE_IRDATA_HEADER;
/* Insert mce packet data */
if (cmdcount < MCE_CMDBUF_SIZE)
@ -570,7 +691,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
/* Fix packet length in last header */
cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] =
0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1;
MCE_COMMAND_IRDATA + (cmdcount - MCE_TX_HEADER_LENGTH) %
MCE_CODE_LENGTH - 1;
/* Check if we have room for the empty packet at the end */
if (cmdcount >= MCE_CMDBUF_SIZE) {
@ -579,7 +701,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
}
/* All mce commands end with an empty packet (0x80) */
cmdbuf[cmdcount++] = 0x80;
cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER;
/* Transmit the command to the mce device */
mce_async_out(ir, cmdbuf, cmdcount);
@ -608,7 +730,8 @@ static int mceusb_set_tx_mask(void *priv, u32 mask)
struct mceusb_dev *ir = priv;
if (ir->flags.tx_mask_inverted)
ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1;
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
else
ir->tx_mask = mask;
@ -621,7 +744,8 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
struct mceusb_dev *ir = priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 };
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
MCE_CMD_S_CARRIER, 0x00, 0x00 };
/* Carrier has changed */
if (ir->carrier != carrier) {
@ -629,7 +753,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
if (carrier == 0) {
ir->carrier = carrier;
cmdbuf[2] = 0x01;
cmdbuf[3] = 0x80;
cmdbuf[3] = MCE_IRDATA_TRAILER;
dev_dbg(ir->dev, "%s: disabling carrier "
"modulation\n", __func__);
mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
@ -638,7 +762,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
for (prescaler = 0; prescaler < 4; ++prescaler) {
divisor = (clk >> (2 * prescaler)) / carrier;
if (divisor <= 0xFF) {
if (divisor <= 0xff) {
ir->carrier = carrier;
cmdbuf[2] = prescaler;
cmdbuf[3] = divisor;
@ -660,47 +784,36 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
{
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
int i, start_index = 0;
u8 hdr = MCE_CONTROL_HEADER;
DEFINE_IR_RAW_EVENT(rawir);
int i = 0;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
if (ir->flags.microsoft_gen1)
start_index = 2;
i = 2;
for (i = start_index; i < buf_len;) {
if (ir->rem == 0) {
/* decode mce packets of the form (84),AA,BB,CC,DD */
/* IR data packets can span USB messages - rem */
hdr = ir->buf_in[i];
ir->rem = (hdr & MCE_PACKET_LENGTH_MASK);
ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK);
dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n",
ir->rem, ir->cmd);
i++;
}
/* don't process MCE commands */
if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) {
ir->rem = 0;
return;
}
for (; (ir->rem > 0) && (i < buf_len); i++) {
for (; i < buf_len; i++) {
switch (ir->parser_state) {
case SUBCMD:
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
ir->rem + 2, false);
ir->parser_state = CMD_DATA;
break;
case PARSE_IRDATA:
ir->rem--;
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
* MCE_TIME_UNIT * 1000;
if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
if (ir->rawir.pulse == rawir.pulse)
if (ir->rawir.pulse == rawir.pulse) {
ir->rawir.duration += rawir.duration;
else {
} else {
ir->rawir.duration = rawir.duration;
ir->rawir.pulse = rawir.pulse;
}
continue;
if (ir->rem)
break;
}
rawir.duration += ir->rawir.duration;
ir->rawir.duration = 0;
@ -711,14 +824,40 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
rawir.duration);
ir_raw_event_store(ir->idev, &rawir);
break;
case CMD_DATA:
ir->rem--;
break;
case CMD_HEADER:
/* decode mce packets of the form (84),AA,BB,CC,DD */
/* IR data packets can span USB messages - rem */
ir->cmd = ir->buf_in[i];
if ((ir->cmd == MCE_COMMAND_HEADER) ||
((ir->cmd & MCE_COMMAND_MASK) !=
MCE_COMMAND_IRDATA)) {
ir->parser_state = SUBCMD;
continue;
}
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
if (ir->rem) {
ir->parser_state = PARSE_IRDATA;
break;
}
/*
* a package with len=0 (e. g. 0x80) means end of
* data. We could use it to do the call to
* ir_raw_event_handle(). For now, we don't need to
* use it.
*/
break;
}
if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f)
ir->rem = 0;
dev_dbg(ir->dev, "calling ir_raw_event_handle\n");
ir_raw_event_handle(ir->idev);
if (ir->parser_state != CMD_HEADER && !ir->rem)
ir->parser_state = CMD_HEADER;
}
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
ir_raw_event_handle(ir->idev);
}
static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
@ -737,9 +876,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
buf_len = urb->actual_length;
if (debug)
mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false);
if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
ir->send_flags = SEND_FLAG_COMPLETE;
dev_dbg(ir->dev, "setup answer received %d bytes\n",
@ -760,6 +896,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
case -EPIPE:
default:
dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
break;
}
@ -865,6 +1002,8 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
struct input_dev *idev;
struct ir_dev_props *props;
struct device *dev = ir->dev;
const char *rc_map = RC_MAP_RC6_MCE;
const char *name = "Media Center Ed. eHome Infrared Remote Transceiver";
int ret = -ENODEV;
idev = input_allocate_device();
@ -880,8 +1019,11 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
goto props_alloc_failed;
}
snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome "
"Infrared Remote Transceiver (%04x:%04x)",
if (mceusb_model[ir->model].name)
name = mceusb_model[ir->model].name;
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
name,
le16_to_cpu(ir->usbdev->descriptor.idVendor),
le16_to_cpu(ir->usbdev->descriptor.idProduct));
@ -899,7 +1041,10 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
ir->props = props;
ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME);
if (mceusb_model[ir->model].rc_map)
rc_map = mceusb_model[ir->model].rc_map;
ret = ir_input_register(idev, rc_map, props, DRIVER_NAME);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
goto irdev_failed;
@ -926,17 +1071,26 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
struct mceusb_dev *ir = NULL;
int pipe, maxp, i;
char buf[63], name[128] = "";
enum mceusb_model_type model = id->driver_info;
bool is_gen3;
bool is_microsoft_gen1;
bool tx_mask_inverted;
bool is_polaris;
dev_dbg(&intf->dev, ": %s called\n", __func__);
idesc = intf->cur_altsetting;
is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1;
is_gen3 = mceusb_model[model].mce_gen3;
is_microsoft_gen1 = mceusb_model[model].mce_gen1;
tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
is_polaris = mceusb_model[model].is_polaris;
if (is_polaris) {
/* Interface 0 is IR */
if (idesc->desc.bInterfaceNumber)
return -ENODEV;
}
/* step through the endpoints to find first bulk in and out endpoint */
for (i = 0; i < idesc->desc.bNumEndpoints; ++i) {
@ -997,6 +1151,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
ir->flags.tx_mask_inverted = tx_mask_inverted;
ir->model = model;
init_ir_raw_event(&ir->rawir);
/* Saving usb interface data for use by the transmitter routine */
ir->usb_ep_in = ep_in;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,408 @@
/*
* Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR
*
* Copyright (C) 2010 Jarod Wilson <jarod@redhat.com>
* Copyright (C) 2009 Nuvoton PS Team
*
* Special thanks to Nuvoton for providing hardware, spec sheets and
* sample code upon which portions of this driver are based. Indirect
* thanks also to Maxim Levitsky, whose ene_ir driver this driver is
* modeled after.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <linux/spinlock.h>
#include <linux/ioctl.h>
/* platform driver name to register */
#define NVT_DRIVER_NAME "nuvoton-cir"
/* debugging module parameter */
static int debug;
#define nvt_pr(level, text, ...) \
printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
#define nvt_dbg(text, ...) \
if (debug) \
printk(KERN_DEBUG \
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
#define nvt_dbg_verbose(text, ...) \
if (debug > 1) \
printk(KERN_DEBUG \
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
#define nvt_dbg_wake(text, ...) \
if (debug > 2) \
printk(KERN_DEBUG \
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
/*
* Original lirc driver said min value of 76, and recommended value of 256
* for the buffer length, but then used 2048. Never mind that the size of the
* RX FIFO is 32 bytes... So I'm using 32 for RX and 256 for TX atm, but I'm
* not sure if maybe that TX value is off by a factor of 8 (bits vs. bytes),
* and I don't have TX-capable hardware to test/debug on...
*/
#define TX_BUF_LEN 256
#define RX_BUF_LEN 32
struct nvt_dev {
struct pnp_dev *pdev;
struct input_dev *rdev;
struct ir_dev_props *props;
struct ir_raw_event rawir;
spinlock_t nvt_lock;
bool in_use;
/* for rx */
u8 buf[RX_BUF_LEN];
unsigned int pkts;
struct {
spinlock_t lock;
u8 buf[TX_BUF_LEN];
unsigned int buf_count;
unsigned int cur_buf_num;
wait_queue_head_t queue;
u8 tx_state;
} tx;
/* EFER Config register index/data pair */
u8 cr_efir;
u8 cr_efdr;
/* hardware I/O settings */
unsigned long cir_addr;
unsigned long cir_wake_addr;
int cir_irq;
int cir_wake_irq;
/* hardware id */
u8 chip_major;
u8 chip_minor;
/* hardware features */
bool hw_learning_capable;
bool hw_tx_capable;
/* rx settings */
bool learning_enabled;
bool carrier_detect_enabled;
/* track cir wake state */
u8 wake_state;
/* for study */
u8 study_state;
/* carrier period = 1 / frequency */
u32 carrier;
};
/* study states */
#define ST_STUDY_NONE 0x0
#define ST_STUDY_START 0x1
#define ST_STUDY_CARRIER 0x2
#define ST_STUDY_ALL_RECV 0x4
/* wake states */
#define ST_WAKE_NONE 0x0
#define ST_WAKE_START 0x1
#define ST_WAKE_FINISH 0x2
/* receive states */
#define ST_RX_WAIT_7F 0x1
#define ST_RX_WAIT_HEAD 0x2
#define ST_RX_WAIT_SILENT_END 0x4
/* send states */
#define ST_TX_NONE 0x0
#define ST_TX_REQUEST 0x2
#define ST_TX_REPLY 0x4
/* buffer packet constants */
#define BUF_PULSE_BIT 0x80
#define BUF_LEN_MASK 0x7f
#define BUF_REPEAT_BYTE 0x70
#define BUF_REPEAT_MASK 0xf0
/* CIR settings */
/* total length of CIR and CIR WAKE */
#define CIR_IOREG_LENGTH 0x0f
/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL (0x7d0 = 2000) */
#define CIR_RX_LIMIT_COUNT 0x7d0
/* CIR Regs */
#define CIR_IRCON 0x00
#define CIR_IRSTS 0x01
#define CIR_IREN 0x02
#define CIR_RXFCONT 0x03
#define CIR_CP 0x04
#define CIR_CC 0x05
#define CIR_SLCH 0x06
#define CIR_SLCL 0x07
#define CIR_FIFOCON 0x08
#define CIR_IRFIFOSTS 0x09
#define CIR_SRXFIFO 0x0a
#define CIR_TXFCONT 0x0b
#define CIR_STXFIFO 0x0c
#define CIR_FCCH 0x0d
#define CIR_FCCL 0x0e
#define CIR_IRFSM 0x0f
/* CIR IRCON settings */
#define CIR_IRCON_RECV 0x80
#define CIR_IRCON_WIREN 0x40
#define CIR_IRCON_TXEN 0x20
#define CIR_IRCON_RXEN 0x10
#define CIR_IRCON_WRXINV 0x08
#define CIR_IRCON_RXINV 0x04
#define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00
#define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01
#define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02
#define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03
/* FIXME: make this a runtime option */
/* select sample period as 50us */
#define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50
/* CIR IRSTS settings */
#define CIR_IRSTS_RDR 0x80
#define CIR_IRSTS_RTR 0x40
#define CIR_IRSTS_PE 0x20
#define CIR_IRSTS_RFO 0x10
#define CIR_IRSTS_TE 0x08
#define CIR_IRSTS_TTR 0x04
#define CIR_IRSTS_TFU 0x02
#define CIR_IRSTS_GH 0x01
/* CIR IREN settings */
#define CIR_IREN_RDR 0x80
#define CIR_IREN_RTR 0x40
#define CIR_IREN_PE 0x20
#define CIR_IREN_RFO 0x10
#define CIR_IREN_TE 0x08
#define CIR_IREN_TTR 0x04
#define CIR_IREN_TFU 0x02
#define CIR_IREN_GH 0x01
/* CIR FIFOCON settings */
#define CIR_FIFOCON_TXFIFOCLR 0x80
#define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00
#define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10
#define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20
#define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30
/* FIXME: make this a runtime option */
/* select TX trigger level as 16 */
#define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16
#define CIR_FIFOCON_RXFIFOCLR 0x08
#define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00
#define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01
#define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02
#define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03
/* FIXME: make this a runtime option */
/* select RX trigger level as 24 */
#define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_24
/* CIR IRFIFOSTS settings */
#define CIR_IRFIFOSTS_IR_PENDING 0x80
#define CIR_IRFIFOSTS_RX_GS 0x40
#define CIR_IRFIFOSTS_RX_FTA 0x20
#define CIR_IRFIFOSTS_RX_EMPTY 0x10
#define CIR_IRFIFOSTS_RX_FULL 0x08
#define CIR_IRFIFOSTS_TX_FTA 0x04
#define CIR_IRFIFOSTS_TX_EMPTY 0x02
#define CIR_IRFIFOSTS_TX_FULL 0x01
/* CIR WAKE UP Regs */
#define CIR_WAKE_IRCON 0x00
#define CIR_WAKE_IRSTS 0x01
#define CIR_WAKE_IREN 0x02
#define CIR_WAKE_FIFO_CMP_DEEP 0x03
#define CIR_WAKE_FIFO_CMP_TOL 0x04
#define CIR_WAKE_FIFO_COUNT 0x05
#define CIR_WAKE_SLCH 0x06
#define CIR_WAKE_SLCL 0x07
#define CIR_WAKE_FIFOCON 0x08
#define CIR_WAKE_SRXFSTS 0x09
#define CIR_WAKE_SAMPLE_RX_FIFO 0x0a
#define CIR_WAKE_WR_FIFO_DATA 0x0b
#define CIR_WAKE_RD_FIFO_ONLY 0x0c
#define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0d
#define CIR_WAKE_FIFO_IGNORE 0x0e
#define CIR_WAKE_IRFSM 0x0f
/* CIR WAKE UP IRCON settings */
#define CIR_WAKE_IRCON_DEC_RST 0x80
#define CIR_WAKE_IRCON_MODE1 0x40
#define CIR_WAKE_IRCON_MODE0 0x20
#define CIR_WAKE_IRCON_RXEN 0x10
#define CIR_WAKE_IRCON_R 0x08
#define CIR_WAKE_IRCON_RXINV 0x04
/* FIXME/jarod: make this a runtime option */
/* select a same sample period like cir register */
#define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50
/* CIR WAKE IRSTS Bits */
#define CIR_WAKE_IRSTS_RDR 0x80
#define CIR_WAKE_IRSTS_RTR 0x40
#define CIR_WAKE_IRSTS_PE 0x20
#define CIR_WAKE_IRSTS_RFO 0x10
#define CIR_WAKE_IRSTS_GH 0x08
#define CIR_WAKE_IRSTS_IR_PENDING 0x01
/* CIR WAKE UP IREN Bits */
#define CIR_WAKE_IREN_RDR 0x80
#define CIR_WAKE_IREN_RTR 0x40
#define CIR_WAKE_IREN_PE 0x20
#define CIR_WAKE_IREN_RFO 0x10
#define CIR_WAKE_IREN_TE 0x08
#define CIR_WAKE_IREN_TTR 0x04
#define CIR_WAKE_IREN_TFU 0x02
#define CIR_WAKE_IREN_GH 0x01
/* CIR WAKE FIFOCON settings */
#define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03
/* FIXME: make this a runtime option */
/* select WAKE UP RX trigger level as 67 */
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67
/* CIR WAKE SRXFSTS settings */
#define CIR_WAKE_IRFIFOSTS_RX_GS 0x80
#define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40
#define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20
#define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10
/* CIR Wake FIFO buffer is 67 bytes long */
#define CIR_WAKE_FIFO_LEN 67
/* CIR Wake byte comparison tolerance */
#define CIR_WAKE_CMP_TOLERANCE 5
/*
* Extended Function Enable Registers:
* Extended Function Index Register
* Extended Function Data Register
*/
#define CR_EFIR 0x2e
#define CR_EFDR 0x2f
/* Possible alternate EFER values, depends on how the chip is wired */
#define CR_EFIR2 0x4e
#define CR_EFDR2 0x4f
/* Extended Function Mode enable/disable magic values */
#define EFER_EFM_ENABLE 0x87
#define EFER_EFM_DISABLE 0xaa
/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
#define CHIP_ID_HIGH 0xb4
#define CHIP_ID_LOW 0x72
#define CHIP_ID_LOW2 0x73
/* Config regs we need to care about */
#define CR_SOFTWARE_RESET 0x02
#define CR_LOGICAL_DEV_SEL 0x07
#define CR_CHIP_ID_HI 0x20
#define CR_CHIP_ID_LO 0x21
#define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */
#define CR_OUTPUT_PIN_SEL 0x27
#define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */
/* next three regs valid for both the CIR and CIR_WAKE logical devices */
#define CR_CIR_BASE_ADDR_HI 0x60
#define CR_CIR_BASE_ADDR_LO 0x61
#define CR_CIR_IRQ_RSRC 0x70
/* next three regs valid only for ACPI logical dev */
#define CR_ACPI_CIR_WAKE 0xe0
#define CR_ACPI_IRQ_EVENTS 0xf6
#define CR_ACPI_IRQ_EVENTS2 0xf7
/* Logical devices that we need to care about */
#define LOGICAL_DEV_LPT 0x01
#define LOGICAL_DEV_CIR 0x06
#define LOGICAL_DEV_ACPI 0x0a
#define LOGICAL_DEV_CIR_WAKE 0x0e
#define LOGICAL_DEV_DISABLE 0x00
#define LOGICAL_DEV_ENABLE 0x01
#define CIR_WAKE_ENABLE_BIT 0x08
#define CIR_INTR_MOUSE_IRQ_BIT 0x80
#define PME_INTR_CIR_PASS_BIT 0x08
#define OUTPUT_PIN_SEL_MASK 0xbc
#define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */
#define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */
/* MCE CIR signal length, related on sample period */
/* MCE CIR controller signal length: about 43ms
* 43ms / 50us (sample period) * 0.85 (inaccuracy)
*/
#define CONTROLLER_BUF_LEN_MIN 830
/* MCE CIR keyboard signal length: about 26ms
* 26ms / 50us (sample period) * 0.85 (inaccuracy)
*/
#define KEYBOARD_BUF_LEN_MAX 650
#define KEYBOARD_BUF_LEN_MIN 610
/* MCE CIR mouse signal length: about 24ms
* 24ms / 50us (sample period) * 0.85 (inaccuracy)
*/
#define MOUSE_BUF_LEN_MIN 565
#define CIR_SAMPLE_PERIOD 50
#define CIR_SAMPLE_LOW_INACCURACY 0.85
/* MAX silence time that driver will sent to lirc */
#define MAX_SILENCE_TIME 60000
#if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100
#define SAMPLE_PERIOD 100
#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50
#define SAMPLE_PERIOD 50
#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25
#define SAMPLE_PERIOD 25
#else
#define SAMPLE_PERIOD 1
#endif
/* as VISTA MCE definition, valid carrier value */
#define MAX_CARRIER 60000
#define MIN_CARRIER 30000

View File

@ -38,7 +38,7 @@
#include <linux/input.h>
#include <media/ir-core.h>
#define DRIVER_VERSION "1.60"
#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
#define DRIVER_DESC "Streamzap Remote Control driver"
@ -61,14 +61,21 @@ static struct usb_device_id streamzap_table[] = {
MODULE_DEVICE_TABLE(usb, streamzap_table);
#define STREAMZAP_PULSE_MASK 0xf0
#define STREAMZAP_SPACE_MASK 0x0f
#define STREAMZAP_TIMEOUT 0xff
#define STREAMZAP_RESOLUTION 256
#define SZ_PULSE_MASK 0xf0
#define SZ_SPACE_MASK 0x0f
#define SZ_TIMEOUT 0xff
#define SZ_RESOLUTION 256
/* number of samples buffered */
#define SZ_BUF_LEN 128
/* from ir-rc5-sz-decoder.c */
#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
#else
#define load_rc5_sz_decode() 0
#endif
enum StreamzapDecoderState {
PulseSpace,
FullPulse,
@ -81,7 +88,6 @@ struct streamzap_ir {
/* ir-core */
struct ir_dev_props *props;
struct ir_raw_event rawir;
/* core device info */
struct device *dev;
@ -98,17 +104,6 @@ struct streamzap_ir {
dma_addr_t dma_in;
unsigned int buf_in_len;
/* timer used to support delay buffering */
struct timer_list delay_timer;
bool timer_running;
spinlock_t timer_lock;
struct timer_list flush_timer;
bool flush;
/* delay buffer */
struct kfifo fifo;
bool fifo_initialized;
/* track what state we're in */
enum StreamzapDecoderState decoder_state;
/* tracks whether we are currently receiving some signal */
@ -118,7 +113,7 @@ struct streamzap_ir {
/* start time of signal; necessary for gap tracking */
struct timeval signal_last;
struct timeval signal_start;
/* bool timeout_enabled; */
bool timeout_enabled;
char name[128];
char phys[64];
@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = {
.id_table = streamzap_table,
};
static void streamzap_stop_timer(struct streamzap_ir *sz)
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
unsigned long flags;
spin_lock_irqsave(&sz->timer_lock, flags);
if (sz->timer_running) {
sz->timer_running = false;
spin_unlock_irqrestore(&sz->timer_lock, flags);
del_timer_sync(&sz->delay_timer);
} else {
spin_unlock_irqrestore(&sz->timer_lock, flags);
}
}
static void streamzap_flush_timeout(unsigned long arg)
{
struct streamzap_ir *sz = (struct streamzap_ir *)arg;
dev_info(sz->dev, "%s: callback firing\n", __func__);
/* finally start accepting data */
sz->flush = false;
}
static void streamzap_delay_timeout(unsigned long arg)
{
struct streamzap_ir *sz = (struct streamzap_ir *)arg;
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
unsigned long flags;
int len, ret;
static unsigned long delay;
bool wake = false;
/* deliver data every 10 ms */
delay = msecs_to_jiffies(10);
spin_lock_irqsave(&sz->timer_lock, flags);
if (kfifo_len(&sz->fifo) > 0) {
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
if (ret != sizeof(rawir))
dev_err(sz->dev, "Problem w/kfifo_out...\n");
ir_raw_event_store(sz->idev, &rawir);
wake = true;
}
len = kfifo_len(&sz->fifo);
if (len > 0) {
while ((len < SZ_BUF_LEN / 2) &&
(len < SZ_BUF_LEN * sizeof(int))) {
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
if (ret != sizeof(rawir))
dev_err(sz->dev, "Problem w/kfifo_out...\n");
ir_raw_event_store(sz->idev, &rawir);
wake = true;
len = kfifo_len(&sz->fifo);
}
if (sz->timer_running)
mod_timer(&sz->delay_timer, jiffies + delay);
} else {
sz->timer_running = false;
}
if (wake)
ir_raw_event_handle(sz->idev);
spin_unlock_irqrestore(&sz->timer_lock, flags);
}
static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
{
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
bool wake = false;
int ret;
while (kfifo_len(&sz->fifo) > 0) {
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
if (ret != sizeof(rawir))
dev_err(sz->dev, "Problem w/kfifo_out...\n");
ir_raw_event_store(sz->idev, &rawir);
wake = true;
}
if (wake)
ir_raw_event_handle(sz->idev);
}
static void sz_push(struct streamzap_ir *sz)
{
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
unsigned long flags;
int ret;
spin_lock_irqsave(&sz->timer_lock, flags);
if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
if (ret != sizeof(rawir))
dev_err(sz->dev, "Problem w/kfifo_out...\n");
ir_raw_event_store(sz->idev, &rawir);
}
kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
if (!sz->timer_running) {
sz->delay_timer.expires = jiffies + (HZ / 10);
add_timer(&sz->delay_timer);
sz->timer_running = true;
}
spin_unlock_irqrestore(&sz->timer_lock, flags);
ir_raw_event_store(sz->idev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
unsigned char value)
{
DEFINE_IR_RAW_EVENT(rawir);
if (sz->idle) {
long deltv;
@ -266,57 +155,59 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
do_gettimeofday(&sz->signal_start);
deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
sz->rawir.pulse = false;
rawir.pulse = false;
if (deltv > 15) {
/* really long time */
sz->rawir.duration = IR_MAX_DURATION;
rawir.duration = IR_MAX_DURATION;
} else {
sz->rawir.duration = (int)(deltv * 1000000 +
rawir.duration = (int)(deltv * 1000000 +
sz->signal_start.tv_usec -
sz->signal_last.tv_usec);
sz->rawir.duration -= sz->sum;
sz->rawir.duration *= 1000;
sz->rawir.duration &= IR_MAX_DURATION;
rawir.duration -= sz->sum;
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
}
dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
sz_push(sz);
dev_dbg(sz->dev, "ls %u\n", rawir.duration);
sz_push(sz, rawir);
sz->idle = 0;
sz->idle = false;
sz->sum = 0;
}
sz->rawir.pulse = true;
sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
sz->sum += sz->rawir.duration;
sz->rawir.duration *= 1000;
sz->rawir.duration &= IR_MAX_DURATION;
dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
sz_push(sz);
rawir.pulse = true;
rawir.duration = ((int) value) * SZ_RESOLUTION;
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
dev_dbg(sz->dev, "p %u\n", rawir.duration);
sz_push(sz, rawir);
}
static void sz_push_half_pulse(struct streamzap_ir *sz,
unsigned char value)
{
sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4);
}
static void sz_push_full_space(struct streamzap_ir *sz,
unsigned char value)
{
sz->rawir.pulse = false;
sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
sz->sum += sz->rawir.duration;
sz->rawir.duration *= 1000;
dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
sz_push(sz);
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
rawir.duration = ((int) value) * SZ_RESOLUTION;
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
dev_dbg(sz->dev, "s %u\n", rawir.duration);
sz_push(sz, rawir);
}
static void sz_push_half_space(struct streamzap_ir *sz,
unsigned long value)
{
sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
sz_push_full_space(sz, value & SZ_SPACE_MASK);
}
/**
@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz;
unsigned int i;
int len;
#if 0
static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
IR_MAX_DURATION) | 0x03000000);
#endif
if (!urb)
return;
@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb)
}
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
if (!sz->flush) {
for (i = 0; i < urb->actual_length; i++) {
dev_dbg(sz->dev, "%d: %x\n", i,
(unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) {
case PulseSpace:
if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
STREAMZAP_PULSE_MASK) {
sz->decoder_state = FullPulse;
continue;
} else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
== STREAMZAP_SPACE_MASK) {
sz_push_half_pulse(sz, sz->buf_in[i]);
sz->decoder_state = FullSpace;
continue;
} else {
sz_push_half_pulse(sz, sz->buf_in[i]);
sz_push_half_space(sz, sz->buf_in[i]);
}
break;
case FullPulse:
sz_push_full_pulse(sz, sz->buf_in[i]);
sz->decoder_state = IgnorePulse;
break;
case FullSpace:
if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
sz->idle = 1;
streamzap_stop_timer(sz);
#if 0
if (sz->timeout_enabled) {
sz->rawir.pulse = false;
sz->rawir.duration = timeout;
sz->rawir.duration *= 1000;
sz_push(sz);
}
#endif
streamzap_flush_delay_buffer(sz);
} else
sz_push_full_space(sz, sz->buf_in[i]);
sz->decoder_state = PulseSpace;
break;
case IgnorePulse:
if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
STREAMZAP_SPACE_MASK) {
sz->decoder_state = FullSpace;
continue;
}
for (i = 0; i < len; i++) {
dev_dbg(sz->dev, "sz idx %d: %x\n",
i, (unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) {
case PulseSpace:
if ((sz->buf_in[i] & SZ_PULSE_MASK) ==
SZ_PULSE_MASK) {
sz->decoder_state = FullPulse;
continue;
} else if ((sz->buf_in[i] & SZ_SPACE_MASK)
== SZ_SPACE_MASK) {
sz_push_half_pulse(sz, sz->buf_in[i]);
sz->decoder_state = FullSpace;
continue;
} else {
sz_push_half_pulse(sz, sz->buf_in[i]);
sz_push_half_space(sz, sz->buf_in[i]);
sz->decoder_state = PulseSpace;
break;
}
break;
case FullPulse:
sz_push_full_pulse(sz, sz->buf_in[i]);
sz->decoder_state = IgnorePulse;
break;
case FullSpace:
if (sz->buf_in[i] == SZ_TIMEOUT) {
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
rawir.duration = timeout;
sz->idle = true;
if (sz->timeout_enabled)
sz_push(sz, rawir);
ir_raw_event_handle(sz->idev);
} else {
sz_push_full_space(sz, sz->buf_in[i]);
}
sz->decoder_state = PulseSpace;
break;
case IgnorePulse:
if ((sz->buf_in[i] & SZ_SPACE_MASK) ==
SZ_SPACE_MASK) {
sz->decoder_state = FullSpace;
continue;
}
sz_push_half_space(sz, sz->buf_in[i]);
sz->decoder_state = PulseSpace;
break;
}
}
@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
props->priv = sz;
props->driver_type = RC_DRIVER_IR_RAW;
/* FIXME: not sure about supported protocols, check on this */
props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
props->allowed_protos = IR_TYPE_ALL;
sz->props = props;
ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
goto irdev_failed;
@ -467,29 +351,6 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
return NULL;
}
static int streamzap_delay_buf_init(struct streamzap_ir *sz)
{
int ret;
ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
GFP_KERNEL);
if (ret == 0)
sz->fifo_initialized = 1;
return ret;
}
static void streamzap_start_flush_timer(struct streamzap_ir *sz)
{
sz->flush_timer.expires = jiffies + HZ;
sz->flush = true;
add_timer(&sz->flush_timer);
sz->urb_in->dev = sz->usbdev;
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
dev_err(sz->dev, "urb submit failed\n");
}
/**
* streamzap_probe
*
@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
retval = streamzap_delay_buf_init(sz);
if (retval) {
dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
goto free_urb_in;
}
sz->idev = streamzap_init_input_dev(sz);
if (!sz->idev)
goto input_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
sz->timeout_enabled = false;
sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
#endif
init_timer(&sz->delay_timer);
sz->delay_timer.function = streamzap_delay_timeout;
sz->delay_timer.data = (unsigned long)sz;
spin_lock_init(&sz->timer_lock);
init_timer(&sz->flush_timer);
sz->flush_timer.function = streamzap_flush_timeout;
sz->flush_timer.data = (unsigned long)sz;
do_gettimeofday(&sz->signal_start);
/* Complete final initialisations */
@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
usb_set_intfdata(intf, sz);
streamzap_start_flush_timer(sz);
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
dev_err(sz->dev, "urb submit failed\n");
dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
usbdev->bus->busnum, usbdev->devnum);
/* Load the streamzap not-quite-rc5 decoder too */
load_rc5_sz_decode();
return 0;
input_dev_fail:
kfifo_free(&sz->fifo);
free_urb_in:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
if (!sz)
return;
if (sz->flush) {
sz->flush = false;
del_timer_sync(&sz->flush_timer);
}
streamzap_stop_timer(sz);
sz->usbdev = NULL;
ir_input_unregister(sz->idev);
usb_kill_urb(sz->urb_in);
@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
if (sz->flush) {
sz->flush = false;
del_timer_sync(&sz->flush_timer);
}
streamzap_stop_timer(sz);
usb_kill_urb(sz->urb_in);
return 0;
@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf)
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
if (sz->fifo_initialized)
kfifo_reset(&sz->fifo);
sz->flush_timer.expires = jiffies + HZ;
sz->flush = true;
add_timer(&sz->flush_timer);
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
dev_err(sz->dev, "Error sumbiting urb\n");
return -EIO;

View File

@ -56,7 +56,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
videobuf_waiton(q, &buf->vb, 0, 0);
videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
buf->vb.state = VIDEOBUF_NEEDS_INIT;

View File

@ -414,7 +414,6 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
i2c_adapter->dev.parent = &dev->pci->dev;
i2c_adapter->algo = &saa7146_algo;
i2c_adapter->algo_data = NULL;
i2c_adapter->id = I2C_HW_SAA7146;
i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
i2c_adapter->retries = SAA7146_I2C_RETRIES;
}

View File

@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
sizeof(struct saa7146_buf),
file);
file, NULL);
init_timer(&fh->vbi_read_timeout);
fh->vbi_read_timeout.function = vbi_read_timeout;

View File

@ -1386,7 +1386,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct saa7146_buf),
file);
file, NULL);
return 0;
}

View File

@ -179,4 +179,11 @@ config MEDIA_TUNER_MAX2165
help
A driver for the silicon tuner MAX2165 from Maxim.
config MEDIA_TUNER_TDA18218
tristate "NXP TDA18218 silicon tuner"
depends on VIDEO_MEDIA && I2C
default m if MEDIA_TUNER_CUSTOMISE
help
NXP TDA18218 silicon tuner driver.
endif # MEDIA_TUNER_CUSTOMISE

View File

@ -24,6 +24,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends

View File

@ -0,0 +1,334 @@
/*
* NXP TDA18218HN silicon tuner driver
*
* Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "tda18218.h"
#include "tda18218_priv.h"
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
/* write multiple registers */
static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
{
int ret;
u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
struct i2c_msg msg[1] = {
{
.addr = priv->cfg->i2c_address,
.flags = 0,
.buf = buf,
}
};
msg_len_max = priv->cfg->i2c_wr_max - 1;
quotient = len / msg_len_max;
remainder = len % msg_len_max;
msg_len = msg_len_max;
for (i = 0; (i <= quotient && remainder); i++) {
if (i == quotient) /* set len of the last msg */
msg_len = remainder;
msg[0].len = msg_len + 1;
buf[0] = reg + i * msg_len_max;
memcpy(&buf[1], &val[i * msg_len_max], msg_len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret != 1)
break;
}
if (ret == 1) {
ret = 0;
} else {
warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/* read multiple registers */
static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
{
int ret;
u8 buf[reg+len]; /* we must start read always from reg 0x00 */
struct i2c_msg msg[2] = {
{
.addr = priv->cfg->i2c_address,
.flags = 0,
.len = 1,
.buf = "\x00",
}, {
.addr = priv->cfg->i2c_address,
.flags = I2C_M_RD,
.len = sizeof(buf),
.buf = buf,
}
};
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret == 2) {
memcpy(val, &buf[reg], len);
ret = 0;
} else {
warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/* write single register */
static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
{
return tda18218_wr_regs(priv, reg, &val, 1);
}
/* read single register */
static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
{
return tda18218_rd_regs(priv, reg, val, 1);
}
static int tda18218_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda18218_priv *priv = fe->tuner_priv;
int ret;
u8 buf[3], i, BP_Filter, LP_Fc;
u32 LO_Frac;
/* TODO: find out correct AGC algorithm */
u8 agc[][2] = {
{ R20_AGC11, 0x60 },
{ R23_AGC21, 0x02 },
{ R20_AGC11, 0xa0 },
{ R23_AGC21, 0x09 },
{ R20_AGC11, 0xe0 },
{ R23_AGC21, 0x0c },
{ R20_AGC11, 0x40 },
{ R23_AGC21, 0x01 },
{ R20_AGC11, 0x80 },
{ R23_AGC21, 0x08 },
{ R20_AGC11, 0xc0 },
{ R23_AGC21, 0x0b },
{ R24_AGC22, 0x1c },
{ R24_AGC22, 0x0c },
};
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
/* low-pass filter cut-off frequency */
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
LP_Fc = 0;
LO_Frac = params->frequency + 4000000;
break;
case BANDWIDTH_7_MHZ:
LP_Fc = 1;
LO_Frac = params->frequency + 3500000;
break;
case BANDWIDTH_8_MHZ:
default:
LP_Fc = 2;
LO_Frac = params->frequency + 4000000;
break;
}
/* band-pass filter */
if (LO_Frac < 188000000)
BP_Filter = 3;
else if (LO_Frac < 253000000)
BP_Filter = 4;
else if (LO_Frac < 343000000)
BP_Filter = 5;
else
BP_Filter = 6;
buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
buf[2] = priv->regs[R1C_AGC2B];
ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
if (ret)
goto error;
buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
buf[2] = (LO_Frac / 1000) << 4 |
(priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
if (ret)
goto error;
buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
if (ret)
goto error;
buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
if (ret)
goto error;
/* trigger AGC */
for (i = 0; i < ARRAY_SIZE(agc); i++) {
ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
if (ret)
goto error;
}
error:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
dbg("%s: failed ret:%d", __func__, ret);
return ret;
}
static int tda18218_sleep(struct dvb_frontend *fe)
{
struct tda18218_priv *priv = fe->tuner_priv;
int ret;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
/* standby */
ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
dbg("%s: failed ret:%d", __func__, ret);
return ret;
}
static int tda18218_init(struct dvb_frontend *fe)
{
struct tda18218_priv *priv = fe->tuner_priv;
int ret;
/* TODO: calibrations */
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
dbg("%s: failed ret:%d", __func__, ret);
return ret;
}
static int tda18218_release(struct dvb_frontend *fe)
{
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static const struct dvb_tuner_ops tda18218_tuner_ops = {
.info = {
.name = "NXP TDA18218",
.frequency_min = 174000000,
.frequency_max = 864000000,
.frequency_step = 1000,
},
.release = tda18218_release,
.init = tda18218_init,
.sleep = tda18218_sleep,
.set_params = tda18218_set_params,
};
struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18218_config *cfg)
{
struct tda18218_priv *priv = NULL;
u8 val;
int ret;
/* chip default registers values */
static u8 def_regs[] = {
0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
};
priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->cfg = cfg;
priv->i2c = i2c;
fe->tuner_priv = priv;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
/* check if the tuner is there */
ret = tda18218_rd_reg(priv, R00_ID, &val);
dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
if (ret || val != def_regs[R00_ID]) {
kfree(priv);
return NULL;
}
info("NXP TDA18218HN successfully identified.");
memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
sizeof(struct dvb_tuner_ops));
memcpy(priv->regs, def_regs, sizeof(def_regs));
/* loop-through enabled chip default register values */
if (priv->cfg->loop_through) {
priv->regs[R17_PD1] = 0xb0;
priv->regs[R18_PD2] = 0x59;
}
/* standby */
ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
if (ret)
dbg("%s: failed ret:%d", __func__, ret);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
return fe;
}
EXPORT_SYMBOL(tda18218_attach);
MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,45 @@
/*
* NXP TDA18218HN silicon tuner driver
*
* Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TDA18218_H
#define TDA18218_H
#include "dvb_frontend.h"
struct tda18218_config {
u8 i2c_address;
u8 i2c_wr_max;
u8 loop_through:1;
};
#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
(defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18218_config *cfg);
#else
static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18218_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View File

@ -0,0 +1,106 @@
/*
* NXP TDA18218HN silicon tuner driver
*
* Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TDA18218_PRIV_H
#define TDA18218_PRIV_H
#define LOG_PREFIX "tda18218"
#undef dbg
#define dbg(f, arg...) \
if (debug) \
printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg)
#undef err
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
#undef info
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
#undef warn
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
#define R00_ID 0x00 /* ID byte */
#define R01_R1 0x01 /* Read byte 1 */
#define R02_R2 0x02 /* Read byte 2 */
#define R03_R3 0x03 /* Read byte 3 */
#define R04_R4 0x04 /* Read byte 4 */
#define R05_R5 0x05 /* Read byte 5 */
#define R06_R6 0x06 /* Read byte 6 */
#define R07_MD1 0x07 /* Main divider byte 1 */
#define R08_PSM1 0x08 /* PSM byte 1 */
#define R09_MD2 0x09 /* Main divider byte 2 */
#define R0A_MD3 0x0a /* Main divider byte 1 */
#define R0B_MD4 0x0b /* Main divider byte 4 */
#define R0C_MD5 0x0c /* Main divider byte 5 */
#define R0D_MD6 0x0d /* Main divider byte 6 */
#define R0E_MD7 0x0e /* Main divider byte 7 */
#define R0F_MD8 0x0f /* Main divider byte 8 */
#define R10_CD1 0x10 /* Call divider byte 1 */
#define R11_CD2 0x11 /* Call divider byte 2 */
#define R12_CD3 0x12 /* Call divider byte 3 */
#define R13_CD4 0x13 /* Call divider byte 4 */
#define R14_CD5 0x14 /* Call divider byte 5 */
#define R15_CD6 0x15 /* Call divider byte 6 */
#define R16_CD7 0x16 /* Call divider byte 7 */
#define R17_PD1 0x17 /* Power-down byte 1 */
#define R18_PD2 0x18 /* Power-down byte 2 */
#define R19_XTOUT 0x19 /* XTOUT byte */
#define R1A_IF1 0x1a /* IF byte 1 */
#define R1B_IF2 0x1b /* IF byte 2 */
#define R1C_AGC2B 0x1c /* AGC2b byte */
#define R1D_PSM2 0x1d /* PSM byte 2 */
#define R1E_PSM3 0x1e /* PSM byte 3 */
#define R1F_PSM4 0x1f /* PSM byte 4 */
#define R20_AGC11 0x20 /* AGC1 byte 1 */
#define R21_AGC12 0x21 /* AGC1 byte 2 */
#define R22_AGC13 0x22 /* AGC1 byte 3 */
#define R23_AGC21 0x23 /* AGC2 byte 1 */
#define R24_AGC22 0x24 /* AGC2 byte 2 */
#define R25_AAGC 0x25 /* Analog AGC byte */
#define R26_RC 0x26 /* RC byte */
#define R27_RSSI 0x27 /* RSSI byte */
#define R28_IRCAL1 0x28 /* IR CAL byte 1 */
#define R29_IRCAL2 0x29 /* IR CAL byte 2 */
#define R2A_IRCAL3 0x2a /* IR CAL byte 3 */
#define R2B_IRCAL4 0x2b /* IR CAL byte 4 */
#define R2C_RFCAL1 0x2c /* RF CAL byte 1 */
#define R2D_RFCAL2 0x2d /* RF CAL byte 2 */
#define R2E_RFCAL3 0x2e /* RF CAL byte 3 */
#define R2F_RFCAL4 0x2f /* RF CAL byte 4 */
#define R30_RFCAL5 0x30 /* RF CAL byte 5 */
#define R31_RFCAL6 0x31 /* RF CAL byte 6 */
#define R32_RFCAL7 0x32 /* RF CAL byte 7 */
#define R33_RFCAL8 0x33 /* RF CAL byte 8 */
#define R34_RFCAL9 0x34 /* RF CAL byte 9 */
#define R35_RFCAL10 0x35 /* RF CAL byte 10 */
#define R36_RFCALRAM1 0x36 /* RF CAL RAM byte 1 */
#define R37_RFCALRAM2 0x37 /* RF CAL RAM byte 2 */
#define R38_MARGIN 0x38 /* Margin byte */
#define R39_FMAX1 0x39 /* Fmax byte 1 */
#define R3A_FMAX2 0x3a /* Fmax byte 2 */
#define TDA18218_NUM_REGS 59
struct tda18218_priv {
struct tda18218_config *cfg;
struct i2c_adapter *i2c;
u8 regs[TDA18218_NUM_REGS];
};
#endif

View File

@ -193,25 +193,51 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
unsigned char *regs = priv->tda18271_regs;
unsigned char buf[TDA18271_NUM_REGS + 1];
struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
.buf = buf, .len = len + 1 };
int i, ret;
.buf = buf };
int i, ret = 1, max;
BUG_ON((len == 0) || (idx + len > sizeof(buf)));
buf[0] = idx;
for (i = 1; i <= len; i++)
buf[i] = regs[idx - 1 + i];
switch (priv->small_i2c) {
case TDA18271_03_BYTE_CHUNK_INIT:
max = 3;
break;
case TDA18271_08_BYTE_CHUNK_INIT:
max = 8;
break;
case TDA18271_16_BYTE_CHUNK_INIT:
max = 16;
break;
case TDA18271_39_BYTE_CHUNK_INIT:
default:
max = 39;
}
tda18271_i2c_gate_ctrl(fe, 1);
while (len) {
if (max > len)
max = len;
/* write registers */
ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
buf[0] = idx;
for (i = 1; i <= max; i++)
buf[i] = regs[idx - 1 + i];
msg.len = max + 1;
/* write registers */
ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
if (ret != 1)
break;
idx += max;
len -= max;
}
tda18271_i2c_gate_ctrl(fe, 0);
if (ret != 1)
tda_err("ERROR: idx = 0x%x, len = %d, "
"i2c_transfer returned: %d\n", idx, len, ret);
"i2c_transfer returned: %d\n", idx, max, ret);
return (ret == 1 ? 0 : ret);
}
@ -326,24 +352,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_EB22] = 0x48;
regs[R_EB23] = 0xb0;
switch (priv->small_i2c) {
case TDA18271_08_BYTE_CHUNK_INIT:
tda18271_write_regs(fe, 0x00, 0x08);
tda18271_write_regs(fe, 0x08, 0x08);
tda18271_write_regs(fe, 0x10, 0x08);
tda18271_write_regs(fe, 0x18, 0x08);
tda18271_write_regs(fe, 0x20, 0x07);
break;
case TDA18271_16_BYTE_CHUNK_INIT:
tda18271_write_regs(fe, 0x00, 0x10);
tda18271_write_regs(fe, 0x10, 0x10);
tda18271_write_regs(fe, 0x20, 0x07);
break;
case TDA18271_39_BYTE_CHUNK_INIT:
default:
tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
break;
}
tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
/* setup agc1 gain */
regs[R_EB17] = 0x00;

View File

@ -1156,7 +1156,6 @@ static int tda18271_get_id(struct dvb_frontend *fe)
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
char *name;
int ret = 0;
mutex_lock(&priv->lock);
tda18271_read_regs(fe);
@ -1172,17 +1171,16 @@ static int tda18271_get_id(struct dvb_frontend *fe)
priv->id = TDA18271HDC2;
break;
default:
name = "Unknown device";
ret = -EINVAL;
break;
tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",
regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),
priv->i2c_props.addr);
return -EINVAL;
}
tda_info("%s detected @ %d-%04x%s\n", name,
i2c_adapter_id(priv->i2c_props.adap),
priv->i2c_props.addr,
(0 == ret) ? "" : ", device not supported.");
tda_info("%s detected @ %d-%04x\n", name,
i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);
return ret;
return 0;
}
static int tda18271_setup_configuration(struct dvb_frontend *fe,

View File

@ -80,8 +80,9 @@ enum tda18271_output_options {
enum tda18271_small_i2c {
TDA18271_39_BYTE_CHUNK_INIT = 0,
TDA18271_16_BYTE_CHUNK_INIT = 1,
TDA18271_08_BYTE_CHUNK_INIT = 2,
TDA18271_16_BYTE_CHUNK_INIT = 16,
TDA18271_08_BYTE_CHUNK_INIT = 8,
TDA18271_03_BYTE_CHUNK_INIT = 3,
};
struct tda18271_config {

View File

@ -1042,7 +1042,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg)
const struct xc5000_config *cfg)
{
struct xc5000_priv *priv = NULL;
int instance;

View File

@ -53,11 +53,11 @@ struct xc5000_config {
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg);
const struct xc5000_config *cfg);
#else
static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg)
const struct xc5000_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;

View File

@ -245,9 +245,6 @@ int flexcop_i2c_init(struct flexcop_device *fc)
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
fc->fc_i2c_adap[0].i2c_adap.class =
fc->fc_i2c_adap[1].i2c_adap.class =
fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL;
fc->fc_i2c_adap[0].i2c_adap.algo =
fc->fc_i2c_adap[1].i2c_adap.algo =
fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;

View File

@ -862,7 +862,6 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
i2c_set_adapdata(&dev->i2c_adap, dev);
strcpy(dev->i2c_adap.name, DRIVER_NAME);
dev->i2c_adap.owner = THIS_MODULE;
dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
dev->i2c_adap.dev.parent = &pdev->dev;
dev->i2c_adap.algo = &dm1105_algo;
dev->i2c_adap.algo_data = dev;

View File

@ -702,7 +702,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
kthread_stop(fepriv->thread);
init_MUTEX (&fepriv->sem);
sema_init(&fepriv->sem, 1);
fepriv->state = FESTATE_IDLE;
/* paranoia check in case a signal arrived */
@ -2062,7 +2062,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
}
fepriv = fe->frontend_priv;
init_MUTEX (&fepriv->sem);
sema_init(&fepriv->sem, 1);
init_waitqueue_head (&fepriv->wait_queue);
init_waitqueue_head (&fepriv->events.wait_queue);
mutex_init(&fepriv->events.mtx);

View File

@ -260,7 +260,7 @@ struct dvb_frontend_ops {
int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe);
int (*write)(struct dvb_frontend* fe, u8* buf, int len);
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
/* if this is set, it overrides the default swzigzag */
int (*tune)(struct dvb_frontend* fe,

View File

@ -314,6 +314,8 @@ config DVB_USB_AF9015
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
@ -346,3 +348,13 @@ config DVB_USB_AZ6027
select DVB_STB6100 if !DVB_FE_CUSTOMISE
help
Say Y here to support the AZ6027 device
config DVB_USB_LME2510
tristate "LME DM04/QQBOX DVB-S USB2.0 support"
depends on DVB_USB
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
select DVB_IX2505V if !DVB_FE_CUSTOMISE
help
Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .

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