Commit 0c8027d5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'media/v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - a new frontend driver for new ATSC devices: lgdt3306a

 - a new sensor driver: ov2659

 - a new platform driver: xilinx

 - the m88ts2022 tuner driver was merged at ts2020 driver

 - the media controller gained experimental support for DVB and hybrid
   devices

 - lots of random cleanups, fixes and improvements on media drivers

* tag 'media/v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (404 commits)
  [media] uvcvideo: add support for VIDIOC_QUERY_EXT_CTRL
  [media] uvcvideo: fix cropcap v4l2-compliance failure
  [media] media: omap3isp: remove unused clkdev
  [media] coda: Add tracing support
  [media] coda: drop dma_sync_single_for_device in coda_bitstream_queue
  [media] coda: fix fill bitstream errors in nonstreaming case
  [media] coda: call SEQ_END when the first queue is stopped
  [media] coda: fail to start streaming if userspace set invalid formats
  [media] coda: remove duplicate error messages for buffer allocations
  [media] coda: move parameter buffer in together with context buffer allocation
  [media] coda: allocate bitstream buffer from REQBUFS, size depends on the format
  [media] coda: allocate per-context buffers from REQBUFS
  [media] coda: use strlcpy instead of snprintf
  [media] coda: bitstream payload is unsigned
  [media] coda: fix double call to debugfs_remove
  [media] coda: check kasprintf return value in coda_open
  [media] coda: bitrate can only be set in kbps steps
  [media] v4l2-mem2mem: no need to initialize b in v4l2_m2m_next_buf and v4l2_m2m_buf_remove
  [media] s5p-mfc: set allow_zero_bytesused flag for vb2_queue_init
  [media] coda: set allow_zero_bytesused flag for vb2_queue_init
  ...
