Merge branch 'devel-for-v3.10' into v4l_for_linus

* patchwork: (831 commits)
  [media] cx88: make core less verbose
  [media] em28xx: fix oops at em28xx_dvb_bus_ctrl()
  [media] s5c73m3: fix indentation of the help section in Kconfig
  [media] cx25821-alsa: get rid of a __must_check warning
  [media] cx25821-video: declare cx25821_vidioc_s_std as static
  [media] cx25821-video: remove maxw from cx25821_vidioc_try_fmt_vid_cap
  [media] r820t: Remove a warning for an unused value
  [media] dib0090: Fix a warning at dib0090_set_EFUSE
  [media] dib8000: fix a warning
  [media] dib8000: Fix sub-channel range
  [media] dib8000: store dtv_property_cache in a temp var
  [media] dib8000: warning fix: declare internal functions as static
  [media] r820t: quiet gcc warning on n_ring
  [media] r820t: memory leak in release()
  [media] r820t: precendence bug in r820t_xtal_check()
  [media] videodev2.h: Remove the unused old V4L1 buffer types
  [media] anysee: Grammar s/report the/report to/
  [media] anysee: Initialize ret = 0 in anysee_frontend_attach()
  [media] media: videobuf2: fix the length check for mmap
  [media] em28xx: save isoc endpoint number for DVB only if endpoint has alt settings with xMaxPacketSize != 0
  ...

Conflicts:
	drivers/media/pci/cx25821/cx25821-video.c
	drivers/media/platform/Kconfig
This commit is contained in:
Mauro Carvalho Chehab 2013-04-30 09:01:04 -03:00
commit df90e22589
655 changed files with 41159 additions and 28981 deletions

View File

@ -1,6 +1,6 @@
<section id="FE_GET_SET_PROPERTY">
<title><constant>FE_GET_PROPERTY/FE_SET_PROPERTY</constant></title>
<para>This section describes the DVB version 5 extention of the DVB-API, also
<para>This section describes the DVB version 5 extension of the DVB-API, also
called "S2API", as this API were added to provide support for DVB-S2. It was
designed to be able to replace the old frontend API. Yet, the DISEQC and
the capability ioctls weren't implemented yet via the new way.</para>
@ -903,14 +903,12 @@ enum fe_interleaving {
<constant>svalue</constant> is for signed values of the measure (dB measures)
and <constant>uvalue</constant> is for unsigned values (counters, relative scale)</para></listitem>
<listitem><para><constant>scale</constant> - Scale for the value. It can be:</para>
<section id = "fecap-scale-params">
<itemizedlist mark='bullet'>
<itemizedlist mark='bullet' id="fecap-scale-params">
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - The parameter is supported by the frontend, but it was not possible to collect it (could be a transitory or permanent condition)</para></listitem>
<listitem><para><constant>FE_SCALE_DECIBEL</constant> - parameter is a signed value, measured in 1/1000 dB</para></listitem>
<listitem><para><constant>FE_SCALE_RELATIVE</constant> - parameter is a unsigned value, where 0 means 0% and 65535 means 100%.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - parameter is a unsigned value that counts the occurrence of an event, like bit error, block error, or lapsed time.</para></listitem>
</itemizedlist>
</section>
</listitem>
</itemizedlist>
<section id="DTV-STAT-SIGNAL-STRENGTH">
@ -918,9 +916,9 @@ enum fe_interleaving {
<para>Indicates the signal strength level at the analog part of the tuner or of the demod.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_DECIBEL</constant> - signal strength is in 0.0001 dBm units, power measured in miliwatts. This value is generally negative.</listitem>
<listitem><constant>FE_SCALE_RELATIVE</constant> - The frontend provides a 0% to 100% measurement for power (actually, 0 to 65535).</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_DECIBEL</constant> - signal strength is in 0.0001 dBm units, power measured in miliwatts. This value is generally negative.</para></listitem>
<listitem><para><constant>FE_SCALE_RELATIVE</constant> - The frontend provides a 0% to 100% measurement for power (actually, 0 to 65535).</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-CNR">
@ -928,9 +926,9 @@ enum fe_interleaving {
<para>Indicates the Signal to Noise ratio for the main carrier.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_DECIBEL</constant> - Signal/Noise ratio is in 0.0001 dB units.</listitem>
<listitem><constant>FE_SCALE_RELATIVE</constant> - The frontend provides a 0% to 100% measurement for Signal/Noise (actually, 0 to 65535).</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_DECIBEL</constant> - Signal/Noise ratio is in 0.0001 dB units.</para></listitem>
<listitem><para><constant>FE_SCALE_RELATIVE</constant> - The frontend provides a 0% to 100% measurement for Signal/Noise (actually, 0 to 65535).</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-PRE-ERROR-BIT-COUNT">
@ -943,8 +941,8 @@ enum fe_interleaving {
The frontend may reset it when a channel/transponder is tuned.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of error bits counted before the inner coding.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of error bits counted before the inner coding.</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-PRE-TOTAL-BIT-COUNT">
@ -952,14 +950,14 @@ enum fe_interleaving {
<para>Measures the amount of bits received before the inner code block, during the same period as
<link linkend="DTV-STAT-PRE-ERROR-BIT-COUNT"><constant>DTV_STAT_PRE_ERROR_BIT_COUNT</constant></link> measurement was taken.</para>
<para>It should be noticed that this measurement can be smaller than the total amount of bits on the transport stream,
as the frontend may need to manually restart the measurement, loosing some data between each measurement interval.</para>
as the frontend may need to manually restart the measurement, losing some data between each measurement interval.</para>
<para>This measurement is monotonically increased, as the frontend gets more bit count measurements.
The frontend may reset it when a channel/transponder is tuned.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of bits counted while measuring
<link linkend="DTV-STAT-PRE-ERROR-BIT-COUNT"><constant>DTV_STAT_PRE_ERROR_BIT_COUNT</constant></link>.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of bits counted while measuring
<link linkend="DTV-STAT-PRE-ERROR-BIT-COUNT"><constant>DTV_STAT_PRE_ERROR_BIT_COUNT</constant></link>.</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-POST-ERROR-BIT-COUNT">
@ -972,8 +970,8 @@ enum fe_interleaving {
The frontend may reset it when a channel/transponder is tuned.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of error bits counted after the inner coding.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of error bits counted after the inner coding.</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-POST-TOTAL-BIT-COUNT">
@ -981,14 +979,14 @@ enum fe_interleaving {
<para>Measures the amount of bits received after the inner coding, during the same period as
<link linkend="DTV-STAT-POST-ERROR-BIT-COUNT"><constant>DTV_STAT_POST_ERROR_BIT_COUNT</constant></link> measurement was taken.</para>
<para>It should be noticed that this measurement can be smaller than the total amount of bits on the transport stream,
as the frontend may need to manually restart the measurement, loosing some data between each measurement interval.</para>
as the frontend may need to manually restart the measurement, losing some data between each measurement interval.</para>
<para>This measurement is monotonically increased, as the frontend gets more bit count measurements.
The frontend may reset it when a channel/transponder is tuned.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of bits counted while measuring
<link linkend="DTV-STAT-POST-ERROR-BIT-COUNT"><constant>DTV_STAT_POST_ERROR_BIT_COUNT</constant></link>.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of bits counted while measuring
<link linkend="DTV-STAT-POST-ERROR-BIT-COUNT"><constant>DTV_STAT_POST_ERROR_BIT_COUNT</constant></link>.</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-ERROR-BLOCK-COUNT">
@ -998,8 +996,8 @@ enum fe_interleaving {
The frontend may reset it when a channel/transponder is tuned.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of error blocks counted after the outer coding.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of error blocks counted after the outer coding.</para></listitem>
</itemizedlist>
</section>
<section id="DTV-STAT-TOTAL-BLOCK-COUNT">
@ -1011,9 +1009,9 @@ enum fe_interleaving {
by <link linkend="DTV-STAT-TOTAL-BLOCK-COUNT"><constant>DTV-STAT-TOTAL-BLOCK-COUNT</constant></link>.</para>
<para>Possible scales for this metric are:</para>
<itemizedlist mark='bullet'>
<listitem><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</listitem>
<listitem><constant>FE_SCALE_COUNTER</constant> - Number of blocks counted while measuring
<link linkend="DTV-STAT-ERROR-BLOCK-COUNT"><constant>DTV_STAT_ERROR_BLOCK_COUNT</constant></link>.</listitem>
<listitem><para><constant>FE_SCALE_NOT_AVAILABLE</constant> - it failed to measure it, or the measurement was not complete yet.</para></listitem>
<listitem><para><constant>FE_SCALE_COUNTER</constant> - Number of blocks counted while measuring
<link linkend="DTV-STAT-ERROR-BLOCK-COUNT"><constant>DTV_STAT_ERROR_BLOCK_COUNT</constant></link>.</para></listitem>
</itemizedlist>
</section>
</section>

View File

@ -749,15 +749,6 @@ polarities, frontporch, backporch etc. The <filename>linux/v4l2-dv-timings.h</fi
header can be used to get the timings of the formats in the <xref linkend="cea861" /> and
<xref linkend="vesadmt" /> standards.
</para>
</listitem>
<listitem>
<para>DV Presets: Digital Video (DV) presets (<emphasis role="bold">deprecated</emphasis>).
These are IDs representing a
video timing at the input/output. Presets are pre-defined timings implemented
by the hardware according to video standards. A __u32 data type is used to represent
a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions
to support as many different presets as needed. This API is deprecated in favor of the DV Timings
API.</para>
</listitem>
</itemizedlist>
<para>To enumerate and query the attributes of the DV timings supported by a device,
@ -766,11 +757,6 @@ API.</para>
&VIDIOC-S-DV-TIMINGS; ioctl and to get current DV timings they use the
&VIDIOC-G-DV-TIMINGS; ioctl. To detect the DV timings as seen by the video receiver applications
use the &VIDIOC-QUERY-DV-TIMINGS; ioctl.</para>
<para>To enumerate and query the attributes of DV presets supported by a device,
applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset,
applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the
&VIDIOC-S-DV-PRESET; ioctl. To detect the preset as seen by the video receiver applications
use the &VIDIOC-QUERY-DV-PRESET; ioctl.</para>
<para>Applications can make use of the <xref linkend="input-capabilities" /> and
<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
video timings for the device.</para>

View File

@ -2310,6 +2310,9 @@ more information.</para>
<listitem>
<para>Added FM Modulator (FM TX) Extended Control Class: <constant>V4L2_CTRL_CLASS_FM_TX</constant> and their Control IDs.</para>
</listitem>
<listitem>
<para>Added FM Receiver (FM RX) Extended Control Class: <constant>V4L2_CTRL_CLASS_FM_RX</constant> and their Control IDs.</para>
</listitem>
<listitem>
<para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
</listitem>
@ -2493,6 +2496,23 @@ that used it. It was originally scheduled for removal in 2.6.35.
</orderedlist>
</section>
<section>
<title>V4L2 in Linux 3.10</title>
<orderedlist>
<listitem>
<para>Removed obsolete and unused DV_PRESET ioctls
VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output capability
flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS.
</para>
</listitem>
<listitem>
<para>Added new debugging ioctl &VIDIOC-DBG-G-CHIP-INFO;.
</para>
</listitem>
</orderedlist>
</section>
<section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title>
@ -2625,8 +2645,8 @@ interfaces and should not be implemented in new drivers.</para>
<xref linkend="extended-controls" />.</para>
</listitem>
<listitem>
<para>&VIDIOC-G-DV-PRESET;, &VIDIOC-S-DV-PRESET;, &VIDIOC-ENUM-DV-PRESETS; and
&VIDIOC-QUERY-DV-PRESET; ioctls. Use the DV Timings API (<xref linkend="dv-timings" />).</para>
<para>VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET, VIDIOC_ENUM_DV_PRESETS and
VIDIOC_QUERY_DV_PRESET ioctls. Use the DV Timings API (<xref linkend="dv-timings" />).</para>
</listitem>
<listitem>
<para><constant>VIDIOC_SUBDEV_G_CROP</constant> and

View File

@ -2299,6 +2299,12 @@ Possible values are:</entry>
</entrytbl>
</row>
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER</constant>&nbsp;</entry>
<entry>boolean</entry>
</row><row><entry spanname="descr">Repeat the video sequence headers. Repeating these
headers makes random access to the video stream easier. Applicable to the MPEG1, 2 and 4 encoder.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER</constant>&nbsp;</entry>
<entry>boolean</entry>
@ -3136,6 +3142,13 @@ giving priority to the center of the metered area.</entry>
<entry><constant>V4L2_EXPOSURE_METERING_SPOT</constant>&nbsp;</entry>
<entry>Measure only very small area at the center of the frame.</entry>
</row>
<row>
<entry><constant>V4L2_EXPOSURE_METERING_MATRIX</constant>&nbsp;</entry>
<entry>A multi-zone metering. The light intensity is measured
in several points of the frame and the the results are combined. The
algorithm of the zones selection and their significance in calculating the
final value is device dependant.</entry>
</row>
</tbody>
</entrytbl>
</row>
@ -3848,7 +3861,7 @@ in Hz. The range and step are driver-specific.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TUNE_PREEMPHASIS</constant>&nbsp;</entry>
<entry>integer</entry>
<entry>enum v4l2_preemphasis</entry>
</row>
<row id="v4l2-preemphasis"><entry spanname="descr">Configures the pre-emphasis value for broadcasting.
A pre-emphasis filter is applied to the broadcast to accentuate the high audio frequencies.
@ -4687,4 +4700,76 @@ interface and may change in the future.</para>
</table>
</section>
<section id="fm-rx-controls">
<title>FM Receiver Control Reference</title>
<para>The FM Receiver (FM_RX) class includes controls for common features of
FM Reception capable devices.</para>
<table pgwide="1" frame="none" id="fm-rx-control-id">
<title>FM_RX Control IDs</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="6*" />
<colspec colname="c3" colwidth="2*" />
<colspec colname="c4" colwidth="6*" />
<spanspec namest="c1" nameend="c2" spanname="id" />
<spanspec namest="c2" nameend="c4" spanname="descr" />
<thead>
<row>
<entry spanname="id" align="left">ID</entry>
<entry align="left">Type</entry>
</row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
</row>
</thead>
<tbody valign="top">
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_FM_RX_CLASS</constant>&nbsp;</entry>
<entry>class</entry>
</row><row><entry spanname="descr">The FM_RX class
descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
description of this control class.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RECEPTION</constant>&nbsp;</entry>
<entry>boolean</entry>
</row><row><entry spanname="descr">Enables/disables RDS
reception by the radio tuner</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TUNE_DEEMPHASIS</constant>&nbsp;</entry>
<entry>enum v4l2_deemphasis</entry>
</row>
<row id="v4l2-deemphasis"><entry spanname="descr">Configures the de-emphasis value for reception.
A de-emphasis filter is applied to the broadcast to accentuate the high audio frequencies.
Depending on the region, a time constant of either 50 or 75 useconds is used. The enum&nbsp;v4l2_deemphasis
defines possible values for de-emphasis. Here they are:</entry>
</row><row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_DEEMPHASIS_DISABLED</constant>&nbsp;</entry>
<entry>No de-emphasis is applied.</entry>
</row>
<row>
<entry><constant>V4L2_DEEMPHASIS_50_uS</constant>&nbsp;</entry>
<entry>A de-emphasis of 50 uS is used.</entry>
</row>
<row>
<entry><constant>V4L2_DEEMPHASIS_75_uS</constant>&nbsp;</entry>
<entry>A de-emphasis of 75 uS is used.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row><entry></entry></row>
</tbody>
</tgroup>
</table>
</section>
</section>

View File

@ -1145,6 +1145,12 @@ in which case caches have not been used.</entry>
same clock outside V4L2, use
<function>clock_gettime(2)</function> .</entry>
</row>
<row>
<entry><constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant></entry>
<entry>0x4000</entry>
<entry>The CAPTURE buffer timestamp has been taken from the
corresponding OUTPUT buffer. This flag applies only to mem2mem devices.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -272,6 +272,16 @@
<entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
<entry>Lens controller</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry>
<entry>Video decoder, the basic function of the video decoder is to
accept analogue video from a wide variety of sources such as
broadcast, DVD players, cameras and video cassette recorders, in
either NTSC, PAL or HD format and still occasionally SECAM, separate
it into its component parts, luminance and chrominance, and output
it in some digital video standard, with appropriate embedded timing
signals.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -93,19 +93,35 @@
<table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb">
<title>RGB formats</title>
<tgroup cols="11">
<tgroup cols="27">
<colspec colname="id" align="left" />
<colspec colname="code" align="center"/>
<colspec colname="bit" />
<colspec colnum="4" colname="b07" align="center" />
<colspec colnum="5" colname="b06" align="center" />
<colspec colnum="6" colname="b05" align="center" />
<colspec colnum="7" colname="b04" align="center" />
<colspec colnum="8" colname="b03" align="center" />
<colspec colnum="9" colname="b02" align="center" />
<colspec colnum="10" colname="b01" align="center" />
<colspec colnum="11" colname="b00" align="center" />
<spanspec namest="b07" nameend="b00" spanname="b0" />
<colspec colnum="4" colname="b23" align="center" />
<colspec colnum="5" colname="b22" align="center" />
<colspec colnum="6" colname="b21" align="center" />
<colspec colnum="7" colname="b20" align="center" />
<colspec colnum="8" colname="b19" align="center" />
<colspec colnum="9" colname="b18" align="center" />
<colspec colnum="10" colname="b17" align="center" />
<colspec colnum="11" colname="b16" align="center" />
<colspec colnum="12" colname="b15" align="center" />
<colspec colnum="13" colname="b14" align="center" />
<colspec colnum="14" colname="b13" align="center" />
<colspec colnum="15" colname="b12" align="center" />
<colspec colnum="16" colname="b11" align="center" />
<colspec colnum="17" colname="b10" align="center" />
<colspec colnum="18" colname="b09" align="center" />
<colspec colnum="19" colname="b08" align="center" />
<colspec colnum="20" colname="b07" align="center" />
<colspec colnum="21" colname="b06" align="center" />
<colspec colnum="22" colname="b05" align="center" />
<colspec colnum="23" colname="b04" align="center" />
<colspec colnum="24" colname="b03" align="center" />
<colspec colnum="25" colname="b02" align="center" />
<colspec colnum="26" colname="b01" align="center" />
<colspec colnum="27" colname="b00" align="center" />
<spanspec namest="b23" nameend="b00" spanname="b0" />
<thead>
<row>
<entry>Identifier</entry>
@ -117,6 +133,22 @@
<entry></entry>
<entry></entry>
<entry>Bit</entry>
<entry>23</entry>
<entry>22</entry>
<entry>21</entry>
<entry>20</entry>
<entry>19</entry>
<entry>18</entry>
<entry>17</entry>
<entry>16</entry>
<entry>15</entry>
<entry>14</entry>
<entry>13</entry>
<entry>12</entry>
<entry>11</entry>
<entry>10</entry>
<entry>9</entry>
<entry>8</entry>
<entry>7</entry>
<entry>6</entry>
<entry>5</entry>
@ -132,6 +164,7 @@
<entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry>
<entry>0x1001</entry>
<entry></entry>
&dash-ent-16;
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
@ -145,6 +178,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
@ -158,6 +192,7 @@
<entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry>
<entry>0x1002</entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
@ -171,6 +206,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
@ -184,6 +220,7 @@
<entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry>
<entry>0x1003</entry>
<entry></entry>
&dash-ent-16;
<entry>0</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
@ -197,6 +234,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -210,6 +248,7 @@
<entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry>
<entry>0x1004</entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -223,6 +262,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>0</entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
@ -236,6 +276,7 @@
<entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry>
<entry>0x1005</entry>
<entry></entry>
&dash-ent-16;
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
@ -249,6 +290,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -262,6 +304,7 @@
<entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry>
<entry>0x1006</entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -275,6 +318,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
@ -288,6 +332,7 @@
<entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry>
<entry>0x1007</entry>
<entry></entry>
&dash-ent-16;
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
@ -301,6 +346,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -314,6 +360,7 @@
<entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry>
<entry>0x1008</entry>
<entry></entry>
&dash-ent-16;
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
@ -327,6 +374,7 @@
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-16;
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
@ -336,6 +384,144 @@
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-RGB666-1X18">
<entry>V4L2_MBUS_FMT_RGB666_1X18</entry>
<entry>0x1009</entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-RGB888-1X24">
<entry>V4L2_MBUS_FMT_RGB888_1X24</entry>
<entry>0x100a</entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-RGB888-2X12-BE">
<entry>V4L2_MBUS_FMT_RGB888_2X12_BE</entry>
<entry>0x100b</entry>
<entry></entry>
&dash-ent-10;
<entry>-</entry>
<entry>-</entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-10;
<entry>-</entry>
<entry>-</entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-MBUS-FMT-RGB888-2X12-LE">
<entry>V4L2_MBUS_FMT_RGB888_2X12_LE</entry>
<entry>0x100c</entry>
<entry></entry>
&dash-ent-10;
<entry>-</entry>
<entry>-</entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
&dash-ent-10;
<entry>-</entry>
<entry>-</entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -124,6 +124,7 @@ Remote Controller chapter.</contrib>
<year>2010</year>
<year>2011</year>
<year>2012</year>
<year>2013</year>
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
Pawel Osciak</holder>
@ -139,13 +140,23 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.xml), along with the possible impact on existing drivers and
applications. -->
<revision>
<revnumber>3.10</revnumber>
<date>2013-03-25</date>
<authorinitials>hv</authorinitials>
<revremark>Remove obsolete and unused DV_PRESET ioctls:
VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output capability
flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS. Added VIDIOC_DBG_G_CHIP_INFO.
</revremark>
</revision>
<revision>
<revnumber>3.9</revnumber>
<date>2012-12-03</date>
<authorinitials>sa, sn</authorinitials>
<revremark>Added timestamp types to v4l2_buffer.
Added <constant>V4L2_EVENT_CTRL_CH_RANGE</constant> control
event changes flag, see <xref linkend="changes-flags"/>.
Added V4L2_EVENT_CTRL_CH_RANGE control event changes flag.
</revremark>
</revision>
@ -537,6 +548,7 @@ and discussions on the V4L mailing list.</revremark>
&sub-create-bufs;
&sub-cropcap;
&sub-dbg-g-chip-ident;
&sub-dbg-g-chip-info;
&sub-dbg-g-register;
&sub-decoder-cmd;
&sub-dqevent;
@ -544,7 +556,6 @@ and discussions on the V4L mailing list.</revremark>
&sub-encoder-cmd;
&sub-enumaudio;
&sub-enumaudioout;
&sub-enum-dv-presets;
&sub-enum-dv-timings;
&sub-enum-fmt;
&sub-enum-framesizes;
@ -558,7 +569,6 @@ and discussions on the V4L mailing list.</revremark>
&sub-g-audioout;
&sub-g-crop;
&sub-g-ctrl;
&sub-g-dv-preset;
&sub-g-dv-timings;
&sub-g-enc-index;
&sub-g-ext-ctrls;
@ -582,7 +592,6 @@ and discussions on the V4L mailing list.</revremark>
&sub-querybuf;
&sub-querycap;
&sub-queryctrl;
&sub-query-dv-preset;
&sub-query-dv-timings;
&sub-querystd;
&sub-reqbufs;

View File

@ -200,10 +200,10 @@ the values from <xref linkend="chip-ids" />.</entry>
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
<entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
<entry>0</entry>
<entry>Match the nth chip on the card, zero for the
host chip. Does not match &i2c; chips.</entry>
bridge chip. Does not match sub-devices.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
@ -220,6 +220,11 @@ the values from <xref linkend="chip-ids" />.</entry>
<entry>3</entry>
<entry>Match the nth anciliary AC97 chip.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
<entry>4</entry>
<entry>Match the nth sub-device. Can't be used with this ioctl.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -0,0 +1,223 @@
<refentry id="vidioc-dbg-g-chip-info">
<refmeta>
<refentrytitle>ioctl VIDIOC_DBG_G_CHIP_INFO</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_DBG_G_CHIP_INFO</refname>
<refpurpose>Identify the chips on a TV card</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_dbg_chip_info
*<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_DBG_G_CHIP_INFO</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<note>
<title>Experimental</title>
<para>This is an <link
linkend="experimental">experimental</link> interface and may change in
the future.</para>
</note>
<para>For driver debugging purposes this ioctl allows test
applications to query the driver about the chips present on the TV
card. Regular applications must not use it. When you found a chip
specific bug, please contact the linux-media mailing list (&v4l-ml;)
so it can be fixed.</para>
<para>Additionally the Linux kernel must be compiled with the
<constant>CONFIG_VIDEO_ADV_DEBUG</constant> option to enable this ioctl.</para>
<para>To query the driver applications must initialize the
<structfield>match.type</structfield> and
<structfield>match.addr</structfield> or <structfield>match.name</structfield>
fields of a &v4l2-dbg-chip-info;
and call <constant>VIDIOC_DBG_G_CHIP_INFO</constant> with a pointer to
this structure. On success the driver stores information about the
selected chip in the <structfield>name</structfield> and
<structfield>flags</structfield> fields. On failure the structure
remains unchanged.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
<structfield>match.addr</structfield> selects the nth bridge 'chip'
on the TV card. You can enumerate all chips by starting at zero and
incrementing <structfield>match.addr</structfield> by one until
<constant>VIDIOC_DBG_G_CHIP_INFO</constant> fails with an &EINVAL;.
The number zero always selects the bridge chip itself, &eg; the chip
connected to the PCI or USB bus. Non-zero numbers identify specific
parts of the bridge chip such as an AC97 register block.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_SUBDEV</constant>,
<structfield>match.addr</structfield> selects the nth sub-device. This
allows you to enumerate over all sub-devices.</para>
<para>On success, the <structfield>name</structfield> field will
contain a chip name and the <structfield>flags</structfield> field will
contain <constant>V4L2_CHIP_FL_READABLE</constant> if the driver supports
reading registers from the device or <constant>V4L2_CHIP_FL_WRITABLE</constant>
if the driver supports writing registers to the device.</para>
<para>We recommended the <application>v4l2-dbg</application>
utility over calling this ioctl directly. It is available from the
LinuxTV v4l-dvb repository; see <ulink
url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
access instructions.</para>
<!-- Note for convenience vidioc-dbg-g-register.sgml
contains a duplicate of this table. -->
<table pgwide="1" frame="none" id="name-v4l2-dbg-match">
<title>struct <structname>v4l2_dbg_match</structname></title>
<tgroup cols="4">
&cs-ustr;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>type</structfield></entry>
<entry>See <xref linkend="name-chip-match-types" /> for a list of
possible types.</entry>
</row>
<row>
<entry>union</entry>
<entry>(anonymous)</entry>
</row>
<row>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>addr</structfield></entry>
<entry>Match a chip by this number, interpreted according
to the <structfield>type</structfield> field.</entry>
</row>
<row>
<entry></entry>
<entry>char</entry>
<entry><structfield>name[32]</structfield></entry>
<entry>Match a chip by this name, interpreted according
to the <structfield>type</structfield> field.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-dbg-chip-info">
<title>struct <structname>v4l2_dbg_chip_info</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>struct v4l2_dbg_match</entry>
<entry><structfield>match</structfield></entry>
<entry>How to match the chip, see <xref linkend="name-v4l2-dbg-match" />.</entry>
</row>
<row>
<entry>char</entry>
<entry><structfield>name[32]</structfield></entry>
<entry>The name of the chip.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Set by the driver. If <constant>V4L2_CHIP_FL_READABLE</constant>
is set, then the driver supports reading registers from the device. If
<constant>V4L2_CHIP_FL_WRITABLE</constant> is set, then it supports writing registers.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved[8]</structfield></entry>
<entry>Reserved fields, both application and driver must set these to 0.</entry>
</row>
</tbody>
</tgroup>
</table>
<!-- Note for convenience vidioc-dbg-g-register.sgml
contains a duplicate of this table. -->
<table pgwide="1" frame="none" id="name-chip-match-types">
<title>Chip Match Types</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
<entry>0</entry>
<entry>Match the nth chip on the card, zero for the
bridge chip. Does not match sub-devices.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
<entry>1</entry>
<entry>Match an &i2c; chip by its driver name. Can't be used with this ioctl.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
<entry>2</entry>
<entry>Match a chip by its 7 bit &i2c; bus address. Can't be used with this ioctl.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
<entry>3</entry>
<entry>Match the nth anciliary AC97 chip. Can't be used with this ioctl.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
<entry>4</entry>
<entry>Match the nth sub-device.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The <structfield>match_type</structfield> is invalid or
no device could be matched.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>

View File

@ -87,7 +87,7 @@ written into the register.</para>
<para>To read a register applications must initialize the
<structfield>match.type</structfield>,
<structfield>match.chip</structfield> or <structfield>match.name</structfield> and
<structfield>match.addr</structfield> or <structfield>match.name</structfield> and
<structfield>reg</structfield> fields, and call
<constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
structure. On success the driver stores the register value in the
@ -95,11 +95,11 @@ structure. On success the driver stores the register value in the
unchanged.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_HOST</constant>,
<structfield>match.addr</structfield> selects the nth non-&i2c; chip
<constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
<structfield>match.addr</structfield> selects the nth non-sub-device chip
on the TV card. The number zero always selects the host chip, &eg; the
chip connected to the PCI or USB bus. You can find out which chips are
present with the &VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
present with the &VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
@ -109,7 +109,7 @@ For instance
supported by the saa7127 driver, regardless of its &i2c; bus address.
When multiple chips supported by the same driver are present, the
effect of these ioctls is undefined. Again with the
&VIDIOC-DBG-G-CHIP-IDENT; ioctl you can find out which &i2c; chips are
&VIDIOC-DBG-G-CHIP-INFO; ioctl you can find out which &i2c; chips are
present.</para>
<para>When <structfield>match.type</structfield> is
@ -122,19 +122,23 @@ bus address.</para>
<structfield>match.addr</structfield> selects the nth AC97 chip
on the TV card.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_SUBDEV</constant>,
<structfield>match.addr</structfield> selects the nth sub-device.</para>
<note>
<title>Success not guaranteed</title>
<para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
return successfully without actually reading or writing a register. To
catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-IDENT;
catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-INFO;
call confirming the presence of the selected &i2c; chip.</para>
</note>
<para>These ioctls are optional, not all drivers may support them.
However when a driver supports these ioctls it must also support
&VIDIOC-DBG-G-CHIP-IDENT;. Conversely it may support
<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> but not these ioctls.</para>
&VIDIOC-DBG-G-CHIP-INFO;. Conversely it may support
<constant>VIDIOC_DBG_G_CHIP_INFO</constant> but not these ioctls.</para>
<para><constant>VIDIOC_DBG_G_REGISTER</constant> and
<constant>VIDIOC_DBG_S_REGISTER</constant> were introduced in Linux
@ -217,10 +221,10 @@ register.</entry>
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
<entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
<entry>0</entry>
<entry>Match the nth chip on the card, zero for the
host chip. Does not match &i2c; chips.</entry>
bridge chip. Does not match sub-devices.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
@ -237,6 +241,11 @@ register.</entry>
<entry>3</entry>
<entry>Match the nth anciliary AC97 chip.</entry>
</row>
<row>
<entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
<entry>4</entry>
<entry>Match the nth sub-device.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -1,240 +0,0 @@
<refentry id="vidioc-enum-dv-presets">
<refmeta>
<refentrytitle>ioctl VIDIOC_ENUM_DV_PRESETS</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_ENUM_DV_PRESETS</refname>
<refpurpose>Enumerate supported Digital Video presets</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_dv_enum_preset *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_ENUM_DV_PRESETS</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>This ioctl is <emphasis role="bold">deprecated</emphasis>.
New drivers and applications should use &VIDIOC-ENUM-DV-TIMINGS; instead.
</para>
<para>To query the attributes of a DV preset, applications initialize the
<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset;
and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this
structure. Drivers fill the rest of the structure or return an
&EINVAL; when the index is out of bounds. To enumerate all DV Presets supported,
applications shall begin at index zero, incrementing by one until the
driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
different set of DV presets after switching the video input or
output.</para>
<table pgwide="1" frame="none" id="v4l2-dv-enum-preset">
<title>struct <structname>v4l2_dv_enum_presets</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>index</structfield></entry>
<entry>Number of the DV preset, set by the
application.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>preset</structfield></entry>
<entry>This field identifies one of the DV preset values listed in <xref linkend="v4l2-dv-presets-vals"/>.</entry>
</row>
<row>
<entry>__u8</entry>
<entry><structfield>name</structfield>[24]</entry>
<entry>Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is
intended for the user.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>width</structfield></entry>
<entry>Width of the active video in pixels for the DV preset.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>height</structfield></entry>
<entry>Height of the active video in lines for the DV preset.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[4]</entry>
<entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-dv-presets-vals">
<title>struct <structname>DV Presets</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>Preset</entry>
<entry>Preset value</entry>
<entry>Description</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry></entry>
</row>
<row>
<entry>V4L2_DV_INVALID</entry>
<entry>0</entry>
<entry>Invalid preset value.</entry>
</row>
<row>
<entry>V4L2_DV_480P59_94</entry>
<entry>1</entry>
<entry>720x480 progressive video at 59.94 fps as per BT.1362.</entry>
</row>
<row>
<entry>V4L2_DV_576P50</entry>
<entry>2</entry>
<entry>720x576 progressive video at 50 fps as per BT.1362.</entry>
</row>
<row>
<entry>V4L2_DV_720P24</entry>
<entry>3</entry>
<entry>1280x720 progressive video at 24 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_720P25</entry>
<entry>4</entry>
<entry>1280x720 progressive video at 25 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_720P30</entry>
<entry>5</entry>
<entry>1280x720 progressive video at 30 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_720P50</entry>
<entry>6</entry>
<entry>1280x720 progressive video at 50 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_720P59_94</entry>
<entry>7</entry>
<entry>1280x720 progressive video at 59.94 fps as per SMPTE 274M.</entry>
</row>
<row>
<entry>V4L2_DV_720P60</entry>
<entry>8</entry>
<entry>1280x720 progressive video at 60 fps as per SMPTE 274M/296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080I29_97</entry>
<entry>9</entry>
<entry>1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.</entry>
</row>
<row>
<entry>V4L2_DV_1080I30</entry>
<entry>10</entry>
<entry>1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.</entry>
</row>
<row>
<entry>V4L2_DV_1080I25</entry>
<entry>11</entry>
<entry>1920x1080 interlaced video at 25 fps as per BT.1120.</entry>
</row>
<row>
<entry>V4L2_DV_1080I50</entry>
<entry>12</entry>
<entry>1920x1080 interlaced video at 50 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080I60</entry>
<entry>13</entry>
<entry>1920x1080 interlaced video at 60 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080P24</entry>
<entry>14</entry>
<entry>1920x1080 progressive video at 24 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080P25</entry>
<entry>15</entry>
<entry>1920x1080 progressive video at 25 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080P30</entry>
<entry>16</entry>
<entry>1920x1080 progressive video at 30 fps as per SMPTE 296M.</entry>
</row>
<row>
<entry>V4L2_DV_1080P50</entry>
<entry>17</entry>
<entry>1920x1080 progressive video at 50 fps as per BT.1120.</entry>
</row>
<row>
<entry>V4L2_DV_1080P60</entry>
<entry>18</entry>
<entry>1920x1080 progressive video at 60 fps as per BT.1120.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-dv-enum-preset; <structfield>index</structfield>
is out of bounds.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>ENODATA</errorcode></term>
<listitem>
<para>Digital video presets are not supported for this input or output.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>

View File

@ -277,11 +277,6 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_IN_CAP_PRESETS</constant></entry>
<entry>0x00000001</entry>
<entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
</row>
<row>
<entry><constant>V4L2_IN_CAP_DV_TIMINGS</constant></entry>
<entry>0x00000002</entry>

View File

@ -162,11 +162,6 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_OUT_CAP_PRESETS</constant></entry>
<entry>0x00000001</entry>
<entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
</row>
<row>
<entry><constant>V4L2_OUT_CAP_DV_TIMINGS</constant></entry>
<entry>0x00000002</entry>

View File

@ -1,113 +0,0 @@
<refentry id="vidioc-g-dv-preset">
<refmeta>
<refentrytitle>ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_G_DV_PRESET</refname>
<refname>VIDIOC_S_DV_PRESET</refname>
<refpurpose>Query or select the DV preset of the current input or output</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>These ioctls are <emphasis role="bold">deprecated</emphasis>.
New drivers and applications should use &VIDIOC-G-DV-TIMINGS; and &VIDIOC-S-DV-TIMINGS;
instead.
</para>
<para>To query and select the current DV preset, applications
use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant>
ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
Applications must zero the reserved array in &v4l2-dv-preset;.
<constant>VIDIOC_G_DV_PRESET</constant> returns a dv preset in the field
<structfield>preset</structfield> of &v4l2-dv-preset;.</para>
<para><constant>VIDIOC_S_DV_PRESET</constant> accepts a pointer to a &v4l2-dv-preset;
that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;.
If the preset is not supported, it returns an &EINVAL; </para>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>This ioctl is not supported, or the
<constant>VIDIOC_S_DV_PRESET</constant>,<constant>VIDIOC_S_DV_PRESET</constant> parameter was unsuitable.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>ENODATA</errorcode></term>
<listitem>
<para>Digital video presets are not supported for this input or output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>The device is busy and therefore can not change the preset.</para>
</listitem>
</varlistentry>
</variablelist>
<table pgwide="1" frame="none" id="v4l2-dv-preset">
<title>struct <structname>v4l2_dv_preset</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>preset</structfield></entry>
<entry>Preset value to represent the digital video timings</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved[4]</structfield></entry>
<entry>Reserved fields for future use</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
</refentry>

View File

@ -319,6 +319,15 @@ These controls are described in <xref
processing controls. These controls are described in <xref
linkend="image-process-controls" />.</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_CLASS_FM_RX</constant></entry>
<entry>0xa10000</entry>
<entry>The class containing FM Receiver (FM RX) controls.
These controls are described in <xref
linkend="fm-rx-controls" />.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -1,78 +0,0 @@
<refentry id="vidioc-query-dv-preset">
<refmeta>
<refentrytitle>ioctl VIDIOC_QUERY_DV_PRESET</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_QUERY_DV_PRESET</refname>
<refpurpose>Sense the DV preset received by the current
input</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_dv_preset *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_QUERY_DV_PRESET</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>This ioctl is <emphasis role="bold">deprecated</emphasis>.
New drivers and applications should use &VIDIOC-QUERY-DV-TIMINGS; instead.
</para>
<para>The hardware may be able to detect the current DV preset
automatically, similar to sensing the video standard. To do so, applications
call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
returned in the preset field of &v4l2-dv-preset;. If the preset could not be
detected because there was no signal, or the signal was unreliable, or the
signal did not map to a supported preset, then the value V4L2_DV_INVALID is
returned.</para>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>ENODATA</errorcode></term>
<listitem>
<para>Digital video presets are not supported for this input or output.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>

View File

@ -23,6 +23,7 @@
<!-- LinuxTV v4l-dvb repository. -->
<!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
<!ENTITY dash-ent-10 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
<!ENTITY dash-ent-16 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>">
]>
<book id="media_api">

View File

@ -0,0 +1,14 @@
Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE)
Required properties:
- compatible : should be "samsung,exynos4212-fimc" for Exynos4212 and
Exynos4412 SoCs;
- reg : physical base address and size of the device memory mapped
registers;
- interrupts : should contain FIMC-LITE interrupt;
- clocks : FIMC LITE gate clock should be specified in this property.
- clock-names : should contain "flite" entry.
Each FIMC device should have an alias in the aliases node, in the form of
fimc-lite<n>, where <n> is an integer specifying the IP block instance.

View File

@ -0,0 +1,49 @@
Exynos4x12 SoC series Imaging Subsystem (FIMC-IS)
The FIMC-IS is a subsystem for processing image signal from an image sensor.
The Exynos4x12 SoC series FIMC-IS V1.5 comprises of a dedicated ARM Cortex-A5
processor, ISP, DRC and FD IP blocks and peripheral devices such as UART, I2C
and SPI bus controllers, PWM and ADC.
fimc-is node
------------
Required properties:
- compatible : should be "samsung,exynos4212-fimc-is" for Exynos4212 and
Exynos4412 SoCs;
- reg : physical base address and length of the registers set;
- interrupts : must contain two FIMC-IS interrupts, in order: ISP0, ISP1;
- clocks : list of clock specifiers, corresponding to entries in
clock-names property;
- clock-names : must contain "ppmuispx", "ppmuispx", "lite0", "lite1"
"mpll", "sysreg", "isp", "drc", "fd", "mcuisp", "uart",
"ispdiv0", "ispdiv1", "mcuispdiv0", "mcuispdiv1", "aclk200",
"div_aclk200", "aclk400mcuisp", "div_aclk400mcuisp" entries,
matching entries in the clocks property.
pmu subnode
-----------
Required properties:
- reg : must contain PMU physical base address and size of the register set.
The following are the FIMC-IS peripheral device nodes and can be specified
either standalone or as the fimc-is node child nodes.
i2c-isp (ISP I2C bus controller) nodes
------------------------------------------
Required properties:
- compatible : should be "samsung,exynos4212-i2c-isp" for Exynos4212 and
Exynos4412 SoCs;
- reg : physical base address and length of the registers set;
- clocks : must contain gate clock specifier for this controller;
- clock-names : must contain "i2c_isp" entry.
For the above nodes it is required to specify a pinctrl state named "default",
according to the pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt.
Device tree nodes of the image sensors' controlled directly by the FIMC-IS
firmware must be child nodes of their corresponding ISP I2C bus controller node.
The data link of these image sensors must be specified using the common video
interfaces bindings, defined in video-interfaces.txt.

View File

@ -0,0 +1,197 @@
Samsung S5P/EXYNOS SoC Camera Subsystem (FIMC)
----------------------------------------------
The S5P/Exynos SoC Camera subsystem comprises of multiple sub-devices
represented by separate device tree nodes. Currently this includes: FIMC (in
the S5P SoCs series known as CAMIF), MIPI CSIS, FIMC-LITE and FIMC-IS (ISP).
The sub-subdevices are defined as child nodes of the common 'camera' node which
also includes common properties of the whole subsystem not really specific to
any single sub-device, like common camera port pins or the CAMCLK clock outputs
for external image sensors attached to an SoC.
Common 'camera' node
--------------------
Required properties:
- compatible : must be "samsung,fimc", "simple-bus"
- clocks : list of clock specifiers, corresponding to entries in
the clock-names property;
- clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0",
"pxl_async1" entries, matching entries in the clocks property.
The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used
to define a required pinctrl state named "default" and optional pinctrl states:
"idle", "active-a", active-b". These optional states can be used to switch the
camera port pinmux at runtime. The "idle" state should configure both the camera
ports A and B into high impedance state, especially the CAMCLK clock output
should be inactive. For the "active-a" state the camera port A must be activated
and the port B deactivated and for the state "active-b" it should be the other
way around.
The 'camera' node must include at least one 'fimc' child node.
'fimc' device nodes
-------------------
Required properties:
- compatible: "samsung,s5pv210-fimc" for S5PV210, "samsung,exynos4210-fimc"
for Exynos4210 and "samsung,exynos4212-fimc" for Exynos4x12 SoCs;
- reg: physical base address and length of the registers set for the device;
- interrupts: should contain FIMC interrupt;
- clocks: list of clock specifiers, must contain an entry for each required
entry in clock-names;
- clock-names: must contain "fimc", "sclk_fimc" entries.
- samsung,pix-limits: an array of maximum supported image sizes in pixels, for
details refer to Table 2-1 in the S5PV210 SoC User Manual; The meaning of
each cell is as follows:
0 - scaler input horizontal size,
1 - input horizontal size for the scaler bypassed,
2 - REAL_WIDTH without input rotation,
3 - REAL_HEIGHT with input rotation,
- samsung,sysreg: a phandle to the SYSREG node.
Each FIMC device should have an alias in the aliases node, in the form of
fimc<n>, where <n> is an integer specifying the IP block instance.
Optional properties:
- clock-frequency: maximum FIMC local clock (LCLK) frequency;
- samsung,min-pix-sizes: an array specyfing minimum image size in pixels at
the FIMC input and output DMA, in the first and second cell respectively.
Default value when this property is not present is <16 16>;
- samsung,min-pix-alignment: minimum supported image height alignment (first
cell) and the horizontal image offset (second cell). The values are in pixels
and default to <2 1> when this property is not present;
- samsung,mainscaler-ext: a boolean property indicating whether the FIMC IP
supports extended image size and has CIEXTEN register;
- samsung,rotators: a bitmask specifying whether this IP has the input and
the output rotator. Bits 4 and 0 correspond to input and output rotator
respectively. If a rotator is present its corresponding bit should be set.
Default value when this property is not specified is 0x11.
- samsung,cam-if: a bolean property indicating whether the IP block includes
the camera input interface.
- samsung,isp-wb: this property must be present if the IP block has the ISP
writeback input.
- samsung,lcd-wb: this property must be present if the IP block has the LCD
writeback input.
'parallel-ports' node
---------------------
This node should contain child 'port' nodes specifying active parallel video
input ports. It includes camera A and camera B inputs. 'reg' property in the
port nodes specifies data input - 0, 1 indicates input A, B respectively.
Optional properties
- samsung,camclk-out : specifies clock output for remote sensor,
0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT;
Image sensor nodes
------------------
The sensor device nodes should be added to their control bus controller (e.g.
I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
using the common video interfaces bindings, defined in video-interfaces.txt.
The implementation of this bindings requires clock-frequency property to be
present in the sensor device nodes.
Example:
aliases {
fimc0 = &fimc_0;
};
/* Parallel bus IF sensor */
i2c_0: i2c@13860000 {
s5k6aa: sensor@3c {
compatible = "samsung,s5k6aafx";
reg = <0x3c>;
vddio-supply = <...>;
clock-frequency = <24000000>;
clocks = <...>;
clock-names = "mclk";
port {
s5k6aa_ep: endpoint {
remote-endpoint = <&fimc0_ep>;
bus-width = <8>;
hsync-active = <0>;
vsync-active = <1>;
pclk-sample = <1>;
};
};
};
};
/* MIPI CSI-2 bus IF sensor */
s5c73m3: sensor@0x1a {
compatible = "samsung,s5c73m3";
reg = <0x1a>;
vddio-supply = <...>;
clock-frequency = <24000000>;
clocks = <...>;
clock-names = "mclk";
port {
s5c73m3_1: endpoint {
data-lanes = <1 2 3 4>;
remote-endpoint = <&csis0_ep>;
};
};
};
camera {
compatible = "samsung,fimc", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cam_port_a_clk_active>;
/* parallel camera ports */
parallel-ports {
/* camera A input */
port@0 {
reg = <0>;
fimc0_ep: endpoint {
remote-endpoint = <&s5k6aa_ep>;
bus-width = <8>;
hsync-active = <0>;
vsync-active = <1>;
pclk-sample = <1>;
};
};
};
fimc_0: fimc@11800000 {
compatible = "samsung,exynos4210-fimc";
reg = <0x11800000 0x1000>;
interrupts = <0 85 0>;
status = "okay";
};
csis_0: csis@11880000 {
compatible = "samsung,exynos4210-csis";
reg = <0x11880000 0x1000>;
interrupts = <0 78 0>;
/* camera C input */
port@3 {
reg = <3>;
csis0_ep: endpoint {
remote-endpoint = <&s5c73m3_ep>;
data-lanes = <1 2 3 4>;
samsung,csis-hs-settle = <12>;
};
};
};
};
The MIPI-CSIS device binding is defined in samsung-mipi-csis.txt.

View File

@ -0,0 +1,81 @@
Samsung S5P/EXYNOS SoC series MIPI CSI-2 receiver (MIPI CSIS)
-------------------------------------------------------------
Required properties:
- compatible : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
"samsung,exynos4210-csis" for Exynos4210 (S5PC210),
"samsung,exynos4212-csis" for Exynos4212/Exynos4412
SoC series;
- reg : offset and length of the register set for the device;
- interrupts : should contain MIPI CSIS interrupt; the format of the
interrupt specifier depends on the interrupt controller;
- bus-width : maximum number of data lanes supported (SoC specific);
- vddio-supply : MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V);
- vddcore-supply : MIPI CSIS Core voltage supply (e.g. 1.1V);
- clocks : list of clock specifiers, corresponding to entries in
clock-names property;
- clock-names : must contain "csis", "sclk_csis" entries, matching entries
in the clocks property.
Optional properties:
- clock-frequency : The IP's main (system bus) clock frequency in Hz, default
value when this property is not specified is 166 MHz;
- samsung,csis-wclk : CSI-2 wrapper clock selection. If this property is present
external clock from CMU will be used, or the bus clock if
if it's not specified.
The device node should contain one 'port' child node with one child 'endpoint'
node, according to the bindings defined in Documentation/devicetree/bindings/
media/video-interfaces.txt. The following are properties specific to those nodes.
port node
---------
- reg : (required) must be 3 for camera C input (CSIS0) or 4 for
camera D input (CSIS1);
endpoint node
-------------
- data-lanes : (required) an array specifying active physical MIPI-CSI2
data input lanes and their mapping to logical lanes; the
array's content is unused, only its length is meaningful;
- samsung,csis-hs-settle : (optional) differential receiver (HS-RX) settle time;
Example:
reg0: regulator@0 {
};
reg1: regulator@1 {
};
/* SoC properties */
csis_0: csis@11880000 {
compatible = "samsung,exynos4210-csis";
reg = <0x11880000 0x1000>;
interrupts = <0 78 0>;
#address-cells = <1>;
#size-cells = <0>;
};
/* Board properties */
csis_0: csis@11880000 {
clock-frequency = <166000000>;
vddio-supply = <&reg0>;
vddcore-supply = <&reg1>;
port {
reg = <3>; /* 3 - CSIS0, 4 - CSIS1 */
csis0_ep: endpoint {
remote-endpoint = <...>;
data-lanes = <1>, <2>;
samsung,csis-hs-settle = <12>;
};
};
};

View File

@ -0,0 +1,228 @@
Common bindings for video receiver and transmitter interfaces
General concept
---------------
Video data pipelines usually consist of external devices, e.g. camera sensors,
controlled over an I2C, SPI or UART bus, and SoC internal IP blocks, including
video DMA engines and video data processors.
SoC internal blocks are described by DT nodes, placed similarly to other SoC
blocks. External devices are represented as child nodes of their respective
bus controller nodes, e.g. I2C.
Data interfaces on all video devices are described by their child 'port' nodes.
Configuration of a port depends on other devices participating in the data
transfer and is described by 'endpoint' subnodes.
device {
...
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
...
endpoint@0 { ... };
endpoint@1 { ... };
};
port@1 { ... };
};
};
If a port can be configured to work with more than one remote device on the same
bus, an 'endpoint' child node must be provided for each of them. If more than
one port is present in a device node or there is more than one endpoint at a
port, or port node needs to be associated with a selected hardware interface,
a common scheme using '#address-cells', '#size-cells' and 'reg' properties is
used.
All 'port' nodes can be grouped under optional 'ports' node, which allows to
specify #address-cells, #size-cells properties independently for the 'port'
and 'endpoint' nodes and any child device nodes a device might have.
Two 'endpoint' nodes are linked with each other through their 'remote-endpoint'
phandles. An endpoint subnode of a device contains all properties needed for
configuration of this device for data exchange with other device. In most
cases properties at the peer 'endpoint' nodes will be identical, however they
might need to be different when there is any signal modifications on the bus
between two devices, e.g. there are logic signal inverters on the lines.
It is allowed for multiple endpoints at a port to be active simultaneously,
where supported by a device. For example, in case where a data interface of
a device is partitioned into multiple data busses, e.g. 16-bit input port
divided into two separate ITU-R BT.656 8-bit busses. In such case bus-width
and data-shift properties can be used to assign physical data lines to each
endpoint node (logical bus).
Required properties
-------------------
If there is more than one 'port' or more than one 'endpoint' node or 'reg'
property is present in port and/or endpoint nodes the following properties
are required in a relevant parent node:
- #address-cells : number of cells required to define port/endpoint
identifier, should be 1.
- #size-cells : should be zero.
Optional endpoint properties
----------------------------
- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node.
- slave-mode: a boolean property indicating that the link is run in slave mode.
The default when this property is not specified is master mode. In the slave
mode horizontal and vertical synchronization signals are provided to the
slave device (data source) by the master device (data sink). In the master
mode the data source device is also the source of the synchronization signals.
- bus-width: number of data lines actively used, valid for the parallel busses.
- data-shift: on the parallel data busses, if bus-width is used to specify the
number of data lines, data-shift can be used to specify which data lines are
used, e.g. "bus-width=<8>; data-shift=<2>;" means, that lines 9:2 are used.
- hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively.
- vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively.
Note, that if HSYNC and VSYNC polarities are not specified, embedded
synchronization may be required, where supported.
- data-active: similar to HSYNC and VSYNC, specifies data line polarity.
- field-even-active: field signal level during the even field data transmission.
- pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock
signal.
- data-lanes: an array of physical data lane indexes. Position of an entry
determines the logical lane number, while the value of an entry indicates
physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have
"data-lanes = <1 2>;", assuming the clock lane is on hardware lane 0.
This property is valid for serial busses only (e.g. MIPI CSI-2).
- clock-lanes: an array of physical clock lane indexes. Position of an entry
determines the logical lane number, while the value of an entry indicates
physical lane, e.g. for a MIPI CSI-2 bus we could have "clock-lanes = <0>;",
which places the clock lane on hardware lane 0. This property is valid for
serial busses only (e.g. MIPI CSI-2). Note that for the MIPI CSI-2 bus this
array contains only one entry.
- clock-noncontinuous: a boolean property to allow MIPI CSI-2 non-continuous
clock mode.
Example
-------
The example snippet below describes two data pipelines. ov772x and imx074 are
camera sensors with a parallel and serial (MIPI CSI-2) video bus respectively.
Both sensors are on the I2C control bus corresponding to the i2c0 controller
node. ov772x sensor is linked directly to the ceu0 video host interface.
imx074 is linked to ceu0 through the MIPI CSI-2 receiver (csi2). ceu0 has a
(single) DMA engine writing captured data to memory. ceu0 node has a single
'port' node which may indicate that at any time only one of the following data
pipelines can be active: ov772x -> ceu0 or imx074 -> csi2 -> ceu0.
ceu0: ceu@0xfe910000 {
compatible = "renesas,sh-mobile-ceu";
reg = <0xfe910000 0xa0>;
interrupts = <0x880>;
mclk: master_clock {
compatible = "renesas,ceu-clock";
#clock-cells = <1>;
clock-frequency = <50000000>; /* Max clock frequency */
clock-output-names = "mclk";
};
port {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
ceu0_1: endpoint@1 {
reg = <1>; /* Local endpoint # */
remote = <&ov772x_1_1>; /* Remote phandle */
bus-width = <8>; /* Used data lines */
data-shift = <2>; /* Lines 9:2 are used */
/* If hsync-active/vsync-active are missing,
embedded BT.656 sync is used */
hsync-active = <0>; /* Active low */
vsync-active = <0>; /* Active low */
data-active = <1>; /* Active high */
pclk-sample = <1>; /* Rising */
};
/* MIPI CSI-2 bus endpoint */
ceu0_0: endpoint@0 {
reg = <0>;
remote = <&csi2_2>;
};
};
};
i2c0: i2c@0xfff20000 {
...
ov772x_1: camera@0x21 {
compatible = "omnivision,ov772x";
reg = <0x21>;
vddio-supply = <&regulator1>;
vddcore-supply = <&regulator2>;
clock-frequency = <20000000>;
clocks = <&mclk 0>;
clock-names = "xclk";
port {
/* With 1 endpoint per port no need for addresses. */
ov772x_1_1: endpoint {
bus-width = <8>;
remote-endpoint = <&ceu0_1>;
hsync-active = <1>;
vsync-active = <0>; /* Who came up with an
inverter here ?... */
data-active = <1>;
pclk-sample = <1>;
};
};
};
imx074: camera@0x1a {
compatible = "sony,imx074";
reg = <0x1a>;
vddio-supply = <&regulator1>;
vddcore-supply = <&regulator2>;
clock-frequency = <30000000>; /* Shared clock with ov772x_1 */
clocks = <&mclk 0>;
clock-names = "sysclk"; /* Assuming this is the
name in the datasheet */
port {
imx074_1: endpoint {
clock-lanes = <0>;
data-lanes = <1 2>;
remote-endpoint = <&csi2_1>;
};
};
};
};
csi2: csi2@0xffc90000 {
compatible = "renesas,sh-mobile-csi2";
reg = <0xffc90000 0x1000>;
interrupts = <0x17a0>;
#address-cells = <1>;
#size-cells = <0>;
port@1 {
compatible = "renesas,csi2c"; /* One of CSI2I and CSI2C. */
reg = <1>; /* CSI-2 PHY #1 of 2: PHY_S,
PHY_M has port address 0,
is unused. */
csi2_1: endpoint {
clock-lanes = <0>;
data-lanes = <2 1>;
remote-endpoint = <&imx074_1>;
};
};
port@2 {
reg = <2>; /* port 2: link to the CEU */
csi2_2: endpoint {
remote-endpoint = <&ceu0_0>;
};
};
};

View File

@ -76,7 +76,7 @@
76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340]
77 -> EM2874 Leadership ISDBT (em2874)
78 -> PCTV nanoStick T2 290e (em28174)
79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad]
79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad,0ccd:10b6]
80 -> PCTV DVB-S2 Stick (460e) (em28174)
81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605]
82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2]
@ -85,3 +85,4 @@
85 -> PCTV QuatroStick (510e) (em2884) [2304:0242]
86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251]
87 -> Terratec Cinergy HTC USB XS (em2884) [0ccd:008e,0ccd:00ac]
88 -> C3 Tech Digital Duo HDTV/SDTV USB (em2884) [1b80:e755]

