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

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

Pull media updates from Mauro Carvalho Chehab:
 - removal of sn9c102.  This device driver was replaced a long time ago
   by gspca
 - solo6x10 and go7007 webcam drivers moved from staging into
   mainstream.  They were waiting for an API to allow setting the image
   detection matrix
 - SDR drivers moved from staging into mainstream: sdr-msi3101 (renamed
   as msi2500) and rtl2832
 - added SDR driver for airspy
 - added demux driver: si2165
 - rework at several RC subsystem, making the code for RC-5 SZ variant
   to be added at the standard RC5 decoder
 - added decoder for the XMP IR protocol
 - tuner driver moved from staging into mainstream: msi3101 (renamed as
   msi001)
 - added documentation for some additional SDR pixfmt
 - some device tree bindings documented
 - added support for exynos3250 at s5p-jpeg
 - remove the obsolete, unmaintained and broken mx1_camera driver
 - added support for remote controllers at au0828 driver
 - added a RC driver: sunxi-cir
 - several driver fixes, enhancements and cleanups.

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (455 commits)
  [media] cx23885: fix UNSET/TUNER_ABSENT confusion
  [media] coda: fix build error by making reset control optional
  [media] radio-miropcm20: fix sparse NULL pointer warning
  [media] MAINTAINERS: Update go7007 pattern
  [media] MAINTAINERS: Update solo6x10 patterns
  [media] media: atmel-isi: add primary DT support
  [media] media: atmel-isi: convert the pdata from pointer to structure
  [media] media: atmel-isi: add v4l2 async probe support
  [media] rcar_vin: add devicetree support
  [media] media: pxa_camera device-tree support
  [media] media: mt9m111: add device-tree suppport
  [media] soc_camera: add support for dt binding soc_camera drivers
  [media] media: soc_camera: pxa_camera documentation device-tree support
  [media] media: mt9m111: add device-tree documentation
  [media] s5p-mfc: remove unnecessary calling to function video_devdata()
  [media] s5p-jpeg: add chroma subsampling adjustment for Exynos3250
  [media] s5p-jpeg: Prevent erroneous downscaling for Exynos3250 SoC
  [media] s5p-jpeg: Assure proper crop rectangle initialization
  [media] s5p-jpeg: fix g_selection op
  [media] s5p-jpeg: Adjust jpeg_bound_align_image to Exynos3250 needs
  ...
...@@ -174,7 +174,7 @@ FILENAME = \ ...@@ -174,7 +174,7 @@ FILENAME = \
DOCUMENTED = \ DOCUMENTED = \
-e "s/\(enum *\)v4l2_mpeg_cx2341x_video_\([a-z]*_spatial_filter_type\)/\1<link linkend=\"\2\">v4l2_mpeg_cx2341x_video_\2<\/link>/g" \ -e "s/\(enum *\)v4l2_mpeg_cx2341x_video_\([a-z]*_spatial_filter_type\)/\1<link linkend=\"\2\">v4l2_mpeg_cx2341x_video_\2<\/link>/g" \
-e "s/\(\(enum\|struct\) *\)\(v4l2_[a-zA-Z0-9_]*\)/\1<link linkend=\"\3\">\3<\/link>/g" \ -e "s/\(\(enum\|struct\) *\)\(v4l2_[a-zA-Z0-9_]*\)/\1<link linkend=\"\3\">\3<\/link>/g" \
-e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\) /<link linkend=\"\1\">\1<\/link> /g" \ -e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\)\(\s\+v4l2_fourcc\)/<link linkend=\"\1\">\1<\/link>\2/g" \
-e ":a;s/\(linkend=\".*\)_\(.*\">\)/\1-\2/;ta" \ -e ":a;s/\(linkend=\".*\)_\(.*\">\)/\1-\2/;ta" \
-e "s/v4l2\-mpeg\-vbi\-ITV0/v4l2-mpeg-vbi-itv0-1/g" -e "s/v4l2\-mpeg\-vbi\-ITV0/v4l2-mpeg-vbi-itv0-1/g"
......
...@@ -555,10 +555,46 @@ typedef enum fe_delivery_system { ...@@ -555,10 +555,46 @@ typedef enum fe_delivery_system {
</section> </section>
<section id="DTV-ISDBT-LAYER-TIME-INTERLEAVING"> <section id="DTV-ISDBT-LAYER-TIME-INTERLEAVING">
<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title> <title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para> <para>Valid values: 0, 1, 2, 4, -1 (AUTO)</para>
<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values <para>when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid.</para>
here are referring to what can be found in the TMCC-structure - <para>Note: The real time interleaving length depends on the mode (fft-size). The values
independent of the mode.</para> here are referring to what can be found in the TMCC-structure, as shown in the table below.</para>
<informaltable id="isdbt-layer-interleaving-table">
<tgroup cols="4" align="center">
<tbody>
<row>
<entry>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</entry>
<entry>Mode 1 (2K FFT)</entry>
<entry>Mode 2 (4K FFT)</entry>
<entry>Mode 3 (8K FFT)</entry>
</row>
<row>
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
</row>
<row>
<entry>1</entry>
<entry>4</entry>
<entry>2</entry>
<entry>1</entry>
</row>
<row>
<entry>2</entry>
<entry>8</entry>
<entry>4</entry>
<entry>2</entry>
</row>
<row>
<entry>4</entry>
<entry>16</entry>
<entry>8</entry>
<entry>4</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section> </section>
<section id="DTV-ATSCMH-FIC-VER"> <section id="DTV-ATSCMH-FIC-VER">
<title><constant>DTV_ATSCMH_FIC_VER</constant></title> <title><constant>DTV_ATSCMH_FIC_VER</constant></title>
......
...@@ -150,9 +150,15 @@ signal. Drivers shall not convert the sample format by software.</para></entry> ...@@ -150,9 +150,15 @@ signal. Drivers shall not convert the sample format by software.</para></entry>
<entry>This is the scanning system line number <entry>This is the scanning system line number
associated with the first line of the VBI image, of the first and the associated with the first line of the VBI image, of the first and the
second field respectively. See <xref linkend="vbi-525" /> and second field respectively. See <xref linkend="vbi-525" /> and
<xref linkend="vbi-625" /> for valid values. VBI input drivers can <xref linkend="vbi-625" /> for valid values.
return start values 0 if the hardware cannot reliable identify The <constant>V4L2_VBI_ITU_525_F1_START</constant>,
scanning lines, VBI acquisition may not require this <constant>V4L2_VBI_ITU_525_F2_START</constant>,
<constant>V4L2_VBI_ITU_625_F1_START</constant> and
<constant>V4L2_VBI_ITU_625_F2_START</constant> defines give the start line
numbers for each field for each 525 or 625 line format as a convenience.
Don't forget that ITU line numbering starts at 1, not 0.
VBI input drivers can return start values 0 if the hardware cannot
reliable identify scanning lines, VBI acquisition may not require this
information.</entry> information.</entry>
</row> </row>
<row> <row>
......
...@@ -72,9 +72,12 @@ To use the <link linkend="format">format</link> ioctls applications set the ...@@ -72,9 +72,12 @@ To use the <link linkend="format">format</link> ioctls applications set the
<constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant> and use the &v4l2-sdr-format; <constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant> and use the &v4l2-sdr-format;
<structfield>sdr</structfield> member of the <structfield>fmt</structfield> <structfield>sdr</structfield> member of the <structfield>fmt</structfield>
union as needed per the desired operation. union as needed per the desired operation.
Currently only the <structfield>pixelformat</structfield> field of Currently there is two fields, <structfield>pixelformat</structfield> and
&v4l2-sdr-format; is used. The content of that field is the V4L2 fourcc code <structfield>buffersize</structfield>, of struct &v4l2-sdr-format; which are
of the data format. used. Content of the <structfield>pixelformat</structfield> is V4L2 FourCC
code of the data format. The <structfield>buffersize</structfield> field is
maximum buffer size in bytes required for data transfer, set by the driver in
order to inform application.
</para> </para>
<table pgwide="1" frame="none" id="v4l2-sdr-format"> <table pgwide="1" frame="none" id="v4l2-sdr-format">
...@@ -91,9 +94,16 @@ little endian <link linkend="v4l2-fourcc">four character code</link>. ...@@ -91,9 +94,16 @@ little endian <link linkend="v4l2-fourcc">four character code</link>.
V4L2 defines SDR formats in <xref linkend="sdr-formats" />. V4L2 defines SDR formats in <xref linkend="sdr-formats" />.
</entry> </entry>
</row> </row>
<row>
<entry>__u32</entry>
<entry><structfield>buffersize</structfield></entry>
<entry>
Maximum size in bytes required for data. Value is set by the driver.
</entry>
</row>
<row> <row>
<entry>__u8</entry> <entry>__u8</entry>
<entry><structfield>reserved[28]</structfield></entry> <entry><structfield>reserved[24]</structfield></entry>
<entry>This array is reserved for future extensions. <entry>This array is reserved for future extensions.
Drivers and applications must set it to zero.</entry> Drivers and applications must set it to zero.</entry>
</row> </row>
......
...@@ -185,7 +185,14 @@ tables, sigh. --></para></entry> ...@@ -185,7 +185,14 @@ tables, sigh. --></para></entry>
<entry></entry> <entry></entry>
<entry spanname="hspan">Drivers must set <entry spanname="hspan">Drivers must set
<structfield>service_lines</structfield>[0][0] and <structfield>service_lines</structfield>[0][0] and
<structfield>service_lines</structfield>[1][0] to zero.</entry> <structfield>service_lines</structfield>[1][0] to zero.
The <constant>V4L2_VBI_ITU_525_F1_START</constant>,
<constant>V4L2_VBI_ITU_525_F2_START</constant>,
<constant>V4L2_VBI_ITU_625_F1_START</constant> and
<constant>V4L2_VBI_ITU_625_F2_START</constant> defines give the start
line numbers for each field for each 525 or 625 line format as a
convenience. Don't forget that ITU line numbering starts at 1, not 0.
</entry>
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
......
...@@ -870,7 +870,8 @@ should set this to 0.</entry> ...@@ -870,7 +870,8 @@ should set this to 0.</entry>
If the application sets this to 0 for an output stream, then If the application sets this to 0 for an output stream, then
<structfield>bytesused</structfield> will be set to the size of the <structfield>bytesused</structfield> will be set to the size of the
plane (see the <structfield>length</structfield> field of this struct) plane (see the <structfield>length</structfield> field of this struct)
by the driver.</entry> by the driver. Note that the actual image data starts at
<structfield>data_offset</structfield> which may not be 0.</entry>
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
...@@ -919,6 +920,10 @@ should set this to 0.</entry> ...@@ -919,6 +920,10 @@ should set this to 0.</entry>
<entry>Offset in bytes to video data in the plane. <entry>Offset in bytes to video data in the plane.
Drivers must set this field when <structfield>type</structfield> Drivers must set this field when <structfield>type</structfield>
refers to an input stream, applications when it refers to an output stream. refers to an input stream, applications when it refers to an output stream.
Note that data_offset is included in <structfield>bytesused</structfield>.
So the size of the image in the plane is
<structfield>bytesused</structfield>-<structfield>data_offset</structfield> at
offset <structfield>data_offset</structfield> from the start of the plane.
</entry> </entry>
</row> </row>
<row> <row>
...@@ -1066,7 +1071,7 @@ state, in the application domain so to say.</entry> ...@@ -1066,7 +1071,7 @@ state, in the application domain so to say.</entry>
<entry>Drivers set or clear this flag when calling the <entry>Drivers set or clear this flag when calling the
<constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video <constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
capture devices when the buffer contains a compressed image which is a capture devices when the buffer contains a compressed image which is a
key frame (or field), &ie; can be decompressed on its own. Also know as key frame (or field), &ie; can be decompressed on its own. Also known as
an I-frame. Applications can set this bit when <structfield>type</structfield> an I-frame. Applications can set this bit when <structfield>type</structfield>
refers to an output stream.</entry> refers to an output stream.</entry>
</row> </row>
......
...@@ -15,9 +15,6 @@ typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits ...@@ -15,9 +15,6 @@ typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits
per pixel. These are all packed-pixel formats, meaning all the data per pixel. These are all packed-pixel formats, meaning all the data
for a pixel lie next to each other in memory.</para> for a pixel lie next to each other in memory.</para>
<para>When one of these formats is used, drivers shall report the
colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<table pgwide="1" frame="none" id="rgb-formats"> <table pgwide="1" frame="none" id="rgb-formats">
<title>Packed RGB Image Formats</title> <title>Packed RGB Image Formats</title>
<tgroup cols="37" align="center"> <tgroup cols="37" align="center">
...@@ -130,9 +127,9 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -130,9 +127,9 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-RGB444"> <row id="V4L2-PIX-FMT-ARGB444">
<entry><constant>V4L2_PIX_FMT_RGB444</constant></entry> <entry><constant>V4L2_PIX_FMT_ARGB444</constant></entry>
<entry>'R444'</entry> <entry>'AR12'</entry>
<entry></entry> <entry></entry>
<entry>g<subscript>3</subscript></entry> <entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry> <entry>g<subscript>2</subscript></entry>
...@@ -152,9 +149,31 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -152,9 +149,31 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>r<subscript>1</subscript></entry> <entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry> <entry>r<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-RGB555"> <row id="V4L2-PIX-FMT-XRGB444">
<entry><constant>V4L2_PIX_FMT_RGB555</constant></entry> <entry><constant>V4L2_PIX_FMT_XRGB444</constant></entry>
<entry>'RGBO'</entry> <entry>'XR12'</entry>
<entry></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-ARGB555">
<entry><constant>V4L2_PIX_FMT_ARGB555</constant></entry>
<entry>'AR15'</entry>
<entry></entry> <entry></entry>
<entry>g<subscript>2</subscript></entry> <entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry> <entry>g<subscript>1</subscript></entry>
...@@ -174,6 +193,28 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -174,6 +193,28 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>g<subscript>4</subscript></entry> <entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry> <entry>g<subscript>3</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-XRGB555">
<entry><constant>V4L2_PIX_FMT_XRGB555</constant></entry>
<entry>'XR15'</entry>
<entry></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>-</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB565"> <row id="V4L2-PIX-FMT-RGB565">
<entry><constant>V4L2_PIX_FMT_RGB565</constant></entry> <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
<entry>'RGBP'</entry> <entry>'RGBP'</entry>
...@@ -341,9 +382,9 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -341,9 +382,9 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-BGR32"> <row id="V4L2-PIX-FMT-ABGR32">
<entry><constant>V4L2_PIX_FMT_BGR32</constant></entry> <entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry>
<entry>'BGR4'</entry> <entry>'AR24'</entry>
<entry></entry> <entry></entry>
<entry>b<subscript>7</subscript></entry> <entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry> <entry>b<subscript>6</subscript></entry>
...@@ -381,9 +422,49 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -381,9 +422,49 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>a<subscript>1</subscript></entry> <entry>a<subscript>1</subscript></entry>
<entry>a<subscript>0</subscript></entry> <entry>a<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-RGB32"> <row id="V4L2-PIX-FMT-XBGR32">
<entry><constant>V4L2_PIX_FMT_RGB32</constant></entry> <entry><constant>V4L2_PIX_FMT_XBGR32</constant></entry>
<entry>'RGB4'</entry> <entry>'XR24'</entry>
<entry></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
</row>
<row id="V4L2-PIX-FMT-ARGB32">
<entry><constant>V4L2_PIX_FMT_ARGB32</constant></entry>
<entry>'AX24'</entry>
<entry></entry> <entry></entry>
<entry>a<subscript>7</subscript></entry> <entry>a<subscript>7</subscript></entry>
<entry>a<subscript>6</subscript></entry> <entry>a<subscript>6</subscript></entry>
...@@ -421,18 +502,76 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para> ...@@ -421,18 +502,76 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-XRGB32">
<entry><constant>V4L2_PIX_FMT_XRGB32</constant></entry>
<entry>'BX24'</entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
<para>Bit 7 is the most significant bit. The value of the a = alpha <para>Bit 7 is the most significant bit.</para>
bits is undefined when reading from the driver, ignored when writing
to the driver, except when alpha blending has been negotiated for a <para>The usage and value of the alpha bits (a) in the ARGB and ABGR formats
<link linkend="overlay">Video Overlay</link> or <link linkend="osd"> (collectively referred to as alpha formats) depend on the device type and
Video Output Overlay</link> or when the alpha component has been configured hardware operation. <link linkend="capture">Capture</link> devices
for a <link linkend="capture">Video Capture</link> by means of <link (including capture queues of mem-to-mem devices) fill the alpha component in
linkend="v4l2-alpha-component"> <constant>V4L2_CID_ALPHA_COMPONENT memory. When the device outputs an alpha channel the alpha component will
</constant> </link> control.</para> have a meaningful value. Otherwise, when the device doesn't output an alpha
channel but can set the alpha bit to a user-configurable value, the <link
linkend="v4l2-alpha-component"><constant>V4L2_CID_ALPHA_COMPONENT</constant>
</link> control is used to specify that alpha value, and the alpha component
of all pixels will be set to the value specified by that control. Otherwise
a corresponding format without an alpha component (XRGB or XBGR) must be
used instead of an alpha format.</para>
<para><link linkend="output">Output</link> devices (including output queues
of mem-to-mem devices and <link linkend="osd">video output overlay</link>
devices) read the alpha component from memory. When the device processes the
alpha channel the alpha component must be filled with meaningful values by
applications. Otherwise a corresponding format without an alpha component
(XRGB or XBGR) must be used instead of an alpha format.</para>
<para>The XRGB and XBGR formats contain undefined bits (-). Applications,
devices and drivers must ignore those bits, for both <link
linkend="capture">capture</link> and <link linkend="output">output</link>
devices.</para>
<example> <example>
<title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel <title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
...@@ -512,6 +651,239 @@ image</title> ...@@ -512,6 +651,239 @@ image</title>
</formalpara> </formalpara>
</example> </example>
<para>Formats defined in <xref linkend="rgb-formats-deprecated"/> are
deprecated and must not be used by new drivers. They are documented here for
reference. The meaning of their alpha bits (a) is ill-defined and
interpreted as in either the corresponding ARGB or XRGB format, depending on
the driver.</para>
<table pgwide="1" frame="none" id="rgb-formats-deprecated">
<title>Deprecated Packed RGB Image Formats</title>
<tgroup cols="37" align="center">
<colspec colname="id" align="left" />
<colspec colname="fourcc" />
<colspec colname="bit" />
<colspec colnum="4" colname="b07" align="center" />
<colspec colnum="5" colname="b06" align="center" />
<colspec colnum="6" colname="b05" align="center" />
<colspec colnum="7" colname="b04" align="center" />
<colspec colnum="8" colname="b03" align="center" />
<colspec colnum="9" colname="b02" align="center" />
<colspec colnum="10" colname="b01" align="center" />
<colspec colnum="11" colname="b00" align="center" />
<colspec colnum="13" colname="b17" align="center" />
<colspec colnum="14" colname="b16" align="center" />
<colspec colnum="15" colname="b15" align="center" />
<colspec colnum="16" colname="b14" align="center" />
<colspec colnum="17" colname="b13" align="center" />
<colspec colnum="18" colname="b12" align="center" />
<colspec colnum="19" colname="b11" align="center" />
<colspec colnum="20" colname="b10" align="center" />
<colspec colnum="22" colname="b27" align="center" />
<colspec colnum="23" colname="b26" align="center" />
<colspec colnum="24" colname="b25" align="center" />
<colspec colnum="25" colname="b24" align="center" />
<colspec colnum="26" colname="b23" align="center" />
<colspec colnum="27" colname="b22" align="center" />
<colspec colnum="28" colname="b21" align="center" />
<colspec colnum="29" colname="b20" align="center" />
<colspec colnum="31" colname="b37" align="center" />
<colspec colnum="32" colname="b36" align="center" />
<colspec colnum="33" colname="b35" align="center" />
<colspec colnum="34" colname="b34" align="center" />
<colspec colnum="35" colname="b33" align="center" />
<colspec colnum="36" colname="b32" align="center" />
<colspec colnum="37" colname="b31" align="center" />
<colspec colnum="38" colname="b30" align="center" />
<spanspec namest="b07" nameend="b00" spanname="b0" />
<spanspec namest="b17" nameend="b10" spanname="b1" />
<spanspec namest="b27" nameend="b20" spanname="b2" />
<spanspec namest="b37" nameend="b30" spanname="b3" />
<thead>
<row>
<entry>Identifier</entry>
<entry>Code</entry>
<entry>&nbsp;</entry>
<entry spanname="b0">Byte&nbsp;0 in memory</entry>
<entry spanname="b1">Byte&nbsp;1</entry>
<entry spanname="b2">Byte&nbsp;2</entry>
<entry spanname="b3">Byte&nbsp;3</entry>
</row>
<row>
<entry>&nbsp;</entry>
<entry>&nbsp;</entry>
<entry>Bit</entry>
<entry>7</entry>
<entry>6</entry>
<entry>5</entry>
<entry>4</entry>
<entry>3</entry>
<entry>2</entry>
<entry>1</entry>
<entry>0</entry>
<entry>&nbsp;</entry>
<entry>7</entry>
<entry>6</entry>
<entry>5</entry>
<entry>4</entry>
<entry>3</entry>
<entry>2</entry>
<entry>1</entry>
<entry>0</entry>
<entry>&nbsp;</entry>
<entry>7</entry>
<entry>6</entry>
<entry>5</entry>
<entry>4</entry>
<entry>3</entry>
<entry>2</entry>
<entry>1</entry>
<entry>0</entry>
<entry>&nbsp;</entry>
<entry>7</entry>
<entry>6</entry>
<entry>5</entry>
<entry>4</entry>
<entry>3</entry>
<entry>2</entry>
<entry>1</entry>
<entry>0</entry>
</row>
</thead>
<tbody>
<row id="V4L2-PIX-FMT-RGB444">
<entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
<entry>'R444'</entry>
<entry></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>a<subscript>3</subscript></entry>
<entry>a<subscript>2</subscript></entry>
<entry>a<subscript>1</subscript></entry>
<entry>a<subscript>0</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB555">
<entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
<entry>'RGBO'</entry>
<entry></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>a</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-BGR32">
<entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
<entry>'BGR4'</entry>
<entry></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></entry>
<entry>a<subscript>7</subscript></entry>
<entry>a<subscript>6</subscript></entry>
<entry>a<subscript>5</subscript></entry>
<entry>a<subscript>4</subscript></entry>
<entry>a<subscript>3</subscript></entry>
<entry>a<subscript>2</subscript></entry>
<entry>a<subscript>1</subscript></entry>
<entry>a<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-RGB32">
<entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
<entry>'RGB4'</entry>
<entry></entry>
<entry>a<subscript>7</subscript></entry>
<entry>a<subscript>6</subscript></entry>
<entry>a<subscript>5</subscript></entry>
<entry>a<subscript>4</subscript></entry>
<entry>a<subscript>3</subscript></entry>
<entry>a<subscript>2</subscript></entry>
<entry>a<subscript>1</subscript></entry>
<entry>a<subscript>0</subscript></entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
</tbody>
</tgroup>
</table>
<para>A test utility to determine which RGB formats a driver <para>A test utility to determine which RGB formats a driver
actually supports is available from the LinuxTV v4l-dvb repository. actually supports is available from the LinuxTV v4l-dvb repository.
See &v4l-dvb; for access instructions.</para> See &v4l-dvb; for access instructions.</para>
......
<refentry id="V4L2-SDR-FMT-CS08">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_CS8 ('CS08')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_CS8</constant>
</refname>
<refpurpose>Complex signed 8-bit IQ sample</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This format contains sequence of complex number samples. Each complex number
consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
represented as a 8 bit signed number. I value comes first and Q value after
that.
</para>
<example>
<title><constant>V4L2_SDR_FMT_CS8</constant> 1 sample</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="2" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>I'<subscript>0</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;1:</entry>
<entry>Q'<subscript>0</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
<refentry id="V4L2-SDR-FMT-CS14LE">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_CS14LE ('CS14')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_CS14LE</constant>
</refname>
<refpurpose>Complex signed 14-bit little endian IQ sample</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This format contains sequence of complex number samples. Each complex number
consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
represented as a 14 bit signed little endian number. I value comes first
and Q value after that. 14 bit value is stored in 16 bit space with unused
high bits padded with 0.
</para>
<example>
<title><constant>V4L2_SDR_FMT_CS14LE</constant> 1 sample</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="3" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>I'<subscript>0[7:0]</subscript></entry>
<entry>I'<subscript>0[13:8]</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;2:</entry>
<entry>Q'<subscript>0[7:0]</subscript></entry>
<entry>Q'<subscript>0[13:8]</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
<refentry id="V4L2-SDR-FMT-RU12LE">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_RU12LE ('RU12')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_RU12LE</constant>
</refname>
<refpurpose>Real unsigned 12-bit little endian sample</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This format contains sequence of real number samples. Each sample is
represented as a 12 bit unsigned little endian number. Sample is stored
in 16 bit space with unused high bits padded with 0.
</para>
<example>
<title><constant>V4L2_SDR_FMT_RU12LE</constant> 1 sample</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="3" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>I'<subscript>0[7:0]</subscript></entry>
<entry>I'<subscript>0[11:8]</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<title>Description</title> <title>Description</title>
<para>The following four pixel formats are raw sRGB / Bayer formats with <para>The following four pixel formats are raw sRGB / Bayer formats with
12 bits per colour. Each colour component is stored in a 16-bit word, with 6 12 bits per colour. Each colour component is stored in a 16-bit word, with 4
unused high bits filled with zeros. Each n-pixel row contains n/2 green samples 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 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 stored in memory in little endian order. They are conventionally described
......
...@@ -112,9 +112,34 @@ see <xref linkend="colorspaces" />.</entry> ...@@ -112,9 +112,34 @@ see <xref linkend="colorspaces" />.</entry>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>priv</structfield></entry> <entry><structfield>priv</structfield></entry>
<entry>Reserved for custom (driver defined) additional <entry><para>This field indicates whether the remaining fields of the
information about formats. When not used drivers and applications must <structname>v4l2_pix_format</structname> structure, also called the extended
set this field to zero.</entry> fields, are valid. When set to <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, it
indicates that the extended fields have been correctly initialized. When set to
any other value it indicates that the extended fields contain undefined values.
</para>
<para>Applications that wish to use the pixel format extended fields must first
ensure that the feature is supported by querying the device for the
<link linkend="querycap"><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></link>
capability. If the capability isn't set the pixel format extended fields are not
supported and using the extended fields will lead to undefined results.</para>
<para>To use the extended fields, applications must set the
<structfield>priv</structfield> field to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, initialize all the extended fields
and zero the unused bytes of the <structname>v4l2_format</structname>
<structfield>raw_data</structfield> field.</para>
<para>When the <structfield>priv</structfield> field isn't set to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> drivers must act as if all the
extended fields were set to zero. On return drivers must set the
<structfield>priv</structfield> field to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> and all the extended fields to
applicable values.</para></entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Flags set by the application or driver, see <xref
linkend="format-flags" />.</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
...@@ -201,9 +226,15 @@ codes can be used.</entry> ...@@ -201,9 +226,15 @@ codes can be used.</entry>
and the number of valid entries in the and the number of valid entries in the
<structfield>plane_fmt</structfield> array.</entry> <structfield>plane_fmt</structfield> array.</entry>
</row> </row>
<row>
<entry>__u8</entry>
<entry><structfield>flags</structfield></entry>
<entry>Flags set by the application or driver, see <xref
linkend="format-flags" />.</entry>
</row>
<row> <row>
<entry>__u8</entry> <entry>__u8</entry>
<entry><structfield>reserved[11]</structfield></entry> <entry><structfield>reserved[10]</structfield></entry>
<entry>Reserved for future extensions. Should be zeroed by the <entry>Reserved for future extensions. Should be zeroed by the
application.</entry> application.</entry>
</row> </row>
...@@ -248,7 +279,7 @@ has just as many pad bytes after it as the other rows.</para> ...@@ -248,7 +279,7 @@ has just as many pad bytes after it as the other rows.</para>
<para>In V4L2 each format has an identifier which looks like <para>In V4L2 each format has an identifier which looks like
<constant>PIX_FMT_XXX</constant>, defined in the <link <constant>PIX_FMT_XXX</constant>, defined in the <link
linkend="videodev">videodev.h</link> header file. These identifiers linkend="videodev">videodev2.h</link> header file. These identifiers
represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link> represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link>
which are also listed below, however they are not the same as those which are also listed below, however they are not the same as those
used in the Windows world.</para> used in the Windows world.</para>
...@@ -828,6 +859,9 @@ interface only.</para> ...@@ -828,6 +859,9 @@ interface only.</para>
&sub-sdr-cu08; &sub-sdr-cu08;
&sub-sdr-cu16le; &sub-sdr-cu16le;
&sub-sdr-cs08;
&sub-sdr-cs14le;
&sub-sdr-ru12le;
</section> </section>
...@@ -1060,4 +1094,21 @@ concatenated to form the JPEG stream. </para> ...@@ -1060,4 +1094,21 @@ concatenated to form the JPEG stream. </para>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
<table frame="none" pgwide="1" id="format-flags">
<title>Format Flags</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_PIX_FMT_FLAG_PREMUL_ALPHA</constant></entry>
<entry>0x00000001</entry>
<entry>The color values are premultiplied by the alpha channel
value. For example, if a light blue pixel with 50% transparency was described by
RGBA values (128, 192, 255, 128), the same pixel described with premultiplied
colors would be described by RGBA values (64, 96, 128, 128) </entry>
</row>
</tbody>
</tgroup>
</table>
</section> </section>
...@@ -86,47 +86,47 @@ selection targets available for a video capture device. It is recommended to ...@@ -86,47 +86,47 @@ selection targets available for a video capture device. It is recommended to
configure the cropping targets before to the composing targets.</para> configure the cropping targets before to the composing targets.</para>
<para>The range of coordinates of the top left corner, width and height of <para>The range of coordinates of the top left corner, width and height of
areas that can be sampled is given by the <constant> V4L2_SEL_TGT_CROP_BOUNDS areas that can be sampled is given by the <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>
</constant> target. It is recommended for the driver developers to put the target. It is recommended for the driver developers to put the
top/left corner at position <constant> (0,0) </constant>. The rectangle's top/left corner at position <constant>(0,0)</constant>. The rectangle's
coordinates are expressed in pixels.</para> coordinates are expressed in pixels.</para>
<para>The top left corner, width and height of the source rectangle, that is <para>The top left corner, width and height of the source rectangle, that is
the area actually sampled, is given by the <constant> V4L2_SEL_TGT_CROP the area actually sampled, is given by the <constant>V4L2_SEL_TGT_CROP</constant>
</constant> target. It uses the same coordinate system as <constant> target. It uses the same coordinate system as <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>.
V4L2_SEL_TGT_CROP_BOUNDS </constant>. The active cropping area must lie The active cropping area must lie completely inside the capture boundaries. The
completely inside the capture boundaries. The driver may further adjust the driver may further adjust the requested size and/or position according to hardware
requested size and/or position according to hardware limitations.</para> limitations.</para>
<para>Each capture device has a default source rectangle, given by the <para>Each capture device has a default source rectangle, given by the
<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant> target. This rectangle shall <constant>V4L2_SEL_TGT_CROP_DEFAULT</constant> target. This rectangle shall
over what the driver writer considers the complete picture. Drivers shall set over what the driver writer considers the complete picture. Drivers shall set
the active crop rectangle to the default when the driver is first loaded, but the active crop rectangle to the default when the driver is first loaded, but
not later.</para> not later.</para>
<para>The composing targets refer to a memory buffer. The limits of composing <para>The composing targets refer to a memory buffer. The limits of composing
coordinates are obtained using <constant> V4L2_SEL_TGT_COMPOSE_BOUNDS coordinates are obtained using <constant>V4L2_SEL_TGT_COMPOSE_BOUNDS</constant>.
</constant>. All coordinates are expressed in pixels. The rectangle's top/left All coordinates are expressed in pixels. The rectangle's top/left
corner must be located at position <constant> (0,0) </constant>. The width and corner must be located at position <constant>(0,0)</constant>. The width and
height are equal to the image size set by <constant> VIDIOC_S_FMT </constant>. height are equal to the image size set by <constant>VIDIOC_S_FMT</constant>.
</para> </para>
<para>The part of a buffer into which the image is inserted by the hardware is <para>The part of a buffer into which the image is inserted by the hardware is
controlled by the <constant> V4L2_SEL_TGT_COMPOSE </constant> target. controlled by the <constant>V4L2_SEL_TGT_COMPOSE</constant> target.
The rectangle's coordinates are also expressed in the same coordinate system as The rectangle's coordinates are also expressed in the same coordinate system as
the bounds rectangle. The composing rectangle must lie completely inside bounds the bounds rectangle. The composing rectangle must lie completely inside bounds
rectangle. The driver must adjust the composing rectangle to fit to the rectangle. The driver must adjust the composing rectangle to fit to the
bounding limits. Moreover, the driver can perform other adjustments according bounding limits. Moreover, the driver can perform other adjustments according
to hardware limitations. The application can control rounding behaviour using to hardware limitations. The application can control rounding behaviour using
<link linkend="v4l2-selection-flags"> constraint flags </link>.</para> <link linkend="v4l2-selection-flags"> constraint flags</link>.</para>
<para>For capture devices the default composing rectangle is queried using <para>For capture devices the default composing rectangle is queried using
<constant> V4L2_SEL_TGT_COMPOSE_DEFAULT </constant>. It is usually equal to the <constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant>. It is usually equal to the
bounding rectangle.</para> bounding rectangle.</para>
<para>The part of a buffer that is modified by the hardware is given by <para>The part of a buffer that is modified by the hardware is given by
<constant> V4L2_SEL_TGT_COMPOSE_PADDED </constant>. It contains all pixels <constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant>. It contains all pixels
defined using <constant> V4L2_SEL_TGT_COMPOSE </constant> plus all defined using <constant>V4L2_SEL_TGT_COMPOSE</constant> plus all
padding data modified by hardware during insertion process. All pixels outside padding data modified by hardware during insertion process. All pixels outside
this rectangle <emphasis>must not</emphasis> be changed by the hardware. The this rectangle <emphasis>must not</emphasis> be changed by the hardware. The
content of pixels that lie inside the padded area but outside active area is content of pixels that lie inside the padded area but outside active area is
...@@ -140,52 +140,51 @@ where the rubbish pixels are located and remove them if needed.</para> ...@@ -140,52 +140,51 @@ where the rubbish pixels are located and remove them if needed.</para>
<title>Configuration of video output</title> <title>Configuration of video output</title>
<para>For output devices targets and ioctls are used similarly to the video <para>For output devices targets and ioctls are used similarly to the video
capture case. The <emphasis> composing </emphasis> rectangle refers to the capture case. The <emphasis>composing</emphasis> rectangle refers to the
insertion of an image into a video signal. The cropping rectangles refer to a insertion of an image into a video signal. The cropping rectangles refer to a
memory buffer. It is recommended to configure the composing targets before to memory buffer. It is recommended to configure the composing targets before to
the cropping targets.</para> the cropping targets.</para>
<para>The cropping targets refer to the memory buffer that contains an image to <para>The cropping targets refer to the memory buffer that contains an image to
be inserted into a video signal or graphical screen. The limits of cropping be inserted into a video signal or graphical screen. The limits of cropping
coordinates are obtained using <constant> V4L2_SEL_TGT_CROP_BOUNDS </constant>. coordinates are obtained using <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>.
All coordinates are expressed in pixels. The top/left corner is always point All coordinates are expressed in pixels. The top/left corner is always point
<constant> (0,0) </constant>. The width and height is equal to the image size <constant>(0,0)</constant>. The width and height is equal to the image size
specified using <constant> VIDIOC_S_FMT </constant> ioctl.</para> specified using <constant>VIDIOC_S_FMT</constant> ioctl.</para>
<para>The top left corner, width and height of the source rectangle, that is <para>The top left corner, width and height of the source rectangle, that is
the area from which image date are processed by the hardware, is given by the the area from which image date are processed by the hardware, is given by the
<constant> V4L2_SEL_TGT_CROP </constant>. Its coordinates are expressed <constant>V4L2_SEL_TGT_CROP</constant>. Its coordinates are expressed
in in the same coordinate system as the bounds rectangle. The active cropping in in the same coordinate system as the bounds rectangle. The active cropping
area must lie completely inside the crop boundaries and the driver may further area must lie completely inside the crop boundaries and the driver may further
adjust the requested size and/or position according to hardware adjust the requested size and/or position according to hardware
limitations.</para> limitations.</para>
<para>For output devices the default cropping rectangle is queried using <para>For output devices the default cropping rectangle is queried using
<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant>. It is usually equal to the <constant>V4L2_SEL_TGT_CROP_DEFAULT</constant>. It is usually equal to the
bounding rectangle.</para> bounding rectangle.</para>
<para>The part of a video signal or graphics display where the image is <para>The part of a video signal or graphics display where the image is
inserted by the hardware is controlled by <constant> inserted by the hardware is controlled by <constant>V4L2_SEL_TGT_COMPOSE</constant>
V4L2_SEL_TGT_COMPOSE </constant> target. The rectangle's coordinates target. The rectangle's coordinates are expressed in pixels. The composing
are expressed in pixels. The composing rectangle must lie completely inside the rectangle must lie completely inside the bounds rectangle. The driver must
bounds rectangle. The driver must adjust the area to fit to the bounding adjust the area to fit to the bounding limits. Moreover, the driver can
limits. Moreover, the driver can perform other adjustments according to perform other adjustments according to hardware limitations.</para>
hardware limitations. </para>
<para>The device has a default composing rectangle, given by the
<para>The device has a default composing rectangle, given by the <constant> <constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant> target. This rectangle shall cover what
V4L2_SEL_TGT_COMPOSE_DEFAULT </constant> target. This rectangle shall cover what
the driver writer considers the complete picture. It is recommended for the the driver writer considers the complete picture. It is recommended for the
driver developers to put the top/left corner at position <constant> (0,0) driver developers to put the top/left corner at position <constant>(0,0)</constant>.
</constant>. Drivers shall set the active composing rectangle to the default Drivers shall set the active composing rectangle to the default
one when the driver is first loaded.</para> one when the driver is first loaded.</para>
<para>The devices may introduce additional content to video signal other than <para>The devices may introduce additional content to video signal other than
an image from memory buffers. It includes borders around an image. However, an image from memory buffers. It includes borders around an image. However,
such a padded area is driver-dependent feature not covered by this document. such a padded area is driver-dependent feature not covered by this document.
Driver developers are encouraged to keep padded rectangle equal to active one. Driver developers are encouraged to keep padded rectangle equal to active one.
The padded target is accessed by the <constant> V4L2_SEL_TGT_COMPOSE_PADDED The padded target is accessed by the <constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant>
</constant> identifier. It must contain all pixels from the <constant> identifier. It must contain all pixels from the <constant>V4L2_SEL_TGT_COMPOSE</constant>
V4L2_SEL_TGT_COMPOSE </constant> target.</para> target.</para>
</section> </section>
...@@ -194,8 +193,8 @@ V4L2_SEL_TGT_COMPOSE </constant> target.</para> ...@@ -194,8 +193,8 @@ V4L2_SEL_TGT_COMPOSE </constant> target.</para>
<title>Scaling control</title> <title>Scaling control</title>
<para>An application can detect if scaling is performed by comparing the width <para>An application can detect if scaling is performed by comparing the width
and the height of rectangles obtained using <constant> V4L2_SEL_TGT_CROP and the height of rectangles obtained using <constant>V4L2_SEL_TGT_CROP</constant>
</constant> and <constant> V4L2_SEL_TGT_COMPOSE </constant> targets. If and <constant>V4L2_SEL_TGT_COMPOSE</constant> targets. If
these are not equal then the scaling is applied. The application can compute these are not equal then the scaling is applied. The application can compute
the scaling ratios using these values.</para> the scaling ratios using these values.</para>
...@@ -208,7 +207,7 @@ the scaling ratios using these values.</para> ...@@ -208,7 +207,7 @@ the scaling ratios using these values.</para>
<title>Comparison with old cropping API</title> <title>Comparison with old cropping API</title>
<para>The selection API was introduced to cope with deficiencies of previous <para>The selection API was introduced to cope with deficiencies of previous
<link linkend="crop"> API </link>, that was designed to control simple capture <link linkend="crop"> API</link>, that was designed to control simple capture
devices. Later the cropping API was adopted by video output drivers. The ioctls devices. Later the cropping API was adopted by video output drivers. The ioctls
are used to select a part of the display were the video signal is inserted. It are used to select a part of the display were the video signal is inserted. It
should be considered as an API abuse because the described operation is should be considered as an API abuse because the described operation is
...@@ -220,7 +219,7 @@ part of an image by abusing V4L2 API. Cropping a smaller image from a larger ...@@ -220,7 +219,7 @@ part of an image by abusing V4L2 API. Cropping a smaller image from a larger
one is achieved by setting the field one is achieved by setting the field
&v4l2-pix-format;<structfield>::bytesperline</structfield>. Introducing an image offsets &v4l2-pix-format;<structfield>::bytesperline</structfield>. Introducing an image offsets
could be done by modifying field &v4l2-buffer;<structfield>::m_userptr</structfield> could be done by modifying field &v4l2-buffer;<structfield>::m_userptr</structfield>
before calling <constant> VIDIOC_QBUF </constant>. Those before calling <constant>VIDIOC_QBUF</constant>. Those
operations should be avoided because they are not portable (endianness), and do operations should be avoided because they are not portable (endianness), and do
not work for macroblock and Bayer formats and mmap buffers. The selection API not work for macroblock and Bayer formats and mmap buffers. The selection API
deals with configuration of buffer cropping/composing in a clear, intuitive and deals with configuration of buffer cropping/composing in a clear, intuitive and
...@@ -229,7 +228,7 @@ and constraints flags are introduced. Finally, &v4l2-crop; and &v4l2-cropcap; ...@@ -229,7 +228,7 @@ and constraints flags are introduced. Finally, &v4l2-crop; and &v4l2-cropcap;
have no reserved fields. Therefore there is no way to extend their functionality. have no reserved fields. Therefore there is no way to extend their functionality.
The new &v4l2-selection; provides a lot of place for future The new &v4l2-selection; provides a lot of place for future
extensions. Driver developers are encouraged to implement only selection API. extensions. Driver developers are encouraged to implement only selection API.
The former cropping API would be simulated using the new one. </para> The former cropping API would be simulated using the new one.</para>
</section> </section>
...@@ -238,9 +237,9 @@ The former cropping API would be simulated using the new one. </para> ...@@ -238,9 +237,9 @@ The former cropping API would be simulated using the new one. </para>
<example> <example>
<title>Resetting the cropping parameters</title> <title>Resetting the cropping parameters</title>
<para>(A video capture device is assumed; change <constant> <para>(A video capture device is assumed; change
V4L2_BUF_TYPE_VIDEO_CAPTURE </constant> for other devices; change target to <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other devices; change target to
<constant> V4L2_SEL_TGT_COMPOSE_* </constant> family to configure composing <constant>V4L2_SEL_TGT_COMPOSE_*</constant> family to configure composing
area)</para> area)</para>
<programlisting> <programlisting>
...@@ -292,8 +291,8 @@ area)</para> ...@@ -292,8 +291,8 @@ area)</para>
<example> <example>
<title>Querying for scaling factors</title> <title>Querying for scaling factors</title>
<para>A video output device is assumed; change <constant> <para>A video output device is assumed; change
V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> for other devices</para> <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> for other devices</para>
<programlisting> <programlisting>
&v4l2-selection; compose = { &v4l2-selection; compose = {
......
...@@ -151,6 +151,14 @@ structs, ioctls) must be noted in more detail in the history chapter ...@@ -151,6 +151,14 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.xml), along with the possible impact on existing drivers and (compat.xml), along with the possible impact on existing drivers and
applications. --> applications. -->
<revision>
<revnumber>3.16</revnumber>
<date>2014-05-27</date>
<authorinitials>lp</authorinitials>
<revremark>Extended &v4l2-pix-format;. Added format flags.
</revremark>
</revision>
<revision> <revision>
<revnumber>3.15</revnumber> <revnumber>3.15</revnumber>
<date>2014-02-03</date> <date>2014-02-03</date>
......
...@@ -92,6 +92,18 @@ ...@@ -92,6 +92,18 @@
<entry><structfield>frame_sync</structfield></entry> <entry><structfield>frame_sync</structfield></entry>
<entry>Event data for event V4L2_EVENT_FRAME_SYNC.</entry> <entry>Event data for event V4L2_EVENT_FRAME_SYNC.</entry>
</row> </row>
<row>
<entry></entry>
<entry>&v4l2-event-motion-det;</entry>
<entry><structfield>motion_det</structfield></entry>
<entry>Event data for event V4L2_EVENT_MOTION_DET.</entry>
</row>
<row>
<entry></entry>
<entry>&v4l2-event-src-change;</entry>
<entry><structfield>src_change</structfield></entry>
<entry>Event data for event V4L2_EVENT_SOURCE_CHANGE.</entry>
</row>
<row> <row>
<entry></entry> <entry></entry>
<entry>__u8</entry> <entry>__u8</entry>
...@@ -258,6 +270,44 @@ ...@@ -258,6 +270,44 @@
</tgroup> </tgroup>
</table> </table>
<table frame="none" pgwide="1" id="v4l2-event-motion-det">
<title>struct <structname>v4l2_event_motion_det</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>
Currently only one flag is available: if <constant>V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ</constant>
is set, then the <structfield>frame_sequence</structfield> field is valid,
otherwise that field should be ignored.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>frame_sequence</structfield></entry>
<entry>
The sequence number of the frame being received. Only valid if the
<constant>V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ</constant> flag was set.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>region_mask</structfield></entry>
<entry>
The bitmask of the regions that reported motion. There is at least one
region. If this field is 0, then no motion was detected at all.
If there is no <constant>V4L2_CID_DETECT_MD_REGION_GRID</constant> control
(see <xref linkend="detect-controls" />) to assign a different region
to each cell in the motion detection grid, then that all cells
are automatically assigned to the default region 0.
</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="changes-flags"> <table pgwide="1" frame="none" id="changes-flags">
<title>Changes</title> <title>Changes</title>
<tgroup cols="3"> <tgroup cols="3">
......
...@@ -72,23 +72,30 @@ initialize the <structfield>id</structfield>, ...@@ -72,23 +72,30 @@ initialize the <structfield>id</structfield>,
<structfield>size</structfield> and <structfield>reserved2</structfield> fields <structfield>size</structfield> and <structfield>reserved2</structfield> fields
of each &v4l2-ext-control; and call the of each &v4l2-ext-control; and call the
<constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls <constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls
must also set the <structfield>string</structfield> field.</para> must also set the <structfield>string</structfield> field. Controls
of compound types (<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is set)
must set the <structfield>ptr</structfield> field.</para>
<para>If the <structfield>size</structfield> is too small to <para>If the <structfield>size</structfield> is too small to
receive the control result (only relevant for pointer-type controls receive the control result (only relevant for pointer-type controls
like strings), then the driver will set <structfield>size</structfield> like strings), then the driver will set <structfield>size</structfield>
to a valid value and return an &ENOSPC;. You should re-allocate the to a valid value and return an &ENOSPC;. You should re-allocate the
string memory to this new size and try again. It is possible that the memory to this new size and try again. For the string type it is possible that
same issue occurs again if the string has grown in the meantime. It is the same issue occurs again if the string has grown in the meantime. It is
recommended to call &VIDIOC-QUERYCTRL; first and use recommended to call &VIDIOC-QUERYCTRL; first and use
<structfield>maximum</structfield>+1 as the new <structfield>size</structfield> <structfield>maximum</structfield>+1 as the new <structfield>size</structfield>
value. It is guaranteed that that is sufficient memory. value. It is guaranteed that that is sufficient memory.
</para> </para>
<para>N-dimensional arrays are set and retrieved row-by-row. You cannot set a partial
array, all elements have to be set or retrieved. The total size is calculated
as <structfield>elems</structfield> * <structfield>elem_size</structfield>.
These values can be obtained by calling &VIDIOC-QUERY-EXT-CTRL;.</para>
<para>To change the value of a set of controls applications <para>To change the value of a set of controls applications
initialize the <structfield>id</structfield>, <structfield>size</structfield>, initialize the <structfield>id</structfield>, <structfield>size</structfield>,
<structfield>reserved2</structfield> and <structfield>reserved2</structfield> and
<structfield>value/string</structfield> fields of each &v4l2-ext-control; and <structfield>value/value64/string/ptr</structfield> fields of each &v4l2-ext-control; and
call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls
will only be set if <emphasis>all</emphasis> control values are will only be set if <emphasis>all</emphasis> control values are
valid.</para> valid.</para>
...@@ -96,7 +103,7 @@ valid.</para> ...@@ -96,7 +103,7 @@ valid.</para>
<para>To check if a set of controls have correct values applications <para>To check if a set of controls have correct values applications
initialize the <structfield>id</structfield>, <structfield>size</structfield>, initialize the <structfield>id</structfield>, <structfield>size</structfield>,
<structfield>reserved2</structfield> and <structfield>reserved2</structfield> and
<structfield>value/string</structfield> fields of each &v4l2-ext-control; and <structfield>value/value64/string/ptr</structfield> fields of each &v4l2-ext-control; and
call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to
the driver whether wrong values are automatically adjusted to a valid the driver whether wrong values are automatically adjusted to a valid
value or if an error is returned.</para> value or if an error is returned.</para>
...@@ -158,19 +165,47 @@ applications must set the array to zero.</entry> ...@@ -158,19 +165,47 @@ applications must set the array to zero.</entry>
<entry></entry> <entry></entry>
<entry>__s32</entry> <entry>__s32</entry>
<entry><structfield>value</structfield></entry> <entry><structfield>value</structfield></entry>
<entry>New value or current value.</entry> <entry>New value or current value. Valid if this control is not of
type <constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is not set.</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
<entry>__s64</entry> <entry>__s64</entry>
<entry><structfield>value64</structfield></entry> <entry><structfield>value64</structfield></entry>
<entry>New value or current value.</entry> <entry>New value or current value. Valid if this control is of
type <constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is not set.</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
<entry>char *</entry> <entry>char *</entry>
<entry><structfield>string</structfield></entry> <entry><structfield>string</structfield></entry>
<entry>A pointer to a string.</entry> <entry>A pointer to a string. Valid if this control is of
type <constant>V4L2_CTRL_TYPE_STRING</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>__u8 *</entry>
<entry><structfield>p_u8</structfield></entry>
<entry>A pointer to a matrix control of unsigned 8-bit values.
Valid if this control is of type <constant>V4L2_CTRL_TYPE_U8</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>__u16 *</entry>
<entry><structfield>p_u16</structfield></entry>
<entry>A pointer to a matrix control of unsigned 16-bit values.
Valid if this control is of type <constant>V4L2_CTRL_TYPE_U16</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>void *</entry>
<entry><structfield>ptr</structfield></entry>
<entry>A pointer to a compound type which can be an N-dimensional array and/or a
compound type (the control's type is >= <constant>V4L2_CTRL_COMPOUND_TYPES</constant>).
Valid if <constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is set for this control.
</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
......
...@@ -152,13 +152,10 @@ a valid base address, so applications can find the corresponding Linux ...@@ -152,13 +152,10 @@ a valid base address, so applications can find the corresponding Linux
framebuffer device (see <xref linkend="osd" />).</entry> framebuffer device (see <xref linkend="osd" />).</entry>
</row> </row>
<row> <row>
<entry>&v4l2-pix-format;</entry> <entry>struct</entry>
<entry><structfield>fmt</structfield></entry> <entry><structfield>fmt</structfield></entry>
<entry></entry> <entry></entry>
<entry>Layout of the frame buffer. The <entry>Layout of the frame buffer.</entry>
<structname>v4l2_pix_format</structname> structure is defined in <xref
linkend="pixfmt" />, for clarification the fields and acceptable values
are listed below:</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
...@@ -276,9 +273,8 @@ see <xref linkend="colorspaces" />.</entry> ...@@ -276,9 +273,8 @@ see <xref linkend="colorspaces" />.</entry>
<entry></entry> <entry></entry>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>priv</structfield></entry> <entry><structfield>priv</structfield></entry>
<entry>Reserved for additional information about custom <entry>Reserved. Drivers and applications must set this field to
(driver defined) formats. When not used drivers and applications must zero.</entry>
set this field to zero.</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
......
...@@ -58,17 +58,16 @@ ...@@ -58,17 +58,16 @@
<para>The ioctls are used to query and configure selection rectangles.</para> <para>The ioctls are used to query and configure selection rectangles.</para>
<para> To query the cropping (composing) rectangle set &v4l2-selection; <para>To query the cropping (composing) rectangle set &v4l2-selection;
<structfield> type </structfield> field to the respective buffer type. <structfield> type </structfield> field to the respective buffer type.
Do not use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE Do not use multiplanar buffers. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. Use
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is
setting the value of &v4l2-selection; <structfield>target</structfield> field setting the value of &v4l2-selection; <structfield>target</structfield> field
to <constant> V4L2_SEL_TGT_CROP </constant> (<constant> to <constant>V4L2_SEL_TGT_CROP</constant> (<constant>V4L2_SEL_TGT_COMPOSE</constant>).
V4L2_SEL_TGT_COMPOSE </constant>). Please refer to table <xref Please refer to table <xref linkend="v4l2-selections-common" /> or <xref linkend="selection-api" />
linkend="v4l2-selections-common" /> or <xref linkend="selection-api" /> for additional for additional targets. The <structfield>flags</structfield> and <structfield>reserved
targets. The <structfield>flags</structfield> and <structfield>reserved
</structfield> fields of &v4l2-selection; are ignored and they must be filled </structfield> fields of &v4l2-selection; are ignored and they must be filled
with zeros. The driver fills the rest of the structure or with zeros. The driver fills the rest of the structure or
returns &EINVAL; if incorrect buffer type or target was used. If cropping returns &EINVAL; if incorrect buffer type or target was used. If cropping
...@@ -77,19 +76,18 @@ always equal to the bounds rectangle. Finally, the &v4l2-rect; ...@@ -77,19 +76,18 @@ always equal to the bounds rectangle. Finally, the &v4l2-rect;
<structfield>r</structfield> rectangle is filled with the current cropping <structfield>r</structfield> rectangle is filled with the current cropping
(composing) coordinates. The coordinates are expressed in driver-dependent (composing) coordinates. The coordinates are expressed in driver-dependent
units. The only exception are rectangles for images in raw formats, whose units. The only exception are rectangles for images in raw formats, whose
coordinates are always expressed in pixels. </para> coordinates are always expressed in pixels.</para>
<para> To change the cropping (composing) rectangle set the &v4l2-selection; <para>To change the cropping (composing) rectangle set the &v4l2-selection;
<structfield>type</structfield> field to the respective buffer type. Do not <structfield>type</structfield> field to the respective buffer type. Do not
use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE use multiplanar buffers. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. Use
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is
setting the value of &v4l2-selection; <structfield>target</structfield> to setting the value of &v4l2-selection; <structfield>target</structfield> to
<constant>V4L2_SEL_TGT_CROP</constant> (<constant> <constant>V4L2_SEL_TGT_CROP</constant> (<constant>V4L2_SEL_TGT_COMPOSE</constant>).
V4L2_SEL_TGT_COMPOSE </constant>). Please refer to table <xref Please refer to table <xref linkend="v4l2-selections-common" /> or <xref linkend="selection-api" />
linkend="v4l2-selections-common" /> or <xref linkend="selection-api" /> for additional for additional targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be
targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be
set to the desired active area. Field &v4l2-selection; <structfield> reserved set to the desired active area. Field &v4l2-selection; <structfield> reserved
</structfield> is ignored and must be filled with zeros. The driver may adjust </structfield> is ignored and must be filled with zeros. The driver may adjust
coordinates of the requested rectangle. An application may coordinates of the requested rectangle. An application may
...@@ -149,8 +147,8 @@ On success the &v4l2-rect; <structfield>r</structfield> field contains ...@@ -149,8 +147,8 @@ On success the &v4l2-rect; <structfield>r</structfield> field contains
the adjusted rectangle. When the parameters are unsuitable the application may the adjusted rectangle. When the parameters are unsuitable the application may
modify the cropping (composing) or image parameters and repeat the cycle until modify the cropping (composing) or image parameters and repeat the cycle until
satisfactory parameters have been negotiated. If constraints flags have to be satisfactory parameters have been negotiated. If constraints flags have to be
violated at then ERANGE is returned. The error indicates that <emphasis> there violated at then ERANGE is returned. The error indicates that <emphasis>there
exist no rectangle </emphasis> that satisfies the constraints.</para> exist no rectangle</emphasis> that satisfies the constraints.</para>
<para>Selection targets and flags are documented in <xref <para>Selection targets and flags are documented in <xref
linkend="v4l2-selections-common"/>.</para> linkend="v4l2-selections-common"/>.</para>
......
...@@ -300,6 +300,12 @@ modulator programming see ...@@ -300,6 +300,12 @@ modulator programming see
<entry>0x00100000</entry> <entry>0x00100000</entry>
<entry>The device supports the <entry>The device supports the
<link linkend="sdr">SDR Capture</link> interface.</entry> <link linkend="sdr">SDR Capture</link> interface.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></entry>
<entry>0x00200000</entry>
<entry>The device supports the &v4l2-pix-format; extended
fields.</entry>
</row> </row>
<row> <row>
<entry><constant>V4L2_CAP_READWRITE</constant></entry> <entry><constant>V4L2_CAP_READWRITE</constant></entry>
......
<refentry id="vidioc-queryctrl"> <refentry id="vidioc-queryctrl">
<refmeta> <refmeta>
<refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</refentrytitle> <refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL, VIDIOC_QUERYMENU</refentrytitle>
&manvol; &manvol;
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname>VIDIOC_QUERYCTRL</refname> <refname>VIDIOC_QUERYCTRL</refname>
<refname>VIDIOC_QUERY_EXT_CTRL</refname>
<refname>VIDIOC_QUERYMENU</refname> <refname>VIDIOC_QUERYMENU</refname>
<refpurpose>Enumerate controls and menu control items</refpurpose> <refpurpose>Enumerate controls and menu control items</refpurpose>
</refnamediv> </refnamediv>
...@@ -19,6 +20,14 @@ ...@@ -19,6 +20,14 @@
<paramdef>struct v4l2_queryctrl *<parameter>argp</parameter></paramdef> <paramdef>struct v4l2_queryctrl *<parameter>argp</parameter></paramdef>
</funcprototype> </funcprototype>
</funcsynopsis> </funcsynopsis>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_query_ext_ctrl *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<funcsynopsis> <funcsynopsis>
<funcprototype> <funcprototype>
<funcdef>int <function>ioctl</function></funcdef> <funcdef>int <function>ioctl</function></funcdef>
...@@ -42,7 +51,7 @@ ...@@ -42,7 +51,7 @@
<varlistentry> <varlistentry>
<term><parameter>request</parameter></term> <term><parameter>request</parameter></term>
<listitem> <listitem>
<para>VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</para> <para>VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL, VIDIOC_QUERYMENU</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
...@@ -67,7 +76,7 @@ structure. The driver fills the rest of the structure or returns an ...@@ -67,7 +76,7 @@ structure. The driver fills the rest of the structure or returns an
<constant>VIDIOC_QUERYCTRL</constant> with successive <constant>VIDIOC_QUERYCTRL</constant> with successive
<structfield>id</structfield> values starting from <structfield>id</structfield> values starting from
<constant>V4L2_CID_BASE</constant> up to and exclusive <constant>V4L2_CID_BASE</constant> up to and exclusive
<constant>V4L2_CID_BASE_LASTP1</constant>. Drivers may return <constant>V4L2_CID_LASTP1</constant>. Drivers may return
<errorcode>EINVAL</errorcode> if a control in this range is not <errorcode>EINVAL</errorcode> if a control in this range is not
supported. Further applications can enumerate private controls, which supported. Further applications can enumerate private controls, which
are not defined in this specification, by starting at are not defined in this specification, by starting at
...@@ -89,9 +98,23 @@ prematurely end the enumeration).</para></footnote></para> ...@@ -89,9 +98,23 @@ prematurely end the enumeration).</para></footnote></para>
<para>When the application ORs <structfield>id</structfield> with <para>When the application ORs <structfield>id</structfield> with
<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the
next supported control, or <errorcode>EINVAL</errorcode> if there is next supported non-compound control, or <errorcode>EINVAL</errorcode>
none. Drivers which do not support this flag yet always return if there is none. In addition, the <constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant>
<errorcode>EINVAL</errorcode>.</para> flag can be specified to enumerate all compound controls (i.e. controls
with type &ge; <constant>V4L2_CTRL_COMPOUND_TYPES</constant>). Specify both
<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> and
<constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant> in order to enumerate
all controls, compound or not. Drivers which do not support these flags yet
always return <errorcode>EINVAL</errorcode>.</para>
<para>The <constant>VIDIOC_QUERY_EXT_CTRL</constant> ioctl was
introduced in order to better support controls that can use compound
types, and to expose additional control information that cannot be
returned in &v4l2-queryctrl; since that structure is full.</para>
<para><constant>VIDIOC_QUERY_EXT_CTRL</constant> is used in the
same way as <constant>VIDIOC_QUERYCTRL</constant>, except that the
<structfield>reserved</structfield> array must be zeroed as well.</para>
<para>Additional information is required for menu controls: the <para>Additional information is required for menu controls: the
names of the menu items. To query them applications set the names of the menu items. To query them applications set the
...@@ -142,38 +165,23 @@ string. This information is intended for the user.</entry> ...@@ -142,38 +165,23 @@ string. This information is intended for the user.</entry>
<entry>__s32</entry> <entry>__s32</entry>
<entry><structfield>minimum</structfield></entry> <entry><structfield>minimum</structfield></entry>
<entry>Minimum value, inclusive. This field gives a lower <entry>Minimum value, inclusive. This field gives a lower
bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the bound for the control. See &v4l2-ctrl-type; how the minimum value is to
lowest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant> controls. be used for each possible control type. Note that this a signed 32-bit value.</entry>
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
<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
signed value.</entry>
</row> </row>
<row> <row>
<entry>__s32</entry> <entry>__s32</entry>
<entry><structfield>maximum</structfield></entry> <entry><structfield>maximum</structfield></entry>
<entry>Maximum value, inclusive. This field gives an upper <entry>Maximum value, inclusive. This field gives an upper
bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the bound for the control. See &v4l2-ctrl-type; how the maximum value is to
highest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant> be used for each possible control type. Note that this a signed 32-bit value.</entry>
controls. For <constant>V4L2_CTRL_TYPE_BITMASK</constant> controls it is the
set of usable bits.
For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the maximum value
gives the maximum 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
<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
signed value.</entry>
</row> </row>
<row> <row>
<entry>__s32</entry> <entry>__s32</entry>
<entry><structfield>step</structfield></entry> <entry><structfield>step</structfield></entry>
<entry><para>This field gives a step size for <entry><para>This field gives a step size for the control.
<constant>V4L2_CTRL_TYPE_INTEGER</constant> controls. For See &v4l2-ctrl-type; how the step value is to be used for each possible
<constant>V4L2_CTRL_TYPE_STRING</constant> controls this field refers to control type. Note that this an unsigned 32-bit value.
the string length that has to be a multiple of this step size. </para><para>Generally drivers should not scale hardware
It may not be valid for any other type of control, including
<constant>V4L2_CTRL_TYPE_INTEGER64</constant>
controls.</para><para>Generally drivers should not scale hardware
control values. It may be necessary for example when the control values. It may be necessary for example when the
<structfield>name</structfield> or <structfield>id</structfield> imply <structfield>name</structfield> or <structfield>id</structfield> imply
a particular unit and the hardware actually accepts only multiples of a particular unit and the hardware actually accepts only multiples of
...@@ -192,10 +200,11 @@ be always positive.</para></entry> ...@@ -192,10 +200,11 @@ be always positive.</para></entry>
<entry><structfield>default_value</structfield></entry> <entry><structfield>default_value</structfield></entry>
<entry>The default value of a <entry>The default value of a
<constant>V4L2_CTRL_TYPE_INTEGER</constant>, <constant>V4L2_CTRL_TYPE_INTEGER</constant>,
<constant>_BOOLEAN</constant> or <constant>_MENU</constant> control. <constant>_BOOLEAN</constant>, <constant>_BITMASK</constant>,
Not valid for other types of controls. Drivers reset controls only <constant>_MENU</constant> or <constant>_INTEGER_MENU</constant> control.
when the driver is loaded, not later, in particular not when the Not valid for other types of controls.
func-open; is called.</entry> Note that drivers reset controls to their default value only when the
driver is first loaded, never afterwards.</entry>
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
...@@ -213,6 +222,126 @@ the array to zero.</entry> ...@@ -213,6 +222,126 @@ the array to zero.</entry>
</tgroup> </tgroup>
</table> </table>
<table pgwide="1" frame="none" id="v4l2-query-ext-ctrl">
<title>struct <structname>v4l2_query_ext_ctrl</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>id</structfield></entry>
<entry>Identifies the control, set by the application. See
<xref linkend="control-id" /> for predefined IDs. When the ID is ORed
with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver clears the
flag and returns the first non-compound control with a higher ID. When the
ID is ORed with <constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant> the driver
clears the flag and returns the first compound control with a higher ID.
Set both to get the first control (compound or not) with a higher ID.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>type</structfield></entry>
<entry>Type of control, see <xref
linkend="v4l2-ctrl-type" />.</entry>
</row>
<row>
<entry>char</entry>
<entry><structfield>name</structfield>[32]</entry>
<entry>Name of the control, a NUL-terminated ASCII
string. This information is intended for the user.</entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>minimum</structfield></entry>
<entry>Minimum value, inclusive. This field gives a lower
bound for the control. See &v4l2-ctrl-type; how the minimum value is to
be used for each possible control type. Note that this a signed 64-bit value.</entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>maximum</structfield></entry>
<entry>Maximum value, inclusive. This field gives an upper
bound for the control. See &v4l2-ctrl-type; how the maximum value is to
be used for each possible control type. Note that this a signed 64-bit value.</entry>
</row>
<row>
<entry>__u64</entry>
<entry><structfield>step</structfield></entry>
<entry><para>This field gives a step size for the control.
See &v4l2-ctrl-type; how the step value is to be used for each possible
control type. Note that this an unsigned 64-bit value.
</para><para>Generally drivers should not scale hardware
control values. It may be necessary for example when the
<structfield>name</structfield> or <structfield>id</structfield> imply
a particular unit and the hardware actually accepts only multiples of
said unit. If so, drivers must take care values are properly rounded
when scaling, such that errors will not accumulate on repeated
read-write cycles.</para><para>This field gives the smallest change of
an integer control actually affecting hardware. Often the information
is needed when the user can change controls by keyboard or GUI
buttons, rather than a slider. When for example a hardware register
accepts values 0-511 and the driver reports 0-65535, step should be
128.</para></entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>default_value</structfield></entry>
<entry>The default value of a
<constant>V4L2_CTRL_TYPE_INTEGER</constant>, <constant>_INTEGER64</constant>,
<constant>_BOOLEAN</constant>, <constant>_BITMASK</constant>,
<constant>_MENU</constant>, <constant>_INTEGER_MENU</constant>,
<constant>_U8</constant> or <constant>_U16</constant> control.
Not valid for other types of controls.
Note that drivers reset controls to their default value only when the
driver is first loaded, never afterwards.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Control flags, see <xref
linkend="control-flags" />.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>elem_size</structfield></entry>
<entry>The size in bytes of a single element of the array.
Given a char pointer <constant>p</constant> to a 3-dimensional array you can find the
position of cell <constant>(z, y, x)</constant> as follows:
<constant>p + ((z * dims[1] + y) * dims[0] + x) * elem_size</constant>. <structfield>elem_size</structfield>
is always valid, also when the control isn't an array. For string controls
<structfield>elem_size</structfield> is equal to <structfield>maximum + 1</structfield>.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>elems</structfield></entry>
<entry>The number of elements in the N-dimensional array. If this control
is not an array, then <structfield>elems</structfield> is 1. The <structfield>elems</structfield>
field can never be 0.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>nr_of_dims</structfield></entry>
<entry>The number of dimension in the N-dimensional array. If this control
is not an array, then this field is 0.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>dims[V4L2_CTRL_MAX_DIMS]</structfield></entry>
<entry>The size of each dimension. The first <structfield>nr_of_dims</structfield>
elements of this array must be non-zero, all remaining elements must be zero.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[32]</entry>
<entry>Reserved for future extensions. Applications and drivers
must set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-querymenu"> <table pgwide="1" frame="none" id="v4l2-querymenu">
<title>struct <structname>v4l2_querymenu</structname></title> <title>struct <structname>v4l2_querymenu</structname></title>
<tgroup cols="4"> <tgroup cols="4">
...@@ -347,11 +476,14 @@ Drivers must ignore the value passed with ...@@ -347,11 +476,14 @@ Drivers must ignore the value passed with
</row> </row>
<row> <row>
<entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry> <entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry>
<entry>n/a</entry> <entry>any</entry>
<entry>n/a</entry> <entry>any</entry>
<entry>n/a</entry> <entry>any</entry>
<entry>A 64-bit integer valued control. Minimum, maximum <entry>A 64-bit integer valued control. Minimum, maximum
and step size cannot be queried.</entry> and step size cannot be queried using <constant>VIDIOC_QUERYCTRL</constant>.
Only <constant>VIDIOC_QUERY_EXT_CTRL</constant> can retrieve the 64-bit
min/max/step values, they should be interpreted as n/a when using
<constant>VIDIOC_QUERYCTRL</constant>.</entry>
</row> </row>
<row> <row>
<entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry> <entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry>
...@@ -379,6 +511,26 @@ ioctl returns the name of the control class and this control type. ...@@ -379,6 +511,26 @@ ioctl returns the name of the control class and this control type.
Older drivers which do not support this feature return an Older drivers which do not support this feature return an
&EINVAL;.</entry> &EINVAL;.</entry>
</row> </row>
<row>
<entry><constant>V4L2_CTRL_TYPE_U8</constant></entry>
<entry>any</entry>
<entry>any</entry>
<entry>any</entry>
<entry>An unsigned 8-bit valued control ranging from minimum to
maximum inclusive. The step value indicates the increment between
values which are actually different on the hardware.
</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_U16</constant></entry>
<entry>any</entry>
<entry>any</entry>
<entry>any</entry>
<entry>An unsigned 16-bit valued control ranging from minimum to
maximum inclusive. The step value indicates the increment between
values which are actually different on the hardware.
</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
...@@ -450,6 +602,14 @@ is in auto-gain mode. In such a case the hardware calculates the gain value base ...@@ -450,6 +602,14 @@ is in auto-gain mode. In such a case the hardware calculates the gain value base
the lighting conditions which can change over time. Note that setting a new value for the lighting conditions which can change over time. Note that setting a new value for
a volatile control will have no effect. The new value will just be ignored.</entry> a volatile control will have no effect. The new value will just be ignored.</entry>
</row> </row>
<row>
<entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry>
<entry>0x0100</entry>
<entry>This control has a pointer type, so its value has to be accessed
using one of the pointer fields of &v4l2-ext-control;. This flag is set for controls
that are an array, string, or have a compound type. In all cases you have to set a
pointer to memory containing the payload of the control.</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
......
...@@ -174,6 +174,14 @@ ...@@ -174,6 +174,14 @@
will have the ORed value of all the events generated.</para> will have the ORed value of all the events generated.</para>
</entry> </entry>
</row> </row>
<row>
<entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
<entry>5</entry>
<entry>
<para>Triggered whenever the motion detection state for one or more of the regions
changes. This event has a &v4l2-event-motion-det; associated with it.</para>
</entry>
</row>
<row> <row>
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry> <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
<entry>0x08000000</entry> <entry>0x08000000</entry>
......
Atmel Image Sensor Interface (ISI) SoC Camera Subsystem
----------------------------------------------
Required properties:
- compatible: must be "atmel,at91sam9g45-isi"
- reg: physical base address and length of the registers set for the device;
- interrupts: should contain IRQ line for the ISI;
- clocks: list of clock specifiers, corresponding to entries in
the clock-names property;
- clock-names: must contain "isi_clk", which is the isi peripherial clock.
ISI supports a single port node with parallel bus. It should contain one
'port' child node with child 'endpoint' node. Please refer to the bindings
defined in Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
isi: isi@f0034000 {
compatible = "atmel,at91sam9g45-isi";
reg = <0xf0034000 0x4000>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;
clocks = <&isi_clk>;
clock-names = "isi_clk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_isi>;
port {
#address-cells = <1>;
#size-cells = <0>;
isi_0: endpoint {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
};
};
};
i2c1: i2c@f0018000 {
ov2640: camera@0x30 {
compatible = "omnivision,ov2640";
reg = <0x30>;
port {
ov2640_0: endpoint {
remote-endpoint = <&isi_0>;
bus-width = <8>;
};
};
};
};
...@@ -3,9 +3,13 @@ Samsung S5P/EXYNOS SoC series JPEG codec ...@@ -3,9 +3,13 @@ Samsung S5P/EXYNOS SoC series JPEG codec
Required properties: Required properties:
- compatible : should be one of: - compatible : should be one of:
"samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg"; "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
"samsung,exynos3250-jpeg";
- reg : address and length of the JPEG codec IP register set; - reg : address and length of the JPEG codec IP register set;
- interrupts : specifies the JPEG codec IP interrupt; - interrupts : specifies the JPEG codec IP interrupt;
- clocks : should contain the JPEG codec IP gate clock specifier, from the - clock-names : should contain:
common clock bindings; - "jpeg" for the core gate clock,
- clock-names : should contain "jpeg" entry. - "sclk" for the special clock (optional).
- clocks : should contain the clock specifier and clock ID list
matching entries in the clock-names property; from
the common clock bindings.
Micron 1.3Mp CMOS Digital Image Sensor
The Micron MT9M111 is a CMOS active pixel digital image sensor with an active
array size of 1280H x 1024V. It is programmable through a simple two-wire serial
interface.
Required Properties:
- compatible: value should be "micron,mt9m111"
For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
i2c_master {
mt9m111@5d {
compatible = "micron,mt9m111";
reg = <0x5d>;
remote = <&pxa_camera>;
port {
mt9m111_1: endpoint {
bus-width = <8>;
remote-endpoint = <&pxa_camera>;
};
};
};
};
Marvell PXA camera host interface
Required properties:
- compatible: Should be "marvell,pxa270-qci"
- reg: register base and size
- interrupts: the interrupt number
- any required generic properties defined in video-interfaces.txt
Optional properties:
- clocks: input clock (see clock-bindings.txt)
- clock-output-names: should contain the name of the clock driving the
sensor master clock MCLK
- clock-frequency: host interface is driving MCLK, and MCLK rate is this rate
Example:
pxa_camera: pxa_camera@50000000 {
compatible = "marvell,pxa270-qci";
reg = <0x50000000 0x1000>;
interrupts = <33>;
clocks = <&pxa2xx_clks 24>;
clock-names = "ciclk";
clock-frequency = <50000000>;
clock-output-names = "qci_mclk";
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
qci: endpoint@0 {
reg = <0>; /* Local endpoint # */
remote-endpoint = <&mt9m111_1>;
bus-width = <8>; /* Used data lines */
hsync-active = <0>; /* Active low */
vsync-active = <0>; /* Active low */
pclk-sample = <1>; /* Rising */
};
};
};
Renesas RCar Video Input driver (rcar_vin)
------------------------------------------
The rcar_vin device provides video input capabilities for the Renesas R-Car
family of devices. The current blocks are always slaves and suppot one input
channel which can be either RGB, YUYV or BT656.
- compatible: Must be one of the following
- "renesas,vin-r8a7791" for the R8A7791 device
- "renesas,vin-r8a7790" for the R8A7790 device
- "renesas,vin-r8a7779" for the R8A7779 device
- "renesas,vin-r8a7778" for the R8A7778 device
- reg: the register base and size for the device registers
- interrupts: the interrupt for the device
- clocks: Reference to the parent clock
Additionally, an alias named vinX will need to be created to specify
which video input device this is.
The per-board settings:
- port sub-node describing a single endpoint connected to the vin
as described in video-interfaces.txt[1]. Only the first one will
be considered as each vin interface has one input port.
These settings are used to work out video input format and widths
into the system.
Device node example
-------------------
aliases {
vin0 = &vin0;
};
vin0: vin@0xe6ef0000 {
compatible = "renesas,vin-r8a7790";
clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
reg = <0 0xe6ef0000 0 0x1000>;
interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
Board setup example (vin1 composite video input)
------------------------------------------------
&i2c2 {
status = "ok";
pinctrl-0 = <&i2c2_pins>;
pinctrl-names = "default";
adv7180@20 {
compatible = "adi,adv7180";
reg = <0x20>;
remote = <&vin1>;
port {
adv7180: endpoint {
bus-width = <8>;
remote-endpoint = <&vin1ep0>;
};
};
};
};
/* composite video input */
&vin1 {
pinctrl-0 = <&vin1_pins>;
pinctrl-names = "default";
status = "ok";
port {
#address-cells = <1>;
#size-cells = <0>;
vin1ep0: endpoint {
remote-endpoint = <&adv7180>;
bus-width = <8>;
};
};
};
[1] video-interfaces.txt common video media interface
Device-Tree bindings for SUNXI IR controller found in sunXi SoC family
Required properties:
- compatible : should be "allwinner,sun4i-a10-ir";
- clocks : list of clock specifiers, corresponding to
entries in clock-names property;
- clock-names : should contain "apb" and "ir" entries;
- interrupts : should contain IR IRQ number;
- reg : should contain IO map address for IR.
Optional properties:
- linux,rc-map-name : Remote control map name.
Example:
ir0: ir@01c21800 {
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clock-names = "apb", "ir";
interrupts = <0 5 1>;
reg = <0x01C21800 0x40>;
linux,rc-map-name = "rc-rc6-mce";
};
...@@ -29,7 +29,7 @@ use IO::Handle; ...@@ -29,7 +29,7 @@ use IO::Handle;
"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
"lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv", "drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv",
"drxk_terratec_htc_stick", "sms1xxx_hcw"); "drxk_terratec_htc_stick", "sms1xxx_hcw", "si2165");
# Check args # Check args
syntax() if (scalar(@ARGV) != 1); syntax() if (scalar(@ARGV) != 1);
...@@ -783,6 +783,37 @@ sub sms1xxx_hcw { ...@@ -783,6 +783,37 @@ sub sms1xxx_hcw {
$allfiles; $allfiles;
} }
sub si2165 {
my $sourcefile = "model_111xxx_122xxx_driver_6_0_119_31191_WHQL.zip";
my $url = "http://www.hauppauge.de/files/drivers/";
my $hash = "76633e7c76b0edee47c3ba18ded99336";
my $fwfile = "dvb-demod-si2165.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url . $sourcefile);
verify($sourcefile, $hash);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/Driver10/Hcw10bda.sys", 0x80788, 0x81E08-0x80788, "$tmpdir/fw1");
delzero("$tmpdir/fw1","$tmpdir/fw1-1");
#verify("$tmpdir/fw1","5e0909858fdf0b5b09ad48b9fe622e70");
my $CRC="\x0A\xCC";
my $BLOCKS_MAIN="\x27";
open FW,">$fwfile";
print FW "\x01\x00"; # just a version id for the driver itself
print FW "\x9A"; # fw version
print FW "\x00"; # padding
print FW "$BLOCKS_MAIN"; # number of blocks of main part
print FW "\x00"; # padding
print FW "$CRC"; # 16bit crc value of main part
appendfile(FW,"$tmpdir/fw1");
"$fwfile";
}
# --------------------------------------------------------------- # ---------------------------------------------------------------
# Utilities # Utilities
......
...@@ -41,3 +41,5 @@ ...@@ -41,3 +41,5 @@
40 -> TurboSight TBS 6981 [6981:8888] 40 -> TurboSight TBS 6981 [6981:8888]
41 -> TurboSight TBS 6980 [6980:8888] 41 -> TurboSight TBS 6980 [6980:8888]
42 -> Leadtek Winfast PxPVR2200 [107d:6f21] 42 -> Leadtek Winfast PxPVR2200 [107d:6f21]
43 -> Hauppauge ImpactVCB-e [0070:7133]
44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98]
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340]
77 -> EM2874 Leadership ISDBT (em2874) 77 -> EM2874 Leadership ISDBT (em2874)
78 -> PCTV nanoStick T2 290e (em28174) 78 -> PCTV nanoStick T2 290e (em28174)
79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad,0ccd:10b6] 79 -> Terratec Cinergy H5 (em2884) [eb1a:2885,0ccd:10a2,0ccd:10ad,0ccd:10b6]
80 -> PCTV DVB-S2 Stick (460e) (em28174) 80 -> PCTV DVB-S2 Stick (460e) (em28174)
81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605] 81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605]
82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2] 82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2]
......
...@@ -77,9 +77,9 @@ Basic usage for V4L2 and sub-device drivers ...@@ -77,9 +77,9 @@ Basic usage for V4L2 and sub-device drivers
Where foo->v4l2_dev is of type struct v4l2_device. Where foo->v4l2_dev is of type struct v4l2_device.
Finally, remove all control functions from your v4l2_ioctl_ops: Finally, remove all control functions from your v4l2_ioctl_ops (if any):
vidioc_queryctrl, vidioc_querymenu, vidioc_g_ctrl, vidioc_s_ctrl, vidioc_queryctrl, vidioc_query_ext_ctrl, vidioc_querymenu, vidioc_g_ctrl,
vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls. vidioc_s_ctrl, vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls.
Those are now no longer needed. Those are now no longer needed.
1.3.2) For sub-device drivers do this: 1.3.2) For sub-device drivers do this:
...@@ -258,8 +258,8 @@ The new control value has already been validated, so all you need to do is ...@@ -258,8 +258,8 @@ The new control value has already been validated, so all you need to do is
to actually update the hardware registers. to actually update the hardware registers.
You're done! And this is sufficient for most of the drivers we have. No need You're done! And this is sufficient for most of the drivers we have. No need
to do any validation of control values, or implement QUERYCTRL/QUERYMENU. And to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported. and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
============================================================================== ==============================================================================
...@@ -288,30 +288,45 @@ of v4l2_device. ...@@ -288,30 +288,45 @@ of v4l2_device.
Accessing Control Values Accessing Control Values
======================== ========================
The v4l2_ctrl struct contains these two unions: The following union is used inside the control framework to access control
values:
/* The current control value. */ union v4l2_ctrl_ptr {
union { s32 *p_s32;
s64 *p_s64;
char *p_char;
void *p;
};
The v4l2_ctrl struct contains these fields that can be used to access both
current and new values:
s32 val;
struct {
s32 val; s32 val;
s64 val64;
char *string;
} cur; } cur;
/* The new control value. */
union {
s32 val;
s64 val64;
char *string;
};
Within the control ops you can freely use these. The val and val64 speak for union v4l2_ctrl_ptr p_new;
themselves. The string pointers point to character buffers of length union v4l2_ctrl_ptr p_cur;
If the control has a simple s32 type type, then:
&ctrl->val == ctrl->p_new.p_s32
&ctrl->cur.val == ctrl->p_cur.p_s32
For all other types use ctrl->p_cur.p<something>. Basically the val
and cur.val fields can be considered an alias since these are used so often.
Within the control ops you can freely use these. The val and cur.val speak for
themselves. The p_char pointers point to character buffers of length
ctrl->maximum + 1, and are always 0-terminated. ctrl->maximum + 1, and are always 0-terminated.
In most cases 'cur' contains the current cached control value. When you create Unless the control is marked volatile the p_cur field points to the the
a new control this value is made identical to the default value. After calling current cached control value. When you create a new control this value is made
v4l2_ctrl_handler_setup() this value is passed to the hardware. It is generally identical to the default value. After calling v4l2_ctrl_handler_setup() this
a good idea to call this function. value is passed to the hardware. It is generally a good idea to call this
function.
Whenever a new value is set that new value is automatically cached. This means Whenever a new value is set that new value is automatically cached. This means
that most drivers do not need to implement the g_volatile_ctrl() op. The that most drivers do not need to implement the g_volatile_ctrl() op. The
...@@ -362,8 +377,8 @@ will result in a deadlock since these helpers lock the handler as well. ...@@ -362,8 +377,8 @@ will result in a deadlock since these helpers lock the handler as well.
You can also take the handler lock yourself: You can also take the handler lock yourself:
mutex_lock(&state->ctrl_handler.lock); mutex_lock(&state->ctrl_handler.lock);
printk(KERN_INFO "String value is '%s'\n", ctrl1->cur.string); pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
printk(KERN_INFO "Integer value is '%s'\n", ctrl2->cur.val); pr_info("Integer value is '%s'\n", ctrl2->cur.val);
mutex_unlock(&state->ctrl_handler.lock); mutex_unlock(&state->ctrl_handler.lock);
......
...@@ -675,11 +675,6 @@ You should also set these fields: ...@@ -675,11 +675,6 @@ You should also set these fields:
video_device is initialized you *do* know which parent PCI device to use and video_device is initialized you *do* know which parent PCI device to use and
so you set dev_device to the correct PCI device. so you set dev_device to the correct PCI device.
- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
v4l2_fh. Eventually this flag will disappear once all drivers use the core
priority handling. But for now it has to be set explicitly.
If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2 If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
in your v4l2_file_operations struct. in your v4l2_file_operations struct.
...@@ -909,8 +904,7 @@ struct v4l2_fh ...@@ -909,8 +904,7 @@ struct v4l2_fh
struct v4l2_fh provides a way to easily keep file handle specific data struct v4l2_fh provides a way to easily keep file handle specific data
that is used by the V4L2 framework. New drivers must use struct v4l2_fh that is used by the V4L2 framework. New drivers must use struct v4l2_fh
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY) since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY).
if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
The users of v4l2_fh (in the V4L2 framework, not the driver) know The users of v4l2_fh (in the V4L2 framework, not the driver) know
whether a driver uses v4l2_fh as its file->private_data pointer by whether a driver uses v4l2_fh as its file->private_data pointer by
......
...@@ -883,11 +883,6 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -883,11 +883,6 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
vdev->v4l2_dev = &skel->v4l2_dev; vdev->v4l2_dev = &skel->v4l2_dev;
/* Supported SDTV standards, if any */ /* Supported SDTV standards, if any */
vdev->tvnorms = SKEL_TVNORMS; vdev->tvnorms = SKEL_TVNORMS;
/* If this bit is set, then the v4l2 core will provide the support
* for the VIDIOC_G/S_PRIORITY ioctls. This flag will eventually
* go away once all drivers have been converted to use struct v4l2_fh.
*/
set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
video_set_drvdata(vdev, skel); video_set_drvdata(vdev, skel);
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
......
...@@ -580,11 +580,6 @@ release()回调必须被设置,且在最后一个 video_device 用户退出之 ...@@ -580,11 +580,6 @@ release()回调必须被设置,且在最后一个 video_device 用户退出之
v4l2_device 无法与特定的 PCI 设备关联,所有没有设置父设备。但当 v4l2_device 无法与特定的 PCI 设备关联,所有没有设置父设备。但当
video_device 配置后,就知道使用哪个父 PCI 设备了。 video_device 配置后,就知道使用哪个父 PCI 设备了。
- flags:可选。如果你要让框架处理设置 VIDIOC_G/S_PRIORITY ioctls,
请设置 V4L2_FL_USE_FH_PRIO。这要求你使用 v4l2_fh 结构体。
一旦所有驱动使用了核心的优先级处理,最终这个标志将消失。但现在它
必须被显式设置。
如果你使用 v4l2_ioctl_ops,则应该在 v4l2_file_operations 结构体中 如果你使用 v4l2_ioctl_ops,则应该在 v4l2_file_operations 结构体中
设置 .unlocked_ioctl 指向 video_ioctl2。 设置 .unlocked_ioctl 指向 video_ioctl2。
...@@ -789,7 +784,7 @@ v4l2_fh 结构体 ...@@ -789,7 +784,7 @@ v4l2_fh 结构体
------------- -------------
v4l2_fh 结构体提供一个保存用于 V4L2 框架的文件句柄特定数据的简单方法。 v4l2_fh 结构体提供一个保存用于 V4L2 框架的文件句柄特定数据的简单方法。
如果 video_device 的 flag 设置了 V4L2_FL_USE_FH_PRIO 标志,新驱动 如果 video_device 标志,新驱动
必须使用 v4l2_fh 结构体,因为它也用于实现优先级处理(VIDIOC_G/S_PRIORITY)。 必须使用 v4l2_fh 结构体,因为它也用于实现优先级处理(VIDIOC_G/S_PRIORITY)。
v4l2_fh 的用户(位于 V4l2 框架中,并非驱动)可通过测试 v4l2_fh 的用户(位于 V4l2 框架中,并非驱动)可通过测试
......
...@@ -516,6 +516,16 @@ S: Supported ...@@ -516,6 +516,16 @@ S: Supported
F: fs/aio.c F: fs/aio.c
F: include/linux/*aio*.h F: include/linux/*aio*.h
AIRSPY MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/airspy/
ALCATEL SPEEDTOUCH USB DRIVER ALCATEL SPEEDTOUCH USB DRIVER
M: Duncan Sands <duncan.sands@free.fr> M: Duncan Sands <duncan.sands@free.fr>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
...@@ -3993,6 +4003,12 @@ F: Documentation/isdn/README.gigaset ...@@ -3993,6 +4003,12 @@ F: Documentation/isdn/README.gigaset
F: drivers/isdn/gigaset/ F: drivers/isdn/gigaset/
F: include/uapi/linux/gigaset_dev.h F: include/uapi/linux/gigaset_dev.h
GO7007 MPEG CODEC
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/usb/go7007/
GPIO SUBSYSTEM GPIO SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org> M: Linus Walleij <linus.walleij@linaro.org>
M: Alexandre Courbot <gnurou@gmail.com> M: Alexandre Courbot <gnurou@gmail.com>
...@@ -5965,9 +5981,9 @@ W: http://palosaari.fi/linux/ ...@@ -5965,9 +5981,9 @@ W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/ Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained S: Maintained
F: drivers/staging/media/msi3101/msi001* F: drivers/media/tuners/msi001*
MSI3101 MEDIA DRIVER MSI2500 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi> M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
W: http://linuxtv.org/ W: http://linuxtv.org/
...@@ -5975,7 +5991,7 @@ W: http://palosaari.fi/linux/ ...@@ -5975,7 +5991,7 @@ W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/ Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained S: Maintained
F: drivers/staging/media/msi3101/sdr-msi3101* F: drivers/media/usb/msi2500/
MT9M032 APTINA SENSOR DRIVER MT9M032 APTINA SENSOR DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
...@@ -6499,11 +6515,12 @@ L: linux-omap@vger.kernel.org ...@@ -6499,11 +6515,12 @@ L: linux-omap@vger.kernel.org
S: Maintained S: Maintained
F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
OMAP IMAGE SIGNAL PROCESSOR (ISP) OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
S: Maintained S: Maintained
F: drivers/media/platform/omap3isp/ F: drivers/media/platform/omap3isp/
F: drivers/staging/media/omap4iss/
OMAP USB SUPPORT OMAP USB SUPPORT
M: Felipe Balbi <balbi@ti.com> M: Felipe Balbi <balbi@ti.com>
...@@ -7611,7 +7628,7 @@ W: http://palosaari.fi/linux/ ...@@ -7611,7 +7628,7 @@ W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/ Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained S: Maintained
F: drivers/staging/media/rtl2832u_sdr/rtl2832_sdr* F: drivers/media/dvb-frontends/rtl2832_sdr*
RTL8180 WIRELESS DRIVER RTL8180 WIRELESS DRIVER
M: "John W. Linville" <linville@tuxdriver.com> M: "John W. Linville" <linville@tuxdriver.com>
...@@ -8380,6 +8397,12 @@ M: Chris Boot <bootc@bootc.net> ...@@ -8380,6 +8397,12 @@ M: Chris Boot <bootc@bootc.net>
S: Maintained S: Maintained
F: drivers/leds/leds-net48xx.c F: drivers/leds/leds-net48xx.c
SOFTLOGIC 6x10 MPEG CODEC
M: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/pci/solo6x10/
SOFTWARE RAID (Multiple Disks) SUPPORT SOFTWARE RAID (Multiple Disks) SUPPORT
M: Neil Brown <neilb@suse.de> M: Neil Brown <neilb@suse.de>
L: linux-raid@vger.kernel.org L: linux-raid@vger.kernel.org
...@@ -8586,11 +8609,6 @@ M: Marek Belisko <marek.belisko@gmail.com> ...@@ -8586,11 +8609,6 @@ M: Marek Belisko <marek.belisko@gmail.com>
S: Odd Fixes S: Odd Fixes
F: drivers/staging/ft1000/ F: drivers/staging/ft1000/
STAGING - GO7007 MPEG CODEC
M: Hans Verkuil <hans.verkuil@cisco.com>
S: Maintained
F: drivers/staging/media/go7007/
STAGING - INDUSTRIAL IO STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@kernel.org> M: Jonathan Cameron <jic23@kernel.org>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
...@@ -8648,11 +8666,6 @@ M: Christopher Harrer <charrer@alacritech.com> ...@@ -8648,11 +8666,6 @@ M: Christopher Harrer <charrer@alacritech.com>
S: Odd Fixes S: Odd Fixes
F: drivers/staging/slicoss/ F: drivers/staging/slicoss/
STAGING - SOFTLOGIC 6x10 MPEG CODEC
M: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
S: Supported
F: drivers/staging/media/solo6x10/
STAGING - SPEAKUP CONSOLE SPEECH DRIVER STAGING - SPEAKUP CONSOLE SPEECH DRIVER
M: William Hubbs <w.d.hubbs@gmail.com> M: William Hubbs <w.d.hubbs@gmail.com>
M: Chris Brannon <chris@the-brannons.com> M: Chris Brannon <chris@the-brannons.com>
...@@ -9519,15 +9532,6 @@ L: netdev@vger.kernel.org ...@@ -9519,15 +9532,6 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/usb/smsc95xx.* F: drivers/net/usb/smsc95xx.*
USB SN9C1xx DRIVER
M: Luca Risolia <luca.risolia@studio.unibo.it>
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://www.linux-projects.org
S: Maintained
F: drivers/staging/media/sn9c102/
USB SUBSYSTEM USB SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
......
...@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) ...@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
rdev->priv = data; rdev->priv = data;
rdev->driver_type = RC_DRIVER_IR_RAW; rdev->driver_type = RC_DRIVER_IR_RAW;
rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = picolcd_cir_open; rdev->open = picolcd_cir_open;
rdev->close = picolcd_cir_close; rdev->close = picolcd_cir_close;
rdev->input_name = data->hdev->name; rdev->input_name = data->hdev->name;
......
...@@ -59,6 +59,13 @@ config MEDIA_RADIO_SUPPORT ...@@ -59,6 +59,13 @@ config MEDIA_RADIO_SUPPORT
support radio reception. Disabling this option will support radio reception. Disabling this option will
disable support for them. disable support for them.
config MEDIA_SDR_SUPPORT
bool "Software defined radio support"
---help---
Enable software defined radio support.
Say Y when you have a software defined radio device.
config MEDIA_RC_SUPPORT config MEDIA_RC_SUPPORT
bool "Remote Controller support" bool "Remote Controller support"
depends on INPUT depends on INPUT
...@@ -95,7 +102,7 @@ config MEDIA_CONTROLLER ...@@ -95,7 +102,7 @@ config MEDIA_CONTROLLER
config VIDEO_DEV config VIDEO_DEV
tristate tristate
depends on MEDIA_SUPPORT depends on MEDIA_SUPPORT
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
default y default y
config VIDEO_V4L2_SUBDEV_API config VIDEO_V4L2_SUBDEV_API
...@@ -171,10 +178,11 @@ comment "Media ancillary drivers (tuners, sensors, i2c, frontends)" ...@@ -171,10 +178,11 @@ comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
config MEDIA_SUBDRV_AUTOSELECT config MEDIA_SUBDRV_AUTOSELECT
bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)" bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)"
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT || MEDIA_SDR_SUPPORT
depends on HAS_IOMEM depends on HAS_IOMEM
select I2C select I2C
select I2C_MUX select I2C_MUX
select SPI
default y default y
help help
By default, a media driver auto-selects all possible ancillary By default, a media driver auto-selects all possible ancillary
......
...@@ -533,13 +533,12 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) ...@@ -533,13 +533,12 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
saa7146_vbi_uops.init(dev,vv); saa7146_vbi_uops.init(dev,vv);
fmt = &vv->ov_fb.fmt; vv->ov_fb.fmt.width = vv->standard->h_max_out;
fmt->width = vv->standard->h_max_out; vv->ov_fb.fmt.height = vv->standard->v_max_out;
fmt->height = vv->standard->v_max_out; vv->ov_fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
fmt->pixelformat = V4L2_PIX_FMT_RGB565; vv->ov_fb.fmt.bytesperline = 2 * vv->ov_fb.fmt.width;
fmt->bytesperline = 2 * fmt->width; vv->ov_fb.fmt.sizeimage = vv->ov_fb.fmt.bytesperline * vv->ov_fb.fmt.height;
fmt->sizeimage = fmt->bytesperline * fmt->height; vv->ov_fb.fmt.colorspace = V4L2_COLORSPACE_SRGB;
fmt->colorspace = V4L2_COLORSPACE_SRGB;
fmt = &vv->video_fmt; fmt = &vv->video_fmt;
fmt->width = 384; fmt->width = 384;
...@@ -613,7 +612,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, ...@@ -613,7 +612,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
vfd->lock = &dev->v4l2_lock; vfd->lock = &dev->v4l2_lock;
vfd->v4l2_dev = &dev->v4l2_dev; vfd->v4l2_dev = &dev->v4l2_dev;
vfd->tvnorms = 0; vfd->tvnorms = 0;
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
for (i = 0; i < dev->ext_vv_data->num_stds; i++) for (i = 0; i < dev->ext_vv_data->num_stds; i++)
vfd->tvnorms |= dev->ext_vv_data->stds[i].id; vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
strlcpy(vfd->name, name, sizeof(vfd->name)); strlcpy(vfd->name, name, sizeof(vfd->name));
......
...@@ -22,8 +22,7 @@ config SMS_SIANO_DEBUGFS ...@@ -22,8 +22,7 @@ config SMS_SIANO_DEBUGFS
bool "Enable debugfs for smsdvb" bool "Enable debugfs for smsdvb"
depends on SMS_SIANO_MDTV depends on SMS_SIANO_MDTV
depends on DEBUG_FS depends on DEBUG_FS
depends on SMS_USB_DRV depends on SMS_USB_DRV = SMS_SDIO_DRV
depends on CONFIG_SMS_USB_DRV = CONFIG_SMS_SDIO_DRV
---help--- ---help---
Choose Y to enable visualizing a dump of the frontend Choose Y to enable visualizing a dump of the frontend
......
...@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev) ...@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
dev->priv = coredev; dev->priv = coredev;
dev->driver_type = RC_DRIVER_IR_RAW; dev->driver_type = RC_DRIVER_IR_RAW;
rc_set_allowed_protocols(dev, RC_BIT_ALL); dev->allowed_protocols = RC_BIT_ALL;
dev->map_name = sms_get_board(board_id)->rc_codes; dev->map_name = sms_get_board(board_id)->rc_codes;
dev->driver_name = MODULE_NAME; dev->driver_name = MODULE_NAME;
......
...@@ -244,6 +244,7 @@ ...@@ -244,6 +244,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d #define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
...@@ -363,6 +364,7 @@ ...@@ -363,6 +364,7 @@
#define USB_PID_TVWAY_PLUS 0x0002 #define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d #define USB_PID_SVEON_STV20 0xe39d
#define USB_PID_SVEON_STV20_RTL2832U 0xd39d #define USB_PID_SVEON_STV20_RTL2832U 0xd39d
#define USB_PID_SVEON_STV21 0xd3b0
#define USB_PID_SVEON_STV22 0xe401 #define USB_PID_SVEON_STV22 0xe401
#define USB_PID_SVEON_STV22_IT9137 0xe411 #define USB_PID_SVEON_STV22_IT9137 0xe411
#define USB_PID_AZUREWAVE_AZ6027 0x3275 #define USB_PID_AZUREWAVE_AZ6027 0x3275
......
...@@ -96,10 +96,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open( ...@@ -96,10 +96,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
* FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
*/ */
#define DVB_FE_NO_EXIT 0
#define DVB_FE_NORMAL_EXIT 1
#define DVB_FE_DEVICE_REMOVED 2
static DEFINE_MUTEX(frontend_mutex); static DEFINE_MUTEX(frontend_mutex);
struct dvb_frontend_private { struct dvb_frontend_private {
...@@ -113,7 +109,6 @@ struct dvb_frontend_private { ...@@ -113,7 +109,6 @@ struct dvb_frontend_private {
wait_queue_head_t wait_queue; wait_queue_head_t wait_queue;
struct task_struct *thread; struct task_struct *thread;
unsigned long release_jiffies; unsigned long release_jiffies;
unsigned int exit;
unsigned int wakeup; unsigned int wakeup;
fe_status_t status; fe_status_t status;
unsigned long tune_mode_flags; unsigned long tune_mode_flags;
...@@ -565,7 +560,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) ...@@ -565,7 +560,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
{ {
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
if (fepriv->exit != DVB_FE_NO_EXIT) if (fe->exit != DVB_FE_NO_EXIT)
return 1; return 1;
if (fepriv->dvbdev->writers == 1) if (fepriv->dvbdev->writers == 1)
...@@ -629,7 +624,7 @@ static int dvb_frontend_thread(void *data) ...@@ -629,7 +624,7 @@ static int dvb_frontend_thread(void *data)
/* got signal or quitting */ /* got signal or quitting */
if (!down_interruptible(&fepriv->sem)) if (!down_interruptible(&fepriv->sem))
semheld = true; semheld = true;
fepriv->exit = DVB_FE_NORMAL_EXIT; fe->exit = DVB_FE_NORMAL_EXIT;
break; break;
} }
...@@ -739,9 +734,9 @@ static int dvb_frontend_thread(void *data) ...@@ -739,9 +734,9 @@ static int dvb_frontend_thread(void *data)
fepriv->thread = NULL; fepriv->thread = NULL;
if (kthread_should_stop()) if (kthread_should_stop())
fepriv->exit = DVB_FE_DEVICE_REMOVED; fe->exit = DVB_FE_DEVICE_REMOVED;
else else
fepriv->exit = DVB_FE_NO_EXIT; fe->exit = DVB_FE_NO_EXIT;
mb(); mb();
if (semheld) if (semheld)
...@@ -756,7 +751,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) ...@@ -756,7 +751,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__); dev_dbg(fe->dvb->device, "%s:\n", __func__);
fepriv->exit = DVB_FE_NORMAL_EXIT; if (fe->exit != DVB_FE_DEVICE_REMOVED)
fe->exit = DVB_FE_NORMAL_EXIT;
mb(); mb();
if (!fepriv->thread) if (!fepriv->thread)
...@@ -826,7 +822,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -826,7 +822,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__); dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->thread) { if (fepriv->thread) {
if (fepriv->exit == DVB_FE_NO_EXIT) if (fe->exit == DVB_FE_NO_EXIT)
return 0; return 0;
else else
dvb_frontend_stop (fe); dvb_frontend_stop (fe);
...@@ -838,7 +834,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -838,7 +834,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return -EINTR; return -EINTR;
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
fepriv->exit = DVB_FE_NO_EXIT; fe->exit = DVB_FE_NO_EXIT;
fepriv->thread = NULL; fepriv->thread = NULL;
mb(); mb();
...@@ -1906,7 +1902,7 @@ static int dvb_frontend_ioctl(struct file *file, ...@@ -1906,7 +1902,7 @@ static int dvb_frontend_ioctl(struct file *file,
if (down_interruptible(&fepriv->sem)) if (down_interruptible(&fepriv->sem))
return -ERESTARTSYS; return -ERESTARTSYS;
if (fepriv->exit != DVB_FE_NO_EXIT) { if (fe->exit != DVB_FE_NO_EXIT) {
up(&fepriv->sem); up(&fepriv->sem);
return -ENODEV; return -ENODEV;
} }
...@@ -2424,7 +2420,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) ...@@ -2424,7 +2420,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
int ret; int ret;
dev_dbg(fe->dvb->device, "%s:\n", __func__); dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->exit == DVB_FE_DEVICE_REMOVED) if (fe->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV; return -ENODEV;
if (adapter->mfe_shared) { if (adapter->mfe_shared) {
...@@ -2529,7 +2525,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) ...@@ -2529,7 +2525,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (dvbdev->users == -1) { if (dvbdev->users == -1) {
wake_up(&fepriv->wait_queue); wake_up(&fepriv->wait_queue);
if (fepriv->exit != DVB_FE_NO_EXIT) if (fe->exit != DVB_FE_NO_EXIT)
wake_up(&dvbdev->wait_queue); wake_up(&dvbdev->wait_queue);
if (fe->ops.ts_bus_ctrl) if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0); fe->ops.ts_bus_ctrl(fe, 0);
...@@ -2572,12 +2568,14 @@ int dvb_frontend_resume(struct dvb_frontend *fe) ...@@ -2572,12 +2568,14 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num, dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
fe->id); fe->id);
fe->exit = DVB_FE_DEVICE_RESUME;
if (fe->ops.init) if (fe->ops.init)
ret = fe->ops.init(fe); ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.init) if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe); ret = fe->ops.tuner_ops.init(fe);
fe->exit = DVB_FE_NO_EXIT;
fepriv->state = FESTATE_RETUNE; fepriv->state = FESTATE_RETUNE;
dvb_frontend_wakeup(fe); dvb_frontend_wakeup(fe);
...@@ -2666,20 +2664,20 @@ void dvb_frontend_detach(struct dvb_frontend* fe) ...@@ -2666,20 +2664,20 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
if (fe->ops.release_sec) { if (fe->ops.release_sec) {
fe->ops.release_sec(fe); fe->ops.release_sec(fe);
symbol_put_addr(fe->ops.release_sec); dvb_detach(fe->ops.release_sec);
} }
if (fe->ops.tuner_ops.release) { if (fe->ops.tuner_ops.release) {
fe->ops.tuner_ops.release(fe); fe->ops.tuner_ops.release(fe);
symbol_put_addr(fe->ops.tuner_ops.release); dvb_detach(fe->ops.tuner_ops.release);
} }
if (fe->ops.analog_ops.release) { if (fe->ops.analog_ops.release) {
fe->ops.analog_ops.release(fe); fe->ops.analog_ops.release(fe);
symbol_put_addr(fe->ops.analog_ops.release); dvb_detach(fe->ops.analog_ops.release);
} }
ptr = (void*)fe->ops.release; ptr = (void*)fe->ops.release;
if (ptr) { if (ptr) {
fe->ops.release(fe); fe->ops.release(fe);
symbol_put_addr(ptr); dvb_detach(ptr);
} }
} }
#else #else
......
...@@ -405,6 +405,11 @@ struct dtv_frontend_properties { ...@@ -405,6 +405,11 @@ struct dtv_frontend_properties {
struct dtv_fe_stats block_count; struct dtv_fe_stats block_count;
}; };
#define DVB_FE_NO_EXIT 0
#define DVB_FE_NORMAL_EXIT 1
#define DVB_FE_DEVICE_REMOVED 2
#define DVB_FE_DEVICE_RESUME 3
struct dvb_frontend { struct dvb_frontend {
struct dvb_frontend_ops ops; struct dvb_frontend_ops ops;
struct dvb_adapter *dvb; struct dvb_adapter *dvb;
...@@ -418,6 +423,7 @@ struct dvb_frontend { ...@@ -418,6 +423,7 @@ struct dvb_frontend {
#define DVB_FRONTEND_COMPONENT_DEMOD 1 #define DVB_FRONTEND_COMPONENT_DEMOD 1
int (*callback)(void *adapter_priv, int component, int cmd, int arg); int (*callback)(void *adapter_priv, int component, int cmd, int arg);
int id; int id;
unsigned int exit;
}; };
extern int dvb_register_frontend(struct dvb_adapter *dvb, extern int dvb_register_frontend(struct dvb_adapter *dvb,
......
...@@ -136,11 +136,15 @@ extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, ...@@ -136,11 +136,15 @@ extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
__r; \ __r; \
}) })
#define dvb_detach(FUNC) symbol_put_addr(FUNC)
#else #else
#define dvb_attach(FUNCTION, ARGS...) ({ \ #define dvb_attach(FUNCTION, ARGS...) ({ \
FUNCTION(ARGS); \ FUNCTION(ARGS); \
}) })
#define dvb_detach(FUNC) {}
#endif #endif
#endif /* #ifndef _DVBDEV_H_ */ #endif /* #ifndef _DVBDEV_H_ */
...@@ -63,6 +63,15 @@ config DVB_TDA18271C2DD ...@@ -63,6 +63,15 @@ config DVB_TDA18271C2DD
Say Y when you want to support this tuner. Say Y when you want to support this tuner.
config DVB_SI2165
tristate "Silicon Labs si2165 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C/T demodulator.
Say Y when you want to support this frontend.
comment "DVB-S (satellite) frontends" comment "DVB-S (satellite) frontends"
depends on DVB_CORE depends on DVB_CORE
...@@ -446,6 +455,15 @@ config DVB_RTL2832 ...@@ -446,6 +455,15 @@ config DVB_RTL2832
help help
Say Y when you want to support this frontend. Say Y when you want to support this frontend.
config DVB_RTL2832_SDR
tristate "Realtek RTL2832 SDR"
depends on DVB_CORE && I2C && I2C_MUX && VIDEO_V4L2 && MEDIA_SDR_SUPPORT && USB
select DVB_RTL2832
select VIDEOBUF2_VMALLOC
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this SDR module.
config DVB_SI2168 config DVB_SI2168
tristate "Silicon Labs Si2168" tristate "Silicon Labs Si2168"
depends on DVB_CORE && I2C && I2C_MUX depends on DVB_CORE && I2C && I2C_MUX
......
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
ccflags-y += -I$(srctree)/drivers/media/dvb-core/ ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/ ccflags-y += -I$(srctree)/drivers/media/tuners/
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
ifdef CONFIG_DVB_RTL2832_SDR
ccflags-y += -I$(srctree)/drivers/media/usb/dvb-usb-v2
endif
stb0899-objs := stb0899_drv.o stb0899_algo.o stb0899-objs := stb0899_drv.o stb0899_algo.o
stv0900-objs := stv0900_core.o stv0900_sw.o stv0900-objs := stv0900_core.o stv0900_sw.o
drxd-objs := drxd_firm.o drxd_hard.o drxd-objs := drxd_firm.o drxd_hard.o
...@@ -100,10 +105,12 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o ...@@ -100,10 +105,12 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o obj-$(CONFIG_DVB_AF9033) += af9033.o
...@@ -470,7 +470,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe) ...@@ -470,7 +470,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
break; break;
default: default:
goto err; goto err;
break;
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
......
...@@ -220,7 +220,7 @@ static void setup_vbi(struct au8522_state *state, int aud_input) ...@@ -220,7 +220,7 @@ static void setup_vbi(struct au8522_state *state, int aud_input)
} }
static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) static void setup_decoder_defaults(struct au8522_state *state, bool is_svideo)
{ {
int i; int i;
int filter_coef_type; int filter_coef_type;
...@@ -237,13 +237,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) ...@@ -237,13 +237,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
/* Other decoder registers */ /* Other decoder registers */
au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
if (input_mode == 0x23) { if (is_svideo)
/* S-Video input mapping */
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04); au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
} else { else
/* All other modes (CVBS/ATVRF etc.) */
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00); au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
}
au8522_writereg(state, AU8522_TVDEC_PGA_REG012H, au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
AU8522_TVDEC_PGA_REG012H_CVBS); AU8522_TVDEC_PGA_REG012H_CVBS);
...@@ -251,12 +248,23 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) ...@@ -251,12 +248,23 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_MODE_REG015H_CVBS); AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H, au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
AU8522_TVDED_DBG_MODE_REG060H_CVBS); AU8522_TVDED_DBG_MODE_REG060H_CVBS);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 | if (state->std == V4L2_STD_PAL_M) {
AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 | au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN); AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H, AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC); AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M);
} else {
/* NTSC */
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
}
au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H, au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS); AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H, au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
...@@ -275,8 +283,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) ...@@ -275,8 +283,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS); AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH, au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS); AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || if (is_svideo) {
input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH, au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO); AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH, au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
...@@ -317,8 +324,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) ...@@ -317,8 +324,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
setup_vbi(state, 0); setup_vbi(state, 0);
if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || if (is_svideo) {
input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
/* Despite what the table says, for the HVR-950q we still need /* Despite what the table says, for the HVR-950q we still need
to be in CVBS mode for the S-Video input (reason unknown). */ to be in CVBS mode for the S-Video input (reason unknown). */
/* filter_coef_type = 3; */ /* filter_coef_type = 3; */
...@@ -346,7 +352,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) ...@@ -346,7 +352,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
au8522_writereg(state, AU8522_REG436H, 0x3c); au8522_writereg(state, AU8522_REG436H, 0x3c);
} }
static void au8522_setup_cvbs_mode(struct au8522_state *state) static void au8522_setup_cvbs_mode(struct au8522_state *state, u8 input_mode)
{ {
/* here we're going to try the pre-programmed route */ /* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
...@@ -358,16 +364,16 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state) ...@@ -358,16 +364,16 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
/* Enable clamping control */ /* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00); au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); setup_decoder_defaults(state, false);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
} }
static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state) static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state,
u8 input_mode)
{ {
/* here we're going to try the pre-programmed route */ /* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
...@@ -384,24 +390,22 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state) ...@@ -384,24 +390,22 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */ /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
setup_decoder_defaults(state, setup_decoder_defaults(state, false);
AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
} }
static void au8522_setup_svideo_mode(struct au8522_state *state) static void au8522_setup_svideo_mode(struct au8522_state *state,
u8 input_mode)
{ {
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO); AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
/* Set input to Y on Channe1, C on Channel 3 */ /* Set input to Y on Channe1, C on Channel 3 */
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
/* PGA in automatic mode */ /* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
...@@ -409,8 +413,7 @@ static void au8522_setup_svideo_mode(struct au8522_state *state) ...@@ -409,8 +413,7 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
/* Enable clamping control */ /* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00); au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
setup_decoder_defaults(state, setup_decoder_defaults(state, true);
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
...@@ -432,8 +435,9 @@ static void disable_audio_input(struct au8522_state *state) ...@@ -432,8 +435,9 @@ static void disable_audio_input(struct au8522_state *state)
} }
/* 0=disable, 1=SIF */ /* 0=disable, 1=SIF */
static void set_audio_input(struct au8522_state *state, int aud_input) static void set_audio_input(struct au8522_state *state)
{ {
int aud_input = state->aud_input;
int i; int i;
/* Note that this function needs to be used in conjunction with setting /* Note that this function needs to be used in conjunction with setting
...@@ -465,8 +469,9 @@ static void set_audio_input(struct au8522_state *state, int aud_input) ...@@ -465,8 +469,9 @@ static void set_audio_input(struct au8522_state *state, int aud_input)
au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
msleep(150); msleep(150);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00); au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
msleep(1); msleep(10);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d); au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
msleep(50); msleep(50);
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
...@@ -539,58 +544,109 @@ static int au8522_s_register(struct v4l2_subdev *sd, ...@@ -539,58 +544,109 @@ static int au8522_s_register(struct v4l2_subdev *sd,
} }
#endif #endif
static void au8522_video_set(struct au8522_state *state)
{
u8 input_mode;
au8522_writereg(state, 0xa4, 1 << 5);
switch (state->vid_input) {
case AU8522_COMPOSITE_CH1:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH1;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH2:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH2;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH3:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH3;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH4:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_SVIDEO_CH13:
input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13;
au8522_setup_svideo_mode(state, input_mode);
break;
case AU8522_SVIDEO_CH24:
input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24;
au8522_setup_svideo_mode(state, input_mode);
break;
default:
case AU8522_COMPOSITE_CH4_SIF:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF;
au8522_setup_cvbs_tuner_mode(state, input_mode);
break;
}
}
static int au8522_s_stream(struct v4l2_subdev *sd, int enable) static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
{ {
struct au8522_state *state = to_state(sd); struct au8522_state *state = to_state(sd);
if (enable) { if (enable) {
/*
* Clear out any state associated with the digital side of the
* chip, so that when it gets powered back up it won't think
* that it is already tuned
*/
state->current_frequency = 0;
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
0x01); 0x01);
msleep(1); msleep(10);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); au8522_video_set(state);
set_audio_input(state);
state->operational_mode = AU8522_ANALOG_MODE;
} else { } else {
/* This does not completely power down the device /* This does not completely power down the device
(it only reduces it from around 140ma to 80ma) */ (it only reduces it from around 140ma to 80ma) */
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
1 << 5); 1 << 5);
state->operational_mode = AU8522_SUSPEND_MODE;
} }
return 0; return 0;
} }
static int au8522_reset(struct v4l2_subdev *sd, u32 val) static int au8522_s_video_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{ {
struct au8522_state *state = to_state(sd); struct au8522_state *state = to_state(sd);
state->operational_mode = AU8522_ANALOG_MODE; switch(input) {
case AU8522_COMPOSITE_CH1:
/* Clear out any state associated with the digital side of the case AU8522_SVIDEO_CH13:
chip, so that when it gets powered back up it won't think case AU8522_COMPOSITE_CH4_SIF:
that it is already tuned */ state->vid_input = input;
state->current_frequency = 0; break;
default:
printk(KERN_ERR "au8522 mode not currently supported\n");
return -EINVAL;
}
au8522_writereg(state, 0xa4, 1 << 5); if (state->operational_mode == AU8522_ANALOG_MODE)
au8522_video_set(state);
return 0; return 0;
} }
static int au8522_s_video_routing(struct v4l2_subdev *sd, static int au8522_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
u32 input, u32 output, u32 config)
{ {
struct au8522_state *state = to_state(sd); struct au8522_state *state = to_state(sd);
au8522_reset(sd, 0); if ((std & (V4L2_STD_PAL_M | V4L2_STD_NTSC_M)) == 0)
if (input == AU8522_COMPOSITE_CH1) {
au8522_setup_cvbs_mode(state);
} else if (input == AU8522_SVIDEO_CH13) {
au8522_setup_svideo_mode(state);
} else if (input == AU8522_COMPOSITE_CH4_SIF) {
au8522_setup_cvbs_tuner_mode(state);
} else {
printk(KERN_ERR "au8522 mode not currently supported\n");
return -EINVAL; return -EINVAL;
}
state->std = std;
if (state->operational_mode == AU8522_ANALOG_MODE)
au8522_video_set(state);
return 0; return 0;
} }
...@@ -598,7 +654,12 @@ static int au8522_s_audio_routing(struct v4l2_subdev *sd, ...@@ -598,7 +654,12 @@ static int au8522_s_audio_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config) u32 input, u32 output, u32 config)
{ {
struct au8522_state *state = to_state(sd); struct au8522_state *state = to_state(sd);
set_audio_input(state, input);
state->aud_input = input;
if (state->operational_mode == AU8522_ANALOG_MODE)
set_audio_input(state);
return 0; return 0;
} }
...@@ -629,7 +690,6 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) ...@@ -629,7 +690,6 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
static const struct v4l2_subdev_core_ops au8522_core_ops = { static const struct v4l2_subdev_core_ops au8522_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status, .log_status = v4l2_ctrl_subdev_log_status,
.reset = au8522_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = au8522_g_register, .g_register = au8522_g_register,
.s_register = au8522_s_register, .s_register = au8522_s_register,
...@@ -647,6 +707,7 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = { ...@@ -647,6 +707,7 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
static const struct v4l2_subdev_video_ops au8522_video_ops = { static const struct v4l2_subdev_video_ops au8522_video_ops = {
.s_routing = au8522_s_video_routing, .s_routing = au8522_s_video_routing,
.s_stream = au8522_s_stream, .s_stream = au8522_s_stream,
.s_std = au8522_s_std,
}; };
static const struct v4l2_subdev_ops au8522_ops = { static const struct v4l2_subdev_ops au8522_ops = {
...@@ -729,6 +790,7 @@ static int au8522_probe(struct i2c_client *client, ...@@ -729,6 +790,7 @@ static int au8522_probe(struct i2c_client *client,
} }
state->c = client; state->c = client;
state->std = V4L2_STD_NTSC_M;
state->vid_input = AU8522_COMPOSITE_CH1; state->vid_input = AU8522_COMPOSITE_CH1;
state->aud_input = AU8522_AUDIO_NONE; state->aud_input = AU8522_AUDIO_NONE;
state->id = 8522; state->id = 8522;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define AU8522_ANALOG_MODE 0 #define AU8522_ANALOG_MODE 0
#define AU8522_DIGITAL_MODE 1 #define AU8522_DIGITAL_MODE 1
#define AU8522_SUSPEND_MODE 2
struct au8522_state { struct au8522_state {
struct i2c_client *c; struct i2c_client *c;
...@@ -347,6 +348,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led); ...@@ -347,6 +348,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
/* Format control 2 */ /* Format control 2 */
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT 0x00 #define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT 0x00
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC 0x01 #define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC 0x01
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M 0x02
#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 #define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
......
...@@ -52,6 +52,12 @@ struct cxd2820r_config { ...@@ -52,6 +52,12 @@ struct cxd2820r_config {
*/ */
u8 ts_mode; u8 ts_mode;
/* TS clock inverted.
* Default: 0
* Values: 0, 1
*/
bool ts_clock_inv;
/* IF AGC polarity. /* IF AGC polarity.
* Default: 0 * Default: 0
* Values: 0, 1 * Values: 0, 1
......
...@@ -45,6 +45,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) ...@@ -45,6 +45,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
{ 0x1008b, 0x07, 0xff }, { 0x1008b, 0x07, 0xff },
{ 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 }, { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
{ 0x10070, priv->cfg.ts_mode, 0xff }, { 0x10070, priv->cfg.ts_mode, 0xff },
{ 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 },
}; };
dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__,
......
...@@ -46,6 +46,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) ...@@ -46,6 +46,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
{ 0x00088, 0x01, 0xff }, { 0x00088, 0x01, 0xff },
{ 0x00070, priv->cfg.ts_mode, 0xff }, { 0x00070, priv->cfg.ts_mode, 0xff },
{ 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 },
{ 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 }, { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x000a5, 0x00, 0x01 }, { 0x000a5, 0x00, 0x01 },
{ 0x00082, 0x20, 0x60 }, { 0x00082, 0x20, 0x60 },
......
...@@ -47,6 +47,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) ...@@ -47,6 +47,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
{ 0x02083, 0x0a, 0xff }, { 0x02083, 0x0a, 0xff },
{ 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 }, { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x02070, priv->cfg.ts_mode, 0xff }, { 0x02070, priv->cfg.ts_mode, 0xff },
{ 0x02071, !priv->cfg.ts_clock_inv << 6, 0x40 },
{ 0x020b5, priv->cfg.spec_inv << 4, 0x10 }, { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
{ 0x02567, 0x07, 0x0f }, { 0x02567, 0x07, 0x0f },
{ 0x02569, 0x03, 0x03 }, { 0x02569, 0x03, 0x03 },
......
...@@ -2557,10 +2557,19 @@ static int dib0090_set_params(struct dvb_frontend *fe) ...@@ -2557,10 +2557,19 @@ static int dib0090_set_params(struct dvb_frontend *fe)
do { do {
ret = dib0090_tune(fe); ret = dib0090_tune(fe);
if (ret != FE_CALLBACK_TIME_NEVER) if (ret == FE_CALLBACK_TIME_NEVER)
msleep(ret / 10);
else
break; break;
/*
* Despite dib0090_tune returns time at a 0.1 ms range,
* the actual sleep time depends on CONFIG_HZ. The worse case
* is when CONFIG_HZ=100. In such case, the minimum granularity
* is 10ms. On some real field tests, the tuner sometimes don't
* lock when this timer is lower than 10ms. So, enforce a 10ms
* granularity and use usleep_range() instead of msleep().
*/
ret = 10 * (ret + 99)/100;
usleep_range(ret * 1000, (ret + 1) * 1000);
} while (state->tune_state != CT_TUNER_STOP); } while (state->tune_state != CT_TUNER_STOP);
return 0; return 0;
......
...@@ -1041,10 +1041,7 @@ static int dib7000m_tune(struct dvb_frontend *demod) ...@@ -1041,10 +1041,7 @@ static int dib7000m_tune(struct dvb_frontend *demod)
u16 value; u16 value;
// we are already tuned - just resuming from suspend // we are already tuned - just resuming from suspend
if (ch != NULL) dib7000m_set_channel(state, ch, 0);
dib7000m_set_channel(state, ch, 0);
else
return -EINVAL;
// restart demod // restart demod
ret |= dib7000m_write_word(state, 898, 0x4000); ret |= dib7000m_write_word(state, 898, 0x4000);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/div64.h>
#include "dvb_math.h" #include "dvb_math.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
...@@ -72,6 +73,12 @@ struct dib7000p_state { ...@@ -72,6 +73,12 @@ struct dib7000p_state {
struct mutex i2c_buffer_lock; struct mutex i2c_buffer_lock;
u8 input_mode_mpeg; u8 input_mode_mpeg;
/* for DVBv5 stats */
s64 old_ucb;
unsigned long per_jiffies_stats;
unsigned long ber_jiffies_stats;
unsigned long get_stats_time;
}; };
enum dib7000p_power_mode { enum dib7000p_power_mode {
...@@ -401,7 +408,7 @@ static int dib7000p_sad_calib(struct dib7000p_state *state) ...@@ -401,7 +408,7 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
return 0; return 0;
} }
int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) static int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
{ {
struct dib7000p_state *state = demod->demodulator_priv; struct dib7000p_state *state = demod->demodulator_priv;
if (value > 4095) if (value > 4095)
...@@ -409,9 +416,8 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) ...@@ -409,9 +416,8 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
state->wbd_ref = value; state->wbd_ref = value;
return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
} }
EXPORT_SYMBOL(dib7000p_set_wbd_ref);
int dib7000p_get_agc_values(struct dvb_frontend *fe, static int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd) u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
...@@ -427,14 +433,12 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe, ...@@ -427,14 +433,12 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe,
return 0; return 0;
} }
EXPORT_SYMBOL(dib7000p_get_agc_values);
int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v) static int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
return dib7000p_write_word(state, 108, v); return dib7000p_write_word(state, 108, v);
} }
EXPORT_SYMBOL(dib7000p_set_agc1_min);
static void dib7000p_reset_pll(struct dib7000p_state *state) static void dib7000p_reset_pll(struct dib7000p_state *state)
{ {
...@@ -478,7 +482,7 @@ static u32 dib7000p_get_internal_freq(struct dib7000p_state *state) ...@@ -478,7 +482,7 @@ static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
return internal; return internal;
} }
int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw) static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856); u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
...@@ -513,7 +517,6 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config ...@@ -513,7 +517,6 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config
} }
return -EIO; return -EIO;
} }
EXPORT_SYMBOL(dib7000p_update_pll);
static int dib7000p_reset_gpio(struct dib7000p_state *st) static int dib7000p_reset_gpio(struct dib7000p_state *st)
{ {
...@@ -546,12 +549,11 @@ static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) ...@@ -546,12 +549,11 @@ static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
return 0; return 0;
} }
int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val) static int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
{ {
struct dib7000p_state *state = demod->demodulator_priv; struct dib7000p_state *state = demod->demodulator_priv;
return dib7000p_cfg_gpio(state, num, dir, val); return dib7000p_cfg_gpio(state, num, dir, val);
} }
EXPORT_SYMBOL(dib7000p_set_gpio);
static u16 dib7000p_defaults[] = { static u16 dib7000p_defaults[] = {
// auto search configuration // auto search configuration
...@@ -636,6 +638,8 @@ static u16 dib7000p_defaults[] = { ...@@ -636,6 +638,8 @@ static u16 dib7000p_defaults[] = {
0, 0,
}; };
static void dib7000p_reset_stats(struct dvb_frontend *fe);
static int dib7000p_demod_reset(struct dib7000p_state *state) static int dib7000p_demod_reset(struct dib7000p_state *state)
{ {
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
...@@ -934,7 +938,7 @@ static void dib7000p_update_timf(struct dib7000p_state *state) ...@@ -934,7 +938,7 @@ static void dib7000p_update_timf(struct dib7000p_state *state)
} }
u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) static u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
switch (op) { switch (op) {
...@@ -950,7 +954,6 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf) ...@@ -950,7 +954,6 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
dib7000p_set_bandwidth(state, state->current_bandwidth); dib7000p_set_bandwidth(state, state->current_bandwidth);
return state->timf; return state->timf;
} }
EXPORT_SYMBOL(dib7000p_ctrl_timf);
static void dib7000p_set_channel(struct dib7000p_state *state, static void dib7000p_set_channel(struct dib7000p_state *state,
struct dtv_frontend_properties *ch, u8 seq) struct dtv_frontend_properties *ch, u8 seq)
...@@ -1360,6 +1363,9 @@ static int dib7000p_tune(struct dvb_frontend *demod) ...@@ -1360,6 +1363,9 @@ static int dib7000p_tune(struct dvb_frontend *demod)
dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz)); dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
dib7000p_reset_stats(demod);
return 0; return 0;
} }
...@@ -1552,6 +1558,8 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe) ...@@ -1552,6 +1558,8 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe)
return ret; return ret;
} }
static int dib7000p_get_stats(struct dvb_frontend *fe, fe_status_t stat);
static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat) static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
...@@ -1570,6 +1578,8 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat) ...@@ -1570,6 +1578,8 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
if ((lock & 0x0038) == 0x38) if ((lock & 0x0038) == 0x38)
*stat |= FE_HAS_LOCK; *stat |= FE_HAS_LOCK;
dib7000p_get_stats(fe, *stat);
return 0; return 0;
} }
...@@ -1595,7 +1605,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength ...@@ -1595,7 +1605,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength
return 0; return 0;
} }
static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr) static u32 dib7000p_get_snr(struct dvb_frontend *fe)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
u16 val; u16 val;
...@@ -1625,10 +1635,351 @@ static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr) ...@@ -1625,10 +1635,351 @@ static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
else else
result -= intlog10(2) * 10 * noise_exp - 100; result -= intlog10(2) * 10 * noise_exp - 100;
return result;
}
static int dib7000p_read_snr(struct dvb_frontend *fe, u16 *snr)
{
u32 result;
result = dib7000p_get_snr(fe);
*snr = result / ((1 << 24) / 10); *snr = result / ((1 << 24) / 10);
return 0; return 0;
} }
static void dib7000p_reset_stats(struct dvb_frontend *demod)
{
struct dib7000p_state *state = demod->demodulator_priv;
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
u32 ucb;
memset(&c->strength, 0, sizeof(c->strength));
memset(&c->cnr, 0, sizeof(c->cnr));
memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
memset(&c->block_error, 0, sizeof(c->block_error));
c->strength.len = 1;
c->cnr.len = 1;
c->block_error.len = 1;
c->block_count.len = 1;
c->post_bit_error.len = 1;
c->post_bit_count.len = 1;
c->strength.stat[0].scale = FE_SCALE_DECIBEL;
c->strength.stat[0].uvalue = 0;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
dib7000p_read_unc_blocks(demod, &ucb);
state->old_ucb = ucb;
state->ber_jiffies_stats = 0;
state->per_jiffies_stats = 0;
}
struct linear_segments {
unsigned x;
signed y;
};
/*
* Table to estimate signal strength in dBm.
* This table should be empirically determinated by measuring the signal
* strength generated by a RF generator directly connected into
* a device.
* This table was determinated by measuring the signal strength generated
* by a DTA-2111 RF generator directly connected into a dib7000p device
* (a Hauppauge Nova-TD stick), using a good quality 3 meters length
* RC6 cable and good RC6 connectors, connected directly to antenna 1.
* As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
* were used, for the lower power values.
* The real value can actually be on other devices, or even at the
* second antena input, depending on several factors, like if LNA
* is enabled or not, if diversity is enabled, type of connectors, etc.
* Yet, it is better to use this measure in dB than a random non-linear
* percentage value, especially for antenna adjustments.
* On my tests, the precision of the measure using this table is about
* 0.5 dB, with sounds reasonable enough to adjust antennas.
*/
#define DB_OFFSET 131000
static struct linear_segments strength_to_db_table[] = {
{ 63630, DB_OFFSET - 20500},
{ 62273, DB_OFFSET - 21000},
{ 60162, DB_OFFSET - 22000},
{ 58730, DB_OFFSET - 23000},
{ 58294, DB_OFFSET - 24000},
{ 57778, DB_OFFSET - 25000},
{ 57320, DB_OFFSET - 26000},
{ 56779, DB_OFFSET - 27000},
{ 56293, DB_OFFSET - 28000},
{ 55724, DB_OFFSET - 29000},
{ 55145, DB_OFFSET - 30000},
{ 54680, DB_OFFSET - 31000},
{ 54293, DB_OFFSET - 32000},
{ 53813, DB_OFFSET - 33000},
{ 53427, DB_OFFSET - 34000},
{ 52981, DB_OFFSET - 35000},
{ 52636, DB_OFFSET - 36000},
{ 52014, DB_OFFSET - 37000},
{ 51674, DB_OFFSET - 38000},
{ 50692, DB_OFFSET - 39000},
{ 49824, DB_OFFSET - 40000},
{ 49052, DB_OFFSET - 41000},
{ 48436, DB_OFFSET - 42000},
{ 47836, DB_OFFSET - 43000},
{ 47368, DB_OFFSET - 44000},
{ 46468, DB_OFFSET - 45000},
{ 45597, DB_OFFSET - 46000},
{ 44586, DB_OFFSET - 47000},
{ 43667, DB_OFFSET - 48000},
{ 42673, DB_OFFSET - 49000},
{ 41816, DB_OFFSET - 50000},
{ 40876, DB_OFFSET - 51000},
{ 0, 0},
};
static u32 interpolate_value(u32 value, struct linear_segments *segments,
unsigned len)
{
u64 tmp64;
u32 dx;
s32 dy;
int i, ret;
if (value >= segments[0].x)
return segments[0].y;
if (value < segments[len-1].x)
return segments[len-1].y;
for (i = 1; i < len - 1; i++) {
/* If value is identical, no need to interpolate */
if (value == segments[i].x)
return segments[i].y;
if (value > segments[i].x)
break;
}
/* Linear interpolation between the two (x,y) points */
dy = segments[i - 1].y - segments[i].y;
dx = segments[i - 1].x - segments[i].x;
tmp64 = value - segments[i].x;
tmp64 *= dy;
do_div(tmp64, dx);
ret = segments[i].y + tmp64;
return ret;
}
/* FIXME: may require changes - this one was borrowed from dib8000 */
static u32 dib7000p_get_time_us(struct dvb_frontend *demod, int layer)
{
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
u64 time_us, tmp64;
u32 tmp, denom;
int guard, rate_num, rate_denum = 1, bits_per_symbol;
int interleaving = 0, fft_div;
switch (c->guard_interval) {
case GUARD_INTERVAL_1_4:
guard = 4;
break;
case GUARD_INTERVAL_1_8:
guard = 8;
break;
case GUARD_INTERVAL_1_16:
guard = 16;
break;
default:
case GUARD_INTERVAL_1_32:
guard = 32;
break;
}
switch (c->transmission_mode) {
case TRANSMISSION_MODE_2K:
fft_div = 4;
break;
case TRANSMISSION_MODE_4K:
fft_div = 2;
break;
default:
case TRANSMISSION_MODE_8K:
fft_div = 1;
break;
}
switch (c->modulation) {
case DQPSK:
case QPSK:
bits_per_symbol = 2;
break;
case QAM_16:
bits_per_symbol = 4;
break;
default:
case QAM_64:
bits_per_symbol = 6;
break;
}
switch ((c->hierarchy == 0 || 1 == 1) ? c->code_rate_HP : c->code_rate_LP) {
case FEC_1_2:
rate_num = 1;
rate_denum = 2;
break;
case FEC_2_3:
rate_num = 2;
rate_denum = 3;
break;
case FEC_3_4:
rate_num = 3;
rate_denum = 4;
break;
case FEC_5_6:
rate_num = 5;
rate_denum = 6;
break;
default:
case FEC_7_8:
rate_num = 7;
rate_denum = 8;
break;
}
interleaving = interleaving;
denom = bits_per_symbol * rate_num * fft_div * 384;
/* If calculus gets wrong, wait for 1s for the next stats */
if (!denom)
return 0;
/* Estimate the period for the total bit rate */
time_us = rate_denum * (1008 * 1562500L);
tmp64 = time_us;
do_div(tmp64, guard);
time_us = time_us + tmp64;
time_us += denom / 2;
do_div(time_us, denom);
tmp = 1008 * 96 * interleaving;
time_us += tmp + tmp / guard;
return time_us;
}
static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
{
struct dib7000p_state *state = demod->demodulator_priv;
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
int i;
int show_per_stats = 0;
u32 time_us = 0, val, snr;
u64 blocks, ucb;
s32 db;
u16 strength;
/* Get Signal strength */
dib7000p_read_signal_strength(demod, &strength);
val = strength;
db = interpolate_value(val,
strength_to_db_table,
ARRAY_SIZE(strength_to_db_table)) - DB_OFFSET;
c->strength.stat[0].svalue = db;
/* UCB/BER/CNR measures require lock */
if (!(stat & FE_HAS_LOCK)) {
c->cnr.len = 1;
c->block_count.len = 1;
c->block_error.len = 1;
c->post_bit_error.len = 1;
c->post_bit_count.len = 1;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
}
/* Check if time for stats was elapsed */
if (time_after(jiffies, state->per_jiffies_stats)) {
state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
/* Get SNR */
snr = dib7000p_get_snr(demod);
if (snr)
snr = (1000L * snr) >> 24;
else
snr = 0;
c->cnr.stat[0].svalue = snr;
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
/* Get UCB measures */
dib7000p_read_unc_blocks(demod, &val);
ucb = val - state->old_ucb;
if (val < state->old_ucb)
ucb += 0x100000000LL;
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue = ucb;
/* Estimate the number of packets based on bitrate */
if (!time_us)
time_us = dib7000p_get_time_us(demod, -1);
if (time_us) {
blocks = 1250000ULL * 1000000ULL;
do_div(blocks, time_us * 8 * 204);
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
c->block_count.stat[0].uvalue += blocks;
}
show_per_stats = 1;
}
/* Get post-BER measures */
if (time_after(jiffies, state->ber_jiffies_stats)) {
time_us = dib7000p_get_time_us(demod, -1);
state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
dprintk("Next all layers stats available in %u us.", time_us);
dib7000p_read_ber(demod, &val);
c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_error.stat[0].uvalue += val;
c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_count.stat[0].uvalue += 100000000;
}
/* Get PER measures */
if (show_per_stats) {
dib7000p_read_unc_blocks(demod, &val);
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue += val;
time_us = dib7000p_get_time_us(demod, i);
if (time_us) {
blocks = 1250000ULL * 1000000ULL;
do_div(blocks, time_us * 8 * 204);
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
c->block_count.stat[0].uvalue += blocks;
}
}
return 0;
}
static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
{ {
tune->min_delay_ms = 1000; tune->min_delay_ms = 1000;
...@@ -1643,7 +1994,7 @@ static void dib7000p_release(struct dvb_frontend *demod) ...@@ -1643,7 +1994,7 @@ static void dib7000p_release(struct dvb_frontend *demod)
kfree(st); kfree(st);
} }
int dib7000pc_detection(struct i2c_adapter *i2c_adap) static int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{ {
u8 *tx, *rx; u8 *tx, *rx;
struct i2c_msg msg[2] = { struct i2c_msg msg[2] = {
...@@ -1688,16 +2039,14 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap) ...@@ -1688,16 +2039,14 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
kfree(tx); kfree(tx);
return ret; return ret;
} }
EXPORT_SYMBOL(dib7000pc_detection);
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) static struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
{ {
struct dib7000p_state *st = demod->demodulator_priv; struct dib7000p_state *st = demod->demodulator_priv;
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
} }
EXPORT_SYMBOL(dib7000p_get_i2c_master);
int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
u16 val = dib7000p_read_word(state, 235) & 0xffef; u16 val = dib7000p_read_word(state, 235) & 0xffef;
...@@ -1705,17 +2054,15 @@ int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) ...@@ -1705,17 +2054,15 @@ int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
dprintk("PID filter enabled %d", onoff); dprintk("PID filter enabled %d", onoff);
return dib7000p_write_word(state, 235, val); return dib7000p_write_word(state, 235, val);
} }
EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
} }
EXPORT_SYMBOL(dib7000p_pid_filter);
int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
{ {
struct dib7000p_state *dpst; struct dib7000p_state *dpst;
int k = 0; int k = 0;
...@@ -1774,7 +2121,6 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau ...@@ -1774,7 +2121,6 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
kfree(dpst); kfree(dpst);
return 0; return 0;
} }
EXPORT_SYMBOL(dib7000p_i2c_enumeration);
static const s32 lut_1000ln_mant[] = { static const s32 lut_1000ln_mant[] = {
6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
...@@ -2032,12 +2378,11 @@ static struct i2c_algorithm dib7090_tuner_xfer_algo = { ...@@ -2032,12 +2378,11 @@ static struct i2c_algorithm dib7090_tuner_xfer_algo = {
.functionality = dib7000p_i2c_func, .functionality = dib7000p_i2c_func,
}; };
struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe) static struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
{ {
struct dib7000p_state *st = fe->demodulator_priv; struct dib7000p_state *st = fe->demodulator_priv;
return &st->dib7090_tuner_adap; return &st->dib7090_tuner_adap;
} }
EXPORT_SYMBOL(dib7090_get_i2c_tuner);
static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive) static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
{ {
...@@ -2329,7 +2674,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode) ...@@ -2329,7 +2674,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
return ret; return ret;
} }
int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
u16 en_cur_state; u16 en_cur_state;
...@@ -2352,15 +2697,13 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff) ...@@ -2352,15 +2697,13 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
return 0; return 0;
} }
EXPORT_SYMBOL(dib7090_tuner_sleep);
int dib7090_get_adc_power(struct dvb_frontend *fe) static int dib7090_get_adc_power(struct dvb_frontend *fe)
{ {
return dib7000p_get_adc_power(fe); return dib7000p_get_adc_power(fe);
} }
EXPORT_SYMBOL(dib7090_get_adc_power);
int dib7090_slave_reset(struct dvb_frontend *fe) static int dib7090_slave_reset(struct dvb_frontend *fe)
{ {
struct dib7000p_state *state = fe->demodulator_priv; struct dib7000p_state *state = fe->demodulator_priv;
u16 reg; u16 reg;
...@@ -2371,10 +2714,9 @@ int dib7090_slave_reset(struct dvb_frontend *fe) ...@@ -2371,10 +2714,9 @@ int dib7090_slave_reset(struct dvb_frontend *fe)
dib7000p_write_word(state, 1032, 0xffff); dib7000p_write_word(state, 1032, 0xffff);
return 0; return 0;
} }
EXPORT_SYMBOL(dib7090_slave_reset);
static struct dvb_frontend_ops dib7000p_ops; static struct dvb_frontend_ops dib7000p_ops;
struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
{ {
struct dvb_frontend *demod; struct dvb_frontend *demod;
struct dib7000p_state *st; struct dib7000p_state *st;
...@@ -2423,6 +2765,8 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, ...@@ -2423,6 +2765,8 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
dib7000p_demod_reset(st); dib7000p_demod_reset(st);
dib7000p_reset_stats(demod);
if (st->version == SOC7090) { if (st->version == SOC7090) {
dib7090_set_output_mode(demod, st->cfg.output_mode); dib7090_set_output_mode(demod, st->cfg.output_mode);
dib7090_set_diversity_in(demod, 0); dib7090_set_diversity_in(demod, 0);
...@@ -2434,6 +2778,31 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, ...@@ -2434,6 +2778,31 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
kfree(st); kfree(st);
return NULL; return NULL;
} }
void *dib7000p_attach(struct dib7000p_ops *ops)
{
if (!ops)
return NULL;
ops->slave_reset = dib7090_slave_reset;
ops->get_adc_power = dib7090_get_adc_power;
ops->dib7000pc_detection = dib7000pc_detection;
ops->get_i2c_tuner = dib7090_get_i2c_tuner;
ops->tuner_sleep = dib7090_tuner_sleep;
ops->init = dib7000p_init;
ops->set_agc1_min = dib7000p_set_agc1_min;
ops->set_gpio = dib7000p_set_gpio;
ops->i2c_enumeration = dib7000p_i2c_enumeration;
ops->pid_filter = dib7000p_pid_filter;
ops->pid_filter_ctrl = dib7000p_pid_filter_ctrl;
ops->get_i2c_master = dib7000p_get_i2c_master;
ops->update_pll = dib7000p_update_pll;
ops->ctrl_timf = dib7000p_ctrl_timf;
ops->get_agc_values = dib7000p_get_agc_values;
ops->set_wbd_ref = dib7000p_set_wbd_ref;
return ops;
}
EXPORT_SYMBOL(dib7000p_attach); EXPORT_SYMBOL(dib7000p_attach);
static struct dvb_frontend_ops dib7000p_ops = { static struct dvb_frontend_ops dib7000p_ops = {
......
...@@ -46,121 +46,34 @@ struct dib7000p_config { ...@@ -46,121 +46,34 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
#if IS_ENABLED(CONFIG_DVB_DIB7000P) struct dib7000p_ops {
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); int (*set_wbd_ref)(struct dvb_frontend *demod, u16 value);
extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); int (*get_agc_values)(struct dvb_frontend *fe,
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
extern int dib7090_get_adc_power(struct dvb_frontend *fe);
extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
extern int dib7090_slave_reset(struct dvb_frontend *fe);
extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd); u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
extern int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v); int (*set_agc1_min)(struct dvb_frontend *fe, u16 v);
#else int (*update_pll)(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) int (*set_gpio)(struct dvb_frontend *demod, u8 num, u8 dir, u8 val);
{ u32 (*ctrl_timf)(struct dvb_frontend *fe, u8 op, u32 timf);
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); int (*dib7000pc_detection)(struct i2c_adapter *i2c_adap);
return NULL; struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating);
} int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x) int (*i2c_enumeration)(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
{ struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
return NULL; int (*get_adc_power)(struct dvb_frontend *fe);
} int (*slave_reset)(struct dvb_frontend *fe);
struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) };
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe) #if IS_ENABLED(CONFIG_DVB_DIB7000P)
void *dib7000p_attach(struct dib7000p_ops *ops);
#else
static inline void *dib7000p_attach(struct dib7000p_ops *ops)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
} }
static inline int dib7090_slave_reset(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif #endif
#endif #endif
...@@ -39,134 +39,34 @@ struct dib8000_config { ...@@ -39,134 +39,34 @@ struct dib8000_config {
#define DEFAULT_DIB8000_I2C_ADDRESS 18 #define DEFAULT_DIB8000_I2C_ADDRESS 18
#if IS_ENABLED(CONFIG_DVB_DIB8000) struct dib8000_ops {
extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); int (*set_wbd_ref)(struct dvb_frontend *fe, u16 value);
extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); int (*update_pll)(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, int (*set_gpio)(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
void (*pwm_agc_reset)(struct dvb_frontend *fe);
struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
s32 (*get_adc_power)(struct dvb_frontend *fe, u8 mode);
int (*get_dc_power)(struct dvb_frontend *fe, u8 IQ);
u32 (*ctrl_timf)(struct dvb_frontend *fe, uint8_t op, uint32_t timf);
enum frontend_tune_state (*get_tune_state)(struct dvb_frontend *fe);
int (*set_tune_state)(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
int (*set_slave_frontend)(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
int (*remove_slave_frontend)(struct dvb_frontend *fe);
struct dvb_frontend *(*get_slave_frontend)(struct dvb_frontend *fe, int slave_index);
int (*i2c_enumeration)(struct i2c_adapter *host, int no_of_demods,
u8 default_addr, u8 first_addr, u8 is_dib8096p); u8 default_addr, u8 first_addr, u8 is_dib8096p);
struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
};
extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); #if IS_ENABLED(CONFIG_DVB_DIB8000)
extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); void *dib8000_attach(struct dib8000_ops *ops);
extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
uint8_t op, uint32_t timf);
extern int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
#else #else
static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) static inline int dib8000_attach(struct dib8000_ops *ops)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
int no_of_demods, u8 default_addr, u8 first_addr,
u8 is_dib8096p)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return CT_SHUTDOWN;
}
static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
}
static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
uint8_t op, uint32_t timf)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
......
...@@ -1040,13 +1040,18 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres ...@@ -1040,13 +1040,18 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres
if (address >= 1024 || !state->platform.risc.fw_is_running) if (address >= 1024 || !state->platform.risc.fw_is_running)
return -EINVAL; return -EINVAL;
if (len > 18)
return -EINVAL;
/* dprintk( "APB access thru wr fw %d %x", address, attribute); */ /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
mb[0] = (unsigned short)address; mb[0] = (u16)address;
for (i = 0; i < len && i < 20; i += 2) for (i = 0; i + 1 < len; i += 2)
mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]); mb[1 + i / 2] = b[i] << 8 | b[i + 1];
if (len & 1)
mb[1 + len / 2] = b[len - 1] << 8;
dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute); dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);
return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL; return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
} }
......
...@@ -69,5 +69,4 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config, ...@@ -69,5 +69,4 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config,
} }
#endif #endif
extern int drxd_config_i2c(struct dvb_frontend *, int);
#endif #endif
...@@ -2840,7 +2840,7 @@ static int drxd_init(struct dvb_frontend *fe) ...@@ -2840,7 +2840,7 @@ static int drxd_init(struct dvb_frontend *fe)
return err; return err;
} }
int drxd_config_i2c(struct dvb_frontend *fe, int onoff) static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
{ {
struct drxd_state *state = fe->demodulator_priv; struct drxd_state *state = fe->demodulator_priv;
...@@ -2849,7 +2849,6 @@ int drxd_config_i2c(struct dvb_frontend *fe, int onoff) ...@@ -2849,7 +2849,6 @@ int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
return DRX_ConfigureI2CBridge(state, onoff); return DRX_ConfigureI2CBridge(state, onoff);
} }
EXPORT_SYMBOL(drxd_config_i2c);
static int drxd_get_tune_settings(struct dvb_frontend *fe, static int drxd_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *sets) struct dvb_frontend_tune_settings *sets)
......
...@@ -879,7 +879,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -879,7 +879,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * ln(X) / ln(10) dB */ /* SNR(X) dB = 10 * ln(X) / ln(10) dB */
tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS); tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
if (tmp) if (tmp)
*snr = 100ul * intlog2(tmp) / intlog2(10); *snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10));
else else
*snr = 0; *snr = 0;
break; break;
...@@ -908,7 +908,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -908,7 +908,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * log10(X) dB */ /* SNR(X) dB = 10 * log10(X) dB */
if (signal > noise) { if (signal > noise) {
tmp = signal / noise; tmp = signal / noise;
*snr = 100ul * intlog10(tmp) / (1 << 24); *snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24));
} else { } else {
*snr = 0; *snr = 0;
} }
...@@ -926,6 +926,86 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -926,6 +926,86 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
return ret; return ret;
} }
static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
unsigned int utmp;
u8 buf[3], u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
switch (c->delivery_system) {
case SYS_DVBS:
ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
if (ret)
goto err;
ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
if (ret)
goto err;
if (!(u8tmp & 0x10)) {
u8tmp |= 0x10;
ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
if (ret)
goto err;
priv->ber = (buf[1] << 8) | (buf[0] << 0);
/* restart counters */
ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
if (ret)
goto err;
}
break;
case SYS_DVBS2:
ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
if (ret)
goto err;
utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
if (utmp > 3000) {
ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
if (ret)
goto err;
priv->ber = (buf[1] << 8) | (buf[0] << 0);
/* restart counters */
ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
if (ret)
goto err;
}
break;
default:
dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
__func__);
ret = -EINVAL;
goto err;
}
*ber = priv->ber;
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int m88ds3103_set_tone(struct dvb_frontend *fe, static int m88ds3103_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t fe_sec_tone_mode) fe_sec_tone_mode_t fe_sec_tone_mode)
...@@ -1284,6 +1364,7 @@ static struct dvb_frontend_ops m88ds3103_ops = { ...@@ -1284,6 +1364,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.read_status = m88ds3103_read_status, .read_status = m88ds3103_read_status,
.read_snr = m88ds3103_read_snr, .read_snr = m88ds3103_read_snr,
.read_ber = m88ds3103_read_ber,
.diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd, .diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
.diseqc_send_burst = m88ds3103_diseqc_send_burst, .diseqc_send_burst = m88ds3103_diseqc_send_burst,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "dvb_math.h" #include "dvb_math.h"
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/i2c-mux.h> #include <linux/i2c-mux.h>
#include <linux/math64.h>
#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw" #define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
#define M88DS3103_MCLK_KHZ 96000 #define M88DS3103_MCLK_KHZ 96000
...@@ -34,6 +35,7 @@ struct m88ds3103_priv { ...@@ -34,6 +35,7 @@ struct m88ds3103_priv {
struct dvb_frontend fe; struct dvb_frontend fe;
fe_delivery_system_t delivery_system; fe_delivery_system_t delivery_system;
fe_status_t fe_status; fe_status_t fe_status;
u32 ber;
bool warm; /* FW running */ bool warm; /* FW running */
struct i2c_adapter *i2c_adapter; struct i2c_adapter *i2c_adapter;
}; };
......
...@@ -459,6 +459,9 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state, ...@@ -459,6 +459,9 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
unsigned layer) unsigned layer)
{ {
int rc; int rc;
int interleaving[] = {
0, 1, 2, 4, 8
};
static unsigned char reg[] = { static unsigned char reg[] = {
[0] = 0x88, /* Layer A */ [0] = 0x88, /* Layer A */
...@@ -475,20 +478,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state, ...@@ -475,20 +478,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
if (rc < 0) if (rc < 0)
return rc; return rc;
switch ((rc >> 4) & 0x07) { return interleaving[(rc >> 4) & 0x07];
case 1:
return GUARD_INTERVAL_1_4;
case 2:
return GUARD_INTERVAL_1_8;
case 3:
return GUARD_INTERVAL_1_16;
case 4:
return GUARD_INTERVAL_1_32;
default:
case 0:
return GUARD_INTERVAL_AUTO;
}
} }
static int mb86a20s_get_segment_count(struct mb86a20s_state *state, static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
...@@ -566,7 +556,7 @@ static u32 isdbt_rate[3][5][4] = { ...@@ -566,7 +556,7 @@ static u32 isdbt_rate[3][5][4] = {
static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
u32 modulation, u32 forward_error_correction, u32 modulation, u32 forward_error_correction,
u32 interleaving, u32 guard_interval,
u32 segment) u32 segment)
{ {
struct mb86a20s_state *state = fe->demodulator_priv; struct mb86a20s_state *state = fe->demodulator_priv;
...@@ -574,7 +564,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, ...@@ -574,7 +564,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
int mod, fec, guard; int mod, fec, guard;
/* /*
* If modulation/fec/interleaving is not detected, the default is * If modulation/fec/guard is not detected, the default is
* to consider the lowest bit rate, to avoid taking too long time * to consider the lowest bit rate, to avoid taking too long time
* to get BER. * to get BER.
*/ */
...@@ -612,7 +602,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, ...@@ -612,7 +602,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
break; break;
} }
switch (interleaving) { switch (guard_interval) {
default: default:
case GUARD_INTERVAL_1_4: case GUARD_INTERVAL_1_4:
guard = 0; guard = 0;
...@@ -703,7 +693,7 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe) ...@@ -703,7 +693,7 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
c->layer[layer].interleaving = rc; c->layer[layer].interleaving = rc;
mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation, mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation,
c->layer[layer].fec, c->layer[layer].fec,
c->layer[layer].interleaving, c->guard_interval,
c->layer[layer].segment_count); c->layer[layer].segment_count);
} }
...@@ -721,11 +711,10 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe) ...@@ -721,11 +711,10 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
rc = mb86a20s_readreg(state, 0x07); rc = mb86a20s_readreg(state, 0x07);
if (rc < 0) if (rc < 0)
return rc; return rc;
c->transmission_mode = TRANSMISSION_MODE_AUTO;
if ((rc & 0x60) == 0x20) { if ((rc & 0x60) == 0x20) {
switch (rc & 0x0c >> 2) { /* Only modes 2 and 3 are supported */
case 0: switch ((rc >> 2) & 0x03) {
c->transmission_mode = TRANSMISSION_MODE_2K;
break;
case 1: case 1:
c->transmission_mode = TRANSMISSION_MODE_4K; c->transmission_mode = TRANSMISSION_MODE_4K;
break; break;
...@@ -734,7 +723,9 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe) ...@@ -734,7 +723,9 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
break; break;
} }
} }
c->guard_interval = GUARD_INTERVAL_AUTO;
if (!(rc & 0x10)) { if (!(rc & 0x10)) {
/* Guard interval 1/32 is not supported */
switch (rc & 0x3) { switch (rc & 0x3) {
case 0: case 0:
c->guard_interval = GUARD_INTERVAL_1_4; c->guard_interval = GUARD_INTERVAL_1_4;
......
...@@ -35,6 +35,10 @@ ...@@ -35,6 +35,10 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/math64.h> #include <linux/math64.h>
static bool rtl2832_sdr_emulated_fmt;
module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644);
MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)");
#define MAX_BULK_BUFS (10) #define MAX_BULK_BUFS (10)
#define BULK_BUFFER_SIZE (128 * 512) #define BULK_BUFFER_SIZE (128 * 512)
...@@ -80,15 +84,18 @@ static const struct v4l2_frequency_band bands_fm[] = { ...@@ -80,15 +84,18 @@ static const struct v4l2_frequency_band bands_fm[] = {
struct rtl2832_sdr_format { struct rtl2832_sdr_format {
char *name; char *name;
u32 pixelformat; u32 pixelformat;
u32 buffersize;
}; };
static struct rtl2832_sdr_format formats[] = { static struct rtl2832_sdr_format formats[] = {
{ {
.name = "IQ U8", .name = "Complex U8",
.pixelformat = V4L2_SDR_FMT_CU8, .pixelformat = V4L2_SDR_FMT_CU8,
.buffersize = BULK_BUFFER_SIZE,
}, { }, {
.name = "IQ U16LE (emulated)", .name = "Complex U16LE (emulated)",
.pixelformat = V4L2_SDR_FMT_CU16LE, .pixelformat = V4L2_SDR_FMT_CU16LE,
.buffersize = BULK_BUFFER_SIZE * 2,
}, },
}; };
...@@ -139,6 +146,8 @@ struct rtl2832_sdr_state { ...@@ -139,6 +146,8 @@ struct rtl2832_sdr_state {
unsigned int f_adc, f_tuner; unsigned int f_adc, f_tuner;
u32 pixelformat; u32 pixelformat;
u32 buffersize;
unsigned int num_formats;
/* Controls */ /* Controls */
struct v4l2_ctrl_handler hdl; struct v4l2_ctrl_handler hdl;
...@@ -348,6 +357,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s, ...@@ -348,6 +357,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
/* convert u8 to u16 */ /* convert u8 to u16 */
unsigned int i; unsigned int i;
u16 *u16dst = dst; u16 *u16dst = dst;
for (i = 0; i < src_len; i++) for (i = 0; i < src_len; i++)
*u16dst++ = (src[i] << 8) | (src[i] >> 0); *u16dst++ = (src[i] << 8) | (src[i] >> 0);
dst_len = 2 * src_len; dst_len = 2 * src_len;
...@@ -359,6 +369,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s, ...@@ -359,6 +369,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
if (unlikely(time_is_before_jiffies(s->jiffies_next))) { if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
#define MSECS 10000UL #define MSECS 10000UL
unsigned int samples = s->sample - s->sample_measured; unsigned int samples = s->sample - s->sample_measured;
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS); s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
s->sample_measured = s->sample; s->sample_measured = s->sample;
dev_dbg(&s->udev->dev, dev_dbg(&s->udev->dev,
...@@ -560,11 +571,13 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s) ...@@ -560,11 +571,13 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s) static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
{ {
unsigned long flags = 0; unsigned long flags = 0;
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
spin_lock_irqsave(&s->queued_bufs_lock, flags); spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) { while (!list_empty(&s->queued_bufs)) {
struct rtl2832_sdr_frame_buf *buf; struct rtl2832_sdr_frame_buf *buf;
buf = list_entry(s->queued_bufs.next, buf = list_entry(s->queued_bufs.next,
struct rtl2832_sdr_frame_buf, list); struct rtl2832_sdr_frame_buf, list);
list_del(&buf->list); list_del(&buf->list);
...@@ -577,6 +590,7 @@ static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s) ...@@ -577,6 +590,7 @@ static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_release_sec(struct dvb_frontend *fe) static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
{ {
struct rtl2832_sdr_state *s = fe->sec_priv; struct rtl2832_sdr_state *s = fe->sec_priv;
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->vb_queue_lock); mutex_lock(&s->vb_queue_lock);
...@@ -598,6 +612,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh, ...@@ -598,6 +612,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
...@@ -615,14 +630,14 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq, ...@@ -615,14 +630,14 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{ {
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq); struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers); dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
/* Need at least 8 buffers */ /* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8) if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers; *nbuffers = 8 - vq->num_buffers;
*nplanes = 1; *nplanes = 1;
/* 2 = max 16-bit sample returned */ sizes[0] = PAGE_ALIGN(s->buffersize);
sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n", dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]); __func__, *nbuffers, sizes[0]);
return 0; return 0;
...@@ -665,6 +680,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s) ...@@ -665,6 +680,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u8 buf[4], u8tmp1, u8tmp2; u8 buf[4], u8tmp1, u8tmp2;
u64 u64tmp; u64 u64tmp;
u32 u32tmp; u32 u32tmp;
dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc); dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
if (!test_bit(POWER_ON, &s->flags)) if (!test_bit(POWER_ON, &s->flags))
...@@ -935,7 +951,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s) ...@@ -935,7 +951,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
/* /*
* bandwidth (Hz) * bandwidth (Hz)
*/ */
bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO); bandwidth_auto = v4l2_ctrl_find(&s->hdl,
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH); bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
if (v4l2_ctrl_g_ctrl(bandwidth_auto)) { if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
c->bandwidth_hz = s->f_adc; c->bandwidth_hz = s->f_adc;
...@@ -987,6 +1004,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -987,6 +1004,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
{ {
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq); struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
int ret; int ret;
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (!s->udev) if (!s->udev)
...@@ -1035,6 +1053,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -1035,6 +1053,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq) static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
{ {
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq); struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->v4l2_lock); mutex_lock(&s->v4l2_lock);
...@@ -1068,6 +1087,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv, ...@@ -1068,6 +1087,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v) struct v4l2_tuner *v)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n", dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
__func__, v->index, v->type); __func__, v->index, v->type);
...@@ -1094,6 +1114,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv, ...@@ -1094,6 +1114,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v) const struct v4l2_tuner *v)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (v->index > 1) if (v->index > 1)
...@@ -1105,6 +1126,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, ...@@ -1105,6 +1126,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
struct v4l2_frequency_band *band) struct v4l2_frequency_band *band)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n", dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
__func__, band->tuner, band->type, band->index); __func__, band->tuner, band->type, band->index);
...@@ -1130,6 +1152,7 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv, ...@@ -1130,6 +1152,7 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
int ret = 0; int ret = 0;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n", dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
__func__, f->tuner, f->type); __func__, f->tuner, f->type);
...@@ -1193,9 +1216,10 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv, ...@@ -1193,9 +1216,10 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (f->index >= NUM_FORMATS) if (f->index >= s->num_formats)
return -EINVAL; return -EINVAL;
strlcpy(f->description, formats[f->index].name, sizeof(f->description)); strlcpy(f->description, formats[f->index].name, sizeof(f->description));
...@@ -1208,9 +1232,12 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv, ...@@ -1208,9 +1232,12 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__); dev_dbg(&s->udev->dev, "%s:\n", __func__);
f->fmt.sdr.pixelformat = s->pixelformat; f->fmt.sdr.pixelformat = s->pixelformat;
f->fmt.sdr.buffersize = s->buffersize;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
return 0; return 0;
...@@ -1222,6 +1249,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv, ...@@ -1222,6 +1249,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
struct vb2_queue *q = &s->vb_queue; struct vb2_queue *q = &s->vb_queue;
int i; int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__, dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat); (char *)&f->fmt.sdr.pixelformat);
...@@ -1229,15 +1257,19 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv, ...@@ -1229,15 +1257,19 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
return -EBUSY; return -EBUSY;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
for (i = 0; i < NUM_FORMATS; i++) { for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
s->pixelformat = f->fmt.sdr.pixelformat; s->pixelformat = formats[i].pixelformat;
s->buffersize = formats[i].buffersize;
f->fmt.sdr.buffersize = formats[i].buffersize;
return 0; return 0;
} }
} }
f->fmt.sdr.pixelformat = formats[0].pixelformat;
s->pixelformat = formats[0].pixelformat; s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
f->fmt.sdr.pixelformat = formats[0].pixelformat;
f->fmt.sdr.buffersize = formats[0].buffersize;
return 0; return 0;
} }
...@@ -1247,16 +1279,20 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv, ...@@ -1247,16 +1279,20 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
{ {
struct rtl2832_sdr_state *s = video_drvdata(file); struct rtl2832_sdr_state *s = video_drvdata(file);
int i; int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__, dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat); (char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
for (i = 0; i < NUM_FORMATS; i++) { for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
f->fmt.sdr.buffersize = formats[i].buffersize;
return 0; return 0;
}
} }
f->fmt.sdr.pixelformat = formats[0].pixelformat; f->fmt.sdr.pixelformat = formats[0].pixelformat;
f->fmt.sdr.buffersize = formats[0].buffersize;
return 0; return 0;
} }
...@@ -1316,8 +1352,9 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl) ...@@ -1316,8 +1352,9 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
struct dvb_frontend *fe = s->fe; struct dvb_frontend *fe = s->fe;
struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret; int ret;
dev_dbg(&s->udev->dev, dev_dbg(&s->udev->dev,
"%s: id=%d name=%s val=%d min=%d max=%d step=%d\n", "%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
__func__, ctrl->id, ctrl->name, ctrl->val, __func__, ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step); ctrl->minimum, ctrl->maximum, ctrl->step);
...@@ -1327,14 +1364,16 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl) ...@@ -1327,14 +1364,16 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
/* TODO: these controls should be moved to tuner drivers */ /* TODO: these controls should be moved to tuner drivers */
if (s->bandwidth_auto->val) { if (s->bandwidth_auto->val) {
/* Round towards the closest legal value */ /* Round towards the closest legal value */
s32 val = s->f_adc + s->bandwidth->step / 2; s32 val = s->f_adc + div_u64(s->bandwidth->step, 2);
u32 offset; u32 offset;
val = clamp(val, s->bandwidth->minimum, s->bandwidth->maximum);
val = clamp_t(s32, val, s->bandwidth->minimum,
s->bandwidth->maximum);
offset = val - s->bandwidth->minimum; offset = val - s->bandwidth->minimum;
offset = s->bandwidth->step * (offset / s->bandwidth->step); offset = s->bandwidth->step *
div_u64(offset, s->bandwidth->step);
s->bandwidth->val = s->bandwidth->minimum + offset; s->bandwidth->val = s->bandwidth->minimum + offset;
} }
c->bandwidth_hz = s->bandwidth->val; c->bandwidth_hz = s->bandwidth->val;
if (!test_bit(POWER_ON, &s->flags)) if (!test_bit(POWER_ON, &s->flags))
...@@ -1390,7 +1429,11 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, ...@@ -1390,7 +1429,11 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->cfg = cfg; s->cfg = cfg;
s->f_adc = bands_adc[0].rangelow; s->f_adc = bands_adc[0].rangelow;
s->f_tuner = bands_fm[0].rangelow; s->f_tuner = bands_fm[0].rangelow;
s->pixelformat = V4L2_SDR_FMT_CU8; s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
s->num_formats = NUM_FORMATS;
if (rtl2832_sdr_emulated_fmt == false)
s->num_formats -= 1;
mutex_init(&s->v4l2_lock); mutex_init(&s->v4l2_lock);
mutex_init(&s->vb_queue_lock); mutex_init(&s->vb_queue_lock);
...@@ -1420,15 +1463,24 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, ...@@ -1420,15 +1463,24 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
break; break;
case RTL2832_TUNER_R820T: case RTL2832_TUNER_R820T:
v4l2_ctrl_handler_init(&s->hdl, 2); v4l2_ctrl_handler_init(&s->hdl, 2);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 0, 8000000, 100000, 0); V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH,
0, 8000000, 100000, 0);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false); v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break; break;
case RTL2832_TUNER_FC0012: case RTL2832_TUNER_FC0012:
case RTL2832_TUNER_FC0013: case RTL2832_TUNER_FC0013:
v4l2_ctrl_handler_init(&s->hdl, 2); v4l2_ctrl_handler_init(&s->hdl, 2);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 6000000, 8000000, 1000000, 6000000); V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH,
6000000, 8000000, 1000000,
6000000);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false); v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break; break;
default: default:
...@@ -1448,7 +1500,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, ...@@ -1448,7 +1500,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->vdev = rtl2832_sdr_template; s->vdev = rtl2832_sdr_template;
s->vdev.queue = &s->vb_queue; s->vdev.queue = &s->vb_queue;
s->vdev.queue->lock = &s->vb_queue_lock; s->vdev.queue->lock = &s->vb_queue_lock;
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
video_set_drvdata(&s->vdev, s); video_set_drvdata(&s->vdev, s);
/* Register the v4l2_device structure */ /* Register the v4l2_device structure */
...@@ -1480,6 +1531,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, ...@@ -1480,6 +1531,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n", dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
KBUILD_MODNAME); KBUILD_MODNAME);
dev_notice(&s->udev->dev,
"%s: SDR API is still slightly experimental and functionality changes may follow\n",
KBUILD_MODNAME);
return fe; return fe;
err_unregister_v4l2_dev: err_unregister_v4l2_dev:
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -1030,7 +1030,7 @@ static int ChannelConfiguration(struct tda_state *state, ...@@ -1030,7 +1030,7 @@ static int ChannelConfiguration(struct tda_state *state,
state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
if ((Standard == HF_FM_Radio) && state->m_bFMInput) if ((Standard == HF_FM_Radio) && state->m_bFMInput)
state->m_Regs[EP4] |= 80; state->m_Regs[EP4] |= 0x80;
state->m_Regs[MPD] &= ~0x80; state->m_Regs[MPD] &= ~0x80;
if (Standard > HF_AnalogMax) if (Standard > HF_AnalogMax)
......
...@@ -551,6 +551,7 @@ config VIDEO_MT9V032 ...@@ -551,6 +551,7 @@ config VIDEO_MT9V032
tristate "Micron MT9V032 sensor support" tristate "Micron MT9V032 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT depends on MEDIA_CAMERA_SUPPORT
select REGMAP_I2C
---help--- ---help---
This is a Video4Linux2 sensor-level driver for the Micron This is a Video4Linux2 sensor-level driver for the Micron
MT9V032 752x480 CMOS sensor. MT9V032 752x480 CMOS sensor.
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册