提交 27c053aa 编写于 作者: 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:
 "This series contains:
   - Exynos s5p-mfc driver got support for VP8 encoder
   - Some SoC drivers gained support for asynchronous registration
     (needed for DT)
   - The RC subsystem gained support for RC activity LED;
   - New drivers added: a video decoder(adv7842), a video encoder
     (adv7511), a new GSPCA driver (stk1135) and support for Renesas
     R-Car (vsp1)
   - the first SDR kernel driver: mirics msi3101.  Due to some troubles
     with the driver, and because the API is still under discussion, it
     will be merged at staging for 3.12.  Need to rework on it
   - usual new boards additions, fixes, cleanups and driver
     improvements"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (242 commits)
  [media] cx88: Fix regression: CX88_AUDIO_WM8775 can't be 0
  [media] exynos4-is: Fix entity unregistration on error path
  [media] exynos-gsc: Register v4l2 device
  [media] exynos4-is: Fix fimc-lite bayer formats
  [media] em28xx: fix assignment of the eeprom data
  [media] hdpvr: fix iteration over uninitialized lists in hdpvr_probe()
  [media] usbtv: Throw corrupted frames away
  [media] usbtv: Fix deinterlacing
  [media] v4l2: added missing mutex.h include to v4l2-ctrls.h
  [media] DocBook: upgrade media_api DocBook version to 4.2
  [media] ml86v7667: fix compile warning: 'ret' set but not used
  [media] s5p-g2d: Fix registration failure
  [media] media: coda: Fix DT driver data pointer for i.MX27
  [media] s5p-mfc: Fix input/output format reporting
  [media] v4l: vsp1: Fix mutex double lock at streamon time
  [media] v4l: vsp1: Add support for RT clock
  [media] v4l: vsp1: Initialize media device bus_info field
  [media] davinci: vpif_capture: fix error return code in vpif_probe()
  [media] davinci: vpif_display: fix error return code in vpif_probe()
  [media] MAINTAINERS: add entries for adv7511 and adv7842
  ...
......@@ -722,17 +722,22 @@ for more details.</para>
</section>
<section id="mpeg-controls">
<title>MPEG Control Reference</title>
<title>Codec Control Reference</title>
<para>Below all controls within the MPEG control class are
<para>Below all controls within the Codec control class are
described. First the generic controls, then controls specific for
certain hardware.</para>
<para>Note: These controls are applicable to all codecs and
not just MPEG. The defines are prefixed with V4L2_CID_MPEG/V4L2_MPEG
as the controls were originally made for MPEG codecs and later
extended to cover all encoding formats.</para>
<section>
<title>Generic MPEG Controls</title>
<title>Generic Codec Controls</title>
<table pgwide="1" frame="none" id="mpeg-control-id">
<title>MPEG Control IDs</title>
<title>Codec Control IDs</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="6*" />
......@@ -752,7 +757,7 @@ certain hardware.</para>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_CLASS</constant>&nbsp;</entry>
<entry>class</entry>
</row><row><entry spanname="descr">The MPEG class
</row><row><entry spanname="descr">The Codec class
descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
description of this control class. This description can be used as the
caption of a Tab page in a GUI, for example.</entry>
......@@ -3009,6 +3014,159 @@ in by the application. 0 = do not insert, 1 = insert packets.</entry>
</tgroup>
</table>
</section>
<section>
<title>VPX Control Reference</title>
<para>The VPX controls include controls for encoding parameters
of VPx video codec.</para>
<table pgwide="1" frame="none" id="vpx-control-id">
<title>VPX Control IDs</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="6*" />
<colspec colname="c3" colwidth="2*" />
<colspec colname="c4" colwidth="6*" />
<spanspec namest="c1" nameend="c2" spanname="id" />
<spanspec namest="c2" nameend="c4" spanname="descr" />
<thead>
<row>
<entry spanname="id" align="left">ID</entry>
<entry align="left">Type</entry>
</row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
</row>
</thead>
<tbody valign="top">
<row><entry></entry></row>
<row><entry></entry></row>
<row id="v4l2-vpx-num-partitions">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS</constant></entry>
<entry>enum v4l2_vp8_num_partitions</entry>
</row>
<row><entry spanname="descr">The number of token partitions to use in VP8 encoder.
Possible values are:</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION</constant></entry>
<entry>1 coefficient partition</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS</constant></entry>
<entry>2 coefficient partitions</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS</constant></entry>
<entry>4 coefficient partitions</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS</constant></entry>
<entry>8 coefficient partitions</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4</constant></entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">Setting this prevents intra 4x4 mode in the intra mode decision.</entry>
</row>
<row><entry></entry></row>
<row id="v4l2-vpx-num-ref-frames">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES</constant></entry>
<entry>enum v4l2_vp8_num_ref_frames</entry>
</row>
<row><entry spanname="descr">The number of reference pictures for encoding P frames.
Possible values are:</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME</constant></entry>
<entry>Last encoded frame will be searched</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME</constant></entry>
<entry>Two frames will be searched among the last encoded frame, the golden frame
and the alternate reference (altref) frame. The encoder implementation will decide which two are chosen.</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME</constant></entry>
<entry>The last encoded frame, the golden frame and the altref frame will be searched.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL</constant></entry>
<entry>integer</entry>
</row>
<row><entry spanname="descr">Indicates the loop filter level. The adjustment of the loop
filter level is done via a delta value against a baseline loop filter value.</entry>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS</constant></entry>
<entry>integer</entry>
</row>
<row><entry spanname="descr">This parameter affects the loop filter. Anything above
zero weakens the deblocking effect on the loop filter.</entry>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD</constant></entry>
<entry>integer</entry>
</row>
<row><entry spanname="descr">Sets the refresh period for the golden frame. The period is defined
in number of frames. For a value of 'n', every nth frame starting from the first key frame will be taken as a golden frame.
For eg. for encoding sequence of 0, 1, 2, 3, 4, 5, 6, 7 where the golden frame refresh period is set as 4, the frames
0, 4, 8 etc will be taken as the golden frames as frame 0 is always a key frame.</entry>
</row>
<row><entry></entry></row>
<row id="v4l2-vpx-golden-frame-sel">
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL</constant></entry>
<entry>enum v4l2_vp8_golden_frame_sel</entry>
</row>
<row><entry spanname="descr">Selects the golden frame for encoding.
Possible values are:</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV</constant></entry>
<entry>Use the (n-2)th frame as a golden frame, current frame index being 'n'.</entry>
</row>
<row>
<entry><constant>V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD</constant></entry>
<entry>Use the previous specific frame indicated by
V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD as a golden frame.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="camera-controls">
......
......@@ -46,7 +46,9 @@ describing an IR signal are read from the chardev.</para>
values. Pulses and spaces are only marked implicitly by their position. The
data must start and end with a pulse, therefore, the data must always include
an uneven number of samples. The write function must block until the data has
been transmitted by the hardware.</para>
been transmitted by the hardware. If more data is provided than the hardware
can send, the driver returns EINVAL.</para>
</section>
<section id="lirc_ioctl">
......
<refentry>
<refmeta>
<refentrytitle>V4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M ('NM61')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname id="V4L2-PIX-FMT-NV16M"><constant>V4L2_PIX_FMT_NV16M</constant></refname>
<refname id="V4L2-PIX-FMT-NV61M"><constant>V4L2_PIX_FMT_NV61M</constant></refname>
<refpurpose>Variation of <constant>V4L2_PIX_FMT_NV16</constant> and <constant>V4L2_PIX_FMT_NV61</constant> with planes
non contiguous in memory. </refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
The three components are separated into two sub-images or planes.
<constant>V4L2_PIX_FMT_NV16M</constant> differs from <constant>V4L2_PIX_FMT_NV16
</constant> in that the two planes are non-contiguous in memory, i.e. the chroma
plane does not necessarily immediately follows the luma plane.
The luminance data occupies the first plane. The Y plane has one byte per pixel.
In the second plane there is chrominance data with alternating chroma samples.
The CbCr plane is the same width and height, in bytes, as the Y plane.
Each CbCr pair belongs to four pixels. For example,
Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
<constant>V4L2_PIX_FMT_NV61M</constant> is the same as <constant>V4L2_PIX_FMT_NV16M</constant>
except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
<para><constant>V4L2_PIX_FMT_NV16M</constant> and
<constant>V4L2_PIX_FMT_NV61M</constant> are intended to be used only in drivers
and applications that support the multi-planar API, described in
<xref linkend="planar-apis"/>. </para>
<example>
<title><constant>V4L2_PIX_FMT_NV16M</constant> 4 &times; 4 pixel image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start0&nbsp;+&nbsp;0:</entry>
<entry>Y'<subscript>00</subscript></entry>
<entry>Y'<subscript>01</subscript></entry>
<entry>Y'<subscript>02</subscript></entry>
<entry>Y'<subscript>03</subscript></entry>
</row>
<row>
<entry>start0&nbsp;+&nbsp;4:</entry>
<entry>Y'<subscript>10</subscript></entry>
<entry>Y'<subscript>11</subscript></entry>
<entry>Y'<subscript>12</subscript></entry>
<entry>Y'<subscript>13</subscript></entry>
</row>
<row>
<entry>start0&nbsp;+&nbsp;8:</entry>
<entry>Y'<subscript>20</subscript></entry>
<entry>Y'<subscript>21</subscript></entry>
<entry>Y'<subscript>22</subscript></entry>
<entry>Y'<subscript>23</subscript></entry>
</row>
<row>
<entry>start0&nbsp;+&nbsp;12:</entry>
<entry>Y'<subscript>30</subscript></entry>
<entry>Y'<subscript>31</subscript></entry>
<entry>Y'<subscript>32</subscript></entry>
<entry>Y'<subscript>33</subscript></entry>
</row>
<row>
<entry></entry>
</row>
<row>
<entry>start1&nbsp;+&nbsp;0:</entry>
<entry>Cb<subscript>00</subscript></entry>
<entry>Cr<subscript>00</subscript></entry>
<entry>Cb<subscript>02</subscript></entry>
<entry>Cr<subscript>02</subscript></entry>
</row>
<row>
<entry>start1&nbsp;+&nbsp;4:</entry>
<entry>Cb<subscript>10</subscript></entry>
<entry>Cr<subscript>10</subscript></entry>
<entry>Cb<subscript>12</subscript></entry>
<entry>Cr<subscript>12</subscript></entry>
</row>
<row>
<entry>start1&nbsp;+&nbsp;8:</entry>
<entry>Cb<subscript>20</subscript></entry>
<entry>Cr<subscript>20</subscript></entry>
<entry>Cb<subscript>22</subscript></entry>
<entry>Cr<subscript>22</subscript></entry>
</row>
<row>
<entry>start1&nbsp;+&nbsp;12:</entry>
<entry>Cb<subscript>30</subscript></entry>
<entry>Cr<subscript>30</subscript></entry>
<entry>Cb<subscript>32</subscript></entry>
<entry>Cr<subscript>32</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
<formalpara>
<title>Color Sample Location.</title>
<para>
<informaltable frame="none">
<tgroup cols="7" align="center">
<tbody valign="top">
<row>
<entry></entry>
<entry>0</entry><entry></entry><entry>1</entry><entry></entry>
<entry>2</entry><entry></entry><entry>3</entry>
</row>
<row>
<entry>0</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
<row>
<entry>1</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
<row>
<entry></entry>
</row>
<row>
<entry>2</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
<row>
<entry>3</entry>
<entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
<entry>Y</entry><entry></entry><entry>Y</entry>
</row>
<row>
<entry></entry>
<entry></entry><entry>C</entry><entry></entry><entry></entry>
<entry></entry><entry>C</entry><entry></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>
......@@ -391,9 +391,9 @@ clamp (double x)
else return r;
}
y1 = (255 / 219.0) * (Y1 - 16);
pb = (255 / 224.0) * (Cb - 128);
pr = (255 / 224.0) * (Cr - 128);
y1 = (Y1 - 16) / 219.0;
pb = (Cb - 128) / 224.0;
pr = (Cr - 128) / 224.0;
r = 1.0 * y1 + 0 * pb + 1.402 * pr;
g = 1.0 * y1 - 0.344 * pb - 0.714 * pr;
......@@ -718,6 +718,7 @@ information.</para>
&sub-nv12m;
&sub-nv12mt;
&sub-nv16;
&sub-nv16m;
&sub-nv24;
&sub-m420;
</section>
......
......@@ -62,18 +62,29 @@ addition to the <constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter
control over buffers is required. This ioctl can be called multiple times to
create buffers of different sizes.</para>
<para>To allocate device buffers applications initialize relevant fields of
the <structname>v4l2_create_buffers</structname> structure. They set the
<structfield>type</structfield> field in the
&v4l2-format; structure, embedded in this
structure, to the respective stream or buffer type.
<structfield>count</structfield> must be set to the number of required buffers.
<structfield>memory</structfield> specifies the required I/O method. The
<structfield>format</structfield> field shall typically be filled in using
either the <constant>VIDIOC_TRY_FMT</constant> or
<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
<structfield>sizeimage</structfield> fields to fit their specific needs. The
<structfield>reserved</structfield> array must be zeroed.</para>
<para>To allocate the device buffers applications must initialize the
relevant fields of the <structname>v4l2_create_buffers</structname> structure.
The <structfield>count</structfield> field must be set to the number of
requested buffers, the <structfield>memory</structfield> field specifies the
requested I/O method and the <structfield>reserved</structfield> array must be
zeroed.</para>
<para>The <structfield>format</structfield> field specifies the image format
that the buffers must be able to handle. The application has to fill in this
&v4l2-format;. Usually this will be done using the
<constant>VIDIOC_TRY_FMT</constant> or <constant>VIDIOC_G_FMT</constant> ioctl()
to ensure that the requested format is supported by the driver. Unsupported
formats will result in an error.</para>
<para>The buffers created by this ioctl will have as minimum size the size
defined by the <structfield>format.pix.sizeimage</structfield> field. If the
<structfield>format.pix.sizeimage</structfield> field is less than the minimum
required for the given format, then <structfield>sizeimage</structfield> will be
increased by the driver to that minimum to allocate the buffers. If it is
larger, then the value will be used as-is. The same applies to the
<structfield>sizeimage</structfield> field of the
<structname>v4l2_plane_pix_format</structname> structure in the case of
multiplanar formats.</para>
<para>When the ioctl is called with a pointer to this structure the driver
will attempt to allocate up to the requested number of buffers and store the
......@@ -144,9 +155,9 @@ mapped</link> I/O.</para>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The buffer type (<structfield>type</structfield> field) or the
requested I/O method (<structfield>memory</structfield>) is not
supported.</para>
<para>The buffer type (<structfield>format.type</structfield> field),
requested I/O method (<structfield>memory</structfield>) or format
(<structfield>format</structfield> field) is not valid.</para>
</listitem>
</varlistentry>
</variablelist>
......
......@@ -156,19 +156,19 @@ bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_H
<entry>__u32</entry>
<entry><structfield>il_vfrontporch</structfield></entry>
<entry>Vertical front porch in lines for the even field (aka field 2) of
interlaced field formats.</entry>
interlaced field formats. Must be 0 for progressive formats.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>il_vsync</structfield></entry>
<entry>Vertical sync length in lines for the even field (aka field 2) of
interlaced field formats.</entry>
interlaced field formats. Must be 0 for progressive formats.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>il_vbackporch</structfield></entry>
<entry>Vertical back porch in lines for the even field (aka field 2) of
interlaced field formats.</entry>
interlaced field formats. Must be 0 for progressive formats.</entry>
</row>
<row>
<entry>__u32</entry>
......
......@@ -92,8 +92,8 @@ to add them.</para>
<entry>int</entry>
<entry><structfield>quality</structfield></entry>
<entry>Deprecated. If <link linkend="jpeg-quality-control"><constant>
V4L2_CID_JPEG_IMAGE_QUALITY</constant></link> control is exposed by
a driver applications should use it instead and ignore this field.
V4L2_CID_JPEG_COMPRESSION_QUALITY</constant></link> control is exposed
by a driver applications should use it instead and ignore this field.
</entry>
</row>
<row>
......
......@@ -22,8 +22,14 @@
<!-- LinuxTV v4l-dvb repository. -->
<!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
<!ENTITY dash-ent-8 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-10 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-12 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-14 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-16 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-20 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-22 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-24 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
]>
<book id="media_api">
......
* Analog Devices adv7343 video encoder
The ADV7343 are high speed, digital-to-analog video encoders in a 64-lead LQFP
package. Six high speed, 3.3 V, 11-bit video DACs provide support for composite
(CVBS), S-Video (Y-C), and component (YPrPb/RGB) analog outputs in standard
definition (SD), enhanced definition (ED), or high definition (HD) video
formats.
Required Properties :
- compatible: Must be "adi,adv7343"
Optional Properties :
- adi,power-mode-sleep-mode: on enable the current consumption is reduced to
micro ampere level. All DACs and the internal PLL
circuit are disabled.
- adi,power-mode-pll-ctrl: PLL and oversampling control. This control allows
internal PLL 1 circuit to be powered down and the
oversampling to be switched off.
- ad,adv7343-power-mode-dac: array configuring the power on/off DAC's 1..6,
0 = OFF and 1 = ON, Default value when this
property is not specified is <0 0 0 0 0 0>.
- ad,adv7343-sd-config-dac-out: array configure SD DAC Output's 1 and 2, 0 = OFF
and 1 = ON, Default value when this property is
not specified is <0 0>.
Example:
i2c0@1c22000 {
...
...
adv7343@2a {
compatible = "adi,adv7343";
reg = <0x2a>;
port {
adv7343_1: endpoint {
adi,power-mode-sleep-mode;
adi,power-mode-pll-ctrl;
/* Use DAC1..3, DAC6 */
adi,dac-enable = <1 1 1 0 0 1>;
/* Use SD DAC output 1 */
adi,sd-dac-enable = <1 0>;
};
};
};
...
};
* Texas Instruments THS8200 video encoder
The ths8200 device is a digital to analog converter used in DVD players, video
recorders, set-top boxes.
Required Properties :
- compatible : value must be "ti,ths8200"
Example:
i2c0@1c22000 {
...
...
ths8200@5c {
compatible = "ti,ths8200";
reg = <0x5c>;
};
...
};
* Texas Instruments TV7002 video decoder
The TVP7002 device supports digitizing of video and graphics signal in RGB and
YPbPr color space.
Required Properties :
- compatible : Must be "ti,tvp7002"
Optional Properties:
- hsync-active: HSYNC Polarity configuration for the bus. Default value when
this property is not specified is <0>.
- vsync-active: VSYNC Polarity configuration for the bus. Default value when
this property is not specified is <0>.
- pclk-sample: Clock polarity of the bus. Default value when this property is
not specified is <0>.
- sync-on-green-active: Active state of Sync-on-green signal property of the
endpoint.
0 = Normal Operation (Active Low, Default)
1 = Inverted operation
- field-even-active: Active-high Field ID output polarity control of the bus.
Under normal operation, the field ID output is set to logic 1 for an odd field
(field 1) and set to logic 0 for an even field (field 0).
0 = Normal Operation (Active Low, Default)
1 = FID output polarity inverted
For further reading of port node refer Documentation/devicetree/bindings/media/
video-interfaces.txt.
Example:
i2c0@1c22000 {
...
...
tvp7002@5c {
compatible = "ti,tvp7002";
reg = <0x5c>;
port {
tvp7002_1: endpoint {
hsync-active = <1>;
vsync-active = <1>;
pclk-sample = <0>;
sync-on-green-active = <1>;
field-even-active = <0>;
};
};
};
...
};
......@@ -10,6 +10,7 @@ Required properties:
- compatible : value should be either one among the following
(a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
(b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
(b) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC
- reg : Physical base address of the IP registers and length of memory
mapped region.
......
......@@ -88,6 +88,8 @@ Optional endpoint properties
- field-even-active: field signal level during the even field data transmission.
- pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock
signal.
- sync-on-green-active: active state of Sync-on-green (SoG) signal, 0/1 for
LOW/HIGH respectively.
- data-lanes: an array of physical data lane indexes. Position of an entry
determines the logical lane number, while the value of an entry indicates
physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have
......
......@@ -124,26 +124,27 @@ You add non-menu controls by calling v4l2_ctrl_new_std:
const struct v4l2_ctrl_ops *ops,
u32 id, s32 min, s32 max, u32 step, s32 def);
Menu controls are added by calling v4l2_ctrl_new_std_menu:
Menu and integer menu controls are added by calling v4l2_ctrl_new_std_menu:
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 skip_mask, s32 def);
Or alternatively for integer menu controls, by calling v4l2_ctrl_new_int_menu:
Menu controls with a driver specific menu are added by calling
v4l2_ctrl_new_std_menu_items:
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
s32 skip_mask, s32 def, const char * const *qmenu);
Integer menu controls with a driver specific menu can be added by calling
v4l2_ctrl_new_int_menu:
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 def, const s64 *qmenu_int);
Standard menu controls with a driver specific menu are added by calling
v4l2_ctrl_new_std_menu_items:
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
s32 skip_mask, s32 def, const char * const *qmenu);
These functions are typically called right after the v4l2_ctrl_handler_init:
static const s64 exp_bias_qmenu[] = {
......
......@@ -580,12 +580,24 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/ad9389b*
ANALOG DEVICES INC ADV7511 DRIVER
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/adv7511*
ANALOG DEVICES INC ADV7604 DRIVER
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/adv7604*
ANALOG DEVICES INC ADV7842 DRIVER
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/adv7842*
ANALOG DEVICES INC ASOC CODEC DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de>
L: device-drivers-devel@blackfin.uclinux.org
......@@ -639,6 +651,12 @@ S: Maintained
F: drivers/net/appletalk/
F: net/appletalk/
APTINA CAMERA SENSOR PLL
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/aptina-pll.*
ARASAN COMPACT FLASH PATA CONTROLLER
M: Viresh Kumar <viresh.linux@gmail.com>
L: linux-ide@vger.kernel.org
......@@ -5518,7 +5536,7 @@ L: platform-driver-x86@vger.kernel.org
S: Supported
F: drivers/platform/x86/msi-wmi.c
MT9M032 SENSOR DRIVER
MT9M032 APTINA SENSOR DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
......@@ -5526,7 +5544,7 @@ S: Maintained
F: drivers/media/i2c/mt9m032.c
F: include/media/mt9m032.h
MT9P031 SENSOR DRIVER
MT9P031 APTINA CAMERA SENSOR
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
......@@ -5534,7 +5552,7 @@ S: Maintained
F: drivers/media/i2c/mt9p031.c
F: include/media/mt9p031.h
MT9T001 SENSOR DRIVER
MT9T001 APTINA CAMERA SENSOR
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
......@@ -5542,7 +5560,7 @@ S: Maintained
F: drivers/media/i2c/mt9t001.c
F: include/media/mt9t001.h
MT9V032 SENSOR DRIVER
MT9V032 APTINA CAMERA SENSOR
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
......
......@@ -82,6 +82,13 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_HWMON is not set
CONFIG_I2C=y
CONFIG_I2C_RCAR=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SOC_CAMERA=y
CONFIG_VIDEO_RCAR_VIN=y
# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
CONFIG_VIDEO_ML86V7667=y
CONFIG_SPI=y
CONFIG_SPI_SH_HSPI=y
CONFIG_USB=y
......
......@@ -84,6 +84,13 @@ CONFIG_GPIO_RCAR=y
CONFIG_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_SSB=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SOC_CAMERA=y
CONFIG_VIDEO_RCAR_VIN=y
# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
CONFIG_VIDEO_ADV7180=y
CONFIG_USB=y
CONFIG_USB_RCAR_PHY=y
CONFIG_MMC=y
......
......@@ -1249,12 +1249,10 @@ static struct vpif_capture_config da850_vpif_capture_config = {
static struct adv7343_platform_data adv7343_pdata = {
.mode_config = {
.dac_3 = 1,
.dac_2 = 1,
.dac_1 = 1,
.dac = { 1, 1, 1 },
},
.sd_config = {
.sd_dac_out1 = 1,
.sd_dac_out = { 1 },
},
};
......
......@@ -3,6 +3,7 @@
*
* Copyright (C) 2013 Renesas Solutions Corp.
* Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
* Copyright (C) 2013 Cogent Embedded, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -28,6 +29,7 @@
#include <linux/smsc911x.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <media/soc_camera.h>
#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/r8a7778.h>
......@@ -143,6 +145,25 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
MMC_CAP_NEEDS_POLL,
};
static struct rcar_vin_platform_data vin_platform_data __initdata = {
.flags = RCAR_VIN_BT656,
};
/* In the default configuration both decoders reside on I2C bus 0 */
#define BOCKW_CAMERA(idx) \
static struct i2c_board_info camera##idx##_info = { \
I2C_BOARD_INFO("ml86v7667", 0x41 + 2 * (idx)), \
}; \
\
static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \
.bus_id = idx, \
.i2c_adapter_id = 0, \
.board_info = &camera##idx##_info, \
}
BOCKW_CAMERA(0);
BOCKW_CAMERA(1);
static const struct pinctrl_map bockw_pinctrl_map[] = {
/* Ether */
PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778",
......@@ -174,6 +195,16 @@ static const struct pinctrl_map bockw_pinctrl_map[] = {
"sdhi0_cd", "sdhi0"),
PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
"sdhi0_wp", "sdhi0"),
/* VIN0 */
PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778",
"vin0_clk", "vin0"),
PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778",
"vin0_data8", "vin0"),
/* VIN1 */
PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778",
"vin1_clk", "vin1"),
PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778",
"vin1_data8", "vin1"),
};
#define FPGA 0x18200000
......@@ -192,6 +223,16 @@ static void __init bockw_init(void)
r8a7778_add_i2c_device(0);
r8a7778_add_hspi_device(0);
r8a7778_add_mmc_device(&sh_mmcif_plat);
r8a7778_add_vin_device(0, &vin_platform_data);
/* VIN1 has a pin conflict with Ether */
if (!IS_ENABLED(CONFIG_SH_ETH))
r8a7778_add_vin_device(1, &vin_platform_data);
platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0,
&iclink0_ml86v7667,
sizeof(iclink0_ml86v7667));
platform_device_register_data(&platform_bus, "soc-camera-pdrv", 1,
&iclink1_ml86v7667,
sizeof(iclink1_ml86v7667));
i2c_register_board_info(0, i2c0_devices,
ARRAY_SIZE(i2c0_devices));
......
/*
* marzen board support
*
* Copyright (C) 2011 Renesas Solutions Corp.
* Copyright (C) 2011, 2013 Renesas Solutions Corp.
* Copyright (C) 2011 Magnus Damm
* Copyright (C) 2013 Cogent Embedded, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -37,6 +38,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <media/soc_camera.h>
#include <mach/hardware.h>
#include <mach/r8a7779.h>
#include <mach/common.h>
......@@ -178,12 +180,40 @@ static struct platform_device leds_device = {
},
};
static struct rcar_vin_platform_data vin_platform_data __initdata = {
.flags = RCAR_VIN_BT656,
};
#define MARZEN_CAMERA(idx) \
static struct i2c_board_info camera##idx##_info = { \
I2C_BOARD_INFO("adv7180", 0x20 + (idx)), \
}; \
\
static struct soc_camera_link iclink##idx##_adv7180 = { \
.bus_id = 1 + 2 * (idx), \
.i2c_adapter_id = 0, \
.board_info = &camera##idx##_info, \
}; \
\
static struct platform_device camera##idx##_device = { \
.name = "soc-camera-pdrv", \
.id = idx, \
.dev = { \
.platform_data = &iclink##idx##_adv7180, \
}, \
};
MARZEN_CAMERA(0);
MARZEN_CAMERA(1);
static struct platform_device *marzen_devices[] __initdata = {
&eth_device,
&sdhi0_device,
&thermal_device,
&hspi_device,
&leds_device,
&camera0_device,
&camera1_device,
};
static const struct pinctrl_map marzen_pinctrl_map[] = {
......@@ -219,6 +249,16 @@ static const struct pinctrl_map marzen_pinctrl_map[] = {
/* USB2 */
PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779",
"usb2", "usb2"),
/* VIN1 */
PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
"vin1_clk", "vin1"),
PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
"vin1_data8", "vin1"),
/* VIN3 */
PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
"vin3_clk", "vin3"),
PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
"vin3_data8", "vin3"),
};
static void __init marzen_init(void)
......@@ -235,6 +275,8 @@ static void __init marzen_init(void)
r8a7779_add_standard_devices();
r8a7779_add_usb_phy_device(&usb_phy_platform_data);
r8a7779_add_vin_device(1, &vin_platform_data);
r8a7779_add_vin_device(3, &vin_platform_data);
platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
}
......
......@@ -106,6 +106,7 @@ enum {
MSTP331,
MSTP323, MSTP322, MSTP321,
MSTP114,
MSTP110, MSTP109,
MSTP100,
MSTP030,
MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
......@@ -119,6 +120,8 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
[MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
[MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
[MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */
[MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */
[MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */
[MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
[MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
......@@ -146,6 +149,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
......
......@@ -112,7 +112,9 @@ static struct clk *main_clks[] = {
};
enum { MSTP323, MSTP322, MSTP321, MSTP320,
MSTP120,
MSTP116, MSTP115, MSTP114,
MSTP110, MSTP109, MSTP108,
MSTP103, MSTP101, MSTP100,
MSTP030,
MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
......@@ -125,9 +127,13 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
[MSTP120] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 20, 0), /* VIN3 */
[MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */
[MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
[MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
[MSTP110] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 10, 0), /* VIN0 */
[MSTP109] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 9, 0), /* VIN1 */
[MSTP108] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 8, 0), /* VIN2 */
[MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
[MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */
[MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */
......@@ -162,10 +168,14 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
/* MSTP32 clocks */
CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
......
......@@ -22,6 +22,7 @@
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/sh_eth.h>
#include <linux/platform_data/usb-rcar-phy.h>
#include <linux/platform_data/camera-rcar.h>
extern void r8a7778_add_standard_devices(void);
extern void r8a7778_add_standard_devices_dt(void);
......@@ -30,6 +31,8 @@ extern void r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata);
extern void r8a7778_add_i2c_device(int id);
extern void r8a7778_add_hspi_device(int id);
extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info);
extern void r8a7778_add_vin_device(int id,
struct rcar_vin_platform_data *pdata);
extern void r8a7778_init_late(void);
extern void r8a7778_init_delay(void);
......
......@@ -5,6 +5,7 @@
#include <linux/pm_domain.h>
#include <linux/sh_eth.h>
#include <linux/platform_data/usb-rcar-phy.h>
#include <linux/platform_data/camera-rcar.h>
struct platform_device;
......@@ -35,6 +36,8 @@ extern void r8a7779_add_standard_devices(void);
extern void r8a7779_add_standard_devices_dt(void);
extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata);
extern void r8a7779_add_vin_device(int idx,
struct rcar_vin_platform_data *pdata);
extern void r8a7779_init_late(void);
extern void r8a7779_clock_init(void);
extern void r8a7779_pinmux_init(void);
......
......@@ -333,6 +333,40 @@ void __init r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info)
info, sizeof(*info));
}
/* VIN */
#define R8A7778_VIN(idx) \
static struct resource vin##idx##_resources[] __initdata = { \
DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
DEFINE_RES_IRQ(gic_iid(0x5a)), \
}; \
\
static struct platform_device_info vin##idx##_info __initdata = { \
.parent = &platform_bus, \
.name = "r8a7778-vin", \
.id = idx, \
.res = vin##idx##_resources, \
.num_res = ARRAY_SIZE(vin##idx##_resources), \
.dma_mask = DMA_BIT_MASK(32), \
}
R8A7778_VIN(0);
R8A7778_VIN(1);
static struct platform_device_info *vin_info_table[] __initdata = {
&vin0_info,
&vin1_info,
};
void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
{
BUG_ON(id < 0 || id > 1);
vin_info_table[id]->data = pdata;
vin_info_table[id]->size_data = sizeof(*pdata);
platform_device_register_full(vin_info_table[id]);
}
void __init r8a7778_add_standard_devices(void)
{
int i;
......
......@@ -559,6 +559,33 @@ static struct resource ether_resources[] = {
},
};
#define R8A7779_VIN(idx) \
static struct resource vin##idx##_resources[] __initdata = { \
DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \
DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \
}; \
\
static struct platform_device_info vin##idx##_info __initdata = { \
.parent = &platform_bus, \
.name = "r8a7779-vin", \
.id = idx, \
.res = vin##idx##_resources, \
.num_res = ARRAY_SIZE(vin##idx##_resources), \
.dma_mask = DMA_BIT_MASK(32), \
}
R8A7779_VIN(0);
R8A7779_VIN(1);
R8A7779_VIN(2);
R8A7779_VIN(3);
static struct platform_device_info *vin_info_table[] __initdata = {
&vin0_info,
&vin1_info,
&vin2_info,
&vin3_info,
};
static struct platform_device *r8a7779_devices_dt[] __initdata = {
&scif0_device,
&scif1_device,
......@@ -610,6 +637,16 @@ void __init r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata)
pdata, sizeof(*pdata));
}
void __init r8a7779_add_vin_device(int id, struct rcar_vin_platform_data *pdata)
{
BUG_ON(id < 0 || id > 3);
vin_info_table[id]->data = pdata;
vin_info_table[id]->size_data = sizeof(*pdata);
platform_device_register_full(vin_info_table[id]);
}
/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
void __init __weak r8a7779_register_twd(void) { }
......
......@@ -23,6 +23,8 @@ config SMS_SIANO_DEBUGFS
depends on SMS_SIANO_MDTV
depends on DEBUG_FS
depends on SMS_USB_DRV
depends on CONFIG_SMS_USB_DRV = CONFIG_SMS_SDIO_DRV
---help---
Choose Y to enable visualizing a dump of the frontend
statistics response packets via debugfs. Currently, works
......
......@@ -276,7 +276,8 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client,
/* Legacy PER/BER */
tmp = p->ets_packets * 65535;
do_div(tmp, p->ts_packets + p->ets_packets);
if (p->ts_packets + p->ets_packets)
do_div(tmp, p->ts_packets + p->ets_packets);
client->legacy_per = tmp;
}
......
......@@ -369,4 +369,6 @@
#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
#define USB_PID_CPYTO_REDI_PC50A 0xa803
#define USB_PID_CTVDIGDUAL_V2 0xe410
#define USB_PID_PCTV_2002E 0x025c
#define USB_PID_PCTV_2002E_SE 0x025d
#endif
......@@ -157,7 +157,6 @@ static struct regdata mb86a20s_init2[] = {
{ 0x45, 0x04 }, /* CN symbol 4 */
{ 0x48, 0x04 }, /* CN manual mode */
{ 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */
{ 0x50, 0xd6 }, { 0x51, 0x1f },
{ 0x50, 0xd2 }, { 0x51, 0x03 },
{ 0x50, 0xd7 }, { 0x51, 0xbf },
......@@ -1860,16 +1859,15 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n",
__func__, state->if_freq, (long long)pll);
if (!state->config->is_serial) {
if (!state->config->is_serial)
regD5 &= ~1;
rc = mb86a20s_writereg(state, 0x50, 0xd5);
if (rc < 0)
goto err;
rc = mb86a20s_writereg(state, 0x51, regD5);
if (rc < 0)
goto err;
}
rc = mb86a20s_writereg(state, 0x50, 0xd5);
if (rc < 0)
goto err;
rc = mb86a20s_writereg(state, 0x51, regD5);
if (rc < 0)
goto err;
rc = mb86a20s_writeregdata(state, mb86a20s_init2);
if (rc < 0)
......
......@@ -206,6 +206,18 @@ config VIDEO_ADV7604
To compile this driver as a module, choose M here: the
module will be called adv7604.
config VIDEO_ADV7842
tristate "Analog Devices ADV7842 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
---help---
Support for the Analog Devices ADV7842 video decoder.
This is a Analog Devices Component/Graphics/SD Digitizer
with 2:1 Multiplexed HDMI Receiver.
To compile this driver as a module, choose M here: the
module will be called adv7842.
config VIDEO_BT819
tristate "BT819A VideoStream decoder"
depends on VIDEO_V4L2 && I2C
......@@ -417,6 +429,17 @@ config VIDEO_ADV7393
To compile this driver as a module, choose M here: the
module will be called adv7393.
config VIDEO_ADV7511
tristate "Analog Devices ADV7511 encoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
---help---
Support for the Analog Devices ADV7511 video encoder.
This is a Analog Devices HDMI transmitter.
To compile this driver as a module, choose M here: the
module will be called adv7511.
config VIDEO_AD9389B
tristate "Analog Devices AD9389B encoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
......
......@@ -26,7 +26,9 @@ obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
obj-$(CONFIG_VIDEO_BT819) += bt819.o
......
......@@ -33,6 +33,7 @@
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ctrls.h>
#include <media/ad9389b.h>
......@@ -442,22 +443,11 @@ static int ad9389b_log_status(struct v4l2_subdev *sd)
vic_detect, vic_sent);
}
}
if (state->dv_timings.type == V4L2_DV_BT_656_1120) {
struct v4l2_bt_timings *bt = bt = &state->dv_timings.bt;
u32 frame_width = bt->width + bt->hfrontporch +
bt->hsync + bt->hbackporch;
u32 frame_height = bt->height + bt->vfrontporch +
bt->vsync + bt->vbackporch;
u32 frame_size = frame_width * frame_height;
v4l2_info(sd, "timings: %ux%u%s%u (%ux%u). Pix freq. = %u Hz. Polarities = 0x%x\n",
bt->width, bt->height, bt->interlaced ? "i" : "p",
frame_size > 0 ? (unsigned)bt->pixelclock / frame_size : 0,
frame_width, frame_height,
(unsigned)bt->pixelclock, bt->polarities);
} else {
if (state->dv_timings.type == V4L2_DV_BT_656_1120)
v4l2_print_dv_timings(sd->name, "timings: ",
&state->dv_timings, false);
else
v4l2_info(sd, "no timings set\n");
}
return 0;
}
......@@ -636,95 +626,34 @@ static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
static const struct v4l2_dv_timings ad9389b_timings[] = {
V4L2_DV_BT_CEA_720X480P59_94,
V4L2_DV_BT_CEA_720X576P50,
V4L2_DV_BT_CEA_1280X720P24,
V4L2_DV_BT_CEA_1280X720P25,
V4L2_DV_BT_CEA_1280X720P30,
V4L2_DV_BT_CEA_1280X720P50,
V4L2_DV_BT_CEA_1280X720P60,
V4L2_DV_BT_CEA_1920X1080P24,
V4L2_DV_BT_CEA_1920X1080P25,
V4L2_DV_BT_CEA_1920X1080P30,
V4L2_DV_BT_CEA_1920X1080P50,
V4L2_DV_BT_CEA_1920X1080P60,
V4L2_DV_BT_DMT_640X350P85,
V4L2_DV_BT_DMT_640X400P85,
V4L2_DV_BT_DMT_720X400P85,
V4L2_DV_BT_DMT_640X480P60,
V4L2_DV_BT_DMT_640X480P72,
V4L2_DV_BT_DMT_640X480P75,
V4L2_DV_BT_DMT_640X480P85,
V4L2_DV_BT_DMT_800X600P56,
V4L2_DV_BT_DMT_800X600P60,
V4L2_DV_BT_DMT_800X600P72,
V4L2_DV_BT_DMT_800X600P75,
V4L2_DV_BT_DMT_800X600P85,
V4L2_DV_BT_DMT_848X480P60,
V4L2_DV_BT_DMT_1024X768P60,
V4L2_DV_BT_DMT_1024X768P70,
V4L2_DV_BT_DMT_1024X768P75,
V4L2_DV_BT_DMT_1024X768P85,
V4L2_DV_BT_DMT_1152X864P75,
V4L2_DV_BT_DMT_1280X768P60_RB,
V4L2_DV_BT_DMT_1280X768P60,
V4L2_DV_BT_DMT_1280X768P75,
V4L2_DV_BT_DMT_1280X768P85,
V4L2_DV_BT_DMT_1280X800P60_RB,
V4L2_DV_BT_DMT_1280X800P60,
V4L2_DV_BT_DMT_1280X800P75,
V4L2_DV_BT_DMT_1280X800P85,
V4L2_DV_BT_DMT_1280X960P60,
V4L2_DV_BT_DMT_1280X960P85,
V4L2_DV_BT_DMT_1280X1024P60,
V4L2_DV_BT_DMT_1280X1024P75,
V4L2_DV_BT_DMT_1280X1024P85,
V4L2_DV_BT_DMT_1360X768P60,
V4L2_DV_BT_DMT_1400X1050P60_RB,
V4L2_DV_BT_DMT_1400X1050P60,
V4L2_DV_BT_DMT_1400X1050P75,
V4L2_DV_BT_DMT_1400X1050P85,
V4L2_DV_BT_DMT_1440X900P60_RB,
V4L2_DV_BT_DMT_1440X900P60,
V4L2_DV_BT_DMT_1600X1200P60,
V4L2_DV_BT_DMT_1680X1050P60_RB,
V4L2_DV_BT_DMT_1680X1050P60,
V4L2_DV_BT_DMT_1792X1344P60,
V4L2_DV_BT_DMT_1856X1392P60,
V4L2_DV_BT_DMT_1920X1200P60_RB,
V4L2_DV_BT_DMT_1366X768P60,
V4L2_DV_BT_DMT_1920X1080P60,
{},
static const struct v4l2_dv_timings_cap ad9389b_timings_cap = {
.type = V4L2_DV_BT_656_1120,
.bt = {
.max_width = 1920,
.max_height = 1200,
.min_pixelclock = 25000000,
.max_pixelclock = 170000000,
.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM,
},
};
static int ad9389b_s_dv_timings(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings)
{
struct ad9389b_state *state = get_ad9389b_state(sd);
int i;
v4l2_dbg(1, debug, sd, "%s:\n", __func__);
/* quick sanity check */
if (timings->type != V4L2_DV_BT_656_1120)
return -EINVAL;
if (timings->bt.interlaced)
return -EINVAL;
if (timings->bt.pixelclock < 27000000 ||
timings->bt.pixelclock > 170000000)
if (!v4l2_valid_dv_timings(timings, &ad9389b_timings_cap, NULL, NULL))
return -EINVAL;
/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
if the format is listed in ad9389b_timings[] */
for (i = 0; ad9389b_timings[i].bt.width; i++) {
if (v4l_match_dv_timings(timings, &ad9389b_timings[i], 0)) {
*timings = ad9389b_timings[i];
break;
}
}
if the format is one of the CEA or DMT timings. */
v4l2_find_dv_timings_cap(timings, &ad9389b_timings_cap, 0, NULL, NULL);
timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
......@@ -762,26 +691,14 @@ static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
struct v4l2_enum_dv_timings *timings)
{
if (timings->index >= ARRAY_SIZE(ad9389b_timings))
return -EINVAL;
memset(timings->reserved, 0, sizeof(timings->reserved));
timings->timings = ad9389b_timings[timings->index];
return 0;
return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
NULL, NULL);
}
static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
{
cap->type = V4L2_DV_BT_656_1120;
cap->bt.max_width = 1920;
cap->bt.max_height = 1200;
cap->bt.min_pixelclock = 27000000;
cap->bt.max_pixelclock = 170000000;
cap->bt.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT;
cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM;
*cap = ad9389b_timings_cap;
return 0;
}
......@@ -930,8 +847,10 @@ static void ad9389b_edid_handler(struct work_struct *work)
* (DVI connectors are particularly prone to this problem). */
if (state->edid.read_retries) {
state->edid.read_retries--;
/* EDID read failed, trigger a retry */
ad9389b_wr(sd, 0xc9, 0xf);
v4l2_dbg(1, debug, sd, "%s: edid read failed\n", __func__);
state->have_monitor = false;
ad9389b_s_power(sd, false);
ad9389b_s_power(sd, true);
queue_delayed_work(state->work_queue,
&state->edid_handler, EDID_DELAY);
return;
......@@ -967,11 +886,9 @@ static void ad9389b_setup(struct v4l2_subdev *sd)
ad9389b_wr_and_or(sd, 0x15, 0xf1, 0x0);
/* Output format: RGB 4:4:4 */
ad9389b_wr_and_or(sd, 0x16, 0x3f, 0x0);
/* CSC fixed point: +/-2, 1st order interpolation 4:2:2 -> 4:4:4 up
conversion, Aspect ratio: 16:9 */
ad9389b_wr_and_or(sd, 0x17, 0xe1, 0x0e);
/* Disable pixel repetition and CSC */
ad9389b_wr_and_or(sd, 0x3b, 0x9e, 0x0);
/* 1st order interpolation 4:2:2 -> 4:4:4 up conversion,
Aspect ratio: 16:9 */
ad9389b_wr_and_or(sd, 0x17, 0xf9, 0x06);
/* Output format: RGB 4:4:4, Active Format Information is valid. */
ad9389b_wr_and_or(sd, 0x45, 0xc7, 0x08);
/* Underscanned */
......@@ -1056,12 +973,12 @@ static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
static bool edid_block_verify_crc(u8 *edid_block)
{
int i;
u8 sum = 0;
int i;
for (i = 0; i < 127; i++)
sum += *(edid_block + i);
return ((255 - sum + 1) == edid_block[127]);
for (i = 0; i < 128; i++)
sum += edid_block[i];
return sum == 0;
}
static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment)
......@@ -1107,6 +1024,8 @@ static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
}
if (!edid_segment_verify_crc(sd, segment)) {
/* edid crc error, force reread of edid segment */
v4l2_err(sd, "%s: edid crc error\n", __func__);
state->have_monitor = false;
ad9389b_s_power(sd, false);
ad9389b_s_power(sd, true);
return false;
......@@ -1190,27 +1109,27 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
state->hdmi_mode_ctrl = v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
0, V4L2_DV_TX_MODE_DVI_D);
state->hdmi_mode_ctrl->is_private = true;
state->hotplug_ctrl = v4l2_ctrl_new_std(hdl, NULL,
V4L2_CID_DV_TX_HOTPLUG, 0, 1, 0, 0);
state->hotplug_ctrl->is_private = true;
state->rx_sense_ctrl = v4l2_ctrl_new_std(hdl, NULL,
V4L2_CID_DV_TX_RXSENSE, 0, 1, 0, 0);
state->rx_sense_ctrl->is_private = true;
state->have_edid0_ctrl = v4l2_ctrl_new_std(hdl, NULL,
V4L2_CID_DV_TX_EDID_PRESENT, 0, 1, 0, 0);
state->have_edid0_ctrl->is_private = true;
state->rgb_quantization_range_ctrl =
v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
0, V4L2_DV_RGB_RANGE_AUTO);
state->rgb_quantization_range_ctrl->is_private = true;
sd->ctrl_handler = hdl;
if (hdl->error) {
err = hdl->error;
goto err_hdl;
}
state->hdmi_mode_ctrl->is_private = true;
state->hotplug_ctrl->is_private = true;
state->rx_sense_ctrl->is_private = true;
state->have_edid0_ctrl->is_private = true;
state->rgb_quantization_range_ctrl->is_private = true;
state->pad.flags = MEDIA_PAD_FL_SINK;
err = media_entity_init(&sd->entity, 1, &state->pad, 0);
......
......@@ -27,8 +27,10 @@
#include <linux/uaccess.h>
#include <media/adv7343.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-of.h>
#include "adv7343_regs.h"
......@@ -226,12 +228,12 @@ static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
else
val = state->pdata->mode_config.sleep_mode << 0 |
state->pdata->mode_config.pll_control << 1 |
state->pdata->mode_config.dac_3 << 2 |
state->pdata->mode_config.dac_2 << 3 |
state->pdata->mode_config.dac_1 << 4 |
state->pdata->mode_config.dac_6 << 5 |
state->pdata->mode_config.dac_5 << 6 |
state->pdata->mode_config.dac_4 << 7;
state->pdata->mode_config.dac[2] << 2 |
state->pdata->mode_config.dac[1] << 3 |
state->pdata->mode_config.dac[0] << 4 |
state->pdata->mode_config.dac[5] << 5 |
state->pdata->mode_config.dac[4] << 6 |
state->pdata->mode_config.dac[3] << 7;
err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
if (err < 0)
......@@ -250,15 +252,15 @@ static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
/* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
if (state->pdata && state->pdata->sd_config.sd_dac_out1)
val = val | (state->pdata->sd_config.sd_dac_out1 << 1);
else if (state->pdata && !state->pdata->sd_config.sd_dac_out1)
val = val & ~(state->pdata->sd_config.sd_dac_out1 << 1);
if (state->pdata && state->pdata->sd_config.sd_dac_out[0])
val = val | (state->pdata->sd_config.sd_dac_out[0] << 1);
else if (state->pdata && !state->pdata->sd_config.sd_dac_out[0])
val = val & ~(state->pdata->sd_config.sd_dac_out[0] << 1);
if (state->pdata && state->pdata->sd_config.sd_dac_out2)
val = val | (state->pdata->sd_config.sd_dac_out2 << 2);
else if (state->pdata && !state->pdata->sd_config.sd_dac_out2)
val = val & ~(state->pdata->sd_config.sd_dac_out2 << 2);
if (state->pdata && state->pdata->sd_config.sd_dac_out[1])
val = val | (state->pdata->sd_config.sd_dac_out[1] << 2);
else if (state->pdata && !state->pdata->sd_config.sd_dac_out[1])
val = val & ~(state->pdata->sd_config.sd_dac_out[1] << 2);
err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
if (err < 0)
......@@ -398,6 +400,40 @@ static int adv7343_initialize(struct v4l2_subdev *sd)
return err;
}
static struct adv7343_platform_data *
adv7343_get_pdata(struct i2c_client *client)
{
struct adv7343_platform_data *pdata;
struct device_node *np;
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
if (!np)
return NULL;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
goto done;
pdata->mode_config.sleep_mode =
of_property_read_bool(np, "adi,power-mode-sleep-mode");
pdata->mode_config.pll_control =
of_property_read_bool(np, "adi,power-mode-pll-ctrl");
of_property_read_u32_array(np, "adi,dac-enable",
pdata->mode_config.dac, 6);
of_property_read_u32_array(np, "adi,sd-dac-enable",
pdata->sd_config.sd_dac_out, 2);
done:
of_node_put(np);
return pdata;
}
static int adv7343_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -416,7 +452,7 @@ static int adv7343_probe(struct i2c_client *client,
return -ENOMEM;
/* Copy board specific information here */
state->pdata = client->dev.platform_data;
state->pdata = adv7343_get_pdata(client);
state->reg00 = 0x80;
state->reg01 = 0x00;
......@@ -445,16 +481,21 @@ static int adv7343_probe(struct i2c_client *client,
ADV7343_GAIN_DEF);
state->sd.ctrl_handler = &state->hdl;
if (state->hdl.error) {
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
return err;
err = state->hdl.error;
goto done;
}
v4l2_ctrl_handler_setup(&state->hdl);
err = adv7343_initialize(&state->sd);
if (err)
goto done;
err = v4l2_async_register_subdev(&state->sd);
done:
if (err < 0)
v4l2_ctrl_handler_free(&state->hdl);
return err;
}
......@@ -463,6 +504,7 @@ static int adv7343_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct adv7343_state *state = to_state(sd);
v4l2_async_unregister_subdev(&state->sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
......@@ -476,8 +518,17 @@ static const struct i2c_device_id adv7343_id[] = {
MODULE_DEVICE_TABLE(i2c, adv7343_id);
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id adv7343_of_match[] = {
{.compatible = "adi,adv7343", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, adv7343_of_match);
#endif
static struct i2c_driver adv7343_driver = {
.driver = {
.of_match_table = of_match_ptr(adv7343_of_match),
.owner = THIS_MODULE,
.name = "adv7343",
},
......
此差异已折叠。
......@@ -38,6 +38,7 @@
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/adv7604.h>
static int debug;
......@@ -76,6 +77,7 @@ struct adv7604_state {
struct delayed_work delayed_work_enable_hotplug;
bool connector_hdmi;
bool restart_stdi_once;
u32 prev_input_status;
/* i2c clients */
struct i2c_client *i2c_avlink;
......@@ -260,22 +262,22 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
static inline unsigned hblanking(const struct v4l2_bt_timings *t)
{
return t->hfrontporch + t->hsync + t->hbackporch;
return V4L2_DV_BT_BLANKING_WIDTH(t);
}
static inline unsigned htotal(const struct v4l2_bt_timings *t)
{
return t->width + t->hfrontporch + t->hsync + t->hbackporch;
return V4L2_DV_BT_FRAME_WIDTH(t);
}
static inline unsigned vblanking(const struct v4l2_bt_timings *t)
{
return t->vfrontporch + t->vsync + t->vbackporch;
return V4L2_DV_BT_BLANKING_HEIGHT(t);
}
static inline unsigned vtotal(const struct v4l2_bt_timings *t)
{
return t->height + t->vfrontporch + t->vsync + t->vbackporch;
return V4L2_DV_BT_FRAME_HEIGHT(t);
}
/* ----------------------------------------------------------------------- */
......@@ -761,7 +763,7 @@ static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
int i;
for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings,
if (!v4l2_match_dv_timings(timings, &predef_vid_timings[i].timings,
DIGITAL_INPUT ? 250000 : 1000000))
continue;
io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
......@@ -990,6 +992,11 @@ static inline bool no_lock_tmds(struct v4l2_subdev *sd)
return (io_read(sd, 0x6a) & 0xe0) != 0xe0;
}
static inline bool is_hdmi(struct v4l2_subdev *sd)
{
return hdmi_read(sd, 0x05) & 0x80;
}
static inline bool no_lock_sspd(struct v4l2_subdev *sd)
{
/* TODO channel 2 */
......@@ -1044,38 +1051,6 @@ static int adv7604_g_input_status(struct v4l2_subdev *sd, u32 *status)
/* ----------------------------------------------------------------------- */
static void adv7604_print_timings(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings, const char *txt, bool detailed)
{
struct v4l2_bt_timings *bt = &timings->bt;
u32 htot, vtot;
if (timings->type != V4L2_DV_BT_656_1120)
return;
htot = htotal(bt);
vtot = vtotal(bt);
v4l2_info(sd, "%s %dx%d%s%d (%dx%d)",
txt, bt->width, bt->height, bt->interlaced ? "i" : "p",
(htot * vtot) > 0 ? ((u32)bt->pixelclock /
(htot * vtot)) : 0,
htot, vtot);
if (detailed) {
v4l2_info(sd, " horizontal: fp = %d, %ssync = %d, bp = %d\n",
bt->hfrontporch,
(bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
bt->hsync, bt->hbackporch);
v4l2_info(sd, " vertical: fp = %d, %ssync = %d, bp = %d\n",
bt->vfrontporch,
(bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
bt->vsync, bt->vbackporch);
v4l2_info(sd, " pixelclock: %lld, flags: 0x%x, standards: 0x%x\n",
bt->pixelclock, bt->flags, bt->standards);
}
}
struct stdi_readback {
u16 bl, lcf, lcvs;
u8 hs_pol, vs_pol;
......@@ -1187,7 +1162,7 @@ static int adv7604_dv_timings_cap(struct v4l2_subdev *sd,
cap->type = V4L2_DV_BT_656_1120;
cap->bt.max_width = 1920;
cap->bt.max_height = 1200;
cap->bt.min_pixelclock = 27000000;
cap->bt.min_pixelclock = 25000000;
if (DIGITAL_INPUT)
cap->bt.max_pixelclock = 225000000;
else
......@@ -1208,7 +1183,7 @@ static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
int i;
for (i = 0; adv7604_timings[i].bt.width; i++) {
if (v4l_match_dv_timings(timings, &adv7604_timings[i],
if (v4l2_match_dv_timings(timings, &adv7604_timings[i],
DIGITAL_INPUT ? 250000 : 1000000)) {
*timings = adv7604_timings[i];
break;
......@@ -1242,12 +1217,21 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
if (DIGITAL_INPUT) {
uint32_t freq;
timings->type = V4L2_DV_BT_656_1120;
bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
bt->pixelclock = (hdmi_read(sd, 0x06) * 1000000) +
freq = (hdmi_read(sd, 0x06) * 1000000) +
((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000;
if (is_hdmi(sd)) {
/* adjust for deep color mode */
unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
freq = freq * 8 / bits_per_channel;
}
bt->pixelclock = freq;
bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
hdmi_read(sd, 0x21);
bt->hsync = (hdmi_read(sd, 0x22) & 0x03) * 256 +
......@@ -1329,8 +1313,8 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
}
if (debug > 1)
adv7604_print_timings(sd, timings,
"adv7604_query_dv_timings:", true);
v4l2_print_dv_timings(sd->name, "adv7604_query_dv_timings: ",
timings, true);
return 0;
}
......@@ -1372,8 +1356,8 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
if (debug > 1)
adv7604_print_timings(sd, timings,
"adv7604_s_dv_timings:", true);
v4l2_print_dv_timings(sd->name, "adv7604_s_dv_timings: ",
timings, true);
return 0;
}
......@@ -1534,6 +1518,7 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
{
struct adv7604_state *state = to_state(sd);
u8 fmt_change, fmt_change_digital, tx_5v;
u32 input_status;
/* format change */
fmt_change = io_read(sd, 0x43) & 0x98;
......@@ -1544,9 +1529,18 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
io_write(sd, 0x6c, fmt_change_digital);
if (fmt_change || fmt_change_digital) {
v4l2_dbg(1, debug, sd,
"%s: ADV7604_FMT_CHANGE, fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
"%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
__func__, fmt_change, fmt_change_digital);
v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL);
adv7604_g_input_status(sd, &input_status);
if (input_status != state->prev_input_status) {
v4l2_dbg(1, debug, sd,
"%s: input_status = 0x%x, prev_input_status = 0x%x\n",
__func__, input_status, state->prev_input_status);
state->prev_input_status = input_status;
v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL);
}
if (handled)
*handled = true;
}
......@@ -1625,7 +1619,7 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
u8 avi_len;
u8 avi_ver;
if (!(hdmi_read(sd, 0x05) & 0x80)) {
if (!is_hdmi(sd)) {
v4l2_info(sd, "receive DVI-D signal (AVI infoframe not supported)\n");
return;
}
......@@ -1686,6 +1680,12 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
"RGB limited range (16-235)",
"RGB full range (0-255)",
};
char *deep_color_mode_txt[4] = {
"8-bits per channel",
"10-bits per channel",
"12-bits per channel",
"16-bits per channel (not supported)"
};
v4l2_info(sd, "-----Chip status-----\n");
v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on");
......@@ -1723,8 +1723,13 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
if (adv7604_query_dv_timings(sd, &timings))
v4l2_info(sd, "No video detected\n");
else
adv7604_print_timings(sd, &timings, "Detected format:", true);
adv7604_print_timings(sd, &state->timings, "Configured format:", true);
v4l2_print_dv_timings(sd->name, "Detected format: ",
&timings, true);
v4l2_print_dv_timings(sd->name, "Configured format: ",
&state->timings, true);
if (no_signal(sd))
return 0;
v4l2_info(sd, "-----Color space-----\n");
v4l2_info(sd, "RGB quantization range ctrl: %s\n",
......@@ -1735,15 +1740,40 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
(reg_io_0x02 & 0x02) ? "RGB" : "YCbCr",
(reg_io_0x02 & 0x04) ? "(16-235)" : "(0-255)",
((reg_io_0x02 & 0x04) ^ (reg_io_0x02 & 0x01)) ?
"enabled" : "disabled");
"enabled" : "disabled");
v4l2_info(sd, "Color space conversion: %s\n",
csc_coeff_sel_rb[cp_read(sd, 0xfc) >> 4]);
/* Digital video */
if (DIGITAL_INPUT) {
v4l2_info(sd, "-----HDMI status-----\n");
v4l2_info(sd, "HDCP encrypted content: %s\n",
hdmi_read(sd, 0x05) & 0x40 ? "true" : "false");
if (!DIGITAL_INPUT)
return 0;
v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D");
v4l2_info(sd, "HDCP encrypted content: %s\n", (hdmi_read(sd, 0x05) & 0x40) ? "true" : "false");
v4l2_info(sd, "HDCP keys read: %s%s\n",
(hdmi_read(sd, 0x04) & 0x20) ? "yes" : "no",
(hdmi_read(sd, 0x04) & 0x10) ? "ERROR" : "");
if (!is_hdmi(sd)) {
bool audio_pll_locked = hdmi_read(sd, 0x04) & 0x01;
bool audio_sample_packet_detect = hdmi_read(sd, 0x18) & 0x01;
bool audio_mute = io_read(sd, 0x65) & 0x40;
v4l2_info(sd, "Audio: pll %s, samples %s, %s\n",
audio_pll_locked ? "locked" : "not locked",
audio_sample_packet_detect ? "detected" : "not detected",
audio_mute ? "muted" : "enabled");
if (audio_pll_locked && audio_sample_packet_detect) {
v4l2_info(sd, "Audio format: %s\n",
(hdmi_read(sd, 0x07) & 0x20) ? "multi-channel" : "stereo");
}
v4l2_info(sd, "Audio CTS: %u\n", (hdmi_read(sd, 0x5b) << 12) +
(hdmi_read(sd, 0x5c) << 8) +
(hdmi_read(sd, 0x5d) & 0xf0));
v4l2_info(sd, "Audio N: %u\n", ((hdmi_read(sd, 0x5d) & 0x0f) << 16) +
(hdmi_read(sd, 0x5e) << 8) +
hdmi_read(sd, 0x5f));
v4l2_info(sd, "AV Mute: %s\n", (hdmi_read(sd, 0x04) & 0x40) ? "on" : "off");
v4l2_info(sd, "Deep color mode: %s\n", deep_color_mode_txt[(hdmi_read(sd, 0x0b) & 0x60) >> 5]);
print_avi_infoframe(sd);
}
......@@ -1952,6 +1982,10 @@ static int adv7604_probe(struct i2c_client *client,
return -ENOMEM;
}
/* initialize variables */
state->restart_stdi_once = true;
state->prev_input_status = ~0;
/* platform data */
if (!pdata) {
v4l_err(client, "No platform data!\n");
......@@ -1987,29 +2021,30 @@ static int adv7604_probe(struct i2c_client *client,
/* private controls */
state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL,
V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0);
state->detect_tx_5v_ctrl->is_private = true;
state->rgb_quantization_range_ctrl =
v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops,
V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
0, V4L2_DV_RGB_RANGE_AUTO);
state->rgb_quantization_range_ctrl->is_private = true;
/* custom controls */
state->analog_sampling_phase_ctrl =
v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL);
state->analog_sampling_phase_ctrl->is_private = true;
state->free_run_color_manual_ctrl =
v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color_manual, NULL);
state->free_run_color_manual_ctrl->is_private = true;
state->free_run_color_ctrl =
v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color, NULL);
state->free_run_color_ctrl->is_private = true;
sd->ctrl_handler = hdl;
if (hdl->error) {
err = hdl->error;
goto err_hdl;
}
state->detect_tx_5v_ctrl->is_private = true;
state->rgb_quantization_range_ctrl->is_private = true;
state->analog_sampling_phase_ctrl->is_private = true;
state->free_run_color_manual_ctrl->is_private = true;
state->free_run_color_ctrl->is_private = true;
if (adv7604_s_detect_tx_5v_ctrl(sd)) {
err = -ENODEV;
goto err_hdl;
......@@ -2035,7 +2070,6 @@ static int adv7604_probe(struct i2c_client *client,
v4l2_err(sd, "failed to create all i2c clients\n");
goto err_i2c;
}
state->restart_stdi_once = true;
/* work queues */
state->work_queues = create_singlethread_workqueue(client->name);
......
此差异已折叠。
......@@ -209,7 +209,8 @@ static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd,
fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt->field = V4L2_FIELD_INTERLACED;
/* The top field is always transferred first by the chip */
fmt->field = V4L2_FIELD_INTERLACED_TB;
fmt->width = 720;
fmt->height = priv->std & V4L2_STD_525_60 ? 480 : 576;
......
......@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/log2.h>
......@@ -135,6 +136,8 @@ struct mt9v032 {
struct mutex power_lock;
int power_count;
struct clk *clk;
struct mt9v032_platform_data *pdata;
u32 sysclk;
......@@ -219,10 +222,9 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
int ret;
if (mt9v032->pdata->set_clock) {
mt9v032->pdata->set_clock(&mt9v032->subdev, mt9v032->sysclk);
udelay(1);
}
clk_set_rate(mt9v032->clk, mt9v032->sysclk);
clk_prepare_enable(mt9v032->clk);
udelay(1);
/* Reset the chip and stop data read out */
ret = mt9v032_write(client, MT9V032_RESET, 1);
......@@ -238,8 +240,7 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
static void mt9v032_power_off(struct mt9v032 *mt9v032)
{
if (mt9v032->pdata->set_clock)
mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
clk_disable_unprepare(mt9v032->clk);
}
static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
......@@ -748,6 +749,10 @@ static int mt9v032_probe(struct i2c_client *client,
if (!mt9v032)
return -ENOMEM;
mt9v032->clk = devm_clk_get(&client->dev, NULL);
if (IS_ERR(mt9v032->clk))
return PTR_ERR(mt9v032->clk);
mutex_init(&mt9v032->power_lock);
mt9v032->pdata = pdata;
......
......@@ -1083,7 +1083,7 @@ static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd,
{
int i = ARRAY_SIZE(ov965x_formats);
if (fse->index > ARRAY_SIZE(ov965x_framesizes))
if (fse->index >= ARRAY_SIZE(ov965x_framesizes))
return -EINVAL;
while (--i)
......
......@@ -1111,6 +1111,11 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
*mf = fmt->format;
if (fmt->pad == OIF_ISP_PAD) {
mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD);
mf->width = fmt->format.width;
mf->height = fmt->format.height;
}
} else {
switch (fmt->pad) {
case OIF_ISP_PAD:
......
......@@ -1003,7 +1003,7 @@ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
const struct s5k6aa_interval *fi;
int ret = 0;
if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
if (fie->index >= ARRAY_SIZE(s5k6aa_intervals))
return -EINVAL;
v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
......
......@@ -225,19 +225,63 @@ static const unsigned char saa7111_init[] = {
0x00, 0x00
};
/* SAA7113/GM7113C init codes
* It's important that R_14... R_17 == 0x00
* for the gm7113c chip to deliver stable video
/*
* This table has one illegal value, and some values that are not
* correct according to the datasheet initialization table.
*
* If you need a table with legal/default values tell the driver in
* i2c_board_info.platform_data, and you will get the gm7113c_init
* table instead.
*/
/* SAA7113 Init codes */
static const unsigned char saa7113_init[] = {
R_01_INC_DELAY, 0x08,
R_02_INPUT_CNTL_1, 0xc2,
R_03_INPUT_CNTL_2, 0x30,
R_04_INPUT_CNTL_3, 0x00,
R_05_INPUT_CNTL_4, 0x00,
R_06_H_SYNC_START, 0x89,
R_06_H_SYNC_START, 0x89, /* Illegal value -119,
* min. value = -108 (0x94) */
R_07_H_SYNC_STOP, 0x0d,
R_08_SYNC_CNTL, 0x88, /* Not datasheet default.
* HTC = VTR mode, should be 0x98 */
R_09_LUMA_CNTL, 0x01,
R_0A_LUMA_BRIGHT_CNTL, 0x80,
R_0B_LUMA_CONTRAST_CNTL, 0x47,
R_0C_CHROMA_SAT_CNTL, 0x40,
R_0D_CHROMA_HUE_CNTL, 0x00,
R_0E_CHROMA_CNTL_1, 0x01,
R_0F_CHROMA_GAIN_CNTL, 0x2a,
R_10_CHROMA_CNTL_2, 0x08, /* Not datsheet default.
* VRLN enabled, should be 0x00 */
R_11_MODE_DELAY_CNTL, 0x0c,
R_12_RT_SIGNAL_CNTL, 0x07, /* Not datasheet default,
* should be 0x01 */
R_13_RT_X_PORT_OUT_CNTL, 0x00,
R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
R_15_VGATE_START_FID_CHG, 0x00,
R_16_VGATE_STOP, 0x00,
R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
0x00, 0x00
};
/*
* GM7113C is a clone of the SAA7113 chip
* This init table is copied out of the saa7113 datasheet.
* In R_08 we enable "Automatic Field Detection" [AUFD],
* this is disabled when saa711x_set_v4lstd is called.
*/
static const unsigned char gm7113c_init[] = {
R_01_INC_DELAY, 0x08,
R_02_INPUT_CNTL_1, 0xc0,
R_03_INPUT_CNTL_2, 0x33,
R_04_INPUT_CNTL_3, 0x00,
R_05_INPUT_CNTL_4, 0x00,
R_06_H_SYNC_START, 0xe9,
R_07_H_SYNC_STOP, 0x0d,
R_08_SYNC_CNTL, 0x88,
R_08_SYNC_CNTL, 0x98,
R_09_LUMA_CNTL, 0x01,
R_0A_LUMA_BRIGHT_CNTL, 0x80,
R_0B_LUMA_CONTRAST_CNTL, 0x47,
......@@ -245,9 +289,9 @@ static const unsigned char saa7113_init[] = {
R_0D_CHROMA_HUE_CNTL, 0x00,
R_0E_CHROMA_CNTL_1, 0x01,
R_0F_CHROMA_GAIN_CNTL, 0x2a,
R_10_CHROMA_CNTL_2, 0x08,
R_10_CHROMA_CNTL_2, 0x00,
R_11_MODE_DELAY_CNTL, 0x0c,
R_12_RT_SIGNAL_CNTL, 0x07,
R_12_RT_SIGNAL_CNTL, 0x01,
R_13_RT_X_PORT_OUT_CNTL, 0x00,
R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
R_15_VGATE_START_FID_CHG, 0x00,
......@@ -462,24 +506,6 @@ static const unsigned char saa7115_cfg_50hz_video[] = {
/* ============== SAA7715 VIDEO templates (end) ======= */
/* ============== GM7113C VIDEO templates ============= */
static const unsigned char gm7113c_cfg_60hz_video[] = {
R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
0x00, 0x00
};
static const unsigned char gm7113c_cfg_50hz_video[] = {
R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
R_0E_CHROMA_CNTL_1, 0x07,
0x00, 0x00
};
/* ============== GM7113C VIDEO templates (end) ======= */
static const unsigned char saa7115_cfg_vbi_on[] = {
R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
......@@ -964,17 +990,24 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
if (std & V4L2_STD_525_60) {
v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
if (state->ident == GM7113C)
saa711x_writeregs(sd, gm7113c_cfg_60hz_video);
else
if (state->ident == GM7113C) {
u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
reg |= SAA7113_R_08_FSEL;
saa711x_write(sd, R_08_SYNC_CNTL, reg);
} else {
saa711x_writeregs(sd, saa7115_cfg_60hz_video);
}
saa711x_set_size(sd, 720, 480);
} else {
v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
if (state->ident == GM7113C)
saa711x_writeregs(sd, gm7113c_cfg_50hz_video);
else
if (state->ident == GM7113C) {
u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
saa711x_write(sd, R_08_SYNC_CNTL, reg);
} else {
saa711x_writeregs(sd, saa7115_cfg_50hz_video);
}
saa711x_set_size(sd, 720, 576);
}
......@@ -1596,6 +1629,65 @@ static const struct v4l2_subdev_ops saa711x_ops = {
/* ----------------------------------------------------------------------- */
static void saa711x_write_platform_data(struct saa711x_state *state,
struct saa7115_platform_data *data)
{
struct v4l2_subdev *sd = &state->sd;
u8 work;
if (state->ident != GM7113C &&
state->ident != SAA7113)
return;
if (data->saa7113_r08_htc) {
work = saa711x_read(sd, R_08_SYNC_CNTL);
work &= ~SAA7113_R_08_HTC_MASK;
work |= ((*data->saa7113_r08_htc) << SAA7113_R_08_HTC_OFFSET);
saa711x_write(sd, R_08_SYNC_CNTL, work);
}
if (data->saa7113_r10_vrln) {
work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
work &= ~SAA7113_R_10_VRLN_MASK;
if (*data->saa7113_r10_vrln)
work |= (1 << SAA7113_R_10_VRLN_OFFSET);
saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
}
if (data->saa7113_r10_ofts) {
work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
work &= ~SAA7113_R_10_OFTS_MASK;
work |= (*data->saa7113_r10_ofts << SAA7113_R_10_OFTS_OFFSET);
saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
}
if (data->saa7113_r12_rts0) {
work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
work &= ~SAA7113_R_12_RTS0_MASK;
work |= (*data->saa7113_r12_rts0 << SAA7113_R_12_RTS0_OFFSET);
/* According to the datasheet,
* SAA7113_RTS_DOT_IN should only be used on RTS1 */
WARN_ON(*data->saa7113_r12_rts0 == SAA7113_RTS_DOT_IN);
saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
}
if (data->saa7113_r12_rts1) {
work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
work &= ~SAA7113_R_12_RTS1_MASK;
work |= (*data->saa7113_r12_rts1 << SAA7113_R_12_RTS1_OFFSET);
saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
}
if (data->saa7113_r13_adlsb) {
work = saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL);
work &= ~SAA7113_R_13_ADLSB_MASK;
if (*data->saa7113_r13_adlsb)
work |= (1 << SAA7113_R_13_ADLSB_OFFSET);
saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL, work);
}
}
/**
* saa711x_detect_chip - Detects the saa711x (or clone) variant
* @client: I2C client structure.
......@@ -1704,6 +1796,7 @@ static int saa711x_probe(struct i2c_client *client,
struct saa711x_state *state;
struct v4l2_subdev *sd;
struct v4l2_ctrl_handler *hdl;
struct saa7115_platform_data *pdata;
int ident;
char name[CHIP_VER_SIZE + 1];
......@@ -1767,21 +1860,31 @@ static int saa711x_probe(struct i2c_client *client,
/* init to 60hz/48khz */
state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
pdata = client->dev.platform_data;
switch (state->ident) {
case SAA7111:
case SAA7111A:
saa711x_writeregs(sd, saa7111_init);
break;
case GM7113C:
saa711x_writeregs(sd, gm7113c_init);
break;
case SAA7113:
saa711x_writeregs(sd, saa7113_init);
if (pdata && pdata->saa7113_force_gm7113c_init)
saa711x_writeregs(sd, gm7113c_init);
else
saa711x_writeregs(sd, saa7113_init);
break;
default:
state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
saa711x_writeregs(sd, saa7115_init_auto_input);
}
if (state->ident > SAA7111A)
if (state->ident > SAA7111A && state->ident != GM7113C)
saa711x_writeregs(sd, saa7115_init_misc);
if (pdata)
saa711x_write_platform_data(state, pdata);
saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
v4l2_ctrl_handler_setup(hdl);
......
......@@ -201,6 +201,25 @@
#define R_FB_PULSE_C_POS_MSB 0xfb
#define R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES 0xff
/* SAA7113 bit-masks */
#define SAA7113_R_08_HTC_OFFSET 3
#define SAA7113_R_08_HTC_MASK (0x3 << SAA7113_R_08_HTC_OFFSET)
#define SAA7113_R_08_FSEL 0x40
#define SAA7113_R_08_AUFD 0x80
#define SAA7113_R_10_VRLN_OFFSET 3
#define SAA7113_R_10_VRLN_MASK (0x1 << SAA7113_R_10_VRLN_OFFSET)
#define SAA7113_R_10_OFTS_OFFSET 6
#define SAA7113_R_10_OFTS_MASK (0x3 << SAA7113_R_10_OFTS_OFFSET)
#define SAA7113_R_12_RTS0_OFFSET 0
#define SAA7113_R_12_RTS0_MASK (0xf << SAA7113_R_12_RTS0_OFFSET)
#define SAA7113_R_12_RTS1_OFFSET 4
#define SAA7113_R_12_RTS1_MASK (0xf << SAA7113_R_12_RTS1_OFFSET)
#define SAA7113_R_13_ADLSB_OFFSET 7
#define SAA7113_R_13_ADLSB_MASK (0x1 << SAA7113_R_13_ADLSB_OFFSET)
#if 0
/* Those structs will be used in the future for debug purposes */
struct saa711x_reg_descr {
......
......@@ -87,6 +87,17 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll)
dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz);
}
/*
* Heuristically guess the PLL tree for a given common multiplier and
* divisor. Begin with the operational timing and continue to video
* timing once operational timing has been verified.
*
* @mul is the PLL multiplier and @div is the common divisor
* (pre_pll_clk_div and op_sys_clk_div combined). The final PLL
* multiplier will be a multiple of @mul.
*
* @return Zero on success, error code on error.
*/
static int __smiapp_pll_calculate(struct device *dev,
const struct smiapp_pll_limits *limits,
struct smiapp_pll *pll, uint32_t mul,
......@@ -95,6 +106,12 @@ static int __smiapp_pll_calculate(struct device *dev,
uint32_t sys_div;
uint32_t best_pix_div = INT_MAX >> 1;
uint32_t vt_op_binning_div;
/*
* Higher multipliers (and divisors) are often required than
* necessitated by the external clock and the output clocks.
* There are limits for all values in the clock tree. These
* are the minimum and maximum multiplier for mul.
*/
uint32_t more_mul_min, more_mul_max;
uint32_t more_mul_factor;
uint32_t min_vt_div, max_vt_div, vt_div;
......
......@@ -1122,9 +1122,9 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
rval = sensor->platform_data->set_xclk(
&sensor->src->sd, sensor->platform_data->ext_clk);
else
rval = clk_enable(sensor->ext_clk);
rval = clk_prepare_enable(sensor->ext_clk);
if (rval < 0) {
dev_dbg(&client->dev, "failed to set xclk\n");
dev_dbg(&client->dev, "failed to enable xclk\n");
goto out_xclk_fail;
}
usleep_range(1000, 1000);
......@@ -1244,7 +1244,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);
else
clk_disable(sensor->ext_clk);
clk_disable_unprepare(sensor->ext_clk);
out_xclk_fail:
regulator_disable(sensor->vana);
......@@ -1270,7 +1270,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);
else
clk_disable(sensor->ext_clk);
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
regulator_disable(sensor->vana);
sensor->streaming = 0;
......@@ -1835,12 +1835,12 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev,
* sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]
/ sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE];
a = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
max(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
b = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
max(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
max_m = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
max(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
a = clamp(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
b = clamp(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
max_m = clamp(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);
......@@ -2363,11 +2363,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
}
if (!sensor->platform_data->set_xclk) {
sensor->ext_clk = devm_clk_get(&client->dev,
sensor->platform_data->ext_clk_name);
sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk");
if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock %s\n",
sensor->platform_data->ext_clk_name);
dev_err(&client->dev, "could not get clock\n");
return -ENODEV;
}
......@@ -2375,8 +2373,7 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
sensor->platform_data->ext_clk);
if (rval < 0) {
dev_err(&client->dev,
"unable to set clock %s freq to %u\n",
sensor->platform_data->ext_clk_name,
"unable to set clock freq to %u\n",
sensor->platform_data->ext_clk);
return -ENODEV;
}
......@@ -2839,7 +2836,7 @@ static int smiapp_remove(struct i2c_client *client)
if (sensor->platform_data->set_xclk)
sensor->platform_data->set_xclk(&sensor->src->sd, 0);
else
clk_disable(sensor->ext_clk);
clk_disable_unprepare(sensor->ext_clk);
sensor->power_count = 0;
}
......
......@@ -946,6 +946,10 @@ static int mt9m111_probe(struct i2c_client *client,
if (!mt9m111)
return -ENOMEM;
mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk))
return -EPROBE_DEFER;
/* Default HIGHPOWER context */
mt9m111->ctx = &context_b;
......@@ -963,8 +967,10 @@ static int mt9m111_probe(struct i2c_client *client,
&mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
V4L2_EXPOSURE_AUTO);
mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
if (mt9m111->hdl.error)
return mt9m111->hdl.error;
if (mt9m111->hdl.error) {
ret = mt9m111->hdl.error;
goto out_clkput;
}
/* Second stage probe - when a capture adapter is there */
mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
......@@ -975,18 +981,25 @@ static int mt9m111_probe(struct i2c_client *client,
mt9m111->lastpage = -1;
mutex_init(&mt9m111->power_lock);
mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk)) {
ret = PTR_ERR(mt9m111->clk);
goto eclkget;
}
ret = soc_camera_power_init(&client->dev, ssdd);
if (ret < 0)
goto out_hdlfree;
ret = mt9m111_video_probe(client);
if (ret) {
v4l2_clk_put(mt9m111->clk);
eclkget:
v4l2_ctrl_handler_free(&mt9m111->hdl);
}
if (ret < 0)
goto out_hdlfree;
mt9m111->subdev.dev = &client->dev;
ret = v4l2_async_register_subdev(&mt9m111->subdev);
if (ret < 0)
goto out_hdlfree;
return 0;
out_hdlfree:
v4l2_ctrl_handler_free(&mt9m111->hdl);
out_clkput:
v4l2_clk_put(mt9m111->clk);
return ret;
}
......@@ -995,6 +1008,7 @@ static int mt9m111_remove(struct i2c_client *client)
{
struct mt9m111 *mt9m111 = to_mt9m111(client);
v4l2_async_unregister_subdev(&mt9m111->subdev);
v4l2_clk_put(mt9m111->clk);
v4l2_device_unregister_subdev(&mt9m111->subdev);
v4l2_ctrl_handler_free(&mt9m111->hdl);
......
......@@ -594,9 +594,12 @@ static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk);
if (ret < 0)
return ret;
vdev->dev.type = &mt9t031_dev_type;
if (vdev)
/* Not needed during probing, when vdev isn't available yet */
vdev->dev.type = &mt9t031_dev_type;
} else {
vdev->dev.type = NULL;
if (vdev)
vdev->dev.type = NULL;
soc_camera_power_off(&client->dev, ssdd, mt9t031->clk);
}
......
......@@ -291,10 +291,8 @@ static int ths7303_log_status(struct v4l2_subdev *sd)
struct v4l2_bt_timings *bt = bt = &state->bt;
u32 frame_width, frame_height;
frame_width = bt->width + bt->hfrontporch +
bt->hsync + bt->hbackporch;
frame_height = bt->height + bt->vfrontporch +
bt->vsync + bt->vbackporch;
frame_width = V4L2_DV_BT_FRAME_WIDTH(bt);
frame_height = V4L2_DV_BT_FRAME_HEIGHT(bt);
v4l2_info(sd,
"timings: %dx%d%s%d (%dx%d). Pix freq. = %d Hz. Polarities = 0x%x\n",
bt->width, bt->height, bt->interlaced ? "i" : "p",
......
此差异已折叠。
......@@ -36,6 +36,7 @@
#include <linux/module.h>
#include <linux/v4l2-mediabus.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-mediabus.h>
......@@ -1175,16 +1176,22 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
sd->ctrl_handler = &decoder->hdl;
if (decoder->hdl.error) {
ret = decoder->hdl.error;
v4l2_ctrl_handler_free(&decoder->hdl);
return ret;
goto done;
}
v4l2_ctrl_handler_setup(&decoder->hdl);
v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
return 0;
ret = v4l2_async_register_subdev(&decoder->sd);
if (!ret)
v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
done:
if (ret < 0) {
v4l2_ctrl_handler_free(&decoder->hdl);
#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&decoder->sd.entity);
#endif
}
return ret;
}
/**
......@@ -1199,6 +1206,7 @@ static int tvp514x_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct tvp514x_decoder *decoder = to_decoder(sd);
v4l2_async_unregister_subdev(&decoder->sd);
v4l2_device_unregister_subdev(sd);
#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&decoder->sd.entity);
......
此差异已折叠。
......@@ -20,6 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/bitmap.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <media/media-entity.h>
......@@ -121,7 +122,6 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph)
return entity;
}
#define stack_peek(en) ((en)->stack[(en)->top - 1].entity)
#define link_top(en) ((en)->stack[(en)->top].link)
#define stack_top(en) ((en)->stack[(en)->top].entity)
......@@ -140,6 +140,12 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
{
graph->top = 0;
graph->stack[graph->top].entity = NULL;
bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID);
if (WARN_ON(entity->id >= MEDIA_ENTITY_ENUM_MAX_ID))
return;
__set_bit(entity->id, graph->entities);
stack_push(graph, entity);
}
EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
......@@ -180,9 +186,11 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
/* Get the entity in the other end of the link . */
next = media_entity_other(entity, link);
if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID))
return NULL;
/* Was it the entity we came here from? */
if (next == stack_peek(graph)) {
/* Has the entity already been visited? */
if (__test_and_set_bit(next->id, graph->entities)) {
link_top(graph)++;
continue;
}
......
......@@ -459,6 +459,9 @@ struct bttv {
int mbox_iow;
int mbox_csel;
/* switch status for multi-controller cards */
char sw_status[4];
/* risc memory management data
- must acquire s_lock before changing these
- only the irq handler is supported to touch top + bottom + vcurr */
......
......@@ -29,6 +29,7 @@ config VIDEO_CX23885
select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA10071 if MEDIA_SUBDRV_AUTOSELECT
select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
......
......@@ -23,6 +23,7 @@
#include "cx23885.h"
#include "cx23885-av.h"
#include "cx23885-video.h"
void cx23885_av_work_handler(struct work_struct *work)
{
......@@ -32,5 +33,17 @@ void cx23885_av_work_handler(struct work_struct *work)
v4l2_subdev_call(dev->sd_cx25840, core, interrupt_service_routine,
PCI_MSK_AV_CORE, &handled);
/* Getting here with the interrupt not handled
then probbaly flatiron does have pending interrupts.
*/
if (!handled) {
/* clear left and right adc channel interrupt request flag */
cx23885_flatiron_write(dev, 0x1f,
cx23885_flatiron_read(dev, 0x1f) | 0x80);
cx23885_flatiron_write(dev, 0x23,
cx23885_flatiron_read(dev, 0x23) | 0x80);
}
cx23885_irq_enable(dev, PCI_MSK_AV_CORE);
}
......@@ -1941,10 +1941,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
if ((pci_status & pci_mask) & PCI_MSK_AV_CORE) {
cx23885_irq_disable(dev, PCI_MSK_AV_CORE);
if (!schedule_work(&dev->cx25840_work))
printk(KERN_ERR "%s: failed to set up deferred work for"
" AV Core/IR interrupt. Interrupt is disabled"
" and won't be re-enabled\n", dev->name);
schedule_work(&dev->cx25840_work);
handled++;
}
......
此差异已折叠。
......@@ -320,6 +320,8 @@ struct cx23885_tsport {
/* Workaround for a temp dvb_frontend that the tuner can attached to */
struct dvb_frontend analog_fe;
int (*set_frontend)(struct dvb_frontend *fe);
};
struct cx23885_kernel_ir {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册