View File

@ -86,3 +86,6 @@ tuner=85 - Philips FQ1236 MK5
tuner=86 - Tena TNF5337 MFD
tuner=87 - Xceive 4000 tuner
tuner=88 - Xceive 5000C tuner
tuner=89 - Sony PAL+SECAM (BTF-PG472Z)
tuner=90 - Sony NTSC-M-JP (BTF-PK467Z)
tuner=91 - Sony NTSC-M (BTF-PB463Z)

View File

@ -0,0 +1,187 @@
SI476x Driver Readme
------------------------------------------------
Copyright (C) 2013 Andrey Smirnov <andrew.smirnov@gmail.com>
TODO for the driver
------------------------------
- According to the SiLabs' datasheet it is possible to update the
firmware of the radio chip in the run-time, thus bringing it to the
most recent version. Unfortunately I couldn't find any mentioning of
the said firmware update for the old chips that I tested the driver
against, so for chips like that the driver only exposes the old
functionality.
Parameters exposed over debugfs
-------------------------------
SI476x allow user to get multiple characteristics that can be very
useful for EoL testing/RF performance estimation, parameters that have
very little to do with V4L2 subsystem. Such parameters are exposed via
debugfs and can be accessed via regular file I/O operations.
The drivers exposes following files:
* /sys/kernel/debug/<device-name>/acf
This file contains ACF(Automatically Controlled Features) status
information. The contents of the file is binary data of the
following layout:
Offset | Name | Description
====================================================================
0x00 | blend_int | Flag, set when stereo separation has
| | crossed below the blend threshold
--------------------------------------------------------------------
0x01 | hblend_int | Flag, set when HiBlend cutoff
| | frequency is lower than threshold
--------------------------------------------------------------------
0x02 | hicut_int | Flag, set when HiCut cutoff
| | frequency is lower than threshold
--------------------------------------------------------------------
0x03 | chbw_int | Flag, set when channel filter
| | bandwidth is less than threshold
--------------------------------------------------------------------
0x04 | softmute_int | Flag indicating that softmute
| | attenuation has increased above
| | softmute threshold
--------------------------------------------------------------------
0x05 | smute | 0 - Audio is not soft muted
| | 1 - Audio is soft muted
--------------------------------------------------------------------
0x06 | smattn | Soft mute attenuation level in dB
--------------------------------------------------------------------
0x07 | chbw | Channel filter bandwidth in kHz
--------------------------------------------------------------------
0x08 | hicut | HiCut cutoff frequency in units of
| | 100Hz
--------------------------------------------------------------------
0x09 | hiblend | HiBlend cutoff frequency in units
| | of 100 Hz
--------------------------------------------------------------------
0x10 | pilot | 0 - Stereo pilot is not present
| | 1 - Stereo pilot is present
--------------------------------------------------------------------
0x11 | stblend | Stereo blend in %
--------------------------------------------------------------------
* /sys/kernel/debug/<device-name>/rds_blckcnt
This file contains statistics about RDS receptions. It's binary data
has the following layout:
Offset | Name | Description
====================================================================
0x00 | expected | Number of expected RDS blocks
--------------------------------------------------------------------
0x02 | received | Number of received RDS blocks
--------------------------------------------------------------------
0x04 | uncorrectable | Number of uncorrectable RDS blocks
--------------------------------------------------------------------
* /sys/kernel/debug/<device-name>/agc
This file contains information about parameters pertaining to
AGC(Automatic Gain Control)
The layout is:
Offset | Name | Description
====================================================================
0x00 | mxhi | 0 - FM Mixer PD high threshold is
| | not tripped
| | 1 - FM Mixer PD high threshold is
| | tripped
--------------------------------------------------------------------
0x01 | mxlo | ditto for FM Mixer PD low
--------------------------------------------------------------------
0x02 | lnahi | ditto for FM LNA PD high
--------------------------------------------------------------------
0x03 | lnalo | ditto for FM LNA PD low
--------------------------------------------------------------------
0x04 | fmagc1 | FMAGC1 attenuator resistance
| | (see datasheet for more detail)
--------------------------------------------------------------------
0x05 | fmagc2 | ditto for FMAGC2
--------------------------------------------------------------------
0x06 | pgagain | PGA gain in dB
--------------------------------------------------------------------
0x07 | fmwblang | FM/WB LNA Gain in dB
--------------------------------------------------------------------
* /sys/kernel/debug/<device-name>/rsq
This file contains information about parameters pertaining to
RSQ(Received Signal Quality)
The layout is:
Offset | Name | Description
====================================================================
0x00 | multhint | 0 - multipath value has not crossed
| | the Multipath high threshold
| | 1 - multipath value has crossed
| | the Multipath high threshold
--------------------------------------------------------------------
0x01 | multlint | ditto for Multipath low threshold
--------------------------------------------------------------------
0x02 | snrhint | 0 - received signal's SNR has not
| | crossed high threshold
| | 1 - received signal's SNR has
| | crossed high threshold
--------------------------------------------------------------------
0x03 | snrlint | ditto for low threshold
--------------------------------------------------------------------
0x04 | rssihint | ditto for RSSI high threshold
--------------------------------------------------------------------
0x05 | rssilint | ditto for RSSI low threshold
--------------------------------------------------------------------
0x06 | bltf | Flag indicating if seek command
| | reached/wrapped seek band limit
--------------------------------------------------------------------
0x07 | snr_ready | Indicates that SNR metrics is ready
--------------------------------------------------------------------
0x08 | rssiready | ditto for RSSI metrics
--------------------------------------------------------------------
0x09 | injside | 0 - Low-side injection is being used
| | 1 - High-side injection is used
--------------------------------------------------------------------
0x10 | afcrl | Flag indicating if AFC rails
--------------------------------------------------------------------
0x11 | valid | Flag indicating if channel is valid
--------------------------------------------------------------------
0x12 | readfreq | Current tuned frequency
--------------------------------------------------------------------
0x14 | freqoff | Singed frequency offset in units of
| | 2ppm
--------------------------------------------------------------------
0x15 | rssi | Signed value of RSSI in dBuV
--------------------------------------------------------------------
0x16 | snr | Signed RF SNR in dB
--------------------------------------------------------------------
0x17 | issi | Signed Image Strength Signal
| | indicator
--------------------------------------------------------------------
0x18 | lassi | Signed Low side adjacent Channel
| | Strength indicator
--------------------------------------------------------------------
0x19 | hassi | ditto fpr High side
--------------------------------------------------------------------
0x20 | mult | Multipath indicator
--------------------------------------------------------------------
0x21 | dev | Frequency deviation
--------------------------------------------------------------------
0x24 | assi | Adjascent channel SSI
--------------------------------------------------------------------
0x25 | usn | Ultrasonic noise indicator
--------------------------------------------------------------------
0x26 | pilotdev | Pilot deviation in units of 100 Hz
--------------------------------------------------------------------
0x27 | rdsdev | ditto for RDS
--------------------------------------------------------------------
0x28 | assidev | ditto for ASSI
--------------------------------------------------------------------
0x29 | strongdev | Frequency deviation
--------------------------------------------------------------------
0x30 | rdspi | RDS PI code
--------------------------------------------------------------------
* /sys/kernel/debug/<device-name>/rsq_primary
This file contains information about parameters pertaining to
RSQ(Received Signal Quality) for primary tuner only. Layout is as
the one above.

View File

@ -2284,7 +2284,7 @@ L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Maintained
F: drivers/media/i2c/cx2341x*
F: drivers/media/common/cx2341x*
F: include/media/cx2341x*
CX88 VIDEO4LINUX DRIVER
@ -2367,6 +2367,16 @@ W: http://www.cyclades.com/
S: Orphan
F: drivers/net/wan/pc300*
CYPRESS_FIRMWARE 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/common/cypress_firmware*
CYTTSP TOUCHSCREEN DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
L: linux-input@vger.kernel.org
@ -2731,16 +2741,6 @@ T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/usb/dvb-usb/cxusb*
DVB_USB_CYPRESS_FIRMWARE MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/dvb-usb-v2/cypress_firmware*
DVB_USB_EC168 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@ -2751,6 +2751,15 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/dvb-usb-v2/ec168*
DVB_USB_GL861 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/dvb-usb-v2/gl861*
DVB_USB_MXL111SF MEDIA DRIVER
M: Michael Krufky <mkrufky@linuxtv.org>
L: linux-media@vger.kernel.org
@ -3593,6 +3602,14 @@ W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
F: drivers/platform/x86/hdaps.c
HDPVR USB VIDEO ENCODER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Odd Fixes
F: drivers/media/usb/hdpvr
HWPOISON MEMORY FAILURE HANDLING
M: Andi Kleen <andi@firstfloor.org>
L: linux-mm@kvack.org
@ -4422,6 +4439,16 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
F: drivers/media/dvb-frontends/it913x-fe*
IT913X 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/it913x*
IVTV VIDEO4LINUX DRIVER
M: Andy Walls <awalls@md.metrocast.net>
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
@ -6692,6 +6719,16 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/dvb-frontends/rtl2830*
RTL2832 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/dvb-frontends/rtl2832*
RTL8180 WIRELESS DRIVER
M: "John W. Linville" <linville@tuxdriver.com>
L: linux-wireless@vger.kernel.org
@ -6794,7 +6831,7 @@ L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
S: Odd fixes
F: Documentation/video4linux/saa7134/
F: Documentation/video4linux/*.saa7134
F: drivers/media/pci/saa7134/
SAA7146 VIDEO4LINUX-2 DRIVER
@ -6887,9 +6924,8 @@ F: drivers/clocksource
TLG2300 VIDEO4LINUX-2 DRIVER
M: Huang Shijie <shijie8@gmail.com>
M: Kang Yong <kangyong@telegent.com>
M: Zhang Xiaobing <xbzhang@telegent.com>
S: Supported
M: Hans Verkuil <hverkuil@xs4all.nl>
S: Odd Fixes
F: drivers/media/usb/tlg2300
SC1200 WDT DRIVER
@ -7135,17 +7171,43 @@ F: drivers/media/radio/si470x/radio-si470x-common.c
F: drivers/media/radio/si470x/radio-si470x.h
F: drivers/media/radio/si470x/radio-si470x-usb.c
SI4713 FM RADIO TRANSMITTER I2C DRIVER
M: Eduardo Valentin <edubezval@gmail.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Odd Fixes
F: drivers/media/radio/si4713-i2c.?
SI4713 FM RADIO TRANSMITTER PLATFORM DRIVER
M: Eduardo Valentin <edubezval@gmail.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Odd Fixes
F: drivers/media/radio/radio-si4713.h
SIANO DVB DRIVER
M: Mauro Carvalho Chehab <mchehab@redhat.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
S: Odd fixes
F: drivers/media/common/siano/
F: drivers/media/dvb/siano/
F: drivers/media/usb/siano/
F: drivers/media/mmc/siano
SH_VEU V4L2 MEM2MEM DRIVER
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/sh_veu.c
F: include/media/sh_veu.h
SH_VOU V4L2 OUTPUT DRIVER
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
L: linux-media@vger.kernel.org
S: Maintained
S: Odd Fixes
F: drivers/media/platform/sh_vou.c
F: include/media/sh_vou.h
@ -7187,14 +7249,13 @@ F: arch/arm/mach-davinci
F: drivers/i2c/busses/i2c-davinci.c
TI DAVINCI SERIES MEDIA DRIVER
M: Manjunath Hadli <manjunath.hadli@ti.com>
M: Prabhakar Lad <prabhakar.lad@ti.com>
M: Lad, Prabhakar <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
L: davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
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: Supported
S: Maintained
F: drivers/media/platform/davinci/
F: include/media/davinci/
@ -7566,6 +7627,11 @@ M: David Täht <d@teklibre.com>
S: Odd Fixes
F: drivers/staging/frontier/
STAGING - GO7007 MPEG CODEC
M: Hans Verkuil <hans.verkuil@cisco.com>
S: Maintained
F: drivers/staging/media/go7007/
STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@cam.ac.uk>
L: linux-iio@vger.kernel.org
@ -7616,8 +7682,8 @@ S: Odd Fixes
F: drivers/staging/sm7xxfb/
STAGING - SOFTLOGIC 6x10 MPEG CODEC
M: Ben Collins <bcollins@bluecherry.net>
S: Odd Fixes
M: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
S: Supported
F: drivers/staging/media/solo6x10/
STAGING - SPEAKUP CONSOLE SPEECH DRIVER

View File

@ -242,6 +242,73 @@ static struct vpfe_config vpfe_cfg = {
.ccdc = "DM355 CCDC",
};
/* venc standards timings */
static struct vpbe_enc_mode_info dm355evm_enc_preset_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_NTSC,
.interlaced = 1,
.xres = 720,
.yres = 480,
.aspect = {11, 10},
.fps = {30000, 1001},
.left_margin = 0x79,
.upper_margin = 0x10,
},
{
.name = "pal",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_PAL,
.interlaced = 1,
.xres = 720,
.yres = 576,
.aspect = {54, 59},
.fps = {25, 1},
.left_margin = 0x7E,
.upper_margin = 0x16
},
};
#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/*
* The outputs available from VPBE + ecnoders. Keep the
* the order same as that of encoders. First those from venc followed by that
* from encoders. Index in the output refers to index on a particular encoder.
* Driver uses this index to pass it to encoder when it supports more than
* one output. Application uses index of the array to set an output.
*/
static struct vpbe_output dm355evm_vpbe_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.std = VENC_STD_ALL,
.capabilities = V4L2_OUT_CAP_STD,
},
.subdev_name = DM355_VPBE_VENC_SUBDEV_NAME,
.default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing),
.modes = dm355evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
};
static struct vpbe_config dm355evm_display_cfg = {
.module_name = "dm355-vpbe-display",
.i2c_adapter_id = 1,
.osd = {
.module_name = DM355_VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = DM355_VPBE_VENC_SUBDEV_NAME,
},
.num_outputs = ARRAY_SIZE(dm355evm_vpbe_outputs),
.outputs = dm355evm_vpbe_outputs,
};
static struct platform_device *davinci_evm_devices[] __initdata = {
&dm355evm_dm9000,
&davinci_nand_device,
@ -253,8 +320,6 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init dm355_evm_map_io(void)
{
/* setup input configuration for VPFE input devices */
dm355_set_vpfe_config(&vpfe_cfg);
dm355_init();
}
@ -344,6 +409,8 @@ static __init void dm355_evm_init(void)
davinci_setup_mmc(0, &dm355evm_mmc_config);
davinci_setup_mmc(1, &dm355evm_mmc_config);
dm355_init_video(&vpfe_cfg, &dm355evm_display_cfg);
dm355_init_spi0(BIT(0), dm355_evm_spi_info,
ARRAY_SIZE(dm355_evm_spi_info));

View File

@ -27,6 +27,7 @@
#include <linux/input.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/v4l2-dv-timings.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -39,6 +40,7 @@
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <media/ths7303.h>
#include <media/tvp514x.h>
#include "davinci.h"
@ -374,6 +376,166 @@ static struct vpfe_config vpfe_cfg = {
.ccdc = "ISIF",
};
/* venc standards timings */
static struct vpbe_enc_mode_info dm365evm_enc_std_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_NTSC,
.interlaced = 1,
.xres = 720,
.yres = 480,
.aspect = {11, 10},
.fps = {30000, 1001},
.left_margin = 0x79,
.upper_margin = 0x10,
},
{
.name = "pal",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_PAL,
.interlaced = 1,
.xres = 720,
.yres = 576,
.aspect = {54, 59},
.fps = {25, 1},
.left_margin = 0x7E,
.upper_margin = 0x16,
},
};
/* venc dv timings */
static struct vpbe_enc_mode_info dm365evm_enc_preset_timing[] = {
{
.name = "480p59_94",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
.interlaced = 0,
.xres = 720,
.yres = 480,
.aspect = {1, 1},
.fps = {5994, 100},
.left_margin = 0x8F,
.upper_margin = 0x2D,
},
{
.name = "576p50",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X576P50,
.interlaced = 0,
.xres = 720,
.yres = 576,
.aspect = {1, 1},
.fps = {50, 1},
.left_margin = 0x8C,
.upper_margin = 0x36,
},
{
.name = "720p60",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_1280X720P60,
.interlaced = 0,
.xres = 1280,
.yres = 720,
.aspect = {1, 1},
.fps = {60, 1},
.left_margin = 0x117,
.right_margin = 70,
.upper_margin = 38,
.lower_margin = 3,
.hsync_len = 80,
.vsync_len = 5,
},
{
.name = "1080i60",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
.interlaced = 1,
.xres = 1920,
.yres = 1080,
.aspect = {1, 1},
.fps = {30, 1},
.left_margin = 0xc9,
.right_margin = 80,
.upper_margin = 30,
.lower_margin = 3,
.hsync_len = 88,
.vsync_len = 5,
},
};
#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/*
* The outputs available from VPBE + ecnoders. Keep the
* the order same as that of encoders. First those from venc followed by that
* from encoders. Index in the output refers to index on a particular
* encoder.Driver uses this index to pass it to encoder when it supports more
* than one output. Application uses index of the array to set an output.
*/
static struct vpbe_output dm365evm_vpbe_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.std = VENC_STD_ALL,
.capabilities = V4L2_OUT_CAP_STD,
},
.subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
.default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm365evm_enc_std_timing),
.modes = dm365evm_enc_std_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
{
.output = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
.subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
.default_mode = "480p59_94",
.num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing),
.modes = dm365evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
};
/*
* Amplifiers on the board
*/
struct ths7303_platform_data ths7303_pdata = {
.ch_1 = 3,
.ch_2 = 3,
.ch_3 = 3,
.init_enable = 1,
};
static struct amp_config_info vpbe_amp = {
.module_name = "ths7303",
.is_i2c = 1,
.board_info = {
I2C_BOARD_INFO("ths7303", 0x2c),
.platform_data = &ths7303_pdata,
}
};
static struct vpbe_config dm365evm_display_cfg = {
.module_name = "dm365-vpbe-display",
.i2c_adapter_id = 1,
.amp = &vpbe_amp,
.osd = {
.module_name = DM365_VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = DM365_VPBE_VENC_SUBDEV_NAME,
},
.num_outputs = ARRAY_SIZE(dm365evm_vpbe_outputs),
.outputs = dm365evm_vpbe_outputs,
};
static void __init evm_init_i2c(void)
{
davinci_init_i2c(&i2c_pdata);
@ -564,8 +726,6 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init dm365_evm_map_io(void)
{
/* setup input configuration for VPFE input devices */
dm365_set_vpfe_config(&vpfe_cfg);
dm365_init();
}
@ -597,6 +757,8 @@ static __init void dm365_evm_init(void)
davinci_setup_mmc(0, &dm365evm_mmc_config);
dm365_init_video(&vpfe_cfg, &dm365evm_display_cfg);
/* maybe setup mmc1/etc ... _after_ mmc0 */
evm_init_cpld();

View File

@ -622,7 +622,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_525_60,
.std_id = V4L2_STD_NTSC,
.interlaced = 1,
.xres = 720,
.yres = 480,
@ -634,7 +634,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
{
.name = "pal",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_625_50,
.std_id = V4L2_STD_PAL,
.interlaced = 1,
.xres = 720,
.yres = 576,
@ -649,7 +649,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
{
.name = "480p59_94",
.timings_type = VPBE_ENC_CUSTOM_TIMINGS,
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
.interlaced = 0,
.xres = 720,
@ -661,7 +661,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
},
{
.name = "576p50",
.timings_type = VPBE_ENC_CUSTOM_TIMINGS,
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X576P50,
.interlaced = 0,
.xres = 720,

View File

@ -514,7 +514,7 @@ static const struct vpif_output dm6467_ch0_outputs[] = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_CUSTOM_TIMINGS,
.capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
.subdev_name = "adv7343",
.output_route = ADV7343_COMPONENT_ID,

View File

@ -36,12 +36,19 @@
#include <media/davinci/vpbe_osd.h>
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
#define SYSMOD_VDAC_CONFIG 0x2c
#define SYSMOD_VIDCLKCTL 0x38
#define SYSMOD_VPSS_CLKCTL 0x44
#define SYSMOD_VDD3P3VPWDN 0x48
#define SYSMOD_VSCLKDIS 0x6c
#define SYSMOD_PUPDCTL1 0x7c
/* VPSS CLKCTL bit definitions */
#define VPSS_MUXSEL_EXTCLK_ENABLE BIT(1)
#define VPSS_VENCCLKEN_ENABLE BIT(3)
#define VPSS_DACCLKEN_ENABLE BIT(4)
#define VPSS_PLLC2SYSCLK5_ENABLE BIT(5)
extern void __iomem *davinci_sysmod_base;
#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
void davinci_map_sysmod(void);
@ -74,7 +81,7 @@ void __init dm355_init(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
void dm355_set_vpfe_config(struct vpfe_config *cfg);
int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
/* DM365 function declarations */
void __init dm365_init(void);
@ -84,7 +91,7 @@ void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
void __init dm365_init_rtc(void);
void dm365_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm365_set_vpfe_config(struct vpfe_config *cfg);
int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
/* DM644x function declarations */
void __init dm644x_init(void);

View File

@ -35,6 +35,8 @@
#include "asp.h"
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
#define DM355_OSD_BASE (IO_PHYS + 0x70200)
#define DM355_VENC_BASE (IO_PHYS + 0x70400)
/*
* Device specific clocks
@ -345,8 +347,8 @@ static struct clk_lookup dm355_clks[] = {
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
CLK(NULL, "vpss_dac", &vpss_dac_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK("vpss", "master", &vpss_master_clk),
CLK("vpss", "slave", &vpss_slave_clk),
CLK(NULL, "clkout1", &clkout1_clk),
CLK(NULL, "clkout2", &clkout2_clk),
CLK(NULL, "pll2", &pll2_clk),
@ -744,11 +746,146 @@ static struct platform_device vpfe_capture_dev = {
},
};
void dm355_set_vpfe_config(struct vpfe_config *cfg)
static struct resource dm355_osd_resources[] = {
{
.start = DM355_OSD_BASE,
.end = DM355_OSD_BASE + 0x17f,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dm355_osd_dev = {
.name = DM355_VPBE_OSD_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm355_osd_resources),
.resource = dm355_osd_resources,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct resource dm355_venc_resources[] = {
{
.start = IRQ_VENCINT,
.end = IRQ_VENCINT,
.flags = IORESOURCE_IRQ,
},
/* venc registers io space */
{
.start = DM355_VENC_BASE,
.end = DM355_VENC_BASE + 0x17f,
.flags = IORESOURCE_MEM,
},
/* VDAC config register io space */
{
.start = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG,
.end = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG + 3,
.flags = IORESOURCE_MEM,
},
};
static struct resource dm355_v4l2_disp_resources[] = {
{
.start = IRQ_VENCINT,
.end = IRQ_VENCINT,
.flags = IORESOURCE_IRQ,
},
/* venc registers io space */
{
.start = DM355_VENC_BASE,
.end = DM355_VENC_BASE + 0x17f,
.flags = IORESOURCE_MEM,
},
};
static int dm355_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type,
int field)
{
vpfe_capture_dev.dev.platform_data = cfg;
switch (if_type) {
case V4L2_MBUS_FMT_SGRBG8_1X8:
davinci_cfg_reg(DM355_VOUT_FIELD_G70);
break;
case V4L2_MBUS_FMT_YUYV10_1X20:
if (field)
davinci_cfg_reg(DM355_VOUT_FIELD);
else
davinci_cfg_reg(DM355_VOUT_FIELD_G70);
break;
default:
return -EINVAL;
}
davinci_cfg_reg(DM355_VOUT_COUTL_EN);
davinci_cfg_reg(DM355_VOUT_COUTH_EN);
return 0;
}
static int dm355_venc_setup_clock(enum vpbe_enc_timings_type type,
unsigned int pclock)
{
void __iomem *vpss_clk_ctrl_reg;
vpss_clk_ctrl_reg = DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL);
switch (type) {
case VPBE_ENC_STD:
writel(VPSS_DACCLKEN_ENABLE | VPSS_VENCCLKEN_ENABLE,
vpss_clk_ctrl_reg);
break;
case VPBE_ENC_DV_TIMINGS:
if (pclock > 27000000)
/*
* For HD, use external clock source since we cannot
* support HD mode with internal clocks.
*/
writel(VPSS_MUXSEL_EXTCLK_ENABLE, vpss_clk_ctrl_reg);
break;
default:
return -EINVAL;
}
return 0;
}
static struct platform_device dm355_vpbe_display = {
.name = "vpbe-v4l2",
.id = -1,
.num_resources = ARRAY_SIZE(dm355_v4l2_disp_resources),
.resource = dm355_v4l2_disp_resources,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
struct venc_platform_data dm355_venc_pdata = {
.setup_pinmux = dm355_vpbe_setup_pinmux,
.setup_clock = dm355_venc_setup_clock,
};
static struct platform_device dm355_venc_dev = {
.name = DM355_VPBE_VENC_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm355_venc_resources),
.resource = dm355_venc_resources,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = (void *)&dm355_venc_pdata,
},
};
static struct platform_device dm355_vpbe_dev = {
.name = "vpbe_controller",
.id = -1,
.dev = {
.dma_mask = &vpfe_capture_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
/*----------------------------------------------------------------------*/
static struct map_desc dm355_io_desc[] = {
@ -868,19 +1005,36 @@ void __init dm355_init(void)
davinci_map_sysmod();
}
int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
struct vpbe_config *vpbe_cfg)
{
if (vpfe_cfg || vpbe_cfg)
platform_device_register(&dm355_vpss_device);
if (vpfe_cfg) {
vpfe_capture_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm355_ccdc_dev);
platform_device_register(&vpfe_capture_dev);
}
if (vpbe_cfg) {
dm355_vpbe_dev.dev.platform_data = vpbe_cfg;
platform_device_register(&dm355_osd_dev);
platform_device_register(&dm355_venc_dev);
platform_device_register(&dm355_vpbe_dev);
platform_device_register(&dm355_vpbe_display);
}
return 0;
}
static int __init dm355_init_devices(void)
{
if (!cpu_is_davinci_dm355())
return 0;
/* Add ccdc clock aliases */
clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
davinci_cfg_reg(DM355_INT_EDMA_CC);
platform_device_register(&dm355_edma_device);
platform_device_register(&dm355_vpss_device);
platform_device_register(&dm355_ccdc_dev);
platform_device_register(&vpfe_capture_dev);
return 0;
}

View File

@ -39,16 +39,13 @@
#include "asp.h"
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
/* Base of key scan register bank */
#define DM365_KEYSCAN_BASE 0x01c69400
#define DM365_RTC_BASE 0x01c69000
#define DM365_KEYSCAN_BASE 0x01c69400
#define DM365_OSD_BASE 0x01c71c00
#define DM365_VENC_BASE 0x01c71e00
#define DAVINCI_DM365_VC_BASE 0x01d0c000
#define DAVINCI_DMA_VC_TX 2
#define DAVINCI_DMA_VC_RX 3
#define DM365_EMAC_BASE 0x01d07000
#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000)
#define DM365_EMAC_CNTRL_OFFSET 0x0000
@ -257,6 +254,12 @@ static struct clk vpss_master_clk = {
.flags = CLK_PSC,
};
static struct clk vpss_slave_clk = {
.name = "vpss_slave",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_VPSSSLV,
};
static struct clk arm_clk = {
.name = "arm_clk",
.parent = &pll2_sysclk2,
@ -449,7 +452,8 @@ static struct clk_lookup dm365_clks[] = {
CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
CLK(NULL, "vpss_dac", &vpss_dac_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK("vpss", "master", &vpss_master_clk),
CLK("vpss", "slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
@ -1226,6 +1230,173 @@ static struct platform_device dm365_isif_dev = {
},
};
static struct resource dm365_osd_resources[] = {
{
.start = DM365_OSD_BASE,
.end = DM365_OSD_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static u64 dm365_video_dma_mask = DMA_BIT_MASK(32);
static struct platform_device dm365_osd_dev = {
.name = DM365_VPBE_OSD_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm365_osd_resources),
.resource = dm365_osd_resources,
.dev = {
.dma_mask = &dm365_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct resource dm365_venc_resources[] = {
{
.start = IRQ_VENCINT,
.end = IRQ_VENCINT,
.flags = IORESOURCE_IRQ,
},
/* venc registers io space */
{
.start = DM365_VENC_BASE,
.end = DM365_VENC_BASE + 0x177,
.flags = IORESOURCE_MEM,
},
/* vdaccfg registers io space */
{
.start = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG,
.end = DAVINCI_SYSTEM_MODULE_BASE + SYSMOD_VDAC_CONFIG + 3,
.flags = IORESOURCE_MEM,
},
};
static struct resource dm365_v4l2_disp_resources[] = {
{
.start = IRQ_VENCINT,
.end = IRQ_VENCINT,
.flags = IORESOURCE_IRQ,
},
/* venc registers io space */
{
.start = DM365_VENC_BASE,
.end = DM365_VENC_BASE + 0x177,
.flags = IORESOURCE_MEM,
},
};
static int dm365_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type,
int field)
{
switch (if_type) {
case V4L2_MBUS_FMT_SGRBG8_1X8:
davinci_cfg_reg(DM365_VOUT_FIELD_G81);
davinci_cfg_reg(DM365_VOUT_COUTL_EN);
davinci_cfg_reg(DM365_VOUT_COUTH_EN);
break;
case V4L2_MBUS_FMT_YUYV10_1X20:
if (field)
davinci_cfg_reg(DM365_VOUT_FIELD);
else
davinci_cfg_reg(DM365_VOUT_FIELD_G81);
davinci_cfg_reg(DM365_VOUT_COUTL_EN);
davinci_cfg_reg(DM365_VOUT_COUTH_EN);
break;
default:
return -EINVAL;
}
return 0;
}
static int dm365_venc_setup_clock(enum vpbe_enc_timings_type type,
unsigned int pclock)
{
void __iomem *vpss_clkctl_reg;
u32 val;
vpss_clkctl_reg = DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL);
switch (type) {
case VPBE_ENC_STD:
val = VPSS_VENCCLKEN_ENABLE | VPSS_DACCLKEN_ENABLE;
break;
case VPBE_ENC_DV_TIMINGS:
if (pclock <= 27000000) {
val = VPSS_VENCCLKEN_ENABLE | VPSS_DACCLKEN_ENABLE;
} else {
/* set sysclk4 to output 74.25 MHz from pll1 */
val = VPSS_PLLC2SYSCLK5_ENABLE | VPSS_DACCLKEN_ENABLE |
VPSS_VENCCLKEN_ENABLE;
}
break;
default:
return -EINVAL;
}
writel(val, vpss_clkctl_reg);
return 0;
}
static struct platform_device dm365_vpbe_display = {
.name = "vpbe-v4l2",
.id = -1,
.num_resources = ARRAY_SIZE(dm365_v4l2_disp_resources),
.resource = dm365_v4l2_disp_resources,
.dev = {
.dma_mask = &dm365_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
struct venc_platform_data dm365_venc_pdata = {
.setup_pinmux = dm365_vpbe_setup_pinmux,
.setup_clock = dm365_venc_setup_clock,
};
static struct platform_device dm365_venc_dev = {
.name = DM365_VPBE_VENC_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm365_venc_resources),
.resource = dm365_venc_resources,
.dev = {
.dma_mask = &dm365_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = (void *)&dm365_venc_pdata,
},
};
static struct platform_device dm365_vpbe_dev = {
.name = "vpbe_controller",
.id = -1,
.dev = {
.dma_mask = &dm365_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
int __init dm365_init_video(struct vpfe_config *vpfe_cfg,
struct vpbe_config *vpbe_cfg)
{
if (vpfe_cfg || vpbe_cfg)
platform_device_register(&dm365_vpss_device);
if (vpfe_cfg) {
vpfe_capture_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm365_isif_dev);
platform_device_register(&vpfe_capture_dev);
}
if (vpbe_cfg) {
dm365_vpbe_dev.dev.platform_data = vpbe_cfg;
platform_device_register(&dm365_osd_dev);
platform_device_register(&dm365_venc_dev);
platform_device_register(&dm365_vpbe_dev);
platform_device_register(&dm365_vpbe_display);
}
return 0;
}
static int __init dm365_init_devices(void)
{
if (!cpu_is_davinci_dm365())
@ -1239,16 +1410,6 @@ static int __init dm365_init_devices(void)
clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev),
NULL, &dm365_emac_device.dev);
/* Add isif clock alias */
clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
platform_device_register(&dm365_vpss_device);
platform_device_register(&dm365_isif_dev);
platform_device_register(&vpfe_capture_dev);
return 0;
}
postcore_initcall(dm365_init_devices);
void dm365_set_vpfe_config(struct vpfe_config *cfg)
{
vpfe_capture_dev.dev.platform_data = cfg;
}

View File

@ -300,8 +300,8 @@ static struct clk_lookup dm644x_clks[] = {
CLK(NULL, "dsp", &dsp_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "vicp", &vicp_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK("vpss", "master", &vpss_master_clk),
CLK("vpss", "slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
@ -706,7 +706,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
break;
case VPBE_ENC_CUSTOM_TIMINGS:
case VPBE_ENC_DV_TIMINGS:
if (pclock <= 27000000) {
v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
@ -901,11 +901,6 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&dm644x_vpfe_dev);
/* Add ccdc clock aliases */
clk_add_alias("master", dm644x_ccdc_dev.name,
"vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name,
"vpss_slave", NULL);
}
if (vpbe_cfg) {

View File

@ -53,7 +53,7 @@ static struct dev_pm_domain davinci_pm_domain = {
static struct pm_clk_notifier_block platform_bus_notifier = {
.pm_domain = &davinci_pm_domain,
.con_ids = { "fck", NULL, },
.con_ids = { "fck", "master", "slave", NULL },
};
static int __init davinci_pm_runtime_init(void)

View File

@ -936,19 +936,19 @@ static struct v4l2_input adv7842_inputs[] = {
.index = 2,
.name = "Component",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS,
.capabilities = V4L2_IN_CAP_DV_TIMINGS,
},
{
.index = 3,
.name = "VGA",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS,
.capabilities = V4L2_IN_CAP_DV_TIMINGS,
},
{
.index = 4,
.name = "HDMI",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_IN_CAP_CUSTOM_TIMINGS,
.capabilities = V4L2_IN_CAP_DV_TIMINGS,
},
};
@ -1074,7 +1074,7 @@ static struct v4l2_output adv7511_outputs[] = {
.index = 0,
.name = "HDMI",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_OUT_CAP_CUSTOM_TIMINGS,
.capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
};

View File

@ -16,6 +16,10 @@ config VIDEO_TVEEPROM
tristate
depends on I2C
config CYPRESS_FIRMWARE
tristate "Cypress firmware helper routines"
depends on USB
source "drivers/media/common/b2c2/Kconfig"
source "drivers/media/common/saa7146/Kconfig"
source "drivers/media/common/siano/Kconfig"

View File

@ -2,3 +2,4 @@ obj-y += b2c2/ saa7146/ siano/
obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o

View File

@ -325,7 +325,7 @@ static int skystar2_rev27_attach(struct flexcop_device *fc,
/* enable no_base_addr - no repeated start when reading */
fc->fc_i2c_adap[2].no_base_addr = 1;
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
0x08, 1, 1)) {
0x08, 1, 1, false)) {
err("ISL6421 could NOT be attached");
goto fail_isl;
}
@ -391,7 +391,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
fc->fc_i2c_adap[2].no_base_addr = 1;
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
0x08, 0, 0)) {
0x08, 0, 0, false)) {
err("ISL6421 could NOT be attached");
fc->fc_i2c_adap[2].no_base_addr = 0;
return 0;

View File

@ -8,7 +8,10 @@
*
*/
#include "dvb_usb.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/firmware.h>
#include "cypress_firmware.h"
struct usb_cypress_controller {
@ -30,75 +33,12 @@ static const struct usb_cypress_controller cypress[] = {
static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
u8 len)
{
dvb_usb_dbg_usb_control_msg(udev,
0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len);
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
}
int usbv2_cypress_load_firmware(struct usb_device *udev,
const struct firmware *fw, int type)
{
struct hexline *hx;
int ret, pos = 0;
hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
if (!hx) {
dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
return -ENOMEM;
}
/* stop the CPU */
hx->data[0] = 1;
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
if (ret != 1) {
dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
KBUILD_MODNAME, ret);
ret = -EIO;
goto err_kfree;
}
/* write firmware to memory */
for (;;) {
ret = dvb_usbv2_get_hexline(fw, hx, &pos);
if (ret < 0)
goto err_kfree;
else if (ret == 0)
break;
ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
if (ret < 0) {
goto err_kfree;
} else if (ret != hx->len) {
dev_err(&udev->dev, "%s: error while transferring " \
"firmware (transferred size=%d, " \
"block size=%d)\n",
KBUILD_MODNAME, ret, hx->len);
ret = -EIO;
goto err_kfree;
}
}
/* start the CPU */
hx->data[0] = 0;
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
if (ret != 1) {
dev_err(&udev->dev, "%s: CPU start failed=%d\n",
KBUILD_MODNAME, ret);
ret = -EIO;
goto err_kfree;
}
ret = 0;
err_kfree:
kfree(hx);
return ret;
}
EXPORT_SYMBOL(usbv2_cypress_load_firmware);
int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
int *pos)
static int cypress_get_hexline(const struct firmware *fw,
struct hexline *hx, int *pos)
{
u8 *b = (u8 *) &fw->data[*pos];
int data_offs = 4;
@ -127,7 +67,65 @@ int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
return *pos;
}
EXPORT_SYMBOL(dvb_usbv2_get_hexline);
int cypress_load_firmware(struct usb_device *udev,
const struct firmware *fw, int type)
{
struct hexline *hx;
int ret, pos = 0;
hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
if (!hx) {
dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
return -ENOMEM;
}
/* stop the CPU */
hx->data[0] = 1;
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
if (ret != 1) {
dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
KBUILD_MODNAME, ret);
ret = -EIO;
goto err_kfree;
}
/* write firmware to memory */
for (;;) {
ret = cypress_get_hexline(fw, hx, &pos);
if (ret < 0)
goto err_kfree;
else if (ret == 0)
break;
ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
if (ret < 0) {
goto err_kfree;
} else if (ret != hx->len) {
dev_err(&udev->dev,
"%s: error while transferring firmware (transferred size=%d, block size=%d)\n",
KBUILD_MODNAME, ret, hx->len);
ret = -EIO;
goto err_kfree;
}
}
/* start the CPU */
hx->data[0] = 0;
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
if (ret != 1) {
dev_err(&udev->dev, "%s: CPU start failed=%d\n",
KBUILD_MODNAME, ret);
ret = -EIO;
goto err_kfree;
}
ret = 0;
err_kfree:
kfree(hx);
return ret;
}
EXPORT_SYMBOL(cypress_load_firmware);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Cypress firmware download");

View File

@ -1,5 +1,4 @@
/* cypress_firmware.h is part of the DVB USB library.
*
/*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
* see dvb-usb-init.c for copyright information.
*
@ -23,9 +22,7 @@ struct hexline {
u8 data[255];
u8 chk;
};
extern int usbv2_cypress_load_firmware(struct usb_device *,
const struct firmware *, int);
extern int dvb_usbv2_get_hexline(const struct firmware *,
struct hexline *, int *);
int cypress_load_firmware(struct usb_device *, const struct firmware *, int);
#endif

View File

@ -832,7 +832,7 @@ static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
}
*/
static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
@ -856,7 +856,7 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
}
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
if (*id & dev->ext_vv_data->stds[i].id)
if (id & dev->ext_vv_data->stds[i].id)
break;
if (i != dev->ext_vv_data->num_stds) {
vv->standard = &dev->ext_vv_data->stds[i];

View File

@ -17,3 +17,15 @@ config SMS_SIANO_RC
default y
---help---
Choose Y to select Remote Controller support for Siano driver.
config SMS_SIANO_DEBUGFS
bool "Enable debugfs for smsdvb"
depends on SMS_SIANO_MDTV
depends on DEBUG_FS
depends on SMS_USB_DRV
---help---
Choose Y to enable visualizing a dump of the frontend
statistics response packets via debugfs. Currently, works
only with Siano USB devices.
Useful only for developers. In doubt, say N.

View File

@ -1,4 +1,5 @@
smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
smsdvb-objs := smsdvb-main.o
obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
@ -6,6 +7,10 @@ ifeq ($(CONFIG_SMS_SIANO_RC),y)
smsmdtv-objs += smsir.o
endif
ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
smsdvb-objs += smsdvb-debugfs.o
endif
ccflags-y += -Idrivers/media/dvb-core
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)

View File

@ -28,43 +28,53 @@ MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
.name = "Unknown board",
.type = SMS_UNKNOWN_TYPE,
.default_mode = DEVICE_MODE_NONE,
},
[SMS1XXX_BOARD_SIANO_STELLAR] = {
.name = "Siano Stellar Digital Receiver",
.type = SMS_STELLAR,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_NOVA_A] = {
.name = "Siano Nova A Digital Receiver",
.type = SMS_NOVA_A0,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_NOVA_B] = {
.name = "Siano Nova B Digital Receiver",
.type = SMS_NOVA_B0,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_VEGA] = {
.name = "Siano Vega Digital Receiver",
.type = SMS_VEGA,
.default_mode = DEVICE_MODE_CMMB,
},
[SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
.name = "Hauppauge Catamount",
.type = SMS_STELLAR,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_STELLAR,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
.name = "Hauppauge Okemo-A",
.type = SMS_NOVA_A0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_A,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
.name = "Hauppauge Okemo-B",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_B,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
.name = "Hauppauge WinTV MiniStick",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.fw[DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_HCW_55XXX,
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
.default_mode = DEVICE_MODE_DVBT_BDA,
.rc_codes = RC_MAP_HAUPPAUGE,
.board_cfg.leds_power = 26,
.board_cfg.led0 = 27,
@ -77,7 +87,8 @@ static struct sms_board sms_boards[] = {
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
.name = "Hauppauge WinTV MiniCard",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
.default_mode = DEVICE_MODE_DVBT_BDA,
.lna_ctrl = 29,
.board_cfg.foreign_lna0_ctrl = 29,
.rf_switch = 17,
@ -86,18 +97,65 @@ static struct sms_board sms_boards[] = {
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
.name = "Hauppauge WinTV MiniCard",
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
.default_mode = DEVICE_MODE_DVBT_BDA,
.lna_ctrl = -1,
},
[SMS1XXX_BOARD_SIANO_NICE] = {
/* 11 */
.name = "Siano Nice Digital Receiver",
.type = SMS_NOVA_B0,
.default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_VENICE] = {
/* 12 */
.name = "Siano Venice Digital Receiver",
.type = SMS_VEGA,
.default_mode = DEVICE_MODE_CMMB,
},
[SMS1XXX_BOARD_SIANO_STELLAR_ROM] = {
.name = "Siano Stellar Digital Receiver ROM",
.type = SMS_STELLAR,
.default_mode = DEVICE_MODE_DVBT_BDA,
.intf_num = 1,
},
[SMS1XXX_BOARD_ZTE_DVB_DATA_CARD] = {
.name = "ZTE Data Card Digital Receiver",
.type = SMS_NOVA_B0,
.default_mode = DEVICE_MODE_DVBT_BDA,
.intf_num = 5,
.mtu = 15792,
},
[SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD] = {
.name = "ONDA Data Card Digital Receiver",
.type = SMS_NOVA_B0,
.default_mode = DEVICE_MODE_DVBT_BDA,
.intf_num = 6,
.mtu = 15792,
},
[SMS1XXX_BOARD_SIANO_MING] = {
.name = "Siano Ming Digital Receiver",
.type = SMS_MING,
.default_mode = DEVICE_MODE_CMMB,
},
[SMS1XXX_BOARD_SIANO_PELE] = {
.name = "Siano Pele Digital Receiver",
.type = SMS_PELE,
.default_mode = DEVICE_MODE_ISDBT_BDA,
},
[SMS1XXX_BOARD_SIANO_RIO] = {
.name = "Siano Rio Digital Receiver",
.type = SMS_RIO,
.default_mode = DEVICE_MODE_ISDBT_BDA,
},
[SMS1XXX_BOARD_SIANO_DENVER_1530] = {
.name = "Siano Denver (ATSC-M/H) Digital Receiver",
.type = SMS_DENVER_1530,
.default_mode = DEVICE_MODE_ATSC,
.crystal = 2400,
},
[SMS1XXX_BOARD_SIANO_DENVER_2160] = {
.name = "Siano Denver (TDMB) Digital Receiver",
.type = SMS_DENVER_2160,
.default_mode = DEVICE_MODE_DAB_TDMB,
},
};
@ -109,20 +167,21 @@ struct sms_board *sms_get_board(unsigned id)
}
EXPORT_SYMBOL_GPL(sms_get_board);
static inline void sms_gpio_assign_11xx_default_led_config(
struct smscore_gpio_config *pGpioConfig) {
pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
pGpioConfig->InputCharacteristics =
SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
struct smscore_config_gpio *p_gpio_config) {
p_gpio_config->direction = SMS_GPIO_DIRECTION_OUTPUT;
p_gpio_config->inputcharacteristics =
SMS_GPIO_INPUTCHARACTERISTICS_NORMAL;
p_gpio_config->outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA;
p_gpio_config->outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
p_gpio_config->pullupdown = SMS_GPIO_PULLUPDOWN_NONE;
}
int sms_board_event(struct smscore_device_t *coredev,
enum SMS_BOARD_EVENTS gevent) {
struct smscore_gpio_config MyGpioConfig;
enum SMS_BOARD_EVENTS gevent)
{
struct smscore_config_gpio my_gpio_config;
sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
sms_gpio_assign_11xx_default_led_config(&my_gpio_config);
switch (gevent) {
case BOARD_EVENT_POWER_INIT: /* including hotplug */
@ -182,8 +241,8 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
.direction = SMS_GPIO_DIRECTION_OUTPUT,
.pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
.outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
.outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
.outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_FAST,
.outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA,
};
if (pin == 0)
@ -293,19 +352,7 @@ EXPORT_SYMBOL_GPL(sms_board_lna_control);
int sms_board_load_modules(int id)
{
switch (id) {
case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
request_module("smsdvb");
break;
default:
/* do nothing */
break;
}
request_module("smsdvb");
return 0;
}
EXPORT_SYMBOL_GPL(sms_board_load_modules);

View File

@ -37,6 +37,14 @@
#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
#define SMS1XXX_BOARD_SIANO_NICE 11
#define SMS1XXX_BOARD_SIANO_VENICE 12
#define SMS1XXX_BOARD_SIANO_STELLAR_ROM 13
#define SMS1XXX_BOARD_ZTE_DVB_DATA_CARD 14
#define SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD 15
#define SMS1XXX_BOARD_SIANO_MING 16
#define SMS1XXX_BOARD_SIANO_PELE 17
#define SMS1XXX_BOARD_SIANO_RIO 18
#define SMS1XXX_BOARD_SIANO_DENVER_1530 19
#define SMS1XXX_BOARD_SIANO_DENVER_2160 20
struct sms_board_gpio_cfg {
int lna_vhf_exist;
@ -79,6 +87,12 @@ struct sms_board {
/* gpios */
int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
char intf_num;
int default_mode;
unsigned int mtu;
unsigned int crystal;
struct sms_antenna_config_ST *antenna_config;
};
struct sms_board *sms_get_board(unsigned id);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,551 @@
/***********************************************************************
*
* Copyright(c) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***********************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include "dmxdev.h"
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
#include "smscoreapi.h"
#include "smsdvb.h"
static struct dentry *smsdvb_debugfs_usb_root;
struct smsdvb_debugfs {
struct kref refcount;
spinlock_t lock;
char stats_data[PAGE_SIZE];
unsigned stats_count;
bool stats_was_read;
wait_queue_head_t stats_queue;
};
static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
struct sms_stats *p)
{
int n = 0;
char *buf;
spin_lock(&debug_data->lock);
if (debug_data->stats_count) {
spin_unlock(&debug_data->lock);
return;
}
buf = debug_data->stats_data;
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_rf_locked = %d\n", p->is_rf_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_demod_locked = %d\n", p->is_demod_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_external_lna_on = %d\n", p->is_external_lna_on);
n += snprintf(&buf[n], PAGE_SIZE - n,
"SNR = %d\n", p->SNR);
n += snprintf(&buf[n], PAGE_SIZE - n,
"ber = %d\n", p->ber);
n += snprintf(&buf[n], PAGE_SIZE - n,
"FIB_CRC = %d\n", p->FIB_CRC);
n += snprintf(&buf[n], PAGE_SIZE - n,
"ts_per = %d\n", p->ts_per);
n += snprintf(&buf[n], PAGE_SIZE - n,
"MFER = %d\n", p->MFER);
n += snprintf(&buf[n], PAGE_SIZE - n,
"RSSI = %d\n", p->RSSI);
n += snprintf(&buf[n], PAGE_SIZE - n,
"in_band_pwr = %d\n", p->in_band_pwr);
n += snprintf(&buf[n], PAGE_SIZE - n,
"carrier_offset = %d\n", p->carrier_offset);
n += snprintf(&buf[n], PAGE_SIZE - n,
"modem_state = %d\n", p->modem_state);
n += snprintf(&buf[n], PAGE_SIZE - n,
"frequency = %d\n", p->frequency);
n += snprintf(&buf[n], PAGE_SIZE - n,
"bandwidth = %d\n", p->bandwidth);
n += snprintf(&buf[n], PAGE_SIZE - n,
"transmission_mode = %d\n", p->transmission_mode);
n += snprintf(&buf[n], PAGE_SIZE - n,
"modem_state = %d\n", p->modem_state);
n += snprintf(&buf[n], PAGE_SIZE - n,
"guard_interval = %d\n", p->guard_interval);
n += snprintf(&buf[n], PAGE_SIZE - n,
"code_rate = %d\n", p->code_rate);
n += snprintf(&buf[n], PAGE_SIZE - n,
"lp_code_rate = %d\n", p->lp_code_rate);
n += snprintf(&buf[n], PAGE_SIZE - n,
"hierarchy = %d\n", p->hierarchy);
n += snprintf(&buf[n], PAGE_SIZE - n,
"constellation = %d\n", p->constellation);
n += snprintf(&buf[n], PAGE_SIZE - n,
"burst_size = %d\n", p->burst_size);
n += snprintf(&buf[n], PAGE_SIZE - n,
"burst_duration = %d\n", p->burst_duration);
n += snprintf(&buf[n], PAGE_SIZE - n,
"burst_cycle_time = %d\n", p->burst_cycle_time);
n += snprintf(&buf[n], PAGE_SIZE - n,
"calc_burst_cycle_time = %d\n",
p->calc_burst_cycle_time);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_rows = %d\n", p->num_of_rows);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_padd_cols = %d\n", p->num_of_padd_cols);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_punct_cols = %d\n", p->num_of_punct_cols);
n += snprintf(&buf[n], PAGE_SIZE - n,
"error_ts_packets = %d\n", p->error_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n,
"total_ts_packets = %d\n", p->total_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
n += snprintf(&buf[n], PAGE_SIZE - n,
"ber_error_count = %d\n", p->ber_error_count);
n += snprintf(&buf[n], PAGE_SIZE - n,
"ber_bit_count = %d\n", p->ber_bit_count);
n += snprintf(&buf[n], PAGE_SIZE - n,
"sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
n += snprintf(&buf[n], PAGE_SIZE - n,
"pre_ber = %d\n", p->pre_ber);
n += snprintf(&buf[n], PAGE_SIZE - n,
"cell_id = %d\n", p->cell_id);
n += snprintf(&buf[n], PAGE_SIZE - n,
"dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
n += snprintf(&buf[n], PAGE_SIZE - n,
"dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_mpe_received = %d\n", p->num_mpe_received);
debug_data->stats_count = n;
spin_unlock(&debug_data->lock);
wake_up(&debug_data->stats_queue);
}
static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
struct sms_isdbt_stats *p)
{
int i, n = 0;
char *buf;
spin_lock(&debug_data->lock);
if (debug_data->stats_count) {
spin_unlock(&debug_data->lock);
return;
}
buf = debug_data->stats_data;
n += snprintf(&buf[n], PAGE_SIZE - n,
"statistics_type = %d\t", p->statistics_type);
n += snprintf(&buf[n], PAGE_SIZE - n,
"full_size = %d\n", p->full_size);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_rf_locked = %d\t\t", p->is_rf_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_demod_locked = %d\t", p->is_demod_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_external_lna_on = %d\n", p->is_external_lna_on);
n += snprintf(&buf[n], PAGE_SIZE - n,
"SNR = %d dB\t\t", p->SNR);
n += snprintf(&buf[n], PAGE_SIZE - n,
"RSSI = %d dBm\t\t", p->RSSI);
n += snprintf(&buf[n], PAGE_SIZE - n,
"in_band_pwr = %d dBm\n", p->in_band_pwr);
n += snprintf(&buf[n], PAGE_SIZE - n,
"carrier_offset = %d\t", p->carrier_offset);
n += snprintf(&buf[n], PAGE_SIZE - n,
"bandwidth = %d\t\t", p->bandwidth);
n += snprintf(&buf[n], PAGE_SIZE - n,
"frequency = %d Hz\n", p->frequency);
n += snprintf(&buf[n], PAGE_SIZE - n,
"transmission_mode = %d\t", p->transmission_mode);
n += snprintf(&buf[n], PAGE_SIZE - n,
"modem_state = %d\t\t", p->modem_state);
n += snprintf(&buf[n], PAGE_SIZE - n,
"guard_interval = %d\n", p->guard_interval);
n += snprintf(&buf[n], PAGE_SIZE - n,
"system_type = %d\t\t", p->system_type);
n += snprintf(&buf[n], PAGE_SIZE - n,
"partial_reception = %d\t", p->partial_reception);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_layers = %d\n", p->num_of_layers);
n += snprintf(&buf[n], PAGE_SIZE - n,
"sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
for (i = 0; i < 3; i++) {
if (p->layer_info[i].number_of_segments < 1 ||
p->layer_info[i].number_of_segments > 13)
continue;
n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
p->layer_info[i].code_rate);
n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
p->layer_info[i].constellation);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
p->layer_info[i].ber);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
p->layer_info[i].ber_error_count);
n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
p->layer_info[i].ber_bit_count);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
p->layer_info[i].pre_ber);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
p->layer_info[i].ts_per);
n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
p->layer_info[i].error_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
p->layer_info[i].total_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
p->layer_info[i].ti_ldepth_i);
n += snprintf(&buf[n], PAGE_SIZE - n,
"\tnumber_of_segments = %d\t",
p->layer_info[i].number_of_segments);
n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
p->layer_info[i].tmcc_errors);
}
debug_data->stats_count = n;
spin_unlock(&debug_data->lock);
wake_up(&debug_data->stats_queue);
}
static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
struct sms_isdbt_stats_ex *p)
{
int i, n = 0;
char *buf;
spin_lock(&debug_data->lock);
if (debug_data->stats_count) {
spin_unlock(&debug_data->lock);
return;
}
buf = debug_data->stats_data;
n += snprintf(&buf[n], PAGE_SIZE - n,
"statistics_type = %d\t", p->statistics_type);
n += snprintf(&buf[n], PAGE_SIZE - n,
"full_size = %d\n", p->full_size);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_rf_locked = %d\t\t", p->is_rf_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_demod_locked = %d\t", p->is_demod_locked);
n += snprintf(&buf[n], PAGE_SIZE - n,
"is_external_lna_on = %d\n", p->is_external_lna_on);
n += snprintf(&buf[n], PAGE_SIZE - n,
"SNR = %d dB\t\t", p->SNR);
n += snprintf(&buf[n], PAGE_SIZE - n,
"RSSI = %d dBm\t\t", p->RSSI);
n += snprintf(&buf[n], PAGE_SIZE - n,
"in_band_pwr = %d dBm\n", p->in_band_pwr);
n += snprintf(&buf[n], PAGE_SIZE - n,
"carrier_offset = %d\t", p->carrier_offset);
n += snprintf(&buf[n], PAGE_SIZE - n,
"bandwidth = %d\t\t", p->bandwidth);
n += snprintf(&buf[n], PAGE_SIZE - n,
"frequency = %d Hz\n", p->frequency);
n += snprintf(&buf[n], PAGE_SIZE - n,
"transmission_mode = %d\t", p->transmission_mode);
n += snprintf(&buf[n], PAGE_SIZE - n,
"modem_state = %d\t\t", p->modem_state);
n += snprintf(&buf[n], PAGE_SIZE - n,
"guard_interval = %d\n", p->guard_interval);
n += snprintf(&buf[n], PAGE_SIZE - n,
"system_type = %d\t\t", p->system_type);
n += snprintf(&buf[n], PAGE_SIZE - n,
"partial_reception = %d\t", p->partial_reception);
n += snprintf(&buf[n], PAGE_SIZE - n,
"num_of_layers = %d\n", p->num_of_layers);
n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
p->segment_number);
n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
p->tune_bw);
for (i = 0; i < 3; i++) {
if (p->layer_info[i].number_of_segments < 1 ||
p->layer_info[i].number_of_segments > 13)
continue;
n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
p->layer_info[i].code_rate);
n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
p->layer_info[i].constellation);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
p->layer_info[i].ber);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
p->layer_info[i].ber_error_count);
n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
p->layer_info[i].ber_bit_count);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
p->layer_info[i].pre_ber);
n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
p->layer_info[i].ts_per);
n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
p->layer_info[i].error_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
p->layer_info[i].total_ts_packets);
n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
p->layer_info[i].ti_ldepth_i);
n += snprintf(&buf[n], PAGE_SIZE - n,
"\tnumber_of_segments = %d\t",
p->layer_info[i].number_of_segments);
n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
p->layer_info[i].tmcc_errors);
}
debug_data->stats_count = n;
spin_unlock(&debug_data->lock);
wake_up(&debug_data->stats_queue);
}
static int smsdvb_stats_open(struct inode *inode, struct file *file)
{
struct smsdvb_client_t *client = inode->i_private;
struct smsdvb_debugfs *debug_data = client->debug_data;
kref_get(&debug_data->refcount);
spin_lock(&debug_data->lock);
debug_data->stats_count = 0;
debug_data->stats_was_read = false;
spin_unlock(&debug_data->lock);
file->private_data = debug_data;
return 0;
}
static void smsdvb_debugfs_data_release(struct kref *ref)
{
struct smsdvb_debugfs *debug_data;
debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
kfree(debug_data);
}
static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
{
int rc = 1;
spin_lock(&debug_data->lock);
if (debug_data->stats_was_read)
goto exit;
rc = debug_data->stats_count;
exit:
spin_unlock(&debug_data->lock);
return rc;
}
static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait)
{
struct smsdvb_debugfs *debug_data = file->private_data;
int rc;
kref_get(&debug_data->refcount);
poll_wait(file, &debug_data->stats_queue, wait);
rc = smsdvb_stats_wait_read(debug_data);
if (rc > 0)
rc = POLLIN | POLLRDNORM;
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
return rc;
}
static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
size_t nbytes, loff_t *ppos)
{
int rc = 0, len;
struct smsdvb_debugfs *debug_data = file->private_data;
kref_get(&debug_data->refcount);
if (file->f_flags & O_NONBLOCK) {
rc = smsdvb_stats_wait_read(debug_data);
if (!rc) {
rc = -EWOULDBLOCK;
goto ret;
}
} else {
rc = wait_event_interruptible(debug_data->stats_queue,
smsdvb_stats_wait_read(debug_data));
if (rc < 0)
goto ret;
}
if (debug_data->stats_was_read) {
rc = 0; /* EOF */
goto ret;
}
len = debug_data->stats_count - *ppos;
if (len >= 0)
rc = simple_read_from_buffer(user_buf, nbytes, ppos,
debug_data->stats_data, len);
else
rc = 0;
if (*ppos >= debug_data->stats_count) {
spin_lock(&debug_data->lock);
debug_data->stats_was_read = true;
spin_unlock(&debug_data->lock);
}
ret:
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
return rc;
}
static int smsdvb_stats_release(struct inode *inode, struct file *file)
{
struct smsdvb_debugfs *debug_data = file->private_data;
spin_lock(&debug_data->lock);
debug_data->stats_was_read = true; /* return EOF to read() */
spin_unlock(&debug_data->lock);
wake_up_interruptible_sync(&debug_data->stats_queue);
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
file->private_data = NULL;
return 0;
}
static const struct file_operations debugfs_stats_ops = {
.open = smsdvb_stats_open,
.poll = smsdvb_stats_poll,
.read = smsdvb_stats_read,
.release = smsdvb_stats_release,
.llseek = generic_file_llseek,
};
/*
* Functions used by smsdvb, in order to create the interfaces
*/
int smsdvb_debugfs_create(struct smsdvb_client_t *client)
{
struct smscore_device_t *coredev = client->coredev;
struct dentry *d;
struct smsdvb_debugfs *debug_data;
if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
return -ENODEV;
client->debugfs = debugfs_create_dir(coredev->devpath,
smsdvb_debugfs_usb_root);
if (IS_ERR_OR_NULL(client->debugfs)) {
pr_info("Unable to create debugfs %s directory.\n",
coredev->devpath);
return -ENODEV;
}
d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
client, &debugfs_stats_ops);
if (!d) {
debugfs_remove(client->debugfs);
return -ENOMEM;
}
debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
if (!debug_data)
return -ENOMEM;
client->debug_data = debug_data;
client->prt_dvb_stats = smsdvb_print_dvb_stats;
client->prt_isdb_stats = smsdvb_print_isdb_stats;
client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
init_waitqueue_head(&debug_data->stats_queue);
spin_lock_init(&debug_data->lock);
kref_init(&debug_data->refcount);
return 0;
}
void smsdvb_debugfs_release(struct smsdvb_client_t *client)
{
if (!client->debugfs)
return;
client->prt_dvb_stats = NULL;
client->prt_isdb_stats = NULL;
client->prt_isdb_stats_ex = NULL;
debugfs_remove_recursive(client->debugfs);
kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
client->debug_data = NULL;
client->debugfs = NULL;
}
int smsdvb_debugfs_register(void)
{
struct dentry *d;
/*
* FIXME: This was written to debug Siano USB devices. So, it creates
* the debugfs node under <debugfs>/usb.
* A similar logic would be needed for Siano sdio devices, but, in that
* case, usb_debug_root is not a good choice.
*
* Perhaps the right fix here would be to create another sysfs root
* node for sdio-based boards, but this may need some logic at sdio
* subsystem.
*/
d = debugfs_create_dir("smsdvb", usb_debug_root);
if (IS_ERR_OR_NULL(d)) {
sms_err("Couldn't create sysfs node for smsdvb");
return PTR_ERR(d);
} else {
smsdvb_debugfs_usb_root = d;
}
return 0;
}
void smsdvb_debugfs_unregister(void)
{
debugfs_remove_recursive(smsdvb_debugfs_usb_root);
smsdvb_debugfs_usb_root = NULL;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
/***********************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***********************************************************************/
struct smsdvb_debugfs;
struct smsdvb_client_t;
typedef void (*sms_prt_dvb_stats_t)(struct smsdvb_debugfs *debug_data,
struct sms_stats *p);
typedef void (*sms_prt_isdb_stats_t)(struct smsdvb_debugfs *debug_data,
struct sms_isdbt_stats *p);
typedef void (*sms_prt_isdb_stats_ex_t)
(struct smsdvb_debugfs *debug_data,
struct sms_isdbt_stats_ex *p);
struct smsdvb_client_t {
struct list_head entry;
struct smscore_device_t *coredev;
struct smscore_client_t *smsclient;
struct dvb_adapter adapter;
struct dvb_demux demux;
struct dmxdev dmxdev;
struct dvb_frontend frontend;
fe_status_t fe_status;
struct completion tune_done;
struct completion stats_done;
int last_per;
int legacy_ber, legacy_per;
int event_fe_state;
int event_unc_state;
unsigned long get_stats_jiffies;
int feed_users;
bool has_tuned;
/* stats debugfs data */
struct dentry *debugfs;
struct smsdvb_debugfs *debug_data;
sms_prt_dvb_stats_t prt_dvb_stats;
sms_prt_isdb_stats_t prt_isdb_stats;
sms_prt_isdb_stats_ex_t prt_isdb_stats_ex;
};
/*
* This struct is a mix of struct sms_rx_stats_ex and
* struct sms_srvm_signal_status.
* It was obtained by comparing the way it was filled by the original code
*/
struct RECEPTION_STATISTICS_PER_SLICES_S {
u32 result;
u32 snr;
s32 in_band_power;
u32 ts_packets;
u32 ets_packets;
u32 constellation;
u32 hp_code;
u32 tps_srv_ind_lp;
u32 tps_srv_ind_hp;
u32 cell_id;
u32 reason;
u32 request_id;
u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
u32 ber; /* Post Viterbi BER [1E-5] */
s32 RSSI; /* dBm */
s32 carrier_offset; /* Carrier Offset in bin/1024 */
u32 is_rf_locked; /* 0 - not locked, 1 - locked */
u32 is_demod_locked; /* 0 - not locked, 1 - locked */
u32 ber_bit_count; /* Total number of SYNC bits. */
u32 ber_error_count; /* Number of erronous SYNC bits. */
s32 MRC_SNR; /* dB */
s32 mrc_in_band_pwr; /* In band power in dBM */
s32 MRC_RSSI; /* dBm */
};
/* From smsdvb-debugfs.c */
#ifdef CONFIG_SMS_SIANO_DEBUGFS
int smsdvb_debugfs_create(struct smsdvb_client_t *client);
void smsdvb_debugfs_release(struct smsdvb_client_t *client);
int smsdvb_debugfs_register(void);
void smsdvb_debugfs_unregister(void);
#else
static inline int smsdvb_debugfs_create(struct smsdvb_client_t *client)
{
return 0;
}
static inline void smsdvb_debugfs_release(struct smsdvb_client_t *client) {}
static inline int smsdvb_debugfs_register(void)
{
return 0;
};
static inline void smsdvb_debugfs_unregister(void) {};
#endif

View File

@ -28,23 +28,23 @@
void smsendian_handle_tx_message(void *buffer)
{
#ifdef __BIG_ENDIAN
struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
int i;
int msgWords;
int msg_words;
switch (msg->xMsgHeader.msgType) {
switch (msg->x_msg_header.msg_type) {
case MSG_SMS_DATA_DOWNLOAD_REQ:
{
msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
msg->msg_data[0] = le32_to_cpu(msg->msg_data[0]);
break;
}
default:
msgWords = (msg->xMsgHeader.msgLength -
sizeof(struct SmsMsgHdr_ST))/4;
msg_words = (msg->x_msg_header.msg_length -
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msgWords; i++)
msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
for (i = 0; i < msg_words; i++)
msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
break;
}
@ -55,16 +55,16 @@ EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
void smsendian_handle_rx_message(void *buffer)
{
#ifdef __BIG_ENDIAN
struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
int i;
int msgWords;
int msg_words;
switch (msg->xMsgHeader.msgType) {
switch (msg->x_msg_header.msg_type) {
case MSG_SMS_GET_VERSION_EX_RES:
{
struct SmsVersionRes_ST *ver =
(struct SmsVersionRes_ST *) msg;
ver->ChipModel = le16_to_cpu(ver->ChipModel);
struct sms_version_res *ver =
(struct sms_version_res *) msg;
ver->chip_model = le16_to_cpu(ver->chip_model);
break;
}
@ -77,11 +77,11 @@ void smsendian_handle_rx_message(void *buffer)
default:
{
msgWords = (msg->xMsgHeader.msgLength -
sizeof(struct SmsMsgHdr_ST))/4;
msg_words = (msg->x_msg_header.msg_length -
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msgWords; i++)
msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
for (i = 0; i < msg_words; i++)
msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
break;
}
@ -93,11 +93,11 @@ EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
void smsendian_handle_message_header(void *msg)
{
#ifdef __BIG_ENDIAN
struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)msg;
phdr->msgType = le16_to_cpu(phdr->msgType);
phdr->msgLength = le16_to_cpu(phdr->msgLength);
phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
phdr->msg_type = le16_to_cpu(phdr->msg_type);
phdr->msg_length = le16_to_cpu(phdr->msg_length);
phdr->msg_flags = le16_to_cpu(phdr->msg_flags);
#endif /* __BIG_ENDIAN */
}
EXPORT_SYMBOL_GPL(smsendian_handle_message_header);

View File

@ -40,7 +40,6 @@ struct ir_t {
char phys[32];
char *rc_codes;
u64 protocol;
u32 timeout;
u32 controller;

View File

@ -83,45 +83,6 @@ enum dmx_success {
#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
the demux device, not to the dvr device */
/* PES type for filters which write to built-in decoder */
/* these should be kept identical to the types in dmx.h */
enum dmx_ts_pes
{ /* also send packets to decoder (if it exists) */
DMX_TS_PES_AUDIO0,
DMX_TS_PES_VIDEO0,
DMX_TS_PES_TELETEXT0,
DMX_TS_PES_SUBTITLE0,
DMX_TS_PES_PCR0,
DMX_TS_PES_AUDIO1,
DMX_TS_PES_VIDEO1,
DMX_TS_PES_TELETEXT1,
DMX_TS_PES_SUBTITLE1,
DMX_TS_PES_PCR1,
DMX_TS_PES_AUDIO2,
DMX_TS_PES_VIDEO2,
DMX_TS_PES_TELETEXT2,
DMX_TS_PES_SUBTITLE2,
DMX_TS_PES_PCR2,
DMX_TS_PES_AUDIO3,
DMX_TS_PES_VIDEO3,
DMX_TS_PES_TELETEXT3,
DMX_TS_PES_SUBTITLE3,
DMX_TS_PES_PCR3,
DMX_TS_PES_OTHER
};
#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0
#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0
#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0
#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0
#define DMX_TS_PES_PCR DMX_TS_PES_PCR0
struct dmx_ts_feed {
int is_filtering; /* Set to non-zero when filtering in progress */
struct dmx_demux *parent; /* Back-pointer */

View File

@ -569,7 +569,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
dmx_output_t otype;
int ret;
int ts_type;
dmx_pes_type_t ts_pes;
enum dmx_ts_pes ts_pes;
struct dmx_ts_feed *tsfeed;
feed->ts = NULL;
@ -852,7 +852,8 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
struct dmxdev_filter *dmxdevfilter,
struct dmx_sct_filter_params *params)
{
dprintk("function : %s\n", __func__);
dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n",
__func__, params->pid, params->flags, params->timeout);
dvb_dmxdev_filter_stop(dmxdevfilter);

View File

@ -124,8 +124,7 @@
#define USB_PID_DIBCOM_STK7770P 0x1e80
#define USB_PID_DIBCOM_NIM7090 0x1bb2
#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4
#define USB_PID_DIBCOM_TFE7090E 0x1bb7
#define USB_PID_DIBCOM_TFE7790E 0x1e6e
#define USB_PID_DIBCOM_TFE7790P 0x1e6e
#define USB_PID_DIBCOM_NIM9090M 0x2383
#define USB_PID_DIBCOM_NIM9090MD 0x2384
#define USB_PID_DPOSH_M9206_COLD 0x9206

View File

@ -440,20 +440,22 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
if (!dvb_demux_feed_err_pkts)
return;
} else /* if TEI bit is set, pid may be wrong- skip pkt counter */
if (demux->cnt_storage && dvb_demux_tscheck) {
/* check pkt counter */
if (pid < MAX_PID) {
if ((buf[3] & 0xf) != demux->cnt_storage[pid])
dprintk_tscheck("TS packet counter mismatch. "
"PID=0x%x expected 0x%x "
"got 0x%x\n",
if (demux->cnt_storage && dvb_demux_tscheck) {
/* check pkt counter */
if (pid < MAX_PID) {
if (buf[3] & 0x10)
demux->cnt_storage[pid] =
(demux->cnt_storage[pid] + 1) & 0xf;
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
pid, demux->cnt_storage[pid],
buf[3] & 0xf);
demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf;
demux->cnt_storage[pid] = buf[3] & 0xf;
}
}
/* end check */
}
/* end check */
}
list_for_each_entry(feed, &demux->feed_list, list_head) {
if ((feed->pid != pid) && (feed->pid != 0x2000))
@ -672,7 +674,7 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
return -ERESTARTSYS;
if (ts_type & TS_DECODER) {
if (pes_type >= DMX_TS_PES_OTHER) {
if (pes_type >= DMX_PES_OTHER) {
mutex_unlock(&demux->mutex);
return -EINVAL;
}
@ -844,7 +846,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
feed->pid = 0xffff;
if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_PES_OTHER)
demux->pesfilter[feed->pes_type] = NULL;
mutex_unlock(&demux->mutex);
@ -1266,7 +1268,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
INIT_LIST_HEAD(&dvbdemux->frontend_list);
for (i = 0; i < DMX_TS_PES_OTHER; i++) {
for (i = 0; i < DMX_PES_OTHER; i++) {
dvbdemux->pesfilter[i] = NULL;
dvbdemux->pids[i] = 0xffff;
}

View File

@ -119,8 +119,8 @@ struct dvb_demux {
struct list_head frontend_list;
struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
u16 pids[DMX_TS_PES_OTHER];
struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
u16 pids[DMX_PES_OTHER];
int playing;
int recording;

View File

@ -920,7 +920,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
u32 delsys;
delsys = c->delivery_system;
memset(c, 0, sizeof(struct dtv_frontend_properties));
memset(c, 0, offsetof(struct dtv_frontend_properties, strength));
c->delivery_system = delsys;
c->state = DTV_CLEAR;
@ -1509,9 +1509,74 @@ static bool is_dvbv3_delsys(u32 delsys)
return status;
}
static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
/**
* emulate_delivery_system - emulate a DVBv5 delivery system with a DVBv3 type
* @fe: struct frontend;
* @delsys: DVBv5 type that will be used for emulation
*
* Provides emulation for delivery systems that are compatible with the old
* DVBv3 call. Among its usages, it provices support for ISDB-T, and allows
* using a DVB-S2 only frontend just like it were a DVB-S, if the frontent
* parameters are compatible with DVB-S spec.
*/
static int emulate_delivery_system(struct dvb_frontend *fe, u32 delsys)
{
int ncaps, i;
int i;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
c->delivery_system = delsys;
/*
* If the call is for ISDB-T, put it into full-seg, auto mode, TV
*/
if (c->delivery_system == SYS_ISDBT) {
dev_dbg(fe->dvb->device,
"%s: Using defaults for SYS_ISDBT\n",
__func__);
if (!c->bandwidth_hz)
c->bandwidth_hz = 6000000;
c->isdbt_partial_reception = 0;
c->isdbt_sb_mode = 0;
c->isdbt_sb_subchannel = 0;
c->isdbt_sb_segment_idx = 0;
c->isdbt_sb_segment_count = 0;
c->isdbt_layer_enabled = 7;
for (i = 0; i < 3; i++) {
c->layer[i].fec = FEC_AUTO;
c->layer[i].modulation = QAM_AUTO;
c->layer[i].interleaving = 0;
c->layer[i].segment_count = 0;
}
}
dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n",
__func__, c->delivery_system);
return 0;
}
/**
* dvbv5_set_delivery_system - Sets the delivery system for a DVBv5 API call
* @fe: frontend struct
* @desired_system: delivery system requested by the user
*
* A DVBv5 call know what's the desired system it wants. So, set it.
*
* There are, however, a few known issues with early DVBv5 applications that
* are also handled by this logic:
*
* 1) Some early apps use SYS_UNDEFINED as the desired delivery system.
* This is an API violation, but, as we don't want to break userspace,
* convert it to the first supported delivery system.
* 2) Some apps might be using a DVBv5 call in a wrong way, passing, for
* example, SYS_DVBT instead of SYS_ISDBT. This is because early usage of
* ISDB-T provided backward compat with DVB-T.
*/
static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
u32 desired_system)
{
int ncaps;
u32 delsys = SYS_UNDEFINED;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
enum dvbv3_emulation_type type;
@ -1522,166 +1587,136 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
* assume that the application wants to use the first supported
* delivery system.
*/
if (c->delivery_system == SYS_UNDEFINED)
c->delivery_system = fe->ops.delsys[0];
if (desired_system == SYS_UNDEFINED)
desired_system = fe->ops.delsys[0];
if (desired_system == SYS_UNDEFINED) {
/*
* A DVBv3 call doesn't know what's the desired system.
* Also, DVBv3 applications don't know that ops.info->type
* could be changed, and they simply dies when it doesn't
* match.
* So, don't change the current delivery system, as it
* may be trying to do the wrong thing, like setting an
* ISDB-T frontend as DVB-T. Instead, find the closest
* DVBv3 system that matches the delivery system.
*/
if (is_dvbv3_delsys(c->delivery_system)) {
/*
* This is a DVBv5 call. So, it likely knows the supported
* delivery systems. So, check if the desired delivery system is
* supported
*/
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (fe->ops.delsys[ncaps] == desired_system) {
c->delivery_system = desired_system;
dev_dbg(fe->dvb->device,
"%s: Using delivery system to %d\n",
__func__, c->delivery_system);
"%s: Changing delivery system to %d\n",
__func__, desired_system);
return 0;
}
type = dvbv3_type(c->delivery_system);
switch (type) {
case DVBV3_QPSK:
desired_system = SYS_DVBS;
break;
case DVBV3_QAM:
desired_system = SYS_DVBC_ANNEX_A;
break;
case DVBV3_ATSC:
desired_system = SYS_ATSC;
break;
case DVBV3_OFDM:
desired_system = SYS_DVBT;
break;
default:
dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n",
__func__);
return -EINVAL;
}
/*
* Get a delivery system that is compatible with DVBv3
* NOTE: in order for this to work with softwares like Kaffeine that
* uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
* DVB-S, drivers that support both should put the SYS_DVBS entry
* before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
* The real fix is that userspace applications should not use DVBv3
* and not trust on calling FE_SET_FRONTEND to switch the delivery
* system.
*/
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (fe->ops.delsys[ncaps] == desired_system) {
delsys = desired_system;
break;
}
ncaps++;
}
if (delsys == SYS_UNDEFINED) {
dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n",
__func__, desired_system);
}
} else {
/*
* This is a DVBv5 call. So, it likely knows the supported
* delivery systems.
*/
/* Check if the desired delivery system is supported */
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (fe->ops.delsys[ncaps] == desired_system) {
c->delivery_system = desired_system;
dev_dbg(fe->dvb->device,
"%s: Changing delivery system to %d\n",
__func__, desired_system);
return 0;
}
ncaps++;
}
type = dvbv3_type(desired_system);
/*
* The delivery system is not supported. See if it can be
* emulated.
* The emulation only works if the desired system is one of the
* DVBv3 delivery systems
*/
if (!is_dvbv3_delsys(desired_system)) {
dev_dbg(fe->dvb->device,
"%s: can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n",
__func__);
return -EINVAL;
}
/*
* Get the last non-DVBv3 delivery system that has the same type
* of the desired system
*/
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) &&
!is_dvbv3_delsys(fe->ops.delsys[ncaps]))
delsys = fe->ops.delsys[ncaps];
ncaps++;
}
/* There's nothing compatible with the desired delivery system */
if (delsys == SYS_UNDEFINED) {
dev_dbg(fe->dvb->device,
"%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n",
__func__);
return -EINVAL;
}
ncaps++;
}
c->delivery_system = delsys;
/*
* The DVBv3 or DVBv5 call is requesting a different system. So,
* emulation is needed.
* The requested delivery system isn't supported. Maybe userspace
* is requesting a DVBv3 compatible delivery system.
*
* Emulate newer delivery systems like ISDBT, DVBT and DTMB
* for older DVBv5 applications. The emulation will try to use
* the auto mode for most things, and will assume that the desired
* delivery system is the last one at the ops.delsys[] array
* The emulation only works if the desired system is one of the
* delivery systems supported by DVBv3 API
*/
dev_dbg(fe->dvb->device,
"%s: Using delivery system %d emulated as if it were a %d\n",
__func__, delsys, desired_system);
if (!is_dvbv3_delsys(desired_system)) {
dev_dbg(fe->dvb->device,
"%s: Delivery system %d not supported.\n",
__func__, desired_system);
return -EINVAL;
}
type = dvbv3_type(desired_system);
/*
* For now, handles ISDB-T calls. More code may be needed here for the
* other emulated stuff
*/
if (type == DVBV3_OFDM) {
if (c->delivery_system == SYS_ISDBT) {
dev_dbg(fe->dvb->device,
"%s: Using defaults for SYS_ISDBT\n",
__func__);
if (!c->bandwidth_hz)
c->bandwidth_hz = 6000000;
c->isdbt_partial_reception = 0;
c->isdbt_sb_mode = 0;
c->isdbt_sb_subchannel = 0;
c->isdbt_sb_segment_idx = 0;
c->isdbt_sb_segment_count = 0;
c->isdbt_layer_enabled = 0;
for (i = 0; i < 3; i++) {
c->layer[i].fec = FEC_AUTO;
c->layer[i].modulation = QAM_AUTO;
c->layer[i].interleaving = 0;
c->layer[i].segment_count = 0;
}
}
* Get the last non-DVBv3 delivery system that has the same type
* of the desired system
*/
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (dvbv3_type(fe->ops.delsys[ncaps]) == type)
delsys = fe->ops.delsys[ncaps];
ncaps++;
}
dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n",
__func__, c->delivery_system);
return 0;
/* There's nothing compatible with the desired delivery system */
if (delsys == SYS_UNDEFINED) {
dev_dbg(fe->dvb->device,
"%s: Delivery system %d not supported on emulation mode.\n",
__func__, desired_system);
return -EINVAL;
}
dev_dbg(fe->dvb->device,
"%s: Using delivery system %d emulated as if it were %d\n",
__func__, delsys, desired_system);
return emulate_delivery_system(fe, desired_system);
}
/**
* dvbv3_set_delivery_system - Sets the delivery system for a DVBv3 API call
* @fe: frontend struct
*
* A DVBv3 call doesn't know what's the desired system it wants. It also
* doesn't allow to switch between different types. Due to that, userspace
* should use DVBv5 instead.
* However, in order to avoid breaking userspace API, limited backward
* compatibility support is provided.
*
* There are some delivery systems that are incompatible with DVBv3 calls.
*
* This routine should work fine for frontends that support just one delivery
* system.
*
* For frontends that support multiple frontends:
* 1) It defaults to use the first supported delivery system. There's an
* userspace application that allows changing it at runtime;
*
* 2) If the current delivery system is not compatible with DVBv3, it gets
* the first one that it is compatible.
*
* NOTE: in order for this to work with applications like Kaffeine that
* uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
* DVB-S, drivers that support both DVB-S and DVB-S2 should have the
* SYS_DVBS entry before the SYS_DVBS2, otherwise it won't switch back
* to DVB-S.
*/
static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
{
int ncaps;
u32 delsys = SYS_UNDEFINED;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
/* If not set yet, defaults to the first supported delivery system */
if (c->delivery_system == SYS_UNDEFINED)
c->delivery_system = fe->ops.delsys[0];
/*
* Trivial case: just use the current one, if it already a DVBv3
* delivery system
*/
if (is_dvbv3_delsys(c->delivery_system)) {
dev_dbg(fe->dvb->device,
"%s: Using delivery system to %d\n",
__func__, c->delivery_system);
return 0;
}
/*
* Seek for the first delivery system that it is compatible with a
* DVBv3 standard
*/
ncaps = 0;
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (dvbv3_type(fe->ops.delsys[ncaps]) != DVBV3_UNKNOWN) {
delsys = fe->ops.delsys[ncaps];
break;
}
ncaps++;
}
if (delsys == SYS_UNDEFINED) {
dev_dbg(fe->dvb->device,
"%s: Couldn't find a delivery system that works with FE_SET_FRONTEND\n",
__func__);
return -EINVAL;
}
return emulate_delivery_system(fe, delsys);
}
static int dtv_property_process_set(struct dvb_frontend *fe,
@ -1742,7 +1777,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
c->rolloff = tvp->u.data;
break;
case DTV_DELIVERY_SYSTEM:
r = set_delivery_system(fe, tvp->u.data);
r = dvbv5_set_delivery_system(fe, tvp->u.data);
break;
case DTV_VOLTAGE:
c->voltage = tvp->u.data;
@ -2335,7 +2370,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
break;
case FE_SET_FRONTEND:
err = set_delivery_system(fe, SYS_UNDEFINED);
err = dvbv3_set_delivery_system(fe);
if (err)
break;
@ -2594,7 +2629,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
* first supported delivery system (ops->delsys[0])
*/
fe->dtv_property_cache.delivery_system = fe->ops.delsys[0];
fe->dtv_property_cache.delivery_system = fe->ops.delsys[0];
dvb_frontend_clear_cache(fe);
mutex_unlock(&frontend_mutex);

View File

@ -245,8 +245,8 @@ struct analog_demod_ops {
void (*set_params)(struct dvb_frontend *fe,
struct analog_parameters *params);
int (*has_signal)(struct dvb_frontend *fe);
int (*get_afc)(struct dvb_frontend *fe);
int (*has_signal)(struct dvb_frontend *fe, u16 *signal);
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
void (*tuner_status)(struct dvb_frontend *fe);
void (*standby)(struct dvb_frontend *fe);
void (*release)(struct dvb_frontend *fe);

View File

@ -1044,7 +1044,7 @@ static int dvb_net_feed_start(struct net_device *dev)
ret = priv->tsfeed->set(priv->tsfeed,
priv->pid, /* pid */
TS_PACKET, /* type */
DMX_TS_PES_OTHER, /* pes type */
DMX_PES_OTHER, /* pes type */
32768, /* circular buffer size */
timeout /* timeout */
);

View File

@ -210,7 +210,7 @@ config DVB_SI21XX
config DVB_TS2020
tristate "Montage Tehnology TS2020 based tuners"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner.

View File

@ -21,12 +21,13 @@
#ifndef A8293_H
#define A8293_H
#include <linux/kconfig.h>
struct a8293_config {
u8 i2c_addr;
};
#if defined(CONFIG_DVB_A8293) || \
(defined(CONFIG_DVB_A8293_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_A8293)
extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg);
#else

View File

@ -25,6 +25,7 @@
#ifndef AF9013_H
#define AF9013_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
/* AF9013/5 GPIOs (mostly guessed)
@ -102,8 +103,7 @@ struct af9013_config {
u8 gpio[4];
};
#if defined(CONFIG_DVB_AF9013) || \
(defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_AF9013)
extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -156,6 +156,37 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
return 0;
}
/* write reg val table using reg addr auto increment */
static int af9033_wr_reg_val_tab(struct af9033_state *state,
const struct reg_val *tab, int tab_len)
{
int ret, i, j;
u8 buf[tab_len];
dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
for (i = 0, j = 0; i < tab_len; i++) {
buf[j] = tab[i].val;
if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
ret = af9033_wr_regs(state, tab[i].reg - j, buf, j + 1);
if (ret < 0)
goto err;
j = 0;
} else {
j++;
}
}
return 0;
err:
dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
{
u32 r = 0, c = 0, i;
@ -223,6 +254,7 @@ static int af9033_init(struct dvb_frontend *fe)
{ 0x80f986, state->ts_mode_parallel, 0x01 },
{ 0x00d827, 0x00, 0xff },
{ 0x00d829, 0x00, 0xff },
{ 0x800045, state->cfg.adc_multiplier, 0xff },
};
/* program clock control */
@ -286,14 +318,29 @@ static int af9033_init(struct dvb_frontend *fe)
/* load OFSM settings */
dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
len = ARRAY_SIZE(ofsm_init);
init = ofsm_init;
for (i = 0; i < len; i++) {
ret = af9033_wr_reg(state, init[i].reg, init[i].val);
if (ret < 0)
goto err;
switch (state->cfg.tuner) {
case AF9033_TUNER_IT9135_38:
case AF9033_TUNER_IT9135_51:
case AF9033_TUNER_IT9135_52:
len = ARRAY_SIZE(ofsm_init_it9135_v1);
init = ofsm_init_it9135_v1;
break;
case AF9033_TUNER_IT9135_60:
case AF9033_TUNER_IT9135_61:
case AF9033_TUNER_IT9135_62:
len = ARRAY_SIZE(ofsm_init_it9135_v2);
init = ofsm_init_it9135_v2;
break;
default:
len = ARRAY_SIZE(ofsm_init);
init = ofsm_init;
break;
}
ret = af9033_wr_reg_val_tab(state, init, len);
if (ret < 0)
goto err;
/* load tuner specific settings */
dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
__func__);
@ -322,6 +369,30 @@ static int af9033_init(struct dvb_frontend *fe)
len = ARRAY_SIZE(tuner_init_fc0012);
init = tuner_init_fc0012;
break;
case AF9033_TUNER_IT9135_38:
len = ARRAY_SIZE(tuner_init_it9135_38);
init = tuner_init_it9135_38;
break;
case AF9033_TUNER_IT9135_51:
len = ARRAY_SIZE(tuner_init_it9135_51);
init = tuner_init_it9135_51;
break;
case AF9033_TUNER_IT9135_52:
len = ARRAY_SIZE(tuner_init_it9135_52);
init = tuner_init_it9135_52;
break;
case AF9033_TUNER_IT9135_60:
len = ARRAY_SIZE(tuner_init_it9135_60);
init = tuner_init_it9135_60;
break;
case AF9033_TUNER_IT9135_61:
len = ARRAY_SIZE(tuner_init_it9135_61);
init = tuner_init_it9135_61;
break;
case AF9033_TUNER_IT9135_62:
len = ARRAY_SIZE(tuner_init_it9135_62);
init = tuner_init_it9135_62;
break;
default:
dev_dbg(&state->i2c->dev, "%s: unsupported tuner ID=%d\n",
__func__, state->cfg.tuner);
@ -329,11 +400,9 @@ static int af9033_init(struct dvb_frontend *fe)
goto err;
}
for (i = 0; i < len; i++) {
ret = af9033_wr_reg(state, init[i].reg, init[i].val);
if (ret < 0)
goto err;
}
ret = af9033_wr_reg_val_tab(state, init, len);
if (ret < 0)
goto err;
if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01);
@ -349,6 +418,15 @@ static int af9033_init(struct dvb_frontend *fe)
goto err;
}
switch (state->cfg.tuner) {
case AF9033_TUNER_IT9135_60:
case AF9033_TUNER_IT9135_61:
case AF9033_TUNER_IT9135_62:
ret = af9033_wr_reg(state, 0x800000, 0x01);
if (ret < 0)
goto err;
}
state->bandwidth_hz = 0; /* force to program all parameters */
return 0;
@ -415,7 +493,8 @@ static int af9033_sleep(struct dvb_frontend *fe)
static int af9033_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *fesettings)
{
fesettings->min_delay_ms = 800;
/* 800 => 2000 because IT9135 v2 is slow to gain lock */
fesettings->min_delay_ms = 2000;
fesettings->step_size = 0;
fesettings->max_drift = 0;
@ -498,17 +577,17 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
if (spec_inv == -1)
freq_cw = 0x800000 - freq_cw;
/* get adc multiplies */
ret = af9033_rd_reg(state, 0x800045, &tmp);
if (ret < 0)
goto err;
if (tmp == 1)
if (state->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
freq_cw /= 2;
buf[0] = (freq_cw >> 0) & 0xff;
buf[1] = (freq_cw >> 8) & 0xff;
buf[2] = (freq_cw >> 16) & 0x7f;
/* FIXME: there seems to be calculation error here... */
if (if_frequency == 0)
buf[2] = 0;
ret = af9033_wr_regs(state, 0x800029, buf, 3);
if (ret < 0)
goto err;
@ -934,13 +1013,24 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
/* sleep */
ret = af9033_wr_reg(state, 0x80004c, 1);
if (ret < 0)
goto err;
switch (state->cfg.tuner) {
case AF9033_TUNER_IT9135_38:
case AF9033_TUNER_IT9135_51:
case AF9033_TUNER_IT9135_52:
case AF9033_TUNER_IT9135_60:
case AF9033_TUNER_IT9135_61:
case AF9033_TUNER_IT9135_62:
/* IT9135 did not like to sleep at that early */
break;
default:
ret = af9033_wr_reg(state, 0x80004c, 1);
if (ret < 0)
goto err;
ret = af9033_wr_reg(state, 0x800000, 0);
if (ret < 0)
goto err;
ret = af9033_wr_reg(state, 0x800000, 0);
if (ret < 0)
goto err;
}
/* configure internal TS mode */
switch (state->cfg.ts_mode) {

View File

@ -22,6 +22,8 @@
#ifndef AF9033_H
#define AF9033_H
#include <linux/kconfig.h>
struct af9033_config {
/*
* I2C address
@ -35,6 +37,13 @@ struct af9033_config {
*/
u32 clock;
/*
* ADC multiplier
*/
#define AF9033_ADC_MULTIPLIER_1X 0
#define AF9033_ADC_MULTIPLIER_2X 1
u8 adc_multiplier;
/*
* tuner
*/
@ -44,6 +53,14 @@ struct af9033_config {
#define AF9033_TUNER_MXL5007T 0xa0 /* MaxLinear MxL5007T */
#define AF9033_TUNER_TDA18218 0xa1 /* NXP TDA 18218HN */
#define AF9033_TUNER_FC2580 0x32 /* FCI FC2580 */
/* 50-5f Omega */
#define AF9033_TUNER_IT9135_38 0x38 /* Omega */
#define AF9033_TUNER_IT9135_51 0x51 /* Omega LNA config 1 */
#define AF9033_TUNER_IT9135_52 0x52 /* Omega LNA config 2 */
/* 60-6f Omega v2 */
#define AF9033_TUNER_IT9135_60 0x60 /* Omega v2 */
#define AF9033_TUNER_IT9135_61 0x61 /* Omega v2 LNA config 1 */
#define AF9033_TUNER_IT9135_62 0x62 /* Omega v2 LNA config 2 */
u8 tuner;
/*
@ -61,8 +78,7 @@ struct af9033_config {
};
#if defined(CONFIG_DVB_AF9033) || \
(defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_AF9033)
extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct i2c_adapter *i2c);
#else

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#ifndef __ATBM8830_H__
#define __ATBM8830_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
@ -60,8 +61,7 @@ struct atbm8830_config {
u8 agc_hold_loop;
};
#if defined(CONFIG_DVB_ATBM8830) || \
(defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_ATBM8830)
extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -22,6 +22,7 @@
#ifndef __AU8522_H__
#define __AU8522_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
enum au8522_if_freq {
@ -60,8 +61,7 @@ struct au8522_config {
enum au8522_if_freq qam_if;
};
#if defined(CONFIG_DVB_AU8522) || \
(defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_AU8522_DTV)
extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -229,15 +229,11 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
/* Provide reasonable defaults for picture tuning values */
au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
state->brightness = 0xed - 128;
au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
state->contrast = 0x79;
au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
state->saturation = 0x80;
au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
state->hue = 0x00;
/* Other decoder registers */
au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
@ -489,75 +485,32 @@ static void set_audio_input(struct au8522_state *state, int aud_input)
/* ----------------------------------------------------------------------- */
static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int au8522_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct au8522_state *state = to_state(sd);
struct au8522_state *state =
container_of(ctrl->handler, struct au8522_state, hdl);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
state->brightness = ctrl->value;
au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
ctrl->value - 128);
ctrl->val - 128);
break;
case V4L2_CID_CONTRAST:
state->contrast = ctrl->value;
au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
ctrl->value);
ctrl->val);
break;
case V4L2_CID_SATURATION:
state->saturation = ctrl->value;
au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
ctrl->value);
ctrl->val);
au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
ctrl->value);
ctrl->val);
break;
case V4L2_CID_HUE:
state->hue = ctrl->value;
au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
ctrl->value >> 8);
ctrl->val >> 8);
au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
ctrl->value & 0xFF);
ctrl->val & 0xFF);
break;
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
/* Not yet implemented */
default:
return -EINVAL;
}
return 0;
}
static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct au8522_state *state = to_state(sd);
/* Note that we are using values cached in the state structure instead
of reading the registers due to issues with i2c reads not working
properly/consistently yet on the HVR-950q */
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = state->brightness;
break;
case V4L2_CID_CONTRAST:
ctrl->value = state->contrast;
break;
case V4L2_CID_SATURATION:
ctrl->value = state->saturation;
break;
case V4L2_CID_HUE:
ctrl->value = state->hue;
break;
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
/* Not yet supported */
default:
return -EINVAL;
}
@ -583,7 +536,7 @@ static int au8522_g_register(struct v4l2_subdev *sd,
}
static int au8522_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
const struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct au8522_state *state = to_state(sd);
@ -616,26 +569,6 @@ static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_CONTRAST:
return v4l2_ctrl_query_fill(qc, 0, 255, 1,
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_HUE:
return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
default:
break;
}
qc->type = 0;
return -EINVAL;
}
static int au8522_reset(struct v4l2_subdev *sd, u32 val)
{
struct au8522_state *state = to_state(sd);
@ -712,20 +645,11 @@ static int au8522_g_chip_ident(struct v4l2_subdev *sd,
return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
}
static int au8522_log_status(struct v4l2_subdev *sd)
{
/* FIXME: Add some status info here */
return 0;
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops au8522_core_ops = {
.log_status = au8522_log_status,
.log_status = v4l2_ctrl_subdev_log_status,
.g_chip_ident = au8522_g_chip_ident,
.g_ctrl = au8522_g_ctrl,
.s_ctrl = au8522_s_ctrl,
.queryctrl = au8522_queryctrl,
.reset = au8522_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = au8522_g_register,
@ -753,12 +677,17 @@ static const struct v4l2_subdev_ops au8522_ops = {
.video = &au8522_video_ops,
};
static const struct v4l2_ctrl_ops au8522_ctrl_ops = {
.s_ctrl = au8522_s_ctrl,
};
/* ----------------------------------------------------------------------- */
static int au8522_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct au8522_state *state;
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
int instance;
struct au8522_config *demod_config;
@ -799,6 +728,27 @@ static int au8522_probe(struct i2c_client *client,
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &au8522_ops);
hdl = &state->hdl;
v4l2_ctrl_handler_init(hdl, 4);
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
V4L2_CID_BRIGHTNESS, 0, 255, 1, 109);
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
V4L2_CID_CONTRAST, 0, 255, 1,
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
V4L2_CID_SATURATION, 0, 255, 1, 128);
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
V4L2_CID_HUE, -32768, 32767, 1, 0);
sd->ctrl_handler = hdl;
if (hdl->error) {
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
kfree(demod_config);
kfree(state);
return err;
}
state->c = client;
state->vid_input = AU8522_COMPOSITE_CH1;
state->aud_input = AU8522_AUDIO_NONE;
@ -815,6 +765,7 @@ static int au8522_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
au8522_release_state(to_state(sd));
return 0;
}

View File

@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <linux/i2c.h>
#include "dvb_frontend.h"
#include "au8522.h"
@ -65,10 +66,7 @@ struct au8522_state {
int aud_input;
u32 id;
u32 rev;
u8 brightness;
u8 contrast;
u8 saturation;
s16 hue;
struct v4l2_ctrl_handler hdl;
};
/* These are routines shared by both the VSB/QAM demodulator and the analog

View File

@ -28,6 +28,7 @@
#ifndef CX22702_H
#define CX22702_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cx22702_config {
@ -40,8 +41,7 @@ struct cx22702_config {
u8 output_mode;
};
#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
&& defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_CX22702)
extern struct dvb_frontend *cx22702_attach(
const struct cx22702_config *config,
struct i2c_adapter *i2c);

View File

@ -22,6 +22,8 @@
#ifndef CX24113_H
#define CX24113_H
#include <linux/kconfig.h>
struct dvb_frontend;
struct cx24113_config {
@ -30,8 +32,7 @@ struct cx24113_config {
u32 xtal_khz;
};
#if defined(CONFIG_DVB_TUNER_CX24113) || \
(defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_TUNER_CX24113)
extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
const struct cx24113_config *config, struct i2c_adapter *i2c);

View File

@ -21,6 +21,7 @@
#ifndef CX24116_H
#define CX24116_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cx24116_config {
@ -40,8 +41,7 @@ struct cx24116_config {
u16 i2c_wr_max;
};
#if defined(CONFIG_DVB_CX24116) || \
(defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_CX24116)
extern struct dvb_frontend *cx24116_attach(
const struct cx24116_config *config,
struct i2c_adapter *i2c);

View File

@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
#include "cx24123.h"
@ -452,7 +453,8 @@ static u32 cx24123_int_log2(u32 a, u32 b)
static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
{
u32 tmp, sample_rate, ratio, sample_gain;
u64 tmp;
u32 sample_rate, ratio, sample_gain;
u8 pll_mult;
/* check if symbol rate is within limits */
@ -482,27 +484,11 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
sample_rate = pll_mult * XTAL;
/*
SYSSymbolRate[21:0] = (srate << 23) / sample_rate
We have to use 32 bit unsigned arithmetic without precision loss.
The maximum srate is 45000000 or 0x02AEA540. This number has
only 6 clear bits on top, hence we can shift it left only 6 bits
at a time. Borrowed from cx24110.c
*/
tmp = srate << 6;
ratio = tmp / sample_rate;
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 5;
ratio = (ratio << 5) + (tmp / sample_rate);
/* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */
tmp = ((u64)srate) << 23;
do_div(tmp, sample_rate);
ratio = (u32) tmp;
cx24123_writereg(state, 0x01, pll_mult * 6);

View File

@ -21,6 +21,7 @@
#ifndef CX24123_H
#define CX24123_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cx24123_config {
@ -38,8 +39,7 @@ struct cx24123_config {
void (*agc_callback) (struct dvb_frontend *);
};
#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
&& defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_CX24123)
extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c);
extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);

View File

@ -22,6 +22,7 @@
#ifndef CXD2820R_H
#define CXD2820R_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#define CXD2820R_GPIO_D (0 << 0) /* disable */
@ -65,8 +66,7 @@ struct cxd2820r_config {
};
#if defined(CONFIG_DVB_CXD2820R) || \
(defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_CXD2820R)
extern struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
struct i2c_adapter *i2c,

View File

@ -660,7 +660,8 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
FE_CAN_2G_MODULATION
FE_CAN_2G_MODULATION |
FE_CAN_MULTISTREAM
},
.release = cxd2820r_release,

View File

@ -124,6 +124,23 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
buf[1] = ((if_ctl >> 8) & 0xff);
buf[2] = ((if_ctl >> 0) & 0xff);
/* PLP filtering */
if (c->stream_id > 255) {
dev_dbg(&priv->i2c->dev, "%s: Disable PLP filtering\n", __func__);
ret = cxd2820r_wr_reg(priv, 0x023ad , 0);
if (ret)
goto error;
} else {
dev_dbg(&priv->i2c->dev, "%s: Enable PLP filtering = %d\n", __func__,
c->stream_id);
ret = cxd2820r_wr_reg(priv, 0x023af , c->stream_id & 0xFF);
if (ret)
goto error;
ret = cxd2820r_wr_reg(priv, 0x023ad , 1);
if (ret)
goto error;
}
ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
if (ret)
goto error;

View File

@ -528,20 +528,19 @@ static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_
u16 PllCfg, i, v;
HARD_RESET(state);
dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
if (cfg->in_soc)
return;
if (!cfg->in_soc) {
/* adcClkOutRatio=8->7, release reset */
dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
if (cfg->clkoutdrive != 0)
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
else
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
}
dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
/* adcClkOutRatio=8->7, release reset */
dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
if (cfg->clkoutdrive != 0)
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
else
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
/* Read Pll current config * */
PllCfg = dib0090_read_reg(state, 0x21);
@ -694,192 +693,174 @@ void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
EXPORT_SYMBOL(dib0090_dcc_freq);
static const u16 bb_ramp_pwm_normal_socs[] = {
550, /* max BB gain in 10th of dB */
(1 << 9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
550, /* max BB gain in 10th of dB */
(1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
440,
(4 << 9) | 0, /* BB_RAMP3 = 26dB */
(0 << 9) | 208, /* BB_RAMP4 */
(4 << 9) | 208, /* BB_RAMP5 = 29dB */
(0 << 9) | 440, /* BB_RAMP6 */
(4 << 9) | 0, /* BB_RAMP3 = 26dB */
(0 << 9) | 208, /* BB_RAMP4 */
(4 << 9) | 208, /* BB_RAMP5 = 29dB */
(0 << 9) | 440, /* BB_RAMP6 */
};
static const u16 rf_ramp_pwm_cband_7090[] = {
280, /* max RF gain in 10th of dB */
18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
504, /* ramp_max = maximum X used on the ramp */
(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
(0 << 10) | 504, /* RF_RAMP6, LNA 1 */
(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
(0 << 10) | 364, /* RF_RAMP8, LNA 2 */
(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
(0 << 10) | 228, /* GAIN_4_2, LNA 3 */
(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
(0 << 10) | 109, /* RF_RAMP4, LNA 4 */
static const u16 rf_ramp_pwm_cband_7090p[] = {
280, /* max RF gain in 10th of dB */
18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
504, /* ramp_max = maximum X used on the ramp */
(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
(0 << 10) | 504, /* RF_RAMP6, LNA 1 */
(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
(0 << 10) | 364, /* RF_RAMP8, LNA 2 */
(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
(0 << 10) | 228, /* GAIN_4_2, LNA 3 */
(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
(0 << 10) | 109, /* RF_RAMP4, LNA 4 */
};
static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
186,
40,
746,
(10 << 10) | 345,
(0 << 10) | 746,
(0 << 10) | 0,
(0 << 10) | 0,
(28 << 10) | 200,
(0 << 10) | 345,
(20 << 10) | 0,
(0 << 10) | 200,
static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
186, /* max RF gain in 10th of dB */
40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
746, /* ramp_max = maximum X used on the ramp */
(10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */
(0 << 10) | 746, /* RF_RAMP6, LNA 1 */
(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
(0 << 10) | 345, /* GAIN_4_2, LNA 3 */
(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
(0 << 10) | 200, /* RF_RAMP4, LNA 4 */
};
static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
86,
40,
345,
(0 << 10) | 0,
(0 << 10) | 0,
(0 << 10) | 0,
(0 << 10) | 0,
(28 << 10) | 200,
(0 << 10) | 345,
(20 << 10) | 0,
(0 << 10) | 200,
static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
86, /* max RF gain in 10th of dB */
40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
345, /* ramp_max = maximum X used on the ramp */
(0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */
(0 << 10) | 0, /* RF_RAMP6, LNA 1 */
(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
(0 << 10) | 345, /* GAIN_4_2, LNA 3 */
(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
(0 << 10) | 200, /* RF_RAMP4, LNA 4 */
};
static const u16 rf_ramp_pwm_cband_8090[] = {
345, /* max RF gain in 10th of dB */
29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
1000, /* ramp_max = maximum X used on the ramp */
(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
(0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
(0 << 10) | 772, /* RF_RAMP6, LNA 2 */
(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
(0 << 10) | 496, /* RF_RAMP8, LNA 3 */
(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
(0 << 10) | 200, /* GAIN_4_2, LNA 4 */
345, /* max RF gain in 10th of dB */
29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
1000, /* ramp_max = maximum X used on the ramp */
(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
(0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
(0 << 10) | 772, /* RF_RAMP6, LNA 2 */
(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
(0 << 10) | 496, /* RF_RAMP8, LNA 3 */
(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
(0 << 10) | 200, /* GAIN_4_2, LNA 4 */
};
static const u16 rf_ramp_pwm_uhf_7090[] = {
407, /* max RF gain in 10th of dB */
13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
529, /* ramp_max = maximum X used on the ramp */
(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
(0 << 10) | 176, /* RF_RAMP4, LNA 1 */
(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
(0 << 10) | 529, /* RF_RAMP6, LNA 2 */
(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
(0 << 10) | 400, /* RF_RAMP8, LNA 3 */
(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
(0 << 10) | 316, /* GAIN_4_2, LNA 4 */
407, /* max RF gain in 10th of dB */
13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
529, /* ramp_max = maximum X used on the ramp */
(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
(0 << 10) | 176, /* RF_RAMP4, LNA 1 */
(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
(0 << 10) | 529, /* RF_RAMP6, LNA 2 */
(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
(0 << 10) | 400, /* RF_RAMP8, LNA 3 */
(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
(0 << 10) | 316, /* GAIN_4_2, LNA 4 */
};
static const u16 rf_ramp_pwm_uhf_8090[] = {
388, /* max RF gain in 10th of dB */
26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
1008, /* ramp_max = maximum X used on the ramp */
(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
(0 << 10) | 369, /* RF_RAMP4, LNA 1 */
(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
(0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
(0 << 10) | 809, /* RF_RAMP8, LNA 3 */
(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
(0 << 10) | 659, /* GAIN_4_2, LNA 4 */
388, /* max RF gain in 10th of dB */
26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
1008, /* ramp_max = maximum X used on the ramp */
(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
(0 << 10) | 369, /* RF_RAMP4, LNA 1 */
(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
(0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
(0 << 10) | 809, /* RF_RAMP8, LNA 3 */
(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
(0 << 10) | 659, /* GAIN_4_2, LNA 4 */
};
/* GENERAL PWM ramp definition for all other Krosus */
static const u16 bb_ramp_pwm_normal[] = {
500, /* max BB gain in 10th of dB */
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
400,
(2 << 9) | 0, /* BB_RAMP3 = 21dB */
(0 << 9) | 168, /* BB_RAMP4 */
(2 << 9) | 168, /* BB_RAMP5 = 29dB */
(0 << 9) | 400, /* BB_RAMP6 */
};
static const u16 bb_ramp_pwm_boost[] = {
550, /* max BB gain in 10th of dB */
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
440,
(2 << 9) | 0, /* BB_RAMP3 = 26dB */
(0 << 9) | 208, /* BB_RAMP4 */
(2 << 9) | 208, /* BB_RAMP5 = 29dB */
(0 << 9) | 440, /* BB_RAMP6 */
};
static const u16 rf_ramp_pwm_cband[] = {
0, /* max RF gain in 10th of dB */
0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
0, /* ramp_max = maximum X used on the ramp */
(0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */
(0 << 10) | 0, /* 0x2d, LNA 1 */
(0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */
(0 << 10) | 0, /* 0x2f, LNA 2 */
(0 << 10) | 0, /* 0x30, LNA 3 = 0dB */
(0 << 10) | 0, /* 0x31, LNA 3 */
(0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
(0 << 10) | 0, /* GAIN_4_2, LNA 4 */
};
static const u16 rf_ramp_vhf[] = {
412, /* max RF gain in 10th of dB */
132, 307, 127, /* LNA1, 13.2dB */
105, 412, 255, /* LNA2, 10.5dB */
50, 50, 127, /* LNA3, 5dB */
125, 175, 127, /* LNA4, 12.5dB */
0, 0, 127, /* CBAND, 0dB */
};
static const u16 rf_ramp_uhf[] = {
412, /* max RF gain in 10th of dB */
132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
105, 412, 255, /* LNA2 : 10.5 dB */
50, 50, 127, /* LNA3 : 5.0 dB */
125, 175, 127, /* LNA4 : 12.5 dB */
0, 0, 127, /* CBAND : 0.0 dB */
};
static const u16 rf_ramp_cband_broadmatching[] = /* for p1G only */
{
314, /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
84, 314, 127, /* LNA1 */
80, 230, 255, /* LNA2 */
80, 150, 127, /* LNA3 It was measured 12dB, do not lock if 120 */
70, 70, 127, /* LNA4 */
0, 0, 127, /* CBAND */
};
static const u16 rf_ramp_cband[] = {
332, /* max RF gain in 10th of dB */
132, 252, 127, /* LNA1, dB */
80, 332, 255, /* LNA2, dB */
0, 0, 127, /* LNA3, dB */
0, 0, 127, /* LNA4, dB */
120, 120, 127, /* LT1 CBAND */
314, /* max RF gain in 10th of dB */
33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
1023, /* ramp_max = maximum X used on the ramp */
(8 << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */
(0 << 10) | 1023, /* RF_RAMP4, LNA 1 */
(15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */
(0 << 10) | 742, /* RF_RAMP6, LNA 2 */
(9 << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */
(0 << 10) | 468, /* RF_RAMP8, LNA 3 */
(9 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
(0 << 10) | 233, /* GAIN_4_2, LNA 4 */
};
static const u16 rf_ramp_pwm_vhf[] = {
404, /* max RF gain in 10th of dB */
25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
1011, /* ramp_max = maximum X used on the ramp */
(6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
(0 << 10) | 756, /* 0x2d, LNA 1 */
(16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
(0 << 10) | 1011, /* 0x2f, LNA 2 */
(16 << 10) | 290, /* 0x30, LNA 3 = 5dB */
(0 << 10) | 417, /* 0x31, LNA 3 */
(7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */
(0 << 10) | 290, /* GAIN_4_2, LNA 4 */
398, /* max RF gain in 10th of dB */
24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
954, /* ramp_max = maximum X used on the ramp */
(7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
(0 << 10) | 290, /* RF_RAMP4, LNA 1 */
(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
(0 << 10) | 954, /* RF_RAMP6, LNA 2 */
(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
(0 << 10) | 699, /* RF_RAMP8, LNA 3 */
(7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
(0 << 10) | 580, /* GAIN_4_2, LNA 4 */
};
static const u16 rf_ramp_pwm_uhf[] = {
404, /* max RF gain in 10th of dB */
25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
1011, /* ramp_max = maximum X used on the ramp */
(6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
(0 << 10) | 756, /* 0x2d, LNA 1 */
(16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
(0 << 10) | 1011, /* 0x2f, LNA 2 */
(16 << 10) | 0, /* 0x30, LNA 3 = 5dB */
(0 << 10) | 127, /* 0x31, LNA 3 */
(7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */
(0 << 10) | 417, /* GAIN_4_2, LNA 4 */
398, /* max RF gain in 10th of dB */
24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
954, /* ramp_max = maximum X used on the ramp */
(7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
(0 << 10) | 290, /* RF_RAMP4, LNA 1 */
(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
(0 << 10) | 954, /* RF_RAMP6, LNA 2 */
(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
(0 << 10) | 699, /* RF_RAMP8, LNA 3 */
(7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
(0 << 10) | 580, /* GAIN_4_2, LNA 4 */
};
static const u16 bb_ramp_boost[] = {
550, /* max BB gain in 10th of dB */
260, 260, 26, /* BB1, 26dB */
290, 550, 29, /* BB2, 29dB */
};
static const u16 bb_ramp_pwm_normal[] = {
500, /* max RF gain in 10th of dB */
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
400,
(2 << 9) | 0, /* 0x35 = 21dB */
(0 << 9) | 168, /* 0x36 */
(2 << 9) | 168, /* 0x37 = 29dB */
(0 << 9) | 400, /* 0x38 */
static const u16 rf_ramp_pwm_sband[] = {
253, /* max RF gain in 10th of dB */
38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
961,
(4 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */
(0 << 10) | 508, /* RF_RAMP4, LNA 1 */
(9 << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */
(0 << 10) | 961, /* RF_RAMP6, LNA 2 */
(0 << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */
(0 << 10) | 0, /* RF_RAMP8, LNA 3 */
(0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
(0 << 10) | 0, /* GAIN_4_2, LNA 4 */
};
struct slope {
@ -1089,70 +1070,69 @@ static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
{
struct dib0090_state *state = fe->tuner_priv;
/* reset the AGC */
u16 *bb_ramp = (u16 *)&bb_ramp_pwm_normal; /* default baseband config */
u16 *rf_ramp = NULL;
u8 en_pwm_rf_mux = 1;
/* reset the AGC */
if (state->config->use_pwm_agc) {
#ifdef CONFIG_BAND_SBAND
if (state->current_band == BAND_SBAND) {
dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
} else
#endif
#ifdef CONFIG_BAND_CBAND
if (state->current_band == BAND_CBAND) {
if (state->identity.in_soc) {
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
else if (state->identity.version == SOC_7090_P1G_11R1
|| state->identity.version == SOC_7090_P1G_21R1) {
rf_ramp = (u16 *)&rf_ramp_pwm_cband_8090;
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
if (state->config->is_dib7090e) {
if (state->rf_ramp == NULL)
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
else
dib0090_set_rframp_pwm(state, state->rf_ramp);
rf_ramp = (u16 *)state->rf_ramp;
} else
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090p;
}
} else {
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
}
} else
rf_ramp = (u16 *)&rf_ramp_pwm_cband;
} else
#endif
#ifdef CONFIG_BAND_VHF
if (state->current_band == BAND_VHF) {
if (state->identity.in_soc) {
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
} else {
dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
}
} else
#endif
{
if (state->identity.in_soc) {
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
} else {
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
}
}
if (state->rf_ramp[0] != 0)
dib0090_write_reg(state, 0x32, (3 << 11));
if (state->current_band == BAND_VHF) {
if (state->identity.in_soc) {
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
/* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */
} else
rf_ramp = (u16 *)&rf_ramp_pwm_vhf;
} else if (state->current_band == BAND_UHF) {
if (state->identity.in_soc) {
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
rf_ramp = (u16 *)&rf_ramp_pwm_uhf_8090;
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
rf_ramp = (u16 *)&rf_ramp_pwm_uhf_7090;
} else
rf_ramp = (u16 *)&rf_ramp_pwm_uhf;
}
if (rf_ramp)
dib0090_set_rframp_pwm(state, rf_ramp);
dib0090_set_bbramp_pwm(state, bb_ramp);
/* activate the ramp generator using PWM control */
dprintk("ramp RF gain = %d BAND = %s version = %d", state->rf_ramp[0], (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND", state->identity.version & 0x1f);
if ((state->rf_ramp[0] == 0) || (state->current_band == BAND_CBAND && (state->identity.version & 0x1f) <= P1D_E_F)) {
dprintk("DE-Engage mux for direct gain reg control");
en_pwm_rf_mux = 0;
} else
dprintk("Engage mux for PWM control");
dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
/* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/
if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
dib0090_write_reg(state, 0x04, 3);
else
dib0090_write_reg(state, 0x32, (0 << 11));
dib0090_write_reg(state, 0x04, 0x03);
dib0090_write_reg(state, 0x39, (1 << 10));
dib0090_write_reg(state, 0x04, 1);
dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
}
}
EXPORT_SYMBOL(dib0090_pwm_gain_reset);
void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
@ -1193,22 +1173,22 @@ int dib0090_gain_control(struct dvb_frontend *fe)
#endif
#ifdef CONFIG_BAND_VHF
if (state->current_band == BAND_VHF && !state->identity.p1g) {
dib0090_set_rframp(state, rf_ramp_vhf);
dib0090_set_bbramp(state, bb_ramp_boost);
dib0090_set_rframp(state, rf_ramp_pwm_vhf);
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
} else
#endif
#ifdef CONFIG_BAND_CBAND
if (state->current_band == BAND_CBAND && !state->identity.p1g) {
dib0090_set_rframp(state, rf_ramp_cband);
dib0090_set_bbramp(state, bb_ramp_boost);
dib0090_set_rframp(state, rf_ramp_pwm_cband);
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
} else
#endif
if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
dib0090_set_bbramp(state, bb_ramp_boost);
dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
} else {
dib0090_set_rframp(state, rf_ramp_uhf);
dib0090_set_bbramp(state, bb_ramp_boost);
dib0090_set_rframp(state, rf_ramp_pwm_uhf);
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
}
dib0090_write_reg(state, 0x32, 0);
@ -1553,14 +1533,16 @@ static void dib0090_set_EFUSE(struct dib0090_state *state)
if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
c = 32;
else
c += 14;
if ((h >= HR_MAX) || (h <= HR_MIN))
h = 34;
if ((n >= POLY_MAX) || (n <= POLY_MIN))
n = 3;
dib0090_write_reg(state, 0x13, (h << 10)) ;
e2 = (n<<11) | ((h>>2)<<6) | (c);
dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
dib0090_write_reg(state, 0x13, (h << 10));
e2 = (n << 11) | ((h >> 2)<<6) | c;
dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
}
}

View File

@ -13,6 +13,8 @@
#ifndef DIB3000MC_H
#define DIB3000MC_H
#include <linux/kconfig.h>
#include "dibx000_common.h"
struct dib3000mc_config {
@ -39,8 +41,7 @@ struct dib3000mc_config {
#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
#define DEFAULT_DIB3000P_I2C_ADDRESS 24
#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DIB3000MC)
extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
u8 i2c_addr,
struct dib3000mc_config *cfg);

View File

@ -1,6 +1,8 @@
#ifndef DIB7000M_H
#define DIB7000M_H
#include <linux/kconfig.h>
#include "dibx000_common.h"
struct dib7000m_config {
@ -38,8 +40,7 @@ struct dib7000m_config {
#define DEFAULT_DIB7000M_I2C_ADDRESS 18
#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DIB7000M)
extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
u8 i2c_addr,
struct dib7000m_config *cfg);

View File

@ -429,6 +429,13 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe,
}
EXPORT_SYMBOL(dib7000p_get_agc_values);
int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
struct dib7000p_state *state = fe->demodulator_priv;
return dib7000p_write_word(state, 108, v);
}
EXPORT_SYMBOL(dib7000p_set_agc1_min);
static void dib7000p_reset_pll(struct dib7000p_state *state)
{
struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
@ -821,6 +828,7 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
u8 agc_split;
u16 reg;
u32 upd_demod_gain_period = 0x1000;
s32 frequency_offset = 0;
switch (state->agc_state) {
case 0:
@ -841,7 +849,14 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
return -1;
dib7000p_set_dds(state, 0);
if (demod->ops.tuner_ops.get_frequency) {
u32 frequency_tuner;
demod->ops.tuner_ops.get_frequency(demod, &frequency_tuner);
frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
}
dib7000p_set_dds(state, frequency_offset);
ret = 7;
(*agc_state)++;
break;

View File

@ -1,6 +1,8 @@
#ifndef DIB7000P_H
#define DIB7000P_H
#include <linux/kconfig.h>
#include "dibx000_common.h"
struct dib7000p_config {
@ -44,8 +46,7 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DIB7000P)
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
@ -62,6 +63,7 @@ extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
extern int dib7090_slave_reset(struct dvb_frontend *fe);
extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
extern int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v);
#else
static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
{
@ -153,6 +155,12 @@ static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,8 @@ struct dib8000_config {
u8 output_mode;
u8 refclksel;
u8 enMpegOutput:1;
struct dibx000_bandwidth_config *plltable;
};
#define DEFAULT_DIB8000_I2C_ADDRESS 18
@ -58,7 +60,7 @@ extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
uint8_t op, uint32_t timf);
extern int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll);
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
@ -147,7 +149,7 @@ static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
return 0;
}
static inline int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll)
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;

View File

@ -193,7 +193,8 @@ enum frontend_tune_state {
CT_DEMOD_STEP_8,
CT_DEMOD_STEP_9,
CT_DEMOD_STEP_10,
CT_DEMOD_SEARCH_NEXT = 41,
CT_DEMOD_STEP_11,
CT_DEMOD_SEARCH_NEXT = 51,
CT_DEMOD_STEP_LOCKED,
CT_DEMOD_STOP,

View File

@ -24,6 +24,7 @@
#ifndef _DRXD_H_
#define _DRXD_H_
#include <linux/kconfig.h>
#include <linux/types.h>
#include <linux/i2c.h>
@ -51,8 +52,7 @@ struct drxd_config {
s16(*osc_deviation) (void *priv, s16 dev, int flag);
};
#if defined(CONFIG_DVB_DRXD) || \
(defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DRXD)
extern
struct dvb_frontend *drxd_attach(const struct drxd_config *config,
void *priv, struct i2c_adapter *i2c,

View File

@ -1,6 +1,7 @@
#ifndef _DRXK_H_
#define _DRXK_H_
#include <linux/kconfig.h>
#include <linux/types.h>
#include <linux/i2c.h>
@ -52,8 +53,7 @@ struct drxk_config {
int qam_demod_parameter_count;
};
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
&& defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DRXK)
extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -1947,8 +1947,7 @@ static int ShutDown(struct drxk_state *state)
return 0;
}
static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
u32 Time)
static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
{
int status = -EINVAL;
@ -2490,32 +2489,6 @@ static int SetAgcIf(struct drxk_state *state,
return status;
}
static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
{
u16 agcDacLvl;
int status;
u16 Level = 0;
dprintk(1, "\n");
status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
if (status < 0) {
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
return status;
}
*pValue = 0;
if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
if (Level < 14000)
*pValue = (14000 - Level) / 4;
else
*pValue = 0;
return status;
}
static int GetQAMSignalToNoise(struct drxk_state *state,
s32 *pSignalToNoise)
{
@ -2654,12 +2627,7 @@ static int GetDVBTSignalToNoise(struct drxk_state *state,
/* log(x) x = (16bits + 16bits) << 15 ->32 bits */
c = Log10Times100(SqrErrIQ);
iMER = a + b;
/* No negative MER, clip to zero */
if (iMER > c)
iMER -= c;
else
iMER = 0;
iMER = a + b - c;
}
*pSignalToNoise = iMER;
@ -6380,46 +6348,257 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Start(state, 0, IF);
/* After set_frontend, stats aren't avaliable */
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
return 0;
}
static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
static int get_strength(struct drxk_state *state, u64 *strength)
{
struct drxk_state *state = fe->demodulator_priv;
u32 stat;
int status;
struct SCfgAgc rfAgc, ifAgc;
u32 totalGain = 0;
u32 atten = 0;
u32 agcRange = 0;
u16 scu_lvl = 0;
u16 scu_coc = 0;
/* FIXME: those are part of the tuner presets */
u16 tunerRfGain = 50; /* Default value on az6007 driver */
u16 tunerIfGain = 40; /* Default value on az6007 driver */
dprintk(1, "\n");
*strength = 0;
if (state->m_DrxkState == DRXK_NO_DEV)
return -ENODEV;
if (state->m_DrxkState == DRXK_UNINITIALIZED)
return -EAGAIN;
if (IsDVBT(state)) {
rfAgc = state->m_dvbtRfAgcCfg;
ifAgc = state->m_dvbtIfAgcCfg;
} else if (IsQAM(state)) {
rfAgc = state->m_qamRfAgcCfg;
ifAgc = state->m_qamIfAgcCfg;
} else {
rfAgc = state->m_atvRfAgcCfg;
ifAgc = state->m_atvIfAgcCfg;
}
if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
/* SCU outputLevel */
status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
if (status < 0)
return status;
/* SCU c.o.c. */
read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
if (status < 0)
return status;
if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
rfAgc.outputLevel = scu_lvl + scu_coc;
else
rfAgc.outputLevel = 0xffff;
/* Take RF gain into account */
totalGain += tunerRfGain;
/* clip output value */
if (rfAgc.outputLevel < rfAgc.minOutputLevel)
rfAgc.outputLevel = rfAgc.minOutputLevel;
if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
rfAgc.outputLevel = rfAgc.maxOutputLevel;
agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
if (agcRange > 0) {
atten += 100UL *
((u32)(tunerRfGain)) *
((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
/ agcRange;
}
}
if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
&ifAgc.outputLevel);
if (status < 0)
return status;
status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
&ifAgc.top);
if (status < 0)
return status;
/* Take IF gain into account */
totalGain += (u32) tunerIfGain;
/* clip output value */
if (ifAgc.outputLevel < ifAgc.minOutputLevel)
ifAgc.outputLevel = ifAgc.minOutputLevel;
if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
ifAgc.outputLevel = ifAgc.maxOutputLevel;
agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
if (agcRange > 0) {
atten += 100UL *
((u32)(tunerIfGain)) *
((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
/ agcRange;
}
}
/*
* Convert to 0..65535 scale.
* If it can't be measured (AGC is disabled), just show 100%.
*/
if (totalGain > 0)
*strength = (65535UL * atten / totalGain / 100);
else
*strength = 65535;
*status = 0;
GetLockStatus(state, &stat, 0);
if (stat == MPEG_LOCK)
*status |= 0x1f;
if (stat == FEC_LOCK)
*status |= 0x0f;
if (stat == DEMOD_LOCK)
*status |= 0x07;
return 0;
}
static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
static int drxk_get_stats(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct drxk_state *state = fe->demodulator_priv;
dprintk(1, "\n");
int status;
u32 stat;
u16 reg16;
u32 post_bit_count;
u32 post_bit_err_count;
u32 post_bit_error_scale;
u32 pre_bit_err_count;
u32 pre_bit_count;
u32 pkt_count;
u32 pkt_error_count;
s32 cnr;
if (state->m_DrxkState == DRXK_NO_DEV)
return -ENODEV;
if (state->m_DrxkState == DRXK_UNINITIALIZED)
return -EAGAIN;
*ber = 0;
/* get status */
state->fe_status = 0;
GetLockStatus(state, &stat);
if (stat == MPEG_LOCK)
state->fe_status |= 0x1f;
if (stat == FEC_LOCK)
state->fe_status |= 0x0f;
if (stat == DEMOD_LOCK)
state->fe_status |= 0x07;
/*
* Estimate signal strength from AGC
*/
get_strength(state, &c->strength.stat[0].uvalue);
c->strength.stat[0].scale = FE_SCALE_RELATIVE;
if (stat >= DEMOD_LOCK) {
GetSignalToNoise(state, &cnr);
c->cnr.stat[0].svalue = cnr * 100;
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
} else {
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
}
if (stat < FEC_LOCK) {
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
}
/* Get post BER */
/* BER measurement is valid if at least FEC lock is achieved */
/* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
to set nr of symbols or bits over which
to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
/* Read registers for post/preViterbi BER calculation */
status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
if (status < 0)
goto error;
pre_bit_err_count = reg16;
status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , &reg16);
if (status < 0)
goto error;
pre_bit_count = reg16;
/* Number of bit-errors */
status = read16(state, FEC_RS_NR_BIT_ERRORS__A, &reg16);
if (status < 0)
goto error;
post_bit_err_count = reg16;
status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, &reg16);
if (status < 0)
goto error;
post_bit_error_scale = reg16;
status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, &reg16);
if (status < 0)
goto error;
pkt_count = reg16;
status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &reg16);
if (status < 0)
goto error;
pkt_error_count = reg16;
write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
post_bit_err_count *= post_bit_error_scale;
post_bit_count = pkt_count * 204 * 8;
/* Store the results */
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue += pkt_error_count;
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
c->block_count.stat[0].uvalue += pkt_count;
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_count.stat[0].uvalue += pre_bit_count;
c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_error.stat[0].uvalue += post_bit_err_count;
c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_count.stat[0].uvalue += post_bit_count;
error:
return status;
}
static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct drxk_state *state = fe->demodulator_priv;
int rc;
dprintk(1, "\n");
rc = drxk_get_stats(fe);
if (rc < 0)
return rc;
*status = state->fe_status;
return 0;
}
@ -6427,7 +6606,7 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
struct drxk_state *state = fe->demodulator_priv;
u32 val = 0;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
dprintk(1, "\n");
@ -6436,8 +6615,7 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe,
if (state->m_DrxkState == DRXK_UNINITIALIZED)
return -EAGAIN;
ReadIFAgc(state, &val);
*strength = val & 0xffff;
*strength = c->strength.stat[0].uvalue;
return 0;
}
@ -6454,6 +6632,10 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
return -EAGAIN;
GetSignalToNoise(state, &snr2);
/* No negative SNR, clip to zero */
if (snr2 < 0)
snr2 = 0;
*snr = snr2 & 0xffff;
return 0;
}
@ -6529,7 +6711,6 @@ static struct dvb_frontend_ops drxk_ops = {
.get_tune_settings = drxk_get_tune_settings,
.read_status = drxk_read_status,
.read_ber = drxk_read_ber,
.read_signal_strength = drxk_read_signal_strength,
.read_snr = drxk_read_snr,
.read_ucblocks = drxk_read_ucblocks,
@ -6538,6 +6719,7 @@ static struct dvb_frontend_ops drxk_ops = {
struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c)
{
struct dtv_frontend_properties *p;
struct drxk_state *state = NULL;
u8 adr = config->adr;
int status;
@ -6618,6 +6800,27 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
} else if (init_drxk(state) < 0)
goto error;
/* Initialize stats */
p = &state->frontend.dtv_property_cache;
p->strength.len = 1;
p->cnr.len = 1;
p->block_error.len = 1;
p->block_count.len = 1;
p->pre_bit_error.len = 1;
p->pre_bit_count.len = 1;
p->post_bit_error.len = 1;
p->post_bit_count.len = 1;
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
printk(KERN_INFO "drxk: frontend initialized.\n");
return &state->frontend;

View File

@ -345,6 +345,8 @@ struct drxk_state {
bool antenna_dvbt;
u16 antenna_gpio;
fe_status_t fe_status;
/* Firmware */
const char *microcode_name;
struct completion fw_wait_load;

View File

@ -10,6 +10,7 @@
#define FEC_RS_COMM_EXEC_STOP 0x0
#define FEC_RS_MEASUREMENT_PERIOD__A 0x1C30012
#define FEC_RS_MEASUREMENT_PRESCALE__A 0x1C30013
#define FEC_RS_NR_BIT_ERRORS__A 0x1C30014
#define FEC_OC_MODE__A 0x1C40011
#define FEC_OC_MODE_PARITY__M 0x1
#define FEC_OC_DTO_MODE__A 0x1C40014
@ -129,6 +130,8 @@
#define OFDM_EC_SB_PRIOR__A 0x3410013
#define OFDM_EC_SB_PRIOR_HI 0x0
#define OFDM_EC_SB_PRIOR_LO 0x1
#define OFDM_EC_VD_ERR_BIT_CNT__A 0x3420017
#define OFDM_EC_VD_IN_BIT_CNT__A 0x3420018
#define OFDM_EQ_TOP_TD_TPS_CONST__A 0x3010054
#define OFDM_EQ_TOP_TD_TPS_CONST__M 0x3
#define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2

View File

@ -22,6 +22,7 @@
#ifndef DS3000_H
#define DS3000_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct ds3000_config {
@ -34,8 +35,7 @@ struct ds3000_config {
void (*set_lock_led)(struct dvb_frontend *fe, int offon);
};
#if defined(CONFIG_DVB_DS3000) || \
(defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DS3000)
extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -22,11 +22,11 @@
#ifndef DVB_DUMMY_FE_H
#define DVB_DUMMY_FE_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_DUMMY_FE)
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);

View File

@ -22,6 +22,7 @@
#ifndef EC100_H
#define EC100_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct ec100_config {
@ -30,8 +31,7 @@ struct ec100_config {
};
#if defined(CONFIG_DVB_EC100) || \
(defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_EC100)
extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -23,6 +23,7 @@
#ifndef HD29L2_H
#define HD29L2_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct hd29l2_config {
@ -50,8 +51,7 @@ struct hd29l2_config {
};
#if defined(CONFIG_DVB_HD29L2) || \
(defined(CONFIG_DVB_HD29L2_MODULE) && defined(MODULE))
#if IS_ENABLED(CONFIG_DVB_HD29L2)
extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
struct i2c_adapter *i2c);
#else

View File

@ -89,6 +89,30 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
}
static int isl6421_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
.buf = &isl6421->config,
.len = sizeof(isl6421->config) };
switch (tone) {
case SEC_TONE_ON:
isl6421->config |= ISL6421_ENT1;
break;
case SEC_TONE_OFF:
isl6421->config &= ~ISL6421_ENT1;
break;
default:
return -EINVAL;
}
isl6421->config |= isl6421->override_or;
isl6421->config &= isl6421->override_and;
return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
}
static void isl6421_release(struct dvb_frontend *fe)
{
/* power off */
@ -100,7 +124,7 @@ static void isl6421_release(struct dvb_frontend *fe)
}
struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear)
u8 override_set, u8 override_clear, bool override_tone)
{
struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
if (!isl6421)
@ -131,6 +155,8 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
/* override frontend ops */
fe->ops.set_voltage = isl6421_set_voltage;
fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
if (override_tone)
fe->ops.set_tone = isl6421_set_tone;
return fe;
}

View File

@ -42,10 +42,10 @@
#if IS_ENABLED(CONFIG_DVB_ISL6421)
/* override_set and override_clear control which system register bits (above) to always set & clear */
extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear);
u8 override_set, u8 override_clear, bool override_tone);
#else
static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear)
u8 override_set, u8 override_clear, bool override_tone)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;

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