parents 1fc14993 64131a87
...@@ -2491,7 +2491,7 @@ that used it. It was originally scheduled for removal in 2.6.35. ...@@ -2491,7 +2491,7 @@ that used it. It was originally scheduled for removal in 2.6.35.
</listitem> </listitem>
<listitem> <listitem>
<para>Added <constant>V4L2_EVENT_CTRL_CH_RANGE</constant> control event <para>Added <constant>V4L2_EVENT_CTRL_CH_RANGE</constant> control event
changes flag. See <xref linkend="changes-flags"/>.</para> changes flag. See <xref linkend="ctrl-changes-flags"/>.</para>
</listitem> </listitem>
</orderedlist> </orderedlist>
</section> </section>
......
...@@ -143,86 +143,28 @@ ...@@ -143,86 +143,28 @@
<row> <row>
<entry></entry> <entry></entry>
<entry>struct</entry> <entry>struct</entry>
<entry><structfield>v4l</structfield></entry> <entry><structfield>dev</structfield></entry>
<entry></entry> <entry></entry>
<entry>Valid for V4L sub-devices and nodes only.</entry> <entry>Valid for (sub-)devices that create a single device node.</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>major</structfield></entry> <entry><structfield>major</structfield></entry>
<entry>V4L device node major number. For V4L sub-devices with no <entry>Device node major number.</entry>
device node, set by the driver to 0.</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>minor</structfield></entry> <entry><structfield>minor</structfield></entry>
<entry>V4L device node minor number. For V4L sub-devices with no <entry>Device node minor number.</entry>
device node, set by the driver to 0.</entry>
</row>
<row>
<entry></entry>
<entry>struct</entry>
<entry><structfield>fb</structfield></entry>
<entry></entry>
<entry>Valid for frame buffer nodes only.</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>major</structfield></entry>
<entry>Frame buffer device node major number.</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>minor</structfield></entry>
<entry>Frame buffer device node minor number.</entry>
</row>
<row>
<entry></entry>
<entry>struct</entry>
<entry><structfield>alsa</structfield></entry>
<entry></entry>
<entry>Valid for ALSA devices only.</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>card</structfield></entry>
<entry>ALSA card number</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>device</structfield></entry>
<entry>ALSA device number</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>subdevice</structfield></entry>
<entry>ALSA sub-device number</entry>
</row>
<row>
<entry></entry>
<entry>int</entry>
<entry><structfield>dvb</structfield></entry>
<entry></entry>
<entry>DVB card number</entry>
</row> </row>
<row> <row>
<entry></entry> <entry></entry>
<entry>__u8</entry> <entry>__u8</entry>
<entry><structfield>raw</structfield>[180]</entry> <entry><structfield>raw</structfield>[184]</entry>
<entry></entry> <entry></entry>
<entry></entry> <entry></entry>
</row> </row>
...@@ -253,8 +195,24 @@ ...@@ -253,8 +195,24 @@
<entry>ALSA card</entry> <entry>ALSA card</entry>
</row> </row>
<row> <row>
<entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry> <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_FE</constant></entry>
<entry>DVB card</entry> <entry>DVB frontend devnode</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DEMUX</constant></entry>
<entry>DVB demux devnode</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DVR</constant></entry>
<entry>DVB DVR devnode</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_DEVNODE_DVB_CA</constant></entry>
<entry>DVB CAM devnode</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_DEVNODE_DVB_NET</constant></entry>
<entry>DVB network devnode</entry>
</row> </row>
<row> <row>
<entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
...@@ -282,6 +240,10 @@ ...@@ -282,6 +240,10 @@
it in some digital video standard, with appropriate embedded timing it in some digital video standard, with appropriate embedded timing
signals.</entry> signals.</entry>
</row> </row>
<row>
<entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry>
<entry>TV and/or radio tuner</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
......
...@@ -303,45 +303,6 @@ for a pixel lie next to each other in memory.</para> ...@@ -303,45 +303,6 @@ for a pixel lie next to each other in memory.</para>
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-BGR666">
<entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
<entry>'BGRH'</entry>
<entry></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
<entry></entry>
</row>
<row id="V4L2-PIX-FMT-BGR24"> <row id="V4L2-PIX-FMT-BGR24">
<entry><constant>V4L2_PIX_FMT_BGR24</constant></entry> <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
<entry>'BGR3'</entry> <entry>'BGR3'</entry>
...@@ -404,6 +365,46 @@ for a pixel lie next to each other in memory.</para> ...@@ -404,6 +365,46 @@ for a pixel lie next to each other in memory.</para>
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </row>
<row id="V4L2-PIX-FMT-BGR666">
<entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
<entry>'BGRH'</entry>
<entry></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
</row>
<row id="V4L2-PIX-FMT-ABGR32"> <row id="V4L2-PIX-FMT-ABGR32">
<entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry> <entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry>
<entry>'AR24'</entry> <entry>'AR24'</entry>
......
...@@ -38,10 +38,10 @@ columns and rows.</para> ...@@ -38,10 +38,10 @@ columns and rows.</para>
</row> </row>
<row> <row>
<entry>start&nbsp;+&nbsp;4:</entry> <entry>start&nbsp;+&nbsp;4:</entry>
<entry>R<subscript>10</subscript></entry> <entry>B<subscript>10</subscript></entry>
<entry>B<subscript>11</subscript></entry> <entry>G<subscript>11</subscript></entry>
<entry>R<subscript>12</subscript></entry> <entry>B<subscript>12</subscript></entry>
<entry>B<subscript>13</subscript></entry> <entry>G<subscript>13</subscript></entry>
</row> </row>
<row> <row>
<entry>start&nbsp;+&nbsp;8:</entry> <entry>start&nbsp;+&nbsp;8:</entry>
...@@ -52,10 +52,10 @@ columns and rows.</para> ...@@ -52,10 +52,10 @@ columns and rows.</para>
</row> </row>
<row> <row>
<entry>start&nbsp;+&nbsp;12:</entry> <entry>start&nbsp;+&nbsp;12:</entry>
<entry>R<subscript>30</subscript></entry> <entry>B<subscript>30</subscript></entry>
<entry>B<subscript>31</subscript></entry> <entry>G<subscript>31</subscript></entry>
<entry>R<subscript>32</subscript></entry> <entry>B<subscript>32</subscript></entry>
<entry>B<subscript>33</subscript></entry> <entry>G<subscript>33</subscript></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
<title>Byte Order.</title> <title>Byte Order.</title>
<para>Each cell is one byte. <para>Each cell is one byte.
<informaltable frame="topbot" colsep="1" rowsep="1"> <informaltable frame="topbot" colsep="1" rowsep="1">
<tgroup cols="5" align="center" border="1"> <tgroup cols="5" align="center">
<colspec align="left" colwidth="2*" /> <colspec align="left" colwidth="2*" />
<tbody valign="top"> <tbody valign="top">
<row> <row>
......
...@@ -29,12 +29,12 @@ and Cr planes have half as many pad bytes after their rows. In other ...@@ -29,12 +29,12 @@ and Cr planes have half as many pad bytes after their rows. In other
words, two Cx rows (including padding) is exactly as long as one Y row words, two Cx rows (including padding) is exactly as long as one Y row
(including padding).</para> (including padding).</para>
<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be <para><constant>V4L2_PIX_FMT_YUV420M</constant> is intended to be
used only in drivers and applications that support the multi-planar API, used only in drivers and applications that support the multi-planar API,
described in <xref linkend="planar-apis"/>. </para> described in <xref linkend="planar-apis"/>. </para>
<example> <example>
<title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4 <title><constant>V4L2_PIX_FMT_YUV420M</constant> 4 &times; 4
pixel image</title> pixel image</title>
<formalpara> <formalpara>
......
This diff is collapsed.
...@@ -136,6 +136,7 @@ Remote Controller chapter.</contrib> ...@@ -136,6 +136,7 @@ Remote Controller chapter.</contrib>
<year>2012</year> <year>2012</year>
<year>2013</year> <year>2013</year>
<year>2014</year> <year>2014</year>
<year>2015</year>
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
Pawel Osciak</holder> Pawel Osciak</holder>
...@@ -151,6 +152,14 @@ structs, ioctls) must be noted in more detail in the history chapter ...@@ -151,6 +152,14 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.xml), along with the possible impact on existing drivers and (compat.xml), along with the possible impact on existing drivers and
applications. --> applications. -->
<revision>
<revnumber>3.21</revnumber>
<date>2015-02-13</date>
<authorinitials>mcc</authorinitials>
<revremark>Fix documentation for media controller device nodes and add support for DVB device nodes.
Add support for Tuner sub-device.
</revremark>
</revision>
<revision> <revision>
<revnumber>3.19</revnumber> <revnumber>3.19</revnumber>
<date>2014-12-05</date> <date>2014-12-05</date>
......
...@@ -59,6 +59,11 @@ constant except when switching the video standard. Remember this ...@@ -59,6 +59,11 @@ constant except when switching the video standard. Remember this
switch can occur implicit when switching the video input or switch can occur implicit when switching the video input or
output.</para> output.</para>
<para>Do not use the multiplanar buffer types. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
and use <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.</para>
<para>This ioctl must be implemented for video capture or output devices that <para>This ioctl must be implemented for video capture or output devices that
support cropping and/or scaling and/or have non-square pixels, and for overlay devices.</para> support cropping and/or scaling and/or have non-square pixels, and for overlay devices.</para>
...@@ -73,9 +78,7 @@ support cropping and/or scaling and/or have non-square pixels, and for overlay d ...@@ -73,9 +78,7 @@ support cropping and/or scaling and/or have non-square pixels, and for overlay d
<entry>Type of the data stream, set by the application. <entry>Type of the data stream, set by the application.
Only these types are valid here: Only these types are valid here:
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>, <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>, <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and
<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry> <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
</row> </row>
<row> <row>
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>type</structfield></entry> <entry><structfield>type</structfield></entry>
<entry></entry> <entry></entry>
<entry>Type of the event.</entry> <entry>Type of the event, see <xref linkend="event-type" />.</entry>
</row> </row>
<row> <row>
<entry>union</entry> <entry>union</entry>
...@@ -154,6 +154,113 @@ ...@@ -154,6 +154,113 @@
</tgroup> </tgroup>
</table> </table>
<table frame="none" pgwide="1" id="event-type">
<title>Event Types</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_EVENT_ALL</constant></entry>
<entry>0</entry>
<entry>All events. V4L2_EVENT_ALL is valid only for
VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_VSYNC</constant></entry>
<entry>1</entry>
<entry>This event is triggered on the vertical sync.
This event has a &v4l2-event-vsync; associated with it.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_EOS</constant></entry>
<entry>2</entry>
<entry>This event is triggered when the end of a stream is reached.
This is typically used with MPEG decoders to report to the application
when the last of the MPEG stream has been decoded.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_CTRL</constant></entry>
<entry>3</entry>
<entry><para>This event requires that the <structfield>id</structfield>
matches the control ID from which you want to receive events.
This event is triggered if the control's value changes, if a
button control is pressed or if the control's flags change.
This event has a &v4l2-event-ctrl; associated with it. This struct
contains much of the same information as &v4l2-queryctrl; and
&v4l2-control;.</para>
<para>If the event is generated due to a call to &VIDIOC-S-CTRL; or
&VIDIOC-S-EXT-CTRLS;, then the event will <emphasis>not</emphasis> be sent to
the file handle that called the ioctl function. This prevents
nasty feedback loops. If you <emphasis>do</emphasis> want to get the
event, then set the <constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant>
flag.
</para>
<para>This event type will ensure that no information is lost when
more events are raised than there is room internally. In that
case the &v4l2-event-ctrl; of the second-oldest event is kept,
but the <structfield>changes</structfield> field of the
second-oldest event is ORed with the <structfield>changes</structfield>
field of the oldest event.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_FRAME_SYNC</constant></entry>
<entry>4</entry>
<entry>
<para>Triggered immediately when the reception of a
frame has begun. This event has a
&v4l2-event-frame-sync; associated with it.</para>
<para>If the hardware needs to be stopped in the case of a
buffer underrun it might not be able to generate this event.
In such cases the <structfield>frame_sequence</structfield>
field in &v4l2-event-frame-sync; will not be incremented. This
causes two consecutive frame sequence numbers to have n times
frame interval in between them.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
<entry>5</entry>
<entry>
<para>This event is triggered when a source parameter change is
detected during runtime by the video device. It can be a
runtime resolution change triggered by a video decoder or the
format change happening on an input connector.
This event requires that the <structfield>id</structfield>
matches the input index (when used with a video device node)
or the pad index (when used with a subdevice node) from which
you want to receive events.</para>
<para>This event has a &v4l2-event-src-change; associated
with it. The <structfield>changes</structfield> bitfield denotes
what has changed for the subscribed pad. If multiple events
occurred before application could dequeue them, then the changes
will have the ORed value of all the events generated.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
<entry>6</entry>
<entry>
<para>Triggered whenever the motion detection state for one or more of the regions
changes. This event has a &v4l2-event-motion-det; associated with it.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
<entry>0x08000000</entry>
<entry>Base event number for driver-private events.</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="none" pgwide="1" id="v4l2-event-vsync"> <table frame="none" pgwide="1" id="v4l2-event-vsync">
<title>struct <structname>v4l2_event_vsync</structname></title> <title>struct <structname>v4l2_event_vsync</structname></title>
<tgroup cols="3"> <tgroup cols="3">
...@@ -177,7 +284,7 @@ ...@@ -177,7 +284,7 @@
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>changes</structfield></entry> <entry><structfield>changes</structfield></entry>
<entry></entry> <entry></entry>
<entry>A bitmask that tells what has changed. See <xref linkend="changes-flags" />.</entry> <entry>A bitmask that tells what has changed. See <xref linkend="ctrl-changes-flags" />.</entry>
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
...@@ -309,8 +416,8 @@ ...@@ -309,8 +416,8 @@
</tgroup> </tgroup>
</table> </table>
<table pgwide="1" frame="none" id="changes-flags"> <table pgwide="1" frame="none" id="ctrl-changes-flags">
<title>Changes</title> <title>Control Changes</title>
<tgroup cols="3"> <tgroup cols="3">
&cs-def; &cs-def;
<tbody valign="top"> <tbody valign="top">
...@@ -318,9 +425,9 @@ ...@@ -318,9 +425,9 @@
<entry><constant>V4L2_EVENT_CTRL_CH_VALUE</constant></entry> <entry><constant>V4L2_EVENT_CTRL_CH_VALUE</constant></entry>
<entry>0x0001</entry> <entry>0x0001</entry>
<entry>This control event was triggered because the value of the control <entry>This control event was triggered because the value of the control
changed. Special case: if a button control is pressed, then this changed. Special cases: Volatile controls do no generate this event;
event is sent as well, even though there is not explicit value If a control has the <constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant>
associated with a button control.</entry> flag set, then this event is sent as well, regardless its value.</entry>
</row> </row>
<row> <row>
<entry><constant>V4L2_EVENT_CTRL_CH_FLAGS</constant></entry> <entry><constant>V4L2_EVENT_CTRL_CH_FLAGS</constant></entry>
......
...@@ -70,6 +70,11 @@ structure or returns the &EINVAL; if cropping is not supported.</para> ...@@ -70,6 +70,11 @@ structure or returns the &EINVAL; if cropping is not supported.</para>
<constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this <constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
structure.</para> structure.</para>
<para>Do not use the multiplanar buffer types. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
and use <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.</para>
<para>The driver first adjusts the requested dimensions against <para>The driver first adjusts the requested dimensions against
hardware limits, &ie; the bounds given by the capture/output window, hardware limits, &ie; the bounds given by the capture/output window,
and it rounds to the closest possible values of horizontal and and it rounds to the closest possible values of horizontal and
......
...@@ -318,10 +318,20 @@ can't generate such frequencies, then the flag will also be cleared. ...@@ -318,10 +318,20 @@ can't generate such frequencies, then the flag will also be cleared.
</row> </row>
<row> <row>
<entry>V4L2_DV_FL_HALF_LINE</entry> <entry>V4L2_DV_FL_HALF_LINE</entry>
<entry>Specific to interlaced formats: if set, then field 1 (aka the odd field) <entry>Specific to interlaced formats: if set, then the vertical frontporch
is really one half-line longer and field 2 (aka the even field) is really one half-line of field 1 (aka the odd field) is really one half-line longer and the vertical backporch
shorter, so each field has exactly the same number of half-lines. Whether half-lines can be of field 2 (aka the even field) is really one half-line shorter, so each field has exactly
detected or used depends on the hardware. the same number of half-lines. Whether half-lines can be detected or used depends on
the hardware.
</entry>
</row>
<row>
<entry>V4L2_DV_FL_IS_CE_VIDEO</entry>
<entry>If set, then this is a Consumer Electronics (CE) video format.
Such formats differ from other formats (commonly called IT formats) in that if
R'G'B' encoding is used then by default the R'G'B' values use limited range
(i.e. 16-235) as opposed to full range (i.e. 0-255). All formats defined in CEA-861
except for the 640x480p59.94 format are CE formats.
</entry> </entry>
</row> </row>
</tbody> </tbody>
......
...@@ -240,9 +240,9 @@ where padding bytes after the last line of an image cross a system ...@@ -240,9 +240,9 @@ where padding bytes after the last line of an image cross a system
page boundary. Capture devices may write padding bytes, the value is page boundary. Capture devices may write padding bytes, the value is
undefined. Output devices ignore the contents of padding undefined. Output devices ignore the contents of padding
bytes.</para><para>When the image format is planar the bytes.</para><para>When the image format is planar the
<structfield>bytesperline</structfield> value applies to the largest <structfield>bytesperline</structfield> value applies to the first
plane and is divided by the same factor as the plane and is divided by the same factor as the
<structfield>width</structfield> field for any smaller planes. For <structfield>width</structfield> field for the other planes. For
example the Cb and Cr planes of a YUV 4:2:0 image have half as many example the Cb and Cr planes of a YUV 4:2:0 image have half as many
padding bytes following each line as the Y plane. To avoid ambiguities padding bytes following each line as the Y plane. To avoid ambiguities
drivers must return a <structfield>bytesperline</structfield> value drivers must return a <structfield>bytesperline</structfield> value
......
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
<para>To query the cropping (composing) rectangle set &v4l2-selection; <para>To query the cropping (composing) rectangle set &v4l2-selection;
<structfield> type </structfield> field to the respective buffer type. <structfield> type </structfield> field to the respective buffer type.
Do not use multiplanar buffers. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> Do not use the multiplanar buffer types. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. Use instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and use
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is
setting the value of &v4l2-selection; <structfield>target</structfield> field setting the value of &v4l2-selection; <structfield>target</structfield> field
......
...@@ -102,10 +102,10 @@ The bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI Express boar ...@@ -102,10 +102,10 @@ The bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI Express boar
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>version</structfield></entry> <entry><structfield>version</structfield></entry>
<entry><para>Version number of the driver.</para> <entry><para>Version number of the driver.</para>
<para>Starting on kernel 3.1, the version reported is provided per <para>Starting with kernel 3.1, the version reported is provided by the
V4L2 subsystem, following the same Kernel numberation scheme. However, it V4L2 subsystem following the kernel numbering scheme. However, it
should not always return the same version as the kernel, if, for example, may not always return the same version as the kernel if, for example,
an stable or distribution-modified kernel uses the V4L2 stack from a a stable or distribution-modified kernel uses the V4L2 stack from a
newer kernel.</para> newer kernel.</para>
<para>The version number is formatted using the <para>The version number is formatted using the
<constant>KERNEL_VERSION()</constant> macro:</para></entry> <constant>KERNEL_VERSION()</constant> macro:</para></entry>
......
...@@ -600,7 +600,9 @@ writing a value will cause the device to carry out a given action ...@@ -600,7 +600,9 @@ writing a value will cause the device to carry out a given action
changes continuously. A typical example would be the current gain value if the device changes continuously. A typical example would be the current gain value if the device
is in auto-gain mode. In such a case the hardware calculates the gain value based on is in auto-gain mode. In such a case the hardware calculates the gain value based on
the lighting conditions which can change over time. Note that setting a new value for the lighting conditions which can change over time. Note that setting a new value for
a volatile control will have no effect. The new value will just be ignored.</entry> a volatile control will have no effect and no <constant>V4L2_EVENT_CTRL_CH_VALUE</constant>
will be sent, unless the <constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant> flag
(see below) is also set. Otherwise the new value will just be ignored.</entry>
</row> </row>
<row> <row>
<entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry> <entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry>
...@@ -610,6 +612,14 @@ using one of the pointer fields of &v4l2-ext-control;. This flag is set for cont ...@@ -610,6 +612,14 @@ using one of the pointer fields of &v4l2-ext-control;. This flag is set for cont
that are an array, string, or have a compound type. In all cases you have to set a that are an array, string, or have a compound type. In all cases you have to set a
pointer to memory containing the payload of the control.</entry> pointer to memory containing the payload of the control.</entry>
</row> </row>
<row>
<entry><constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant></entry>
<entry>0x0200</entry>
<entry>The value provided to the control will be propagated to the driver
even if remains constant. This is required when the control represents an action
on the hardware. For example: clearing an error flag or triggering the flash. All the
controls of the type <constant>V4L2_CTRL_TYPE_BUTTON</constant> have this flag set.</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
......
...@@ -67,9 +67,9 @@ ...@@ -67,9 +67,9 @@
<para>To enumerate frame intervals applications initialize the <para>To enumerate frame intervals applications initialize the
<structfield>index</structfield>, <structfield>pad</structfield>, <structfield>index</structfield>, <structfield>pad</structfield>,
<structfield>code</structfield>, <structfield>width</structfield> and <structfield>which</structfield>, <structfield>code</structfield>,
<structfield>height</structfield> fields of <structfield>width</structfield> and <structfield>height</structfield>
&v4l2-subdev-frame-interval-enum; and call the fields of &v4l2-subdev-frame-interval-enum; and call the
<constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
to this structure. Drivers fill the rest of the structure or return to this structure. Drivers fill the rest of the structure or return
an &EINVAL; if one of the input fields is invalid. All frame intervals are an &EINVAL; if one of the input fields is invalid. All frame intervals are
...@@ -123,7 +123,12 @@ ...@@ -123,7 +123,12 @@
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>reserved</structfield>[9]</entry> <entry><structfield>which</structfield></entry>
<entry>Frame intervals to be enumerated, from &v4l2-subdev-format-whence;.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry>Reserved for future extensions. Applications and drivers must <entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry> set the array to zero.</entry>
</row> </row>
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
ioctl.</para> ioctl.</para>
<para>To enumerate frame sizes applications initialize the <para>To enumerate frame sizes applications initialize the
<structfield>pad</structfield>, <structfield>code</structfield> and <structfield>pad</structfield>, <structfield>which</structfield> ,
<structfield>index</structfield> fields of the <structfield>code</structfield> and <structfield>index</structfield>
&v4l2-subdev-mbus-code-enum; and call the fields of the &v4l2-subdev-mbus-code-enum; and call the
<constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
the structure. Drivers fill the minimum and maximum frame sizes or return the structure. Drivers fill the minimum and maximum frame sizes or return
an &EINVAL; if one of the input parameters is invalid.</para> an &EINVAL; if one of the input parameters is invalid.</para>
...@@ -127,7 +127,12 @@ ...@@ -127,7 +127,12 @@
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>reserved</structfield>[9]</entry> <entry><structfield>which</structfield></entry>
<entry>Frame sizes to be enumerated, from &v4l2-subdev-format-whence;.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry>Reserved for future extensions. Applications and drivers must <entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry> set the array to zero.</entry>
</row> </row>
......
...@@ -56,8 +56,8 @@ ...@@ -56,8 +56,8 @@
</note> </note>
<para>To enumerate media bus formats available at a given sub-device pad <para>To enumerate media bus formats available at a given sub-device pad
applications initialize the <structfield>pad</structfield> and applications initialize the <structfield>pad</structfield>, <structfield>which</structfield>
<structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and and <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
pointer to this structure. Drivers fill the rest of the structure or return pointer to this structure. Drivers fill the rest of the structure or return
an &EINVAL; if either the <structfield>pad</structfield> or an &EINVAL; if either the <structfield>pad</structfield> or
...@@ -93,7 +93,12 @@ ...@@ -93,7 +93,12 @@
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>reserved</structfield>[9]</entry> <entry><structfield>which</structfield></entry>
<entry>Media bus format codes to be enumerated, from &v4l2-subdev-format-whence;.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry>Reserved for future extensions. Applications and drivers must <entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry> set the array to zero.</entry>
</row> </row>
......
...@@ -60,7 +60,9 @@ ...@@ -60,7 +60,9 @@
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>type</structfield></entry> <entry><structfield>type</structfield></entry>
<entry>Type of the event.</entry> <entry>Type of the event, see <xref linkend="event-type" />. Note that
<constant>V4L2_EVENT_ALL</constant> can be used with VIDIOC_UNSUBSCRIBE_EVENT
for unsubscribing all events at once.</entry>
</row> </row>
<row> <row>
<entry>__u32</entry> <entry>__u32</entry>
...@@ -84,113 +86,6 @@ ...@@ -84,113 +86,6 @@
</tgroup> </tgroup>
</table> </table>
<table frame="none" pgwide="1" id="event-type">
<title>Event Types</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_EVENT_ALL</constant></entry>
<entry>0</entry>
<entry>All events. V4L2_EVENT_ALL is valid only for
VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_VSYNC</constant></entry>
<entry>1</entry>
<entry>This event is triggered on the vertical sync.
This event has a &v4l2-event-vsync; associated with it.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_EOS</constant></entry>
<entry>2</entry>
<entry>This event is triggered when the end of a stream is reached.
This is typically used with MPEG decoders to report to the application
when the last of the MPEG stream has been decoded.
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_CTRL</constant></entry>
<entry>3</entry>
<entry><para>This event requires that the <structfield>id</structfield>
matches the control ID from which you want to receive events.
This event is triggered if the control's value changes, if a
button control is pressed or if the control's flags change.
This event has a &v4l2-event-ctrl; associated with it. This struct
contains much of the same information as &v4l2-queryctrl; and
&v4l2-control;.</para>
<para>If the event is generated due to a call to &VIDIOC-S-CTRL; or
&VIDIOC-S-EXT-CTRLS;, then the event will <emphasis>not</emphasis> be sent to
the file handle that called the ioctl function. This prevents
nasty feedback loops. If you <emphasis>do</emphasis> want to get the
event, then set the <constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant>
flag.
</para>
<para>This event type will ensure that no information is lost when
more events are raised than there is room internally. In that
case the &v4l2-event-ctrl; of the second-oldest event is kept,
but the <structfield>changes</structfield> field of the
second-oldest event is ORed with the <structfield>changes</structfield>
field of the oldest event.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_FRAME_SYNC</constant></entry>
<entry>4</entry>
<entry>
<para>Triggered immediately when the reception of a
frame has begun. This event has a
&v4l2-event-frame-sync; associated with it.</para>
<para>If the hardware needs to be stopped in the case of a
buffer underrun it might not be able to generate this event.
In such cases the <structfield>frame_sequence</structfield>
field in &v4l2-event-frame-sync; will not be incremented. This
causes two consecutive frame sequence numbers to have n times
frame interval in between them.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
<entry>5</entry>
<entry>
<para>This event is triggered when a source parameter change is
detected during runtime by the video device. It can be a
runtime resolution change triggered by a video decoder or the
format change happening on an input connector.
This event requires that the <structfield>id</structfield>
matches the input index (when used with a video device node)
or the pad index (when used with a subdevice node) from which
you want to receive events.</para>
<para>This event has a &v4l2-event-src-change; associated
with it. The <structfield>changes</structfield> bitfield denotes
what has changed for the subscribed pad. If multiple events
occurred before application could dequeue them, then the changes
will have the ORed value of all the events generated.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
<entry>6</entry>
<entry>
<para>Triggered whenever the motion detection state for one or more of the regions
changes. This event has a &v4l2-event-motion-det; associated with it.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
<entry>0x08000000</entry>
<entry>Base event number for driver-private events.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="event-flags"> <table pgwide="1" frame="none" id="event-flags">
<title>Event Flags</title> <title>Event Flags</title>
<tgroup cols="3"> <tgroup cols="3">
......
...@@ -4,7 +4,7 @@ Required properties: ...@@ -4,7 +4,7 @@ Required properties:
- compatible : should be one of: - compatible : should be one of:
"samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg", "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
"samsung,exynos3250-jpeg"; "samsung,exynos3250-jpeg", "samsung,exynos5420-jpeg";
- reg : address and length of the JPEG codec IP register set; - reg : address and length of the JPEG codec IP register set;
- interrupts : specifies the JPEG codec IP interrupt; - interrupts : specifies the JPEG codec IP interrupt;
- clock-names : should contain: - clock-names : should contain:
......
* Aptina 1/3-Inch WVGA CMOS Digital Image Sensor
The Aptina MT9V032 is a 1/3-inch CMOS active pixel digital image sensor with
an active array size of 752H x 480V. It is programmable through a simple
two-wire serial interface.
Required Properties:
- compatible: value should be either one among the following
(a) "aptina,mt9v022" for MT9V022 color sensor
(b) "aptina,mt9v022m" for MT9V022 monochrome sensor
(c) "aptina,mt9v024" for MT9V024 color sensor
(d) "aptina,mt9v024m" for MT9V024 monochrome sensor
(e) "aptina,mt9v032" for MT9V032 color sensor
(f) "aptina,mt9v032m" for MT9V032 monochrome sensor
(g) "aptina,mt9v034" for MT9V034 color sensor
(h) "aptina,mt9v034m" for MT9V034 monochrome sensor
Optional Properties:
- link-frequencies: List of allowed link frequencies in Hz. Each frequency is
expressed as a 64-bit big-endian integer.
For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
mt9v032@5c {
compatible = "aptina,mt9v032";
reg = <0x5c>;
port {
mt9v032_out: endpoint {
link-frequencies = /bits/ 64
<13000000 26600000 27000000>;
};
};
};
* Omnivision OV2640 CMOS sensor
The Omnivision OV2640 sensor support multiple resolutions output, such as
CIF, SVGA, UXGA. It also can support YUV422/420, RGB565/555 or raw RGB
output format.
Required Properties:
- compatible: should be "ovti,ov2640"
- clocks: reference to the xvclk input clock.
- clock-names: should be "xvclk".
Optional Properties:
- resetb-gpios: reference to the GPIO connected to the resetb pin, if any.
- pwdn-gpios: reference to the GPIO connected to the pwdn pin, if any.
The device node must contain one 'port' child node for its digital output
video port, in accordance with the video interface bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
i2c1: i2c@f0018000 {
ov2640: camera@0x30 {
compatible = "ovti,ov2640";
reg = <0x30>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pck1 &pinctrl_ov2640_pwdn &pinctrl_ov2640_resetb>;
resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
clocks = <&pck1>;
clock-names = "xvclk";
assigned-clocks = <&pck1>;
assigned-clock-rates = <25000000>;
port {
ov2640_0: endpoint {
remote-endpoint = <&isi_0>;
bus-width = <8>;
};
};
};
};
* OV2659 1/5-Inch 2Mp SOC Camera
The Omnivision OV2659 is a 1/5-inch SOC camera, with an active array size of
1632H x 1212V. It is programmable through a SCCB. The OV2659 sensor supports
multiple resolutions output, such as UXGA, SVGA, 720p. It also can support
YUV422, RGB565/555 or raw RGB output formats.
Required Properties:
- compatible: Must be "ovti,ov2659"
- reg: I2C slave address
- clocks: reference to the xvclk input clock.
- clock-names: should be "xvclk".
- link-frequencies: target pixel clock frequency.
For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
i2c0@1c22000 {
...
...
ov2659@30 {
compatible = "ovti,ov2659";
reg = <0x30>;
clocks = <&clk_ov2659 0>;
clock-names = "xvclk";
port {
ov2659_0: endpoint {
remote-endpoint = <&vpfe_ep>;
link-frequencies = /bits/ 64 <70000000>;
};
};
};
...
};
...@@ -106,6 +106,12 @@ Optional endpoint properties ...@@ -106,6 +106,12 @@ Optional endpoint properties
- link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
instance, this is the actual frequency of the bus, not bits per clock per instance, this is the actual frequency of the bus, not bits per clock per
lane value. An array of 64-bit unsigned integers. lane value. An array of 64-bit unsigned integers.
- lane-polarities: an array of polarities of the lanes starting from the clock
lane and followed by the data lanes in the same order as in data-lanes.
Valid values are 0 (normal) and 1 (inverted). The length of the array
should be the combined length of data-lanes and clock-lanes properties.
If the lane-polarities property is omitted, the value must be interpreted
as 0 (normal). This property is valid for serial busses only.
Example Example
......
DT bindings for Xilinx video IP cores
-------------------------------------
Xilinx video IP cores process video streams by acting as video sinks and/or
sources. They are connected by links through their input and output ports,
creating a video pipeline.
Each video IP core is represented by an AMBA bus child node in the device
tree using bindings documented in this directory. Connections between the IP
cores are represented as defined in ../video-interfaces.txt.
The whole pipeline is represented by an AMBA bus child node in the device
tree using bindings documented in ./xlnx,video.txt.
Common properties
-----------------
The following properties are common to all Xilinx video IP cores.
- xlnx,video-format: This property represents a video format transmitted on an
AXI bus between video IP cores, using its VF code as defined in "AXI4-Stream
Video IP and System Design Guide" [UG934]. How the format relates to the IP
core is decribed in the IP core bindings documentation.
- xlnx,video-width: This property qualifies the video format with the sample
width expressed as a number of bits per pixel component. All components must
use the same width.
- xlnx,cfa-pattern: When the video format is set to Mono/Sensor, this property
describes the sensor's color filter array pattern. Supported values are
"bggr", "gbrg", "grbg", "rggb" and "mono". If not specified, the pattern
defaults to "mono".
[UG934] http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf
Xilinx Video Timing Controller (VTC)
------------------------------------
The Video Timing Controller is a general purpose video timing generator and
detector.
Required properties:
- compatible: Must be "xlnx,v-tc-6.1".
- reg: Physical base address and length of the registers set for the device.
- clocks: Must contain a clock specifier for the VTC core and timing
interfaces clock.
Optional properties:
- xlnx,detector: The VTC has a timing detector
- xlnx,generator: The VTC has a timing generator
At least one of the xlnx,detector and xlnx,generator properties must be
specified.
Example:
vtc: vtc@43c40000 {
compatible = "xlnx,v-tc-6.1";
reg = <0x43c40000 0x10000>;
clocks = <&clkc 15>;
xlnx,generator;
};
Xilinx Video Test Pattern Generator (TPG)
-----------------------------------------
Required properties:
- compatible: Must contain at least one of
"xlnx,v-tpg-5.0" (TPG version 5.0)
"xlnx,v-tpg-6.0" (TPG version 6.0)
TPG versions backward-compatible with previous versions should list all
compatible versions in the newer to older order.
- reg: Physical base address and length of the registers set for the device.
- clocks: Reference to the video core clock.
- xlnx,video-format, xlnx,video-width: Video format and width, as defined in
video.txt.
- port: Video port, using the DT bindings defined in ../video-interfaces.txt.
The TPG has a single output port numbered 0.
Optional properties:
- xlnx,vtc: A phandle referencing the Video Timing Controller that generates
video timings for the TPG test patterns.
- timing-gpios: Specifier for a GPIO that controls the timing mux at the TPG
input. The GPIO active level corresponds to the selection of VTC-generated
video timings.
The xlnx,vtc and timing-gpios properties are mandatory when the TPG is
synthesized with two ports and forbidden when synthesized with one port.
Example:
tpg_0: tpg@40050000 {
compatible = "xlnx,v-tpg-6.0", "xlnx,v-tpg-5.0";
reg = <0x40050000 0x10000>;
clocks = <&clkc 15>;
xlnx,vtc = <&vtc_3>;
timing-gpios = <&ps7_gpio_0 55 GPIO_ACTIVE_LOW>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
xlnx,video-format = <XVIP_VF_YUV_422>;
xlnx,video-width = <8>;
tpg_in: endpoint {
remote-endpoint = <&adv7611_out>;
};
};
port@1 {
reg = <1>;
xlnx,video-format = <XVIP_VF_YUV_422>;
xlnx,video-width = <8>;
tpg1_out: endpoint {
remote-endpoint = <&switch_in0>;
};
}:
};
};
Xilinx Video IP Pipeline (VIPP)
-------------------------------
General concept
---------------
Xilinx video IP pipeline processes video streams through one or more Xilinx
video IP cores. Each video IP core is represented as documented in video.txt
and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
node of the VIPP represents as a top level node of the pipeline and defines
mappings between DMAs and the video IP cores.
Required properties:
- compatible: Must be "xlnx,video".
- dmas, dma-names: List of one DMA specifier and identifier string (as defined
in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
requires a DMA channel with the identifier string set to "port" followed by
the port index.
- ports: Video port, using the DT bindings defined in ../video-interfaces.txt.
Required port properties:
- direction: should be either "input" or "output" depending on the direction
of stream.
Example:
video_cap {
compatible = "xlnx,video";
dmas = <&vdma_1 1>, <&vdma_3 1>;
dma-names = "port0", "port1";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
direction = "input";
vcap0_in0: endpoint {
remote-endpoint = <&scaler0_out>;
};
};
port@1 {
reg = <1>;
direction = "input";
vcap0_in1: endpoint {
remote-endpoint = <&switch_out1>;
};
};
};
};
...@@ -21,6 +21,7 @@ ampire Ampire Co., Ltd. ...@@ -21,6 +21,7 @@ ampire Ampire Co., Ltd.
ams AMS AG ams AMS AG
amstaos AMS-Taos Inc. amstaos AMS-Taos Inc.
apm Applied Micro Circuits Corporation (APM) apm Applied Micro Circuits Corporation (APM)
aptina Aptina Imaging
arasan Arasan Chip Systems arasan Arasan Chip Systems
arm ARM Ltd. arm ARM Ltd.
armadeus ARMadeus Systems SARL armadeus ARMadeus Systems SARL
......
...@@ -344,7 +344,9 @@ implement g_volatile_ctrl like this: ...@@ -344,7 +344,9 @@ implement g_volatile_ctrl like this:
} }
Note that you use the 'new value' union as well in g_volatile_ctrl. In general Note that you use the 'new value' union as well in g_volatile_ctrl. In general
controls that need to implement g_volatile_ctrl are read-only controls. controls that need to implement g_volatile_ctrl are read-only controls. If they
are not, a V4L2_EVENT_CTRL_CH_VALUE will not be generated when the control
changes.
To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE: To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
......
...@@ -793,8 +793,8 @@ video_register_device_no_warn() instead. ...@@ -793,8 +793,8 @@ video_register_device_no_warn() instead.
Whenever a device node is created some attributes are also created for you. Whenever a device node is created some attributes are also created for you.
If you look in /sys/class/video4linux you see the devices. Go into e.g. If you look in /sys/class/video4linux you see the devices. Go into e.g.
video0 and you will see 'name', 'debug' and 'index' attributes. The 'name' video0 and you will see 'name', 'dev_debug' and 'index' attributes. The 'name'
attribute is the 'name' field of the video_device struct. The 'debug' attribute attribute is the 'name' field of the video_device struct. The 'dev_debug' attribute
can be used to enable core debugging. See the next section for more detailed can be used to enable core debugging. See the next section for more detailed
information on this. information on this.
...@@ -821,7 +821,7 @@ unregister the device if the registration failed. ...@@ -821,7 +821,7 @@ unregister the device if the registration failed.
video device debugging video device debugging
---------------------- ----------------------
The 'debug' attribute that is created for each video, vbi, radio or swradio The 'dev_debug' attribute that is created for each video, vbi, radio or swradio
device in /sys/class/video4linux/<devX>/ allows you to enable logging of device in /sys/class/video4linux/<devX>/ allows you to enable logging of
file operations. file operations.
......
...@@ -912,6 +912,11 @@ looped to the video input provided that: ...@@ -912,6 +912,11 @@ looped to the video input provided that:
sequence and field counting in struct v4l2_buffer on the capture side may not sequence and field counting in struct v4l2_buffer on the capture side may not
be 100% accurate. be 100% accurate.
- field settings V4L2_FIELD_SEQ_TB/BT are not supported. While it is possible to
implement this, it would mean a lot of work to get this right. Since these
field values are rarely used the decision was made not to implement this for
now.
- on the input side the "Standard Signal Mode" for the S-Video input or the - on the input side the "Standard Signal Mode" for the S-Video input or the
"DV Timings Signal Mode" for the HDMI input should be configured so that a "DV Timings Signal Mode" for the HDMI input should be configured so that a
valid signal is passed to the video input. valid signal is passed to the video input.
......
...@@ -4474,7 +4474,7 @@ S: Maintained ...@@ -4474,7 +4474,7 @@ S: Maintained
F: block/partitions/efi.* F: block/partitions/efi.*
STK1160 USB VIDEO CAPTURE DRIVER STK1160 USB VIDEO CAPTURE DRIVER
M: Ezequiel Garcia <elezegarcia@gmail.com> M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git T: git git://linuxtv.org/media_tree.git
S: Maintained S: Maintained
...@@ -6166,16 +6166,6 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ ...@@ -6166,16 +6166,6 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained S: Maintained
F: drivers/media/dvb-frontends/m88rs2000* F: drivers/media/dvb-frontends/m88rs2000*
M88TS2022 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/m88ts2022*
MA901 MASTERKIT USB FM RADIO DRIVER MA901 MASTERKIT USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com> M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
...@@ -6599,6 +6589,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> ...@@ -6599,6 +6589,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git T: git git://linuxtv.org/media_tree.git
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/media/i2c/mt9v032.txt
F: drivers/media/i2c/mt9v032.c F: drivers/media/i2c/mt9v032.c
F: include/media/mt9v032.h F: include/media/mt9v032.h
...@@ -8992,6 +8983,16 @@ T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git ...@@ -8992,6 +8983,16 @@ T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
S: Maintained S: Maintained
F: drivers/media/platform/am437x/ F: drivers/media/platform/am437x/
OV2659 OMNIVISION SENSOR DRIVER
M: Lad, Prabhakar <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
S: Maintained
F: drivers/media/i2c/ov2659.c
F: include/media/ov2659.h
SIS 190 ETHERNET DRIVER SIS 190 ETHERNET DRIVER
M: Francois Romieu <romieu@fr.zoreil.com> M: Francois Romieu <romieu@fr.zoreil.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
...@@ -10921,6 +10922,16 @@ L: linux-serial@vger.kernel.org ...@@ -10921,6 +10922,16 @@ L: linux-serial@vger.kernel.org
S: Maintained S: Maintained
F: drivers/tty/serial/uartlite.c F: drivers/tty/serial/uartlite.c
XILINX VIDEO IP CORES
M: Hyun Kwon <hyun.kwon@xilinx.com>
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Supported
F: Documentation/devicetree/bindings/media/xilinx/
F: drivers/media/platform/xilinx/
F: include/uapi/linux/xilinx-v4l2-controls.h
XILLYBUS DRIVER XILLYBUS DRIVER
M: Eli Billauer <eli.billauer@gmail.com> M: Eli Billauer <eli.billauer@gmail.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
......
...@@ -492,34 +492,13 @@ static struct twl4030_platform_data cm_t35_twldata = { ...@@ -492,34 +492,13 @@ static struct twl4030_platform_data cm_t35_twldata = {
#include <media/omap3isp.h> #include <media/omap3isp.h>
#include "devices.h" #include "devices.h"
static struct i2c_board_info cm_t35_isp_i2c_boardinfo[] = { static struct isp_platform_subdev cm_t35_isp_subdevs[] = {
{ {
I2C_BOARD_INFO("mt9t001", 0x5d), .board_info = &(struct i2c_board_info){
I2C_BOARD_INFO("mt9t001", 0x5d)
}, },
{
I2C_BOARD_INFO("tvp5150", 0x5c),
},
};
static struct isp_subdev_i2c_board_info cm_t35_isp_primary_subdevs[] = {
{
.board_info = &cm_t35_isp_i2c_boardinfo[0],
.i2c_adapter_id = 3,
},
{ NULL, 0, },
};
static struct isp_subdev_i2c_board_info cm_t35_isp_secondary_subdevs[] = {
{
.board_info = &cm_t35_isp_i2c_boardinfo[1],
.i2c_adapter_id = 3, .i2c_adapter_id = 3,
}, .bus = &(struct isp_bus_cfg){
{ NULL, 0, },
};
static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
{
.subdevs = cm_t35_isp_primary_subdevs,
.interface = ISP_INTERFACE_PARALLEL, .interface = ISP_INTERFACE_PARALLEL,
.bus = { .bus = {
.parallel = { .parallel = {
...@@ -527,8 +506,13 @@ static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = { ...@@ -527,8 +506,13 @@ static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
}, },
}, },
}, },
},
{ {
.subdevs = cm_t35_isp_secondary_subdevs, .board_info = &(struct i2c_board_info){
I2C_BOARD_INFO("tvp5150", 0x5c),
},
.i2c_adapter_id = 3,
.bus = &(struct isp_bus_cfg){
.interface = ISP_INTERFACE_PARALLEL, .interface = ISP_INTERFACE_PARALLEL,
.bus = { .bus = {
.parallel = { .parallel = {
...@@ -536,7 +520,8 @@ static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = { ...@@ -536,7 +520,8 @@ static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
}, },
}, },
}, },
{ NULL, 0, }, },
{ 0 },
}; };
static struct isp_platform_data cm_t35_isp_pdata = { static struct isp_platform_data cm_t35_isp_pdata = {
......
...@@ -74,82 +74,12 @@ omap_postcore_initcall(omap3_l3_init); ...@@ -74,82 +74,12 @@ omap_postcore_initcall(omap3_l3_init);
static struct resource omap3isp_resources[] = { static struct resource omap3isp_resources[] = {
{ {
.start = OMAP3430_ISP_BASE, .start = OMAP3430_ISP_BASE,
.end = OMAP3430_ISP_END, .end = OMAP3430_ISP_BASE + 0x12fc,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
.start = OMAP3430_ISP_CCP2_BASE, .start = OMAP3430_ISP_BASE2,
.end = OMAP3430_ISP_CCP2_END, .end = OMAP3430_ISP_BASE2 + 0x0600,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CCDC_BASE,
.end = OMAP3430_ISP_CCDC_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_HIST_BASE,
.end = OMAP3430_ISP_HIST_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_H3A_BASE,
.end = OMAP3430_ISP_H3A_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_PREV_BASE,
.end = OMAP3430_ISP_PREV_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_RESZ_BASE,
.end = OMAP3430_ISP_RESZ_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_SBL_BASE,
.end = OMAP3430_ISP_SBL_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CSI2A_REGS1_BASE,
.end = OMAP3430_ISP_CSI2A_REGS1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CSIPHY2_BASE,
.end = OMAP3430_ISP_CSIPHY2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2A_REGS2_BASE,
.end = OMAP3630_ISP_CSI2A_REGS2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2C_REGS1_BASE,
.end = OMAP3630_ISP_CSI2C_REGS1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSIPHY1_BASE,
.end = OMAP3630_ISP_CSIPHY1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2C_REGS2_BASE,
.end = OMAP3630_ISP_CSI2C_REGS2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE,
.end = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL,
.end = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ {
......
...@@ -47,38 +47,8 @@ ...@@ -47,38 +47,8 @@
#define OMAP34XX_IC_BASE 0x48200000 #define OMAP34XX_IC_BASE 0x48200000
#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000) #define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100)
#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400)
#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600)
#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00)
#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00)
#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00)
#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400) #define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
#define OMAP3430_ISP_CSI2A_REGS1_BASE (OMAP3430_ISP_BASE + 0x1800) #define OMAP3430_ISP_BASE2 (OMAP3430_ISP_BASE + 0x1800)
#define OMAP3430_ISP_CSIPHY2_BASE (OMAP3430_ISP_BASE + 0x1970)
#define OMAP3630_ISP_CSI2A_REGS2_BASE (OMAP3430_ISP_BASE + 0x19C0)
#define OMAP3630_ISP_CSI2C_REGS1_BASE (OMAP3430_ISP_BASE + 0x1C00)
#define OMAP3630_ISP_CSIPHY1_BASE (OMAP3430_ISP_BASE + 0x1D70)
#define OMAP3630_ISP_CSI2C_REGS2_BASE (OMAP3430_ISP_BASE + 0x1DC0)
#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF)
#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7)
#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047)
#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F)
#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F)
#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
#define OMAP3430_ISP_CSI2A_REGS1_END (OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
#define OMAP3430_ISP_CSIPHY2_END (OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
#define OMAP3630_ISP_CSI2A_REGS2_END (OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
#define OMAP3630_ISP_CSI2C_REGS1_END (OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
#define OMAP3630_ISP_CSIPHY1_END (OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
#define OMAP3630_ISP_CSI2C_REGS2_END (OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) #define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) #define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
......
...@@ -237,6 +237,18 @@ static u16 ml_calculate_direction(u16 direction, u16 force, ...@@ -237,6 +237,18 @@ static u16 ml_calculate_direction(u16 direction, u16 force,
(force + new_force)) << 1; (force + new_force)) << 1;
} }
#define FRAC_N 8
static inline s16 fixp_new16(s16 a)
{
return ((s32)a) >> (16 - FRAC_N);
}
static inline s16 fixp_mult(s16 a, s16 b)
{
a = ((s32)a * 0x100) / 0x7fff;
return ((s32)(a * b)) >> FRAC_N;
}
/* /*
* Combine two effects and apply gain. * Combine two effects and apply gain.
*/ */
...@@ -247,7 +259,7 @@ static void ml_combine_effects(struct ff_effect *effect, ...@@ -247,7 +259,7 @@ static void ml_combine_effects(struct ff_effect *effect,
struct ff_effect *new = state->effect; struct ff_effect *new = state->effect;
unsigned int strong, weak, i; unsigned int strong, weak, i;
int x, y; int x, y;
fixp_t level; s16 level;
switch (new->type) { switch (new->type) {
case FF_CONSTANT: case FF_CONSTANT:
...@@ -255,8 +267,8 @@ static void ml_combine_effects(struct ff_effect *effect, ...@@ -255,8 +267,8 @@ static void ml_combine_effects(struct ff_effect *effect,
level = fixp_new16(apply_envelope(state, level = fixp_new16(apply_envelope(state,
new->u.constant.level, new->u.constant.level,
&new->u.constant.envelope)); &new->u.constant.envelope));
x = fixp_mult(fixp_sin(i), level) * gain / 0xffff; x = fixp_mult(fixp_sin16(i), level) * gain / 0xffff;
y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff; y = fixp_mult(-fixp_cos16(i), level) * gain / 0xffff;
/* /*
* here we abuse ff_ramp to hold x and y of constant force * here we abuse ff_ramp to hold x and y of constant force
* If in future any driver wants something else than x and y * If in future any driver wants something else than x and y
......
...@@ -980,7 +980,9 @@ config TOUCHSCREEN_SUN4I ...@@ -980,7 +980,9 @@ config TOUCHSCREEN_SUN4I
config TOUCHSCREEN_SUR40 config TOUCHSCREEN_SUR40
tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
depends on USB depends on USB
depends on MEDIA_USB_SUPPORT
select INPUT_POLLDEV select INPUT_POLLDEV
select VIDEOBUF2_DMA_SG
help help
Say Y here if you want support for the Samsung SUR40 touchscreen Say Y here if you want support for the Samsung SUR40 touchscreen
(also known as Microsoft Surface 2.0 or Microsoft PixelSense). (also known as Microsoft Surface 2.0 or Microsoft PixelSense).
......
This diff is collapsed.
...@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT ...@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT
config MEDIA_CONTROLLER config MEDIA_CONTROLLER
bool "Media Controller API" bool "Media Controller API"
depends on MEDIA_CAMERA_SUPPORT depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
---help--- ---help---
Enable the media controller API used to query media devices internal Enable the media controller API used to query media devices internal
topology and configure it dynamically. topology and configure it dynamically.
This API is mostly used by camera interfaces in embedded platforms. This API is mostly used by camera interfaces in embedded platforms.
config MEDIA_CONTROLLER_DVB
bool "Enable Media controller for DVB"
depends on MEDIA_CONTROLLER
---help---
Enable the media controller API support for DVB.
This is currently experimental.
# #
# Video4Linux support # Video4Linux support
# Only enables if one of the V4L2 types (ATV, webcam, radio) is selected # Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
......
...@@ -587,26 +587,20 @@ int saa7146_vv_release(struct saa7146_dev* dev) ...@@ -587,26 +587,20 @@ int saa7146_vv_release(struct saa7146_dev* dev)
} }
EXPORT_SYMBOL_GPL(saa7146_vv_release); EXPORT_SYMBOL_GPL(saa7146_vv_release);
int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
char *name, int type) char *name, int type)
{ {
struct video_device *vfd;
int err; int err;
int i; int i;
DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type); DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
// released by vfd->release
vfd = video_device_alloc();
if (vfd == NULL)
return -ENOMEM;
vfd->fops = &video_fops; vfd->fops = &video_fops;
if (type == VFL_TYPE_GRABBER) if (type == VFL_TYPE_GRABBER)
vfd->ioctl_ops = &dev->ext_vv_data->vid_ops; vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
else else
vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops; vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
vfd->release = video_device_release; vfd->release = video_device_release_empty;
vfd->lock = &dev->v4l2_lock; vfd->lock = &dev->v4l2_lock;
vfd->v4l2_dev = &dev->v4l2_dev; vfd->v4l2_dev = &dev->v4l2_dev;
vfd->tvnorms = 0; vfd->tvnorms = 0;
...@@ -618,25 +612,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, ...@@ -618,25 +612,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
err = video_register_device(vfd, type, -1); err = video_register_device(vfd, type, -1);
if (err < 0) { if (err < 0) {
ERR("cannot register v4l2 device. skipping.\n"); ERR("cannot register v4l2 device. skipping.\n");
video_device_release(vfd);
return err; return err;
} }
pr_info("%s: registered device %s [v4l2]\n", pr_info("%s: registered device %s [v4l2]\n",
dev->name, video_device_node_name(vfd)); dev->name, video_device_node_name(vfd));
*vid = vfd;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(saa7146_register_device); EXPORT_SYMBOL_GPL(saa7146_register_device);
int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) int saa7146_unregister_device(struct video_device *vfd, struct saa7146_dev *dev)
{ {
DEB_EE("dev:%p\n", dev); DEB_EE("dev:%p\n", dev);
video_unregister_device(*vid); video_unregister_device(vfd);
*vid = NULL;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(saa7146_unregister_device); EXPORT_SYMBOL_GPL(saa7146_unregister_device);
......
...@@ -95,7 +95,7 @@ static int vbi_workaround(struct saa7146_dev *dev) ...@@ -95,7 +95,7 @@ static int vbi_workaround(struct saa7146_dev *dev)
/* prepare to wait to be woken up by the irq-handler */ /* prepare to wait to be woken up by the irq-handler */
add_wait_queue(&vv->vbi_wq, &wait); add_wait_queue(&vv->vbi_wq, &wait);
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
/* start rps1 to enable workaround */ /* start rps1 to enable workaround */
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
...@@ -106,7 +106,7 @@ static int vbi_workaround(struct saa7146_dev *dev) ...@@ -106,7 +106,7 @@ static int vbi_workaround(struct saa7146_dev *dev)
DEB_VBI("brs bug workaround %d/1\n", i); DEB_VBI("brs bug workaround %d/1\n", i);
remove_wait_queue(&vv->vbi_wq, &wait); remove_wait_queue(&vv->vbi_wq, &wait);
current->state = TASK_RUNNING; __set_current_state(TASK_RUNNING);
/* disable rps1 irqs */ /* disable rps1 irqs */
SAA7146_IER_DISABLE(dev,MASK_28); SAA7146_IER_DISABLE(dev,MASK_28);
......
...@@ -21,10 +21,6 @@ ...@@ -21,10 +21,6 @@
#include "smsir.h" #include "smsir.h"
#include <linux/module.h> #include <linux/module.h>
static int sms_dbg;
module_param_named(cards_dbg, sms_dbg, int, 0644);
MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = { static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = { [SMS_BOARD_UNKNOWN] = {
.name = "Unknown board", .name = "Unknown board",
...@@ -232,7 +228,7 @@ int sms_board_event(struct smscore_device_t *coredev, ...@@ -232,7 +228,7 @@ int sms_board_event(struct smscore_device_t *coredev,
break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
default: default:
sms_err("Unknown SMS board event"); pr_err("Unknown SMS board event\n");
break; break;
} }
return 0; return 0;
...@@ -342,7 +338,7 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) ...@@ -342,7 +338,7 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
int board_id = smscore_get_board_id(coredev); int board_id = smscore_get_board_id(coredev);
struct sms_board *board = sms_get_board(board_id); struct sms_board *board = sms_get_board(board_id);
sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); pr_debug("%s: LNA %s\n", __func__, onoff ? "enabled" : "disabled");
switch (board_id) { switch (board_id) {
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
......
...@@ -20,8 +20,9 @@ ...@@ -20,8 +20,9 @@
#ifndef __SMS_CARDS_H__ #ifndef __SMS_CARDS_H__
#define __SMS_CARDS_H__ #define __SMS_CARDS_H__
#include <linux/usb.h>
#include "smscoreapi.h" #include "smscoreapi.h"
#include <linux/usb.h>
#include "smsir.h" #include "smsir.h"
#define SMS_BOARD_UNKNOWN 0 #define SMS_BOARD_UNKNOWN 0
......
This diff is collapsed.
...@@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __SMS_CORE_API_H__ #ifndef __SMS_CORE_API_H__
#define __SMS_CORE_API_H__ #define __SMS_CORE_API_H__
#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
#include <linux/device.h> #include <linux/device.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -31,6 +33,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -31,6 +33,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <media/media-device.h>
#include <asm/page.h> #include <asm/page.h>
#include "smsir.h" #include "smsir.h"
...@@ -215,6 +219,10 @@ struct smscore_device_t { ...@@ -215,6 +219,10 @@ struct smscore_device_t {
bool is_usb_device; bool is_usb_device;
int led_state; int led_state;
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
struct media_device *media_dev;
#endif
}; };
/* GPIO definitions for antenna frequency domain control (SMS8021) */ /* GPIO definitions for antenna frequency domain control (SMS8021) */
...@@ -1115,7 +1123,8 @@ extern int smscore_register_hotplug(hotplug_t hotplug); ...@@ -1115,7 +1123,8 @@ extern int smscore_register_hotplug(hotplug_t hotplug);
extern void smscore_unregister_hotplug(hotplug_t hotplug); extern void smscore_unregister_hotplug(hotplug_t hotplug);
extern int smscore_register_device(struct smsdevice_params_t *params, extern int smscore_register_device(struct smsdevice_params_t *params,
struct smscore_device_t **coredev); struct smscore_device_t **coredev,
void *mdev);
extern void smscore_unregister_device(struct smscore_device_t *coredev); extern void smscore_unregister_device(struct smscore_device_t *coredev);
extern int smscore_start_device(struct smscore_device_t *coredev); extern int smscore_start_device(struct smscore_device_t *coredev);
...@@ -1168,25 +1177,4 @@ int smscore_led_state(struct smscore_device_t *core, int led); ...@@ -1168,25 +1177,4 @@ int smscore_led_state(struct smscore_device_t *core, int led);
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
#define DBG_INFO 1
#define DBG_ADV 2
#define sms_printk(kern, fmt, arg...) \
printk(kern "%s: " fmt "\n", __func__, ##arg)
#define dprintk(kern, lvl, fmt, arg...) do {\
if (sms_dbg & lvl) \
sms_printk(kern, fmt, ##arg); \
} while (0)
#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
#define sms_err(fmt, arg...) \
sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
#define sms_info(fmt, arg...) \
dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
#define sms_debug(fmt, arg...) \
dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
#endif /* __SMS_CORE_API_H__ */ #endif /* __SMS_CORE_API_H__ */
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* *
***********************************************************************/ ***********************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include "smscoreapi.h"
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
#include "dvb_demux.h" #include "dvb_demux.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "smscoreapi.h"
#include "smsdvb.h" #include "smsdvb.h"
static struct dentry *smsdvb_debugfs_usb_root; static struct dentry *smsdvb_debugfs_usb_root;
...@@ -536,7 +534,7 @@ int smsdvb_debugfs_register(void) ...@@ -536,7 +534,7 @@ int smsdvb_debugfs_register(void)
*/ */
d = debugfs_create_dir("smsdvb", usb_debug_root); d = debugfs_create_dir("smsdvb", usb_debug_root);
if (IS_ERR_OR_NULL(d)) { if (IS_ERR_OR_NULL(d)) {
sms_err("Couldn't create sysfs node for smsdvb"); pr_err("Couldn't create sysfs node for smsdvb\n");
return PTR_ERR(d); return PTR_ERR(d);
} else { } else {
smsdvb_debugfs_usb_root = d; smsdvb_debugfs_usb_root = d;
......
...@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************/ ****************************************************************/
#include "smscoreapi.h"
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -29,7 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -29,7 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dvb_demux.h" #include "dvb_demux.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "smscoreapi.h"
#include "sms-cards.h" #include "sms-cards.h"
#include "smsdvb.h" #include "smsdvb.h"
...@@ -39,11 +40,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ...@@ -39,11 +40,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static struct list_head g_smsdvb_clients; static struct list_head g_smsdvb_clients;
static struct mutex g_smsdvb_clientslock; static struct mutex g_smsdvb_clientslock;
static int sms_dbg;
module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
static u32 sms_to_guard_interval_table[] = { static u32 sms_to_guard_interval_table[] = {
[0] = GUARD_INTERVAL_1_32, [0] = GUARD_INTERVAL_1_32,
[1] = GUARD_INTERVAL_1_16, [1] = GUARD_INTERVAL_1_16,
...@@ -82,48 +78,48 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, ...@@ -82,48 +78,48 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client,
struct smscore_device_t *coredev = client->coredev; struct smscore_device_t *coredev = client->coredev;
switch (event) { switch (event) {
case DVB3_EVENT_INIT: case DVB3_EVENT_INIT:
sms_debug("DVB3_EVENT_INIT"); pr_debug("DVB3_EVENT_INIT\n");
sms_board_event(coredev, BOARD_EVENT_BIND); sms_board_event(coredev, BOARD_EVENT_BIND);
break; break;
case DVB3_EVENT_SLEEP: case DVB3_EVENT_SLEEP:
sms_debug("DVB3_EVENT_SLEEP"); pr_debug("DVB3_EVENT_SLEEP\n");
sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
break; break;
case DVB3_EVENT_HOTPLUG: case DVB3_EVENT_HOTPLUG:
sms_debug("DVB3_EVENT_HOTPLUG"); pr_debug("DVB3_EVENT_HOTPLUG\n");
sms_board_event(coredev, BOARD_EVENT_POWER_INIT); sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
break; break;
case DVB3_EVENT_FE_LOCK: case DVB3_EVENT_FE_LOCK:
if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
client->event_fe_state = DVB3_EVENT_FE_LOCK; client->event_fe_state = DVB3_EVENT_FE_LOCK;
sms_debug("DVB3_EVENT_FE_LOCK"); pr_debug("DVB3_EVENT_FE_LOCK\n");
sms_board_event(coredev, BOARD_EVENT_FE_LOCK); sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
} }
break; break;
case DVB3_EVENT_FE_UNLOCK: case DVB3_EVENT_FE_UNLOCK:
if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
client->event_fe_state = DVB3_EVENT_FE_UNLOCK; client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
sms_debug("DVB3_EVENT_FE_UNLOCK"); pr_debug("DVB3_EVENT_FE_UNLOCK\n");
sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
} }
break; break;
case DVB3_EVENT_UNC_OK: case DVB3_EVENT_UNC_OK:
if (client->event_unc_state != DVB3_EVENT_UNC_OK) { if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
client->event_unc_state = DVB3_EVENT_UNC_OK; client->event_unc_state = DVB3_EVENT_UNC_OK;
sms_debug("DVB3_EVENT_UNC_OK"); pr_debug("DVB3_EVENT_UNC_OK\n");
sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
} }
break; break;
case DVB3_EVENT_UNC_ERR: case DVB3_EVENT_UNC_ERR:
if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
client->event_unc_state = DVB3_EVENT_UNC_ERR; client->event_unc_state = DVB3_EVENT_UNC_ERR;
sms_debug("DVB3_EVENT_UNC_ERR"); pr_debug("DVB3_EVENT_UNC_ERR\n");
sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
} }
break; break;
default: default:
sms_err("Unknown dvb3 api event"); pr_err("Unknown dvb3 api event\n");
break; break;
} }
} }
...@@ -590,7 +586,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) ...@@ -590,7 +586,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
is_status_update = true; is_status_update = true;
break; break;
default: default:
sms_info("message not handled"); pr_debug("message not handled\n");
} }
smscore_putbuffer(client->coredev, cb); smscore_putbuffer(client->coredev, cb);
...@@ -613,6 +609,19 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) ...@@ -613,6 +609,19 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
return 0; return 0;
} }
static void smsdvb_media_device_unregister(struct smsdvb_client_t *client)
{
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
struct smscore_device_t *coredev = client->coredev;
if (!coredev->media_dev)
return;
media_device_unregister(coredev->media_dev);
kfree(coredev->media_dev);
coredev->media_dev = NULL;
#endif
}
static void smsdvb_unregister_client(struct smsdvb_client_t *client) static void smsdvb_unregister_client(struct smsdvb_client_t *client)
{ {
/* must be called under clientslock */ /* must be called under clientslock */
...@@ -624,6 +633,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client) ...@@ -624,6 +633,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client)
dvb_unregister_frontend(&client->frontend); dvb_unregister_frontend(&client->frontend);
dvb_dmxdev_release(&client->dmxdev); dvb_dmxdev_release(&client->dmxdev);
dvb_dmx_release(&client->demux); dvb_dmx_release(&client->demux);
smsdvb_media_device_unregister(client);
dvb_unregister_adapter(&client->adapter); dvb_unregister_adapter(&client->adapter);
kfree(client); kfree(client);
} }
...@@ -643,7 +653,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) ...@@ -643,7 +653,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed)
container_of(feed->demux, struct smsdvb_client_t, demux); container_of(feed->demux, struct smsdvb_client_t, demux);
struct sms_msg_data pid_msg; struct sms_msg_data pid_msg;
sms_debug("add pid %d(%x)", pr_debug("add pid %d(%x)\n",
feed->pid, feed->pid); feed->pid, feed->pid);
client->feed_users++; client->feed_users++;
...@@ -665,7 +675,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) ...@@ -665,7 +675,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
container_of(feed->demux, struct smsdvb_client_t, demux); container_of(feed->demux, struct smsdvb_client_t, demux);
struct sms_msg_data pid_msg; struct sms_msg_data pid_msg;
sms_debug("remove pid %d(%x)", pr_debug("remove pid %d(%x)\n",
feed->pid, feed->pid); feed->pid, feed->pid);
client->feed_users--; client->feed_users--;
...@@ -835,7 +845,7 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ...@@ -835,7 +845,7 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
static int smsdvb_get_tune_settings(struct dvb_frontend *fe, static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *tune) struct dvb_frontend_tune_settings *tune)
{ {
sms_debug(""); pr_debug("\n");
tune->min_delay_ms = 400; tune->min_delay_ms = 400;
tune->step_size = 250000; tune->step_size = 250000;
...@@ -869,7 +879,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) ...@@ -869,7 +879,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
msg.Data[0] = c->frequency; msg.Data[0] = c->frequency;
msg.Data[2] = 12000000; msg.Data[2] = 12000000;
sms_info("%s: freq %d band %d", __func__, c->frequency, pr_debug("%s: freq %d band %d\n", __func__, c->frequency,
c->bandwidth_hz); c->bandwidth_hz);
switch (c->bandwidth_hz / 1000000) { switch (c->bandwidth_hz / 1000000) {
...@@ -954,7 +964,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) ...@@ -954,7 +964,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
c->bandwidth_hz = 6000000; c->bandwidth_hz = 6000000;
sms_info("%s: freq %d segwidth %d segindex %d", __func__, pr_debug("freq %d segwidth %d segindex %d\n",
c->frequency, c->isdbt_sb_segment_count, c->frequency, c->isdbt_sb_segment_count,
c->isdbt_sb_segment_idx); c->isdbt_sb_segment_idx);
...@@ -1082,10 +1092,8 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1082,10 +1092,8 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
if (!arrival) if (!arrival)
return 0; return 0;
client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
if (!client) { if (!client)
sms_err("kmalloc() failed");
return -ENOMEM; return -ENOMEM;
}
/* register dvb adapter */ /* register dvb adapter */
rc = dvb_register_adapter(&client->adapter, rc = dvb_register_adapter(&client->adapter,
...@@ -1093,9 +1101,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1093,9 +1101,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
smscore_get_board_id(coredev))->name, smscore_get_board_id(coredev))->name,
THIS_MODULE, device, adapter_nr); THIS_MODULE, device, adapter_nr);
if (rc < 0) { if (rc < 0) {
sms_err("dvb_register_adapter() failed %d", rc); pr_err("dvb_register_adapter() failed %d\n", rc);
goto adapter_error; goto adapter_error;
} }
dvb_register_media_controller(&client->adapter, coredev->media_dev);
/* init dvb demux */ /* init dvb demux */
client->demux.dmx.capabilities = DMX_TS_FILTERING; client->demux.dmx.capabilities = DMX_TS_FILTERING;
...@@ -1106,7 +1115,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1106,7 +1115,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
rc = dvb_dmx_init(&client->demux); rc = dvb_dmx_init(&client->demux);
if (rc < 0) { if (rc < 0) {
sms_err("dvb_dmx_init failed %d", rc); pr_err("dvb_dmx_init failed %d\n", rc);
goto dvbdmx_error; goto dvbdmx_error;
} }
...@@ -1117,7 +1126,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1117,7 +1126,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
if (rc < 0) { if (rc < 0) {
sms_err("dvb_dmxdev_init failed %d", rc); pr_err("dvb_dmxdev_init failed %d\n", rc);
goto dmxdev_error; goto dmxdev_error;
} }
...@@ -1138,7 +1147,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1138,7 +1147,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
rc = dvb_register_frontend(&client->adapter, &client->frontend); rc = dvb_register_frontend(&client->adapter, &client->frontend);
if (rc < 0) { if (rc < 0) {
sms_err("frontend registration failed %d", rc); pr_err("frontend registration failed %d\n", rc);
goto frontend_error; goto frontend_error;
} }
...@@ -1150,7 +1159,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1150,7 +1159,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
rc = smscore_register_client(coredev, &params, &client->smsclient); rc = smscore_register_client(coredev, &params, &client->smsclient);
if (rc < 0) { if (rc < 0) {
sms_err("smscore_register_client() failed %d", rc); pr_err("smscore_register_client() failed %d\n", rc);
goto client_error; goto client_error;
} }
...@@ -1169,12 +1178,14 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1169,12 +1178,14 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
client->event_unc_state = -1; client->event_unc_state = -1;
sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
sms_info("success");
sms_board_setup(coredev); sms_board_setup(coredev);
if (smsdvb_debugfs_create(client) < 0) if (smsdvb_debugfs_create(client) < 0)
sms_info("failed to create debugfs node"); pr_info("failed to create debugfs node\n");
dvb_create_media_graph(&client->adapter);
pr_info("DVB interface registered.\n");
return 0; return 0;
client_error: client_error:
...@@ -1187,6 +1198,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, ...@@ -1187,6 +1198,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
dvb_dmx_release(&client->demux); dvb_dmx_release(&client->demux);
dvbdmx_error: dvbdmx_error:
smsdvb_media_device_unregister(client);
dvb_unregister_adapter(&client->adapter); dvb_unregister_adapter(&client->adapter);
adapter_error: adapter_error:
...@@ -1205,7 +1217,7 @@ static int __init smsdvb_module_init(void) ...@@ -1205,7 +1217,7 @@ static int __init smsdvb_module_init(void)
rc = smscore_register_hotplug(smsdvb_hotplug); rc = smscore_register_hotplug(smsdvb_hotplug);
sms_debug(""); pr_debug("\n");
return rc; return rc;
} }
......
...@@ -25,10 +25,11 @@ ...@@ -25,10 +25,11 @@
****************************************************************/ ****************************************************************/
#include "smscoreapi.h"
#include <linux/types.h> #include <linux/types.h>
#include <linux/input.h> #include <linux/input.h>
#include "smscoreapi.h"
#include "smsir.h" #include "smsir.h"
#include "sms-cards.h" #include "sms-cards.h"
...@@ -56,16 +57,14 @@ int sms_ir_init(struct smscore_device_t *coredev) ...@@ -56,16 +57,14 @@ int sms_ir_init(struct smscore_device_t *coredev)
int board_id = smscore_get_board_id(coredev); int board_id = smscore_get_board_id(coredev);
struct rc_dev *dev; struct rc_dev *dev;
sms_log("Allocating rc device"); pr_debug("Allocating rc device\n");
dev = rc_allocate_device(); dev = rc_allocate_device();
if (!dev) { if (!dev)
sms_err("Not enough memory");
return -ENOMEM; return -ENOMEM;
}
coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT; coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms", pr_debug("IR port %d, timeout %d ms\n",
coredev->ir.controller, coredev->ir.timeout); coredev->ir.controller, coredev->ir.timeout);
snprintf(coredev->ir.name, sizeof(coredev->ir.name), snprintf(coredev->ir.name, sizeof(coredev->ir.name),
...@@ -92,11 +91,12 @@ int sms_ir_init(struct smscore_device_t *coredev) ...@@ -92,11 +91,12 @@ int sms_ir_init(struct smscore_device_t *coredev)
dev->map_name = sms_get_board(board_id)->rc_codes; dev->map_name = sms_get_board(board_id)->rc_codes;
dev->driver_name = MODULE_NAME; dev->driver_name = MODULE_NAME;
sms_log("Input device (IR) %s is set for key events", dev->input_name); pr_debug("Input device (IR) %s is set for key events\n",
dev->input_name);
err = rc_register_device(dev); err = rc_register_device(dev);
if (err < 0) { if (err < 0) {
sms_err("Failed to register device"); pr_err("Failed to register device\n");
rc_free_device(dev); rc_free_device(dev);
return err; return err;
} }
...@@ -109,5 +109,5 @@ void sms_ir_exit(struct smscore_device_t *coredev) ...@@ -109,5 +109,5 @@ void sms_ir_exit(struct smscore_device_t *coredev)
{ {
rc_unregister_device(coredev->ir.dev); rc_unregister_device(coredev->ir.dev);
sms_log(""); pr_debug("\n");
} }
...@@ -1136,10 +1136,13 @@ static const struct file_operations dvb_demux_fops = { ...@@ -1136,10 +1136,13 @@ static const struct file_operations dvb_demux_fops = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static struct dvb_device dvbdev_demux = { static const struct dvb_device dvbdev_demux = {
.priv = NULL, .priv = NULL,
.users = 1, .users = 1,
.writers = 1, .writers = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = "dvb-demux",
#endif
.fops = &dvb_demux_fops .fops = &dvb_demux_fops
}; };
...@@ -1209,13 +1212,15 @@ static const struct file_operations dvb_dvr_fops = { ...@@ -1209,13 +1212,15 @@ static const struct file_operations dvb_dvr_fops = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static struct dvb_device dvbdev_dvr = { static const struct dvb_device dvbdev_dvr = {
.priv = NULL, .priv = NULL,
.readers = 1, .readers = 1,
.users = 1, .users = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = "dvb-dvr",
#endif
.fops = &dvb_dvr_fops .fops = &dvb_dvr_fops
}; };
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
{ {
int i; int i;
......
...@@ -245,6 +245,7 @@ ...@@ -245,6 +245,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d #define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
#define USB_PID_TECHNOTREND_CONNECT_S2_4600 0x3011
#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012 #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
...@@ -318,6 +319,7 @@ ...@@ -318,6 +319,7 @@
#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 #define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 #define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
#define USB_PID_WINFAST_DTV2000DS 0x6a04 #define USB_PID_WINFAST_DTV2000DS 0x6a04
#define USB_PID_WINFAST_DTV2000DS_PLUS 0x6f12
#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
...@@ -385,4 +387,5 @@ ...@@ -385,4 +387,5 @@
#define USB_PID_PCTV_2002E 0x025c #define USB_PID_PCTV_2002E 0x025c
#define USB_PID_PCTV_2002E_SE 0x025d #define USB_PID_PCTV_2002E_SE 0x025d
#define USB_PID_SVEON_STV27 0xd3af #define USB_PID_SVEON_STV27 0xd3af
#define USB_PID_TURBOX_DTT_2000 0xd3a4
#endif #endif
...@@ -1638,15 +1638,17 @@ static const struct file_operations dvb_ca_fops = { ...@@ -1638,15 +1638,17 @@ static const struct file_operations dvb_ca_fops = {
.llseek = noop_llseek, .llseek = noop_llseek,
}; };
static struct dvb_device dvbdev_ca = { static const struct dvb_device dvbdev_ca = {
.priv = NULL, .priv = NULL,
.users = 1, .users = 1,
.readers = 1, .readers = 1,
.writers = 1, .writers = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = "dvb-ca-en50221",
#endif
.fops = &dvb_ca_fops, .fops = &dvb_ca_fops,
}; };
/* ******************************************************************************** */ /* ******************************************************************************** */
/* Initialisation/shutdown functions */ /* Initialisation/shutdown functions */
...@@ -1676,14 +1678,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ...@@ -1676,14 +1678,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
/* initialise the system data */ /* initialise the system data */
if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) { if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto exit;
} }
ca->pub = pubca; ca->pub = pubca;
ca->flags = flags; ca->flags = flags;
ca->slot_count = slot_count; ca->slot_count = slot_count;
if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) { if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto free_ca;
} }
init_waitqueue_head(&ca->wait_queue); init_waitqueue_head(&ca->wait_queue);
ca->open = 0; ca->open = 0;
...@@ -1694,7 +1696,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ...@@ -1694,7 +1696,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
/* register the DVB device */ /* register the DVB device */
ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
if (ret) if (ret)
goto error; goto free_slot_info;
/* now initialise each slot */ /* now initialise each slot */
for (i = 0; i < slot_count; i++) { for (i = 0; i < slot_count; i++) {
...@@ -1709,7 +1711,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ...@@ -1709,7 +1711,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
if (signal_pending(current)) { if (signal_pending(current)) {
ret = -EINTR; ret = -EINTR;
goto error; goto unregister_device;
} }
mb(); mb();
...@@ -1720,17 +1722,17 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ...@@ -1720,17 +1722,17 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ret = PTR_ERR(ca->thread); ret = PTR_ERR(ca->thread);
printk("dvb_ca_init: failed to start kernel_thread (%d)\n", printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
ret); ret);
goto error; goto unregister_device;
} }
return 0; return 0;
error: unregister_device:
if (ca != NULL) {
if (ca->dvbdev != NULL)
dvb_unregister_device(ca->dvbdev); dvb_unregister_device(ca->dvbdev);
free_slot_info:
kfree(ca->slot_info); kfree(ca->slot_info);
free_ca:
kfree(ca); kfree(ca);
} exit:
pubca->private = NULL; pubca->private = NULL;
return ret; return ret;
} }
......
...@@ -131,6 +131,11 @@ struct dvb_frontend_private { ...@@ -131,6 +131,11 @@ struct dvb_frontend_private {
int quality; int quality;
unsigned int check_wrapped; unsigned int check_wrapped;
enum dvbfe_search algo_status; enum dvbfe_search algo_status;
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
struct media_pipeline pipe;
struct media_entity *pipe_start_entity;
#endif
}; };
static void dvb_frontend_wakeup(struct dvb_frontend *fe); static void dvb_frontend_wakeup(struct dvb_frontend *fe);
...@@ -590,12 +595,106 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) ...@@ -590,12 +595,106 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
wake_up_interruptible(&fepriv->wait_queue); wake_up_interruptible(&fepriv->wait_queue);
} }
/**
* dvb_enable_media_tuner() - tries to enable the DVB tuner
*
* @fe: struct dvb_frontend pointer
*
* This function ensures that just one media tuner is enabled for a given
* frontend. It has two different behaviors:
* - For trivial devices with just one tuner:
* it just enables the existing tuner->fe link
* - For devices with more than one tuner:
* It is up to the driver to implement the logic that will enable one tuner
* and disable the other ones. However, if more than one tuner is enabled for
* the same frontend, it will print an error message and return -EINVAL.
*
* At return, it will return the error code returned by media_entity_setup_link,
* or 0 if everything is OK, if no tuner is linked to the frontend or if the
* mdev is NULL.
*/
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
static int dvb_enable_media_tuner(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_adapter *adapter = fe->dvb;
struct media_device *mdev = adapter->mdev;
struct media_entity *entity, *source;
struct media_link *link, *found_link = NULL;
int i, ret, n_links = 0, active_links = 0;
fepriv->pipe_start_entity = NULL;
if (!mdev)
return 0;
entity = fepriv->dvbdev->entity;
fepriv->pipe_start_entity = entity;
for (i = 0; i < entity->num_links; i++) {
link = &entity->links[i];
if (link->sink->entity == entity) {
found_link = link;
n_links++;
if (link->flags & MEDIA_LNK_FL_ENABLED)
active_links++;
}
}
if (!n_links || active_links == 1 || !found_link)
return 0;
/*
* If a frontend has more than one tuner linked, it is up to the driver
* to select with one will be the active one, as the frontend core can't
* guess. If the driver doesn't do that, it is a bug.
*/
if (n_links > 1 && active_links != 1) {
dev_err(fe->dvb->device,
"WARNING: there are %d active links among %d tuners. This is a driver's bug!\n",
active_links, n_links);
return -EINVAL;
}
source = found_link->source->entity;
fepriv->pipe_start_entity = source;
for (i = 0; i < source->num_links; i++) {
struct media_entity *sink;
int flags = 0;
link = &source->links[i];
sink = link->sink->entity;
if (sink == entity)
flags = MEDIA_LNK_FL_ENABLED;
ret = media_entity_setup_link(link, flags);
if (ret) {
dev_err(fe->dvb->device,
"Couldn't change link %s->%s to %s. Error %d\n",
source->name, sink->name,
flags ? "enabled" : "disabled",
ret);
return ret;
} else
dev_dbg(fe->dvb->device,
"link %s->%s was %s\n",
source->name, sink->name,
flags ? "ENABLED" : "disabled");
}
return 0;
}
#endif
static int dvb_frontend_thread(void *data) static int dvb_frontend_thread(void *data)
{ {
struct dvb_frontend *fe = data; struct dvb_frontend *fe = data;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
fe_status_t s; fe_status_t s;
enum dvbfe_algo algo; enum dvbfe_algo algo;
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
int ret;
#endif
bool re_tune = false; bool re_tune = false;
bool semheld = false; bool semheld = false;
...@@ -609,6 +708,20 @@ static int dvb_frontend_thread(void *data) ...@@ -609,6 +708,20 @@ static int dvb_frontend_thread(void *data)
fepriv->wakeup = 0; fepriv->wakeup = 0;
fepriv->reinitialise = 0; fepriv->reinitialise = 0;
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
ret = dvb_enable_media_tuner(fe);
if (ret) {
/* FIXME: return an error if it fails */
dev_info(fe->dvb->device,
"proceeding with FE task\n");
} else if (fepriv->pipe_start_entity) {
ret = media_entity_pipeline_start(fepriv->pipe_start_entity,
&fepriv->pipe);
if (ret)
return ret;
}
#endif
dvb_frontend_init(fe); dvb_frontend_init(fe);
set_freezable(); set_freezable();
...@@ -718,6 +831,12 @@ static int dvb_frontend_thread(void *data) ...@@ -718,6 +831,12 @@ static int dvb_frontend_thread(void *data)
} }
} }
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
if (fepriv->pipe_start_entity)
media_entity_pipeline_stop(fepriv->pipe_start_entity);
fepriv->pipe_start_entity = NULL;
#endif
if (dvb_powerdown_on_sleep) { if (dvb_powerdown_on_sleep) {
if (fe->ops.set_voltage) if (fe->ops.set_voltage)
fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
...@@ -2612,11 +2731,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb, ...@@ -2612,11 +2731,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
struct dvb_frontend* fe) struct dvb_frontend* fe)
{ {
struct dvb_frontend_private *fepriv; struct dvb_frontend_private *fepriv;
static const struct dvb_device dvbdev_template = { const struct dvb_device dvbdev_template = {
.users = ~0, .users = ~0,
.writers = 1, .writers = 1,
.readers = (~0)-1, .readers = (~0)-1,
.fops = &dvb_frontend_fops, .fops = &dvb_frontend_fops,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = fe->ops.info.name,
#endif
.kernel_ioctl = dvb_frontend_ioctl .kernel_ioctl = dvb_frontend_ioctl
}; };
......
...@@ -1461,14 +1461,16 @@ static const struct file_operations dvb_net_fops = { ...@@ -1461,14 +1461,16 @@ static const struct file_operations dvb_net_fops = {
.llseek = noop_llseek, .llseek = noop_llseek,
}; };
static struct dvb_device dvbdev_net = { static const struct dvb_device dvbdev_net = {
.priv = NULL, .priv = NULL,
.users = 1, .users = 1,
.writers = 1, .writers = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = "dvb-net",
#endif
.fops = &dvb_net_fops, .fops = &dvb_net_fops,
}; };
void dvb_net_release (struct dvb_net *dvbnet) void dvb_net_release (struct dvb_net *dvbnet)
{ {
int i; int i;
......
...@@ -180,6 +180,93 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) ...@@ -180,6 +180,93 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
return -ENFILE; return -ENFILE;
} }
static void dvb_register_media_device(struct dvb_device *dvbdev,
int type, int minor)
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
int ret = 0, npads;
if (!dvbdev->adapter->mdev)
return;
dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
if (!dvbdev->entity)
return;
dvbdev->entity->info.dev.major = DVB_MAJOR;
dvbdev->entity->info.dev.minor = minor;
dvbdev->entity->name = dvbdev->name;
switch (type) {
case DVB_DEVICE_CA:
case DVB_DEVICE_DEMUX:
case DVB_DEVICE_FRONTEND:
npads = 2;
break;
case DVB_DEVICE_NET:
npads = 0;
break;
default:
npads = 1;
}
if (npads) {
dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
GFP_KERNEL);
if (!dvbdev->pads) {
kfree(dvbdev->entity);
return;
}
}
switch (type) {
case DVB_DEVICE_FRONTEND:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
break;
case DVB_DEVICE_DEMUX:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
break;
case DVB_DEVICE_DVR:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
break;
case DVB_DEVICE_CA:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
break;
case DVB_DEVICE_NET:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
break;
default:
kfree(dvbdev->entity);
dvbdev->entity = NULL;
return;
}
if (npads)
ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
if (!ret)
ret = media_device_register_entity(dvbdev->adapter->mdev,
dvbdev->entity);
if (ret < 0) {
printk(KERN_ERR
"%s: media_device_register_entity failed for %s\n",
__func__, dvbdev->entity->name);
kfree(dvbdev->pads);
kfree(dvbdev->entity);
dvbdev->entity = NULL;
return;
}
printk(KERN_DEBUG "%s: media device '%s' registered.\n",
__func__, dvbdev->entity->name);
#endif
}
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
const struct dvb_device *template, void *priv, int type) const struct dvb_device *template, void *priv, int type)
...@@ -258,10 +345,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -258,10 +345,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
return PTR_ERR(clsdev); return PTR_ERR(clsdev);
} }
dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, minor, minor); adap->num, dnames[type], id, minor, minor);
dvb_register_media_device(dvbdev, type, minor);
return 0; return 0;
} }
EXPORT_SYMBOL(dvb_register_device); EXPORT_SYMBOL(dvb_register_device);
...@@ -278,12 +366,66 @@ void dvb_unregister_device(struct dvb_device *dvbdev) ...@@ -278,12 +366,66 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
if (dvbdev->entity) {
media_device_unregister_entity(dvbdev->entity);
kfree(dvbdev->entity);
kfree(dvbdev->pads);
}
#endif
list_del (&dvbdev->list_head); list_del (&dvbdev->list_head);
kfree (dvbdev->fops); kfree (dvbdev->fops);
kfree (dvbdev); kfree (dvbdev);
} }
EXPORT_SYMBOL(dvb_unregister_device); EXPORT_SYMBOL(dvb_unregister_device);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
void dvb_create_media_graph(struct dvb_adapter *adap)
{
struct media_device *mdev = adap->mdev;
struct media_entity *entity, *tuner = NULL, *fe = NULL;
struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL;
if (!mdev)
return;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
tuner = entity;
break;
case MEDIA_ENT_T_DEVNODE_DVB_FE:
fe = entity;
break;
case MEDIA_ENT_T_DEVNODE_DVB_DEMUX:
demux = entity;
break;
case MEDIA_ENT_T_DEVNODE_DVB_DVR:
dvr = entity;
break;
case MEDIA_ENT_T_DEVNODE_DVB_CA:
ca = entity;
break;
}
}
if (tuner && fe)
media_entity_create_link(tuner, 0, fe, 0, 0);
if (fe && demux)
media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
if (demux && dvr)
media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
if (demux && ca)
media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
}
EXPORT_SYMBOL_GPL(dvb_create_media_graph);
#endif
static int dvbdev_check_free_adapter_num(int num) static int dvbdev_check_free_adapter_num(int num)
{ {
struct list_head *entry; struct list_head *entry;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/list.h> #include <linux/list.h>
#include <media/media-device.h>
#define DVB_MAJOR 212 #define DVB_MAJOR 212
...@@ -71,6 +72,10 @@ struct dvb_adapter { ...@@ -71,6 +72,10 @@ struct dvb_adapter {
int mfe_shared; /* indicates mutually exclusive frontends */ int mfe_shared; /* indicates mutually exclusive frontends */
struct dvb_device *mfe_dvbdev; /* frontend device in use */ struct dvb_device *mfe_dvbdev; /* frontend device in use */
struct mutex mfe_lock; /* access lock for thread creation */ struct mutex mfe_lock; /* access lock for thread creation */
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
struct media_device *mdev;
#endif
}; };
...@@ -92,6 +97,15 @@ struct dvb_device { ...@@ -92,6 +97,15 @@ struct dvb_device {
/* don't really need those !? -- FIXME: use video_usercopy */ /* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
/* Needed for media controller register/unregister */
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
const char *name;
/* Allocated and filled inside dvbdev.c */
struct media_entity *entity;
struct media_pad *pads;
#endif
void *priv; void *priv;
}; };
...@@ -109,6 +123,19 @@ extern int dvb_register_device (struct dvb_adapter *adap, ...@@ -109,6 +123,19 @@ extern int dvb_register_device (struct dvb_adapter *adap,
extern void dvb_unregister_device (struct dvb_device *dvbdev); extern void dvb_unregister_device (struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
void dvb_create_media_graph(struct dvb_adapter *adap);
static inline void dvb_register_media_controller(struct dvb_adapter *adap,
struct media_device *mdev)
{
adap->mdev = mdev;
}
#else
static inline void dvb_create_media_graph(struct dvb_adapter *adap) {}
#define dvb_register_media_controller(a, b) {}
#endif
extern int dvb_generic_open (struct inode *inode, struct file *file); extern int dvb_generic_open (struct inode *inode, struct file *file);
extern int dvb_generic_release (struct inode *inode, struct file *file); extern int dvb_generic_release (struct inode *inode, struct file *file);
extern long dvb_generic_ioctl (struct file *file, extern long dvb_generic_ioctl (struct file *file,
......
...@@ -577,6 +577,14 @@ config DVB_LGDT3305 ...@@ -577,6 +577,14 @@ config DVB_LGDT3305
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend. to support this frontend.
config DVB_LGDT3306A
tristate "LG Electronics LGDT3306A based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM-B 64/256 demodulator module. Say Y when you want
to support this frontend.
config DVB_LG2160 config DVB_LG2160
tristate "LG Electronics LG216x based" tristate "LG Electronics LG216x based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
......
...@@ -54,6 +54,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o ...@@ -54,6 +54,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
obj-$(CONFIG_DVB_LG2160) += lg2160.o obj-$(CONFIG_DVB_LG2160) += lg2160.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
......
...@@ -27,7 +27,7 @@ struct a8293_config { ...@@ -27,7 +27,7 @@ struct a8293_config {
u8 i2c_addr; u8 i2c_addr;
}; };
#if IS_ENABLED(CONFIG_DVB_A8293) #if IS_REACHABLE(CONFIG_DVB_A8293)
extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg); struct i2c_adapter *i2c, const struct a8293_config *cfg);
#else #else
......
...@@ -103,7 +103,7 @@ struct af9013_config { ...@@ -103,7 +103,7 @@ struct af9013_config {
u8 gpio[4]; u8 gpio[4];
}; };
#if IS_ENABLED(CONFIG_DVB_AF9013) #if IS_REACHABLE(CONFIG_DVB_AF9013)
extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
struct i2c_adapter *i2c); struct i2c_adapter *i2c);
#else #else
......
...@@ -61,7 +61,7 @@ struct atbm8830_config { ...@@ -61,7 +61,7 @@ struct atbm8830_config {
u8 agc_hold_loop; u8 agc_hold_loop;
}; };
#if IS_ENABLED(CONFIG_DVB_ATBM8830) #if IS_REACHABLE(CONFIG_DVB_ATBM8830)
extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
struct i2c_adapter *i2c); struct i2c_adapter *i2c);
#else #else
......
...@@ -61,7 +61,7 @@ struct au8522_config { ...@@ -61,7 +61,7 @@ struct au8522_config {
enum au8522_if_freq qam_if; enum au8522_if_freq qam_if;
}; };
#if IS_ENABLED(CONFIG_DVB_AU8522_DTV) #if IS_REACHABLE(CONFIG_DVB_AU8522_DTV)
extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
struct i2c_adapter *i2c); struct i2c_adapter *i2c);
#else #else
......
...@@ -34,7 +34,7 @@ struct bcm3510_config ...@@ -34,7 +34,7 @@ struct bcm3510_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
}; };
#if IS_ENABLED(CONFIG_DVB_BCM3510) #if IS_REACHABLE(CONFIG_DVB_BCM3510)
extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else #else